diff options
| -rw-r--r-- | ext/js/data/database.js | 35 | ||||
| -rw-r--r-- | ext/js/language/dictionary-database.js | 43 | 
2 files changed, 61 insertions, 17 deletions
| diff --git a/ext/js/data/database.js b/ext/js/data/database.js index 068f4a5f..f44ea1d9 100644 --- a/ext/js/data/database.js +++ b/ext/js/data/database.js @@ -111,27 +111,32 @@ class Database {          }      } -    find(objectStoreName, indexName, query, predicate=null, defaultValue) { +    find(objectStoreName, indexName, query, predicate, predicateArg, defaultValue) {          return new Promise((resolve, reject) => {              const transaction = this.transaction([objectStoreName], 'readonly');              const objectStore = transaction.objectStore(objectStoreName);              const objectStoreOrIndex = indexName !== null ? objectStore.index(indexName) : objectStore; -            const request = objectStoreOrIndex.openCursor(query, 'next'); -            request.onerror = (e) => reject(e.target.error); -            request.onsuccess = (e) => { -                const cursor = e.target.result; -                if (cursor) { -                    const value = cursor.value; -                    if (typeof predicate !== 'function' || predicate(value)) { -                        resolve(value); -                    } else { -                        cursor.continue(); -                    } +            this.findFirst(objectStoreOrIndex, query, resolve, reject, predicate, predicateArg, defaultValue); +        }); +    } + +    findFirst(objectStoreOrIndex, query, resolve, reject, predicate, predicateArg, defaultValue) { +        const noPredicate = (typeof predicate !== 'function'); +        const request = objectStoreOrIndex.openCursor(query, 'next'); +        request.onerror = (e) => reject(e.target.error); +        request.onsuccess = (e) => { +            const cursor = e.target.result; +            if (cursor) { +                const {value} = cursor; +                if (noPredicate || predicate(value, predicateArg)) { +                    resolve(value);                  } else { -                    resolve(defaultValue); +                    cursor.continue();                  } -            }; -        }); +            } else { +                resolve(defaultValue); +            } +        };      }      bulkCount(targets, resolve, reject) { diff --git a/ext/js/language/dictionary-database.js b/ext/js/language/dictionary-database.js index 62c22289..40f5362b 100644 --- a/ext/js/language/dictionary-database.js +++ b/ext/js/language/dictionary-database.js @@ -294,9 +294,14 @@ class DictionaryDatabase {          return this._findGenericBulk('kanjiMeta', 'character', kanjiList, dictionaries, this._createKanjiMeta.bind(this));      } +    findTagMetaBulk(items) { +        const predicate = (row, item) => (row.dictionary === item.dictionary); +        return this._findFirstBulk('tagMeta', 'name', items, predicate, this._createTagMeta.bind(this)); +    } +      findTagForTitle(name, title) {          const query = IDBKeyRange.only(name); -        return this._db.find('tagMeta', 'name', query, (row) => (row.dictionary === title), null); +        return this._db.find('tagMeta', 'name', query, (row) => (row.dictionary === title), null, null);      }      getMedia(targets) { @@ -393,7 +398,7 @@ class DictionaryDatabase {      async dictionaryExists(title) {          const query = IDBKeyRange.only(title); -        const result = await this._db.find('dictionaries', 'title', query); +        const result = await this._db.find('dictionaries', 'title', query, null, null, void 0);          return typeof result !== 'undefined';      } @@ -437,6 +442,36 @@ class DictionaryDatabase {          });      } +    _findFirstBulk(objectStoreName, indexName, items, predicate, createResult) { +        return new Promise((resolve, reject) => { +            const count = items.length; +            const results = new Array(count); +            if (count === 0) { +                resolve(results); +                return; +            } + +            const transaction = this._db.transaction([objectStoreName], 'readonly'); +            const terms = transaction.objectStore(objectStoreName); +            const index = terms.index(indexName); + +            let completeCount = 0; +            for (let i = 0; i < count; ++i) { +                const itemIndex = i; +                const item = items[i]; +                const query = IDBKeyRange.only(item.query); + +                const onFind = (row) => { +                    results[itemIndex] = createResult(row, itemIndex); +                    if (++completeCount >= count) { +                        resolve(results); +                    } +                }; +                this._db.findFirst(index, query, onFind, reject, predicate, item, void 0); +            } +        }); +    } +      _createTerm(row, index) {          return {              index, @@ -466,6 +501,10 @@ class DictionaryDatabase {          };      } +    _createTagMeta(row, index) { +        return {row, index}; +    } +      _createTermMeta({expression, mode, data, dictionary}, index) {          return {expression, mode, data, dictionary, index};      } |