Move util database modification functions (#499)

* Update onProgress callback to handle multiple arguments

* Add apiImportDictionaryArchive

* Add apiDeleteDictionary

* Make onProgress the last argument for consistency

* Remove deprecated util functions

* Fix issue with missing progress args

* Remove function calls which modify the database from Translator

* Update tests

* Fix errors not being serialized correctly in _createActionListenerPort
This commit is contained in:
toasted-nutbread 2020-05-06 19:28:26 -04:00 committed by GitHub
parent 501281e887
commit 021ccb5ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 52 deletions

View File

@ -117,7 +117,10 @@ class Backend {
['logIndicatorClear', {handler: this._onApiLogIndicatorClear.bind(this), async: false}], ['logIndicatorClear', {handler: this._onApiLogIndicatorClear.bind(this), async: false}],
['createActionPort', {handler: this._onApiCreateActionPort.bind(this), async: false}] ['createActionPort', {handler: this._onApiCreateActionPort.bind(this), async: false}]
]); ]);
this._messageHandlersWithProgress = new Map(); this._messageHandlersWithProgress = new Map([
['importDictionaryArchive', {handler: this._onApiImportDictionaryArchive.bind(this), async: true}],
['deleteDictionary', {handler: this._onApiDeleteDictionary.bind(this), async: true}]
]);
this._commandHandlers = new Map([ this._commandHandlers = new Map([
['search', this._onCommandSearch.bind(this)], ['search', this._onCommandSearch.bind(this)],
@ -771,7 +774,8 @@ class Backend {
async _onApiPurgeDatabase(params, sender) { async _onApiPurgeDatabase(params, sender) {
this._validatePrivilegedMessageSender(sender); this._validatePrivilegedMessageSender(sender);
return await this.translator.purgeDatabase(); this.translator.clearDatabaseCaches();
await this.database.purge();
} }
async _onApiGetMedia({targets}) { async _onApiGetMedia({targets}) {
@ -814,12 +818,23 @@ class Backend {
return portName; return portName;
} }
async _onApiImportDictionaryArchive({archiveContent, details}, sender, onProgress) {
this._validatePrivilegedMessageSender(sender);
return await this.dictionaryImporter.import(this.database, archiveContent, details, onProgress);
}
async _onApiDeleteDictionary({dictionaryName}, sender, onProgress) {
this._validatePrivilegedMessageSender(sender);
this.translator.clearDatabaseCaches();
await this.database.deleteDictionary(dictionaryName, {rate: 1000}, onProgress);
}
// Command handlers // Command handlers
_createActionListenerPort(port, sender, handlers) { _createActionListenerPort(port, sender, handlers) {
let hasStarted = false; let hasStarted = false;
const onProgress = (data) => { const onProgress = (...data) => {
try { try {
if (port === null) { return; } if (port === null) { return; }
port.postMessage({type: 'progress', data}); port.postMessage({type: 'progress', data});
@ -847,7 +862,7 @@ class Backend {
port.postMessage({type: 'complete', data: result}); port.postMessage({type: 'complete', data: result});
} catch (e) { } catch (e) {
if (port !== null) { if (port !== null) {
port.postMessage({type: 'error', data: e}); port.postMessage({type: 'error', data: errorToJson(e)});
} }
cleanup(); cleanup();
} }

View File

@ -129,7 +129,7 @@ class Database {
await this.prepare(); await this.prepare();
} }
async deleteDictionary(dictionaryName, onProgress, progressSettings) { async deleteDictionary(dictionaryName, progressSettings, onProgress) {
this._validate(); this._validate();
const targets = [ const targets = [

View File

@ -27,7 +27,7 @@ class DictionaryImporter {
this._schemas = new Map(); this._schemas = new Map();
} }
async import(database, archiveSource, onProgress, details) { async import(database, archiveSource, details, onProgress) {
if (!database) { if (!database) {
throw new Error('Invalid database'); throw new Error('Invalid database');
} }

View File

@ -17,8 +17,10 @@
/* global /* global
* PageExitPrevention * PageExitPrevention
* apiDeleteDictionary
* apiGetDictionaryCounts * apiGetDictionaryCounts
* apiGetDictionaryInfo * apiGetDictionaryInfo
* apiImportDictionaryArchive
* apiOptionsGet * apiOptionsGet
* apiOptionsGetFull * apiOptionsGetFull
* apiPurgeDatabase * apiPurgeDatabase
@ -29,8 +31,6 @@
* storageEstimate * storageEstimate
* storageUpdateStats * storageUpdateStats
* utilBackgroundIsolate * utilBackgroundIsolate
* utilDatabaseDeleteDictionary
* utilDatabaseImport
*/ */
let dictionaryUI = null; let dictionaryUI = null;
@ -312,7 +312,7 @@ class SettingsDictionaryEntryUI {
progressBar.style.width = `${percent}%`; progressBar.style.width = `${percent}%`;
}; };
await utilDatabaseDeleteDictionary(this.dictionaryInfo.title, onProgress, {rate: 1000}); await apiDeleteDictionary(this.dictionaryInfo.title, onProgress);
} catch (e) { } catch (e) {
dictionaryErrorsShow([e]); dictionaryErrorsShow([e]);
} finally { } finally {
@ -679,7 +679,8 @@ async function onDictionaryImport(e) {
dictImportInfo.textContent = `(${i + 1} of ${ii})`; dictImportInfo.textContent = `(${i + 1} of ${ii})`;
} }
const {result, errors} = await utilDatabaseImport(files[i], updateProgress, importDetails); const archiveContent = await dictReadFile(files[i]);
const {result, errors} = await apiImportDictionaryArchive(archiveContent, importDetails, updateProgress);
for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) { for (const {options} of toIterable((await getOptionsFullMutable()).profiles)) {
const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions(); const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions();
dictionaryOptions.enabled = true; dictionaryOptions.enabled = true;
@ -713,6 +714,15 @@ async function onDictionaryImport(e) {
} }
} }
function dictReadFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
reader.readAsBinaryString(file);
});
}
async function onDatabaseEnablePrefixWildcardSearchesChanged(e) { async function onDatabaseEnablePrefixWildcardSearchesChanged(e) {
const optionsFull = await getOptionsFullMutable(); const optionsFull = await getOptionsFullMutable();

View File

@ -45,14 +45,8 @@ class Translator {
this.deinflector = new Deinflector(reasons); this.deinflector = new Deinflector(reasons);
} }
async purgeDatabase() { clearDatabaseCaches() {
this.tagCache.clear(); this.tagCache.clear();
await this.database.purge();
}
async deleteDictionary(dictionaryName) {
this.tagCache.clear();
await this.database.deleteDictionary(dictionaryName);
} }
async getSequencedDefinitions(definitions, mainDictionary) { async getSequencedDefinitions(definitions, mainDictionary) {

View File

@ -66,31 +66,6 @@ function utilBackend() {
return backend; return backend;
} }
async function utilDatabaseDeleteDictionary(dictionaryName, onProgress) {
return utilIsolate(await utilBackend().translator.database.deleteDictionary(
utilBackgroundIsolate(dictionaryName),
utilBackgroundFunctionIsolate(onProgress)
));
}
async function utilDatabaseImport(data, onProgress, details) {
data = await utilReadFile(data);
return utilIsolate(await utilBackend().importDictionary(
utilBackgroundIsolate(data),
utilBackgroundFunctionIsolate(onProgress),
utilBackgroundIsolate(details)
));
}
function utilReadFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
reader.readAsBinaryString(file);
});
}
function utilReadFileArrayBuffer(file) { function utilReadFileArrayBuffer(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const reader = new FileReader(); const reader = new FileReader();

View File

@ -152,6 +152,14 @@ function apiLogIndicatorClear() {
return _apiInvoke('logIndicatorClear'); return _apiInvoke('logIndicatorClear');
} }
function apiImportDictionaryArchive(archiveContent, details, onProgress) {
return _apiInvokeWithProgress('importDictionaryArchive', {archiveContent, details}, onProgress);
}
function apiDeleteDictionary(dictionaryName, onProgress) {
return _apiInvokeWithProgress('deleteDictionary', {dictionaryName}, onProgress);
}
function _apiCreateActionPort(timeout=5000) { function _apiCreateActionPort(timeout=5000) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let timer = null; let timer = null;
@ -213,7 +221,7 @@ function _apiInvokeWithProgress(action, params, onProgress, timeout=5000) {
break; break;
case 'progress': case 'progress':
try { try {
onProgress(message.data); onProgress(...message.data);
} catch (e) { } catch (e) {
// NOP // NOP
} }

View File

@ -233,10 +233,10 @@ async function testDatabase1() {
let progressEvent = false; let progressEvent = false;
await database.deleteDictionary( await database.deleteDictionary(
title, title,
{rate: 1000},
() => { () => {
progressEvent = true; progressEvent = true;
}, }
{rate: 1000}
); );
assert.ok(progressEvent); assert.ok(progressEvent);
@ -267,10 +267,10 @@ async function testDatabase1() {
const {result, errors} = await dictionaryImporter.import( const {result, errors} = await dictionaryImporter.import(
database, database,
testDictionarySource, testDictionarySource,
{prefixWildcardsSupported: true},
() => { () => {
progressEvent = true; progressEvent = true;
}, }
{prefixWildcardsSupported: true}
); );
vm.assert.deepStrictEqual(errors, []); vm.assert.deepStrictEqual(errors, []);
vm.assert.deepStrictEqual(result, expectedSummary); vm.assert.deepStrictEqual(result, expectedSummary);
@ -908,7 +908,7 @@ async function testDatabase2() {
// Error: not prepared // Error: not prepared
await assert.rejects(async () => await database.purge()); await assert.rejects(async () => await database.purge());
await assert.rejects(async () => await database.deleteDictionary(title, () => {}, {})); await assert.rejects(async () => await database.deleteDictionary(title, {}, () => {}));
await assert.rejects(async () => await database.findTermsBulk(['?'], titles, null)); await assert.rejects(async () => await database.findTermsBulk(['?'], titles, null));
await assert.rejects(async () => await database.findTermsExactBulk(['?'], ['?'], titles)); await assert.rejects(async () => await database.findTermsExactBulk(['?'], ['?'], titles));
await assert.rejects(async () => await database.findTermsBySequenceBulk([1], title)); await assert.rejects(async () => await database.findTermsBySequenceBulk([1], title));
@ -919,17 +919,17 @@ async function testDatabase2() {
await assert.rejects(async () => await database.findTagForTitle('tag', title)); await assert.rejects(async () => await database.findTagForTitle('tag', title));
await assert.rejects(async () => await database.getDictionaryInfo()); await assert.rejects(async () => await database.getDictionaryInfo());
await assert.rejects(async () => await database.getDictionaryCounts(titles, true)); await assert.rejects(async () => await database.getDictionaryCounts(titles, true));
await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, () => {}, {})); await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, {}, () => {}));
await database.prepare(); await database.prepare();
// Error: already prepared // Error: already prepared
await assert.rejects(async () => await database.prepare()); await assert.rejects(async () => await database.prepare());
await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); await dictionaryImporter.import(database, testDictionarySource, {}, () => {});
// Error: dictionary already imported // Error: dictionary already imported
await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, () => {}, {})); await assert.rejects(async () => await dictionaryImporter.import(database, testDictionarySource, {}, () => {}));
await database.close(); await database.close();
} }
@ -956,7 +956,7 @@ async function testDatabase3() {
let error = null; let error = null;
try { try {
await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); await dictionaryImporter.import(database, testDictionarySource, {}, () => {});
} catch (e) { } catch (e) {
error = e; error = e;
} }