From 021ccb5ac3038f63d07ccc9575ee56480031a251 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 6 May 2020 19:28:26 -0400 Subject: [PATCH] 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 --- ext/bg/js/backend.js | 23 +++++++++++++++++++---- ext/bg/js/database.js | 2 +- ext/bg/js/dictionary-importer.js | 2 +- ext/bg/js/settings/dictionaries.js | 18 ++++++++++++++---- ext/bg/js/translator.js | 8 +------- ext/bg/js/util.js | 25 ------------------------- ext/mixed/js/api.js | 10 +++++++++- test/test-database.js | 18 +++++++++--------- 8 files changed, 54 insertions(+), 52 deletions(-) diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index c5173a2e..d454aa22 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -117,7 +117,10 @@ class Backend { ['logIndicatorClear', {handler: this._onApiLogIndicatorClear.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([ ['search', this._onCommandSearch.bind(this)], @@ -771,7 +774,8 @@ class Backend { async _onApiPurgeDatabase(params, sender) { this._validatePrivilegedMessageSender(sender); - return await this.translator.purgeDatabase(); + this.translator.clearDatabaseCaches(); + await this.database.purge(); } async _onApiGetMedia({targets}) { @@ -814,12 +818,23 @@ class Backend { 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 _createActionListenerPort(port, sender, handlers) { let hasStarted = false; - const onProgress = (data) => { + const onProgress = (...data) => { try { if (port === null) { return; } port.postMessage({type: 'progress', data}); @@ -847,7 +862,7 @@ class Backend { port.postMessage({type: 'complete', data: result}); } catch (e) { if (port !== null) { - port.postMessage({type: 'error', data: e}); + port.postMessage({type: 'error', data: errorToJson(e)}); } cleanup(); } diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index a94aa720..930cd0d0 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -129,7 +129,7 @@ class Database { await this.prepare(); } - async deleteDictionary(dictionaryName, onProgress, progressSettings) { + async deleteDictionary(dictionaryName, progressSettings, onProgress) { this._validate(); const targets = [ diff --git a/ext/bg/js/dictionary-importer.js b/ext/bg/js/dictionary-importer.js index 3727f7ee..10e30cec 100644 --- a/ext/bg/js/dictionary-importer.js +++ b/ext/bg/js/dictionary-importer.js @@ -27,7 +27,7 @@ class DictionaryImporter { this._schemas = new Map(); } - async import(database, archiveSource, onProgress, details) { + async import(database, archiveSource, details, onProgress) { if (!database) { throw new Error('Invalid database'); } diff --git a/ext/bg/js/settings/dictionaries.js b/ext/bg/js/settings/dictionaries.js index 50add4c7..632c01ea 100644 --- a/ext/bg/js/settings/dictionaries.js +++ b/ext/bg/js/settings/dictionaries.js @@ -17,8 +17,10 @@ /* global * PageExitPrevention + * apiDeleteDictionary * apiGetDictionaryCounts * apiGetDictionaryInfo + * apiImportDictionaryArchive * apiOptionsGet * apiOptionsGetFull * apiPurgeDatabase @@ -29,8 +31,6 @@ * storageEstimate * storageUpdateStats * utilBackgroundIsolate - * utilDatabaseDeleteDictionary - * utilDatabaseImport */ let dictionaryUI = null; @@ -312,7 +312,7 @@ class SettingsDictionaryEntryUI { progressBar.style.width = `${percent}%`; }; - await utilDatabaseDeleteDictionary(this.dictionaryInfo.title, onProgress, {rate: 1000}); + await apiDeleteDictionary(this.dictionaryInfo.title, onProgress); } catch (e) { dictionaryErrorsShow([e]); } finally { @@ -679,7 +679,8 @@ async function onDictionaryImport(e) { 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)) { const dictionaryOptions = SettingsDictionaryListUI.createDictionaryOptions(); 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) { const optionsFull = await getOptionsFullMutable(); diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 8708e4d8..3fd329d1 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -45,14 +45,8 @@ class Translator { this.deinflector = new Deinflector(reasons); } - async purgeDatabase() { + clearDatabaseCaches() { this.tagCache.clear(); - await this.database.purge(); - } - - async deleteDictionary(dictionaryName) { - this.tagCache.clear(); - await this.database.deleteDictionary(dictionaryName); } async getSequencedDefinitions(definitions, mainDictionary) { diff --git a/ext/bg/js/util.js b/ext/bg/js/util.js index d2fb0e49..8f86e47a 100644 --- a/ext/bg/js/util.js +++ b/ext/bg/js/util.js @@ -66,31 +66,6 @@ function utilBackend() { 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) { return new Promise((resolve, reject) => { const reader = new FileReader(); diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index ca4bdd6c..af97ac3d 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -152,6 +152,14 @@ function apiLogIndicatorClear() { 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) { return new Promise((resolve, reject) => { let timer = null; @@ -213,7 +221,7 @@ function _apiInvokeWithProgress(action, params, onProgress, timeout=5000) { break; case 'progress': try { - onProgress(message.data); + onProgress(...message.data); } catch (e) { // NOP } diff --git a/test/test-database.js b/test/test-database.js index 3684051b..e8a4a343 100644 --- a/test/test-database.js +++ b/test/test-database.js @@ -233,10 +233,10 @@ async function testDatabase1() { let progressEvent = false; await database.deleteDictionary( title, + {rate: 1000}, () => { progressEvent = true; - }, - {rate: 1000} + } ); assert.ok(progressEvent); @@ -267,10 +267,10 @@ async function testDatabase1() { const {result, errors} = await dictionaryImporter.import( database, testDictionarySource, + {prefixWildcardsSupported: true}, () => { progressEvent = true; - }, - {prefixWildcardsSupported: true} + } ); vm.assert.deepStrictEqual(errors, []); vm.assert.deepStrictEqual(result, expectedSummary); @@ -908,7 +908,7 @@ async function testDatabase2() { // Error: not prepared 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.findTermsExactBulk(['?'], ['?'], titles)); 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.getDictionaryInfo()); 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(); // Error: already prepared await assert.rejects(async () => await database.prepare()); - await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); + await dictionaryImporter.import(database, testDictionarySource, {}, () => {}); // 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(); } @@ -956,7 +956,7 @@ async function testDatabase3() { let error = null; try { - await dictionaryImporter.import(database, testDictionarySource, () => {}, {}); + await dictionaryImporter.import(database, testDictionarySource, {}, () => {}); } catch (e) { error = e; }