diff options
author | Alex Yatskov <alex@foosoft.net> | 2019-10-10 19:50:30 -0700 |
---|---|---|
committer | Alex Yatskov <alex@foosoft.net> | 2019-10-10 19:50:30 -0700 |
commit | 06d7713189be9eb51669d3842b78278371e6cfa4 (patch) | |
tree | e98640dc323c486fb1190280502acbf2fe9d8187 /ext/bg/js/database.js | |
parent | 499239ce94e0480783af93f813c2b4096b495808 (diff) | |
parent | 55b2c1d8f51c658b0457ae8329fb1b0e52f5f799 (diff) |
Merge branch 'master' into testing
Diffstat (limited to 'ext/bg/js/database.js')
-rw-r--r-- | ext/bg/js/database.js | 99 |
1 files changed, 43 insertions, 56 deletions
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index e8214c3c..771a71c9 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -25,7 +25,7 @@ class Database { async prepare() { if (this.db) { - throw 'Database already initialized'; + throw new Error('Database already initialized'); } this.db = new Dexie('dict'); @@ -48,9 +48,7 @@ class Database { } async purge() { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); this.db.close(); await this.db.delete(); @@ -61,9 +59,7 @@ class Database { } async findTerms(term, titles) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.terms.where('expression').equals(term).or('reading').equals(term).each(row => { @@ -80,7 +76,12 @@ class Database { const visited = {}; const results = []; const createResult = Database.createTerm; - const filter = (row) => titles.includes(row.dictionary); + const processRow = (row, index) => { + if (titles.includes(row.dictionary) && !visited.hasOwnProperty(row.id)) { + visited[row.id] = true; + results.push(createResult(row, index)); + } + }; const db = this.db.backendDB(); const dbTransaction = db.transaction(['terms'], 'readonly'); @@ -91,8 +92,8 @@ class Database { for (let i = 0; i < terms.length; ++i) { const only = IDBKeyRange.only(terms[i]); promises.push( - Database.getAll(dbIndex1, only, i, visited, filter, createResult, results), - Database.getAll(dbIndex2, only, i, visited, filter, createResult, results) + Database.getAll(dbIndex1, only, i, processRow), + Database.getAll(dbIndex2, only, i, processRow) ); } @@ -102,9 +103,7 @@ class Database { } async findTermsExact(term, reading, titles) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.terms.where('expression').equals(term).each(row => { @@ -117,9 +116,7 @@ class Database { } async findTermsBySequence(sequence, mainDictionary) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.terms.where('sequence').equals(sequence).each(row => { @@ -132,9 +129,7 @@ class Database { } async findTermMeta(term, titles) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.termMeta.where('expression').equals(term).each(row => { @@ -152,10 +147,13 @@ class Database { async findTermMetaBulk(terms, titles) { const promises = []; - const visited = {}; const results = []; const createResult = Database.createTermMeta; - const filter = (row) => titles.includes(row.dictionary); + const processRow = (row, index) => { + if (titles.includes(row.dictionary)) { + results.push(createResult(row, index)); + } + }; const db = this.db.backendDB(); const dbTransaction = db.transaction(['termMeta'], 'readonly'); @@ -164,7 +162,7 @@ class Database { for (let i = 0; i < terms.length; ++i) { const only = IDBKeyRange.only(terms[i]); - promises.push(Database.getAll(dbIndex, only, i, visited, filter, createResult, results)); + promises.push(Database.getAll(dbIndex, only, i, processRow)); } await Promise.all(promises); @@ -173,9 +171,7 @@ class Database { } async findKanji(kanji, titles) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.kanji.where('character').equals(kanji).each(row => { @@ -196,9 +192,7 @@ class Database { } async findKanjiMeta(kanji, titles) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const results = []; await this.db.kanjiMeta.where('character').equals(kanji).each(row => { @@ -224,9 +218,7 @@ class Database { } async findTagForTitle(name, title) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const cache = (this.tagCache.hasOwnProperty(title) ? this.tagCache[title] : (this.tagCache[title] = {})); @@ -243,17 +235,13 @@ class Database { } async summarize() { - if (this.db) { - return this.db.dictionaries.toArray(); - } else { - throw 'Database not initialized'; - } + this.validate(); + + return this.db.dictionaries.toArray(); } async importDictionary(archive, progressCallback, exceptions) { - if (!this.db) { - throw 'Database not initialized'; - } + this.validate(); const maxTransactionLength = 1000; const bulkAdd = async (table, items, total, current) => { @@ -293,12 +281,12 @@ class Database { const indexDataLoaded = async summary => { if (summary.version > 3) { - throw 'Unsupported dictionary version'; + throw new Error('Unsupported dictionary version'); } const count = await this.db.dictionaries.where('title').equals(summary.title).count(); if (count > 0) { - throw 'Dictionary is already imported'; + throw new Error('Dictionary is already imported'); } await this.db.dictionaries.add(summary); @@ -424,6 +412,12 @@ class Database { ); } + validate() { + if (this.db === null) { + throw new Error('Database not initialized'); + } + } + static async importDictionaryZip( archive, indexDataLoaded, @@ -437,12 +431,12 @@ class Database { const indexFile = zip.files['index.json']; if (!indexFile) { - throw 'No dictionary index found in archive'; + throw new Error('No dictionary index found in archive'); } const index = JSON.parse(await indexFile.async('string')); if (!index.title || !index.revision) { - throw 'Unrecognized dictionary format'; + throw new Error('Unrecognized dictionary format'); } const summary = { @@ -537,39 +531,32 @@ class Database { }; } - static getAll(dbIndex, query, index, visited, filter, createResult, results) { + static getAll(dbIndex, query, context, processRow) { const fn = typeof dbIndex.getAll === 'function' ? Database.getAllFast : Database.getAllUsingCursor; - return fn(dbIndex, query, index, visited, filter, createResult, results); + return fn(dbIndex, query, context, processRow); } - static getAllFast(dbIndex, query, index, visited, filter, createResult, results) { + static getAllFast(dbIndex, query, context, processRow) { return new Promise((resolve, reject) => { const request = dbIndex.getAll(query); request.onerror = (e) => reject(e); request.onsuccess = (e) => { for (const row of e.target.result) { - if (filter(row, index) && !visited.hasOwnProperty(row.id)) { - visited[row.id] = true; - results.push(createResult(row, index)); - } + processRow(row, context); } resolve(); }; }); } - static getAllUsingCursor(dbIndex, query, index, visited, filter, createResult, results) { + static getAllUsingCursor(dbIndex, query, context, processRow) { return new Promise((resolve, reject) => { const request = dbIndex.openCursor(query, 'next'); request.onerror = (e) => reject(e); request.onsuccess = (e) => { const cursor = e.target.result; if (cursor) { - const row = cursor.value; - if (filter(row, index) && !visited.hasOwnProperty(row.id)) { - visited[row.id] = true; - results.push(createResult(row, index)); - } + processRow(cursor.value, context); cursor.continue(); } else { resolve(); |