Dictionary database improvements (#1527)
* Update formatting * Add _findMultiBulk * Update implementation of findTermsBySequenceBulk * Update tests * Generalize query creation * Remove _findGenericBulk * Reduce function creation * Add more bindings * Simplify findTermsExactBulk implementation * Update var names * Update _findMultiBulk to support multiple index queries * Update findTermsBulk * Update getMedia implementation * Pass data arg to getAll and findFirst to avoid having multiple closures
This commit is contained in:
parent
07df1e0117
commit
a52d86a39e
@ -95,11 +95,11 @@ class Database {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll(objectStoreOrIndex, query, resolve, reject) {
|
getAll(objectStoreOrIndex, query, resolve, reject, data) {
|
||||||
if (typeof objectStoreOrIndex.getAll === 'function') {
|
if (typeof objectStoreOrIndex.getAll === 'function') {
|
||||||
this._getAllFast(objectStoreOrIndex, query, resolve, reject);
|
this._getAllFast(objectStoreOrIndex, query, resolve, reject, data);
|
||||||
} else {
|
} else {
|
||||||
this._getAllUsingCursor(objectStoreOrIndex, query, resolve, reject);
|
this._getAllUsingCursor(objectStoreOrIndex, query, resolve, reject, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,25 +116,25 @@ class Database {
|
|||||||
const transaction = this.transaction([objectStoreName], 'readonly');
|
const transaction = this.transaction([objectStoreName], 'readonly');
|
||||||
const objectStore = transaction.objectStore(objectStoreName);
|
const objectStore = transaction.objectStore(objectStoreName);
|
||||||
const objectStoreOrIndex = indexName !== null ? objectStore.index(indexName) : objectStore;
|
const objectStoreOrIndex = indexName !== null ? objectStore.index(indexName) : objectStore;
|
||||||
this.findFirst(objectStoreOrIndex, query, resolve, reject, predicate, predicateArg, defaultValue);
|
this.findFirst(objectStoreOrIndex, query, resolve, reject, null, predicate, predicateArg, defaultValue);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
findFirst(objectStoreOrIndex, query, resolve, reject, predicate, predicateArg, defaultValue) {
|
findFirst(objectStoreOrIndex, query, resolve, reject, data, predicate, predicateArg, defaultValue) {
|
||||||
const noPredicate = (typeof predicate !== 'function');
|
const noPredicate = (typeof predicate !== 'function');
|
||||||
const request = objectStoreOrIndex.openCursor(query, 'next');
|
const request = objectStoreOrIndex.openCursor(query, 'next');
|
||||||
request.onerror = (e) => reject(e.target.error);
|
request.onerror = (e) => reject(e.target.error, data);
|
||||||
request.onsuccess = (e) => {
|
request.onsuccess = (e) => {
|
||||||
const cursor = e.target.result;
|
const cursor = e.target.result;
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
const {value} = cursor;
|
const {value} = cursor;
|
||||||
if (noPredicate || predicate(value, predicateArg)) {
|
if (noPredicate || predicate(value, predicateArg)) {
|
||||||
resolve(value);
|
resolve(value, data);
|
||||||
} else {
|
} else {
|
||||||
cursor.continue();
|
cursor.continue();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resolve(defaultValue);
|
resolve(defaultValue, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -256,23 +256,23 @@ class Database {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getAllFast(objectStoreOrIndex, query, resolve, reject) {
|
_getAllFast(objectStoreOrIndex, query, resolve, reject, data) {
|
||||||
const request = objectStoreOrIndex.getAll(query);
|
const request = objectStoreOrIndex.getAll(query);
|
||||||
request.onerror = (e) => reject(e.target.error);
|
request.onerror = (e) => reject(e.target.error, data);
|
||||||
request.onsuccess = (e) => resolve(e.target.result);
|
request.onsuccess = (e) => resolve(e.target.result, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getAllUsingCursor(objectStoreOrIndex, query, resolve, reject) {
|
_getAllUsingCursor(objectStoreOrIndex, query, resolve, reject, data) {
|
||||||
const results = [];
|
const results = [];
|
||||||
const request = objectStoreOrIndex.openCursor(query, 'next');
|
const request = objectStoreOrIndex.openCursor(query, 'next');
|
||||||
request.onerror = (e) => reject(e.target.error);
|
request.onerror = (e) => reject(e.target.error, data);
|
||||||
request.onsuccess = (e) => {
|
request.onsuccess = (e) => {
|
||||||
const cursor = e.target.result;
|
const cursor = e.target.result;
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
results.push(cursor.value);
|
results.push(cursor.value);
|
||||||
cursor.continue();
|
cursor.continue();
|
||||||
} else {
|
} else {
|
||||||
resolve(results);
|
resolve(results, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,17 @@ class DictionaryDatabase {
|
|||||||
this._db = new Database();
|
this._db = new Database();
|
||||||
this._dbName = 'dict';
|
this._dbName = 'dict';
|
||||||
this._schemas = new Map();
|
this._schemas = new Map();
|
||||||
|
this._createOnlyQuery1 = (item) => IDBKeyRange.only(item);
|
||||||
|
this._createOnlyQuery2 = (item) => IDBKeyRange.only(item.query);
|
||||||
|
this._createOnlyQuery3 = (item) => IDBKeyRange.only(item.expression);
|
||||||
|
this._createOnlyQuery4 = (item) => IDBKeyRange.only(item.path);
|
||||||
|
this._createBoundQuery1 = (item) => IDBKeyRange.bound(item, `${item}\uffff`, false, false);
|
||||||
|
this._createBoundQuery2 = (item) => { item = stringReverse(item); return IDBKeyRange.bound(item, `${item}\uffff`, false, false); };
|
||||||
|
this._createTermBind = this._createTerm.bind(this);
|
||||||
|
this._createTermMetaBind = this._createTermMeta.bind(this);
|
||||||
|
this._createKanjiBind = this._createKanji.bind(this);
|
||||||
|
this._createKanjiMetaBind = this._createKanjiMeta.bind(this);
|
||||||
|
this._createMediaBind = this._createMedia.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public
|
// Public
|
||||||
@ -171,132 +182,61 @@ class DictionaryDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findTermsBulk(termList, dictionaries, wildcard) {
|
findTermsBulk(termList, dictionaries, wildcard) {
|
||||||
return new Promise((resolve, reject) => {
|
const visited = new Set();
|
||||||
const results = [];
|
const predicate = (row) => {
|
||||||
const count = termList.length;
|
if (!dictionaries.has(row.dictionary)) { return false; }
|
||||||
if (count === 0) {
|
const {id} = row;
|
||||||
resolve(results);
|
if (visited.has(id)) { return false; }
|
||||||
return;
|
visited.add(id);
|
||||||
}
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const visited = new Set();
|
const indexNames = (wildcard === 'prefix') ? ['expressionReverse', 'readingReverse'] : ['expression', 'reading'];
|
||||||
const useWildcard = !!wildcard;
|
|
||||||
const prefixWildcard = wildcard === 'prefix';
|
|
||||||
|
|
||||||
const transaction = this._db.transaction(['terms'], 'readonly');
|
let createQuery;
|
||||||
const terms = transaction.objectStore('terms');
|
switch (wildcard) {
|
||||||
const index1 = terms.index(prefixWildcard ? 'expressionReverse' : 'expression');
|
case 'suffix':
|
||||||
const index2 = terms.index(prefixWildcard ? 'readingReverse' : 'reading');
|
createQuery = this._createBoundQuery1;
|
||||||
|
break;
|
||||||
|
case 'prefix':
|
||||||
|
createQuery = this._createBoundQuery2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
createQuery = this._createOnlyQuery1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const count2 = count * 2;
|
return this._findMultiBulk('terms', indexNames, termList, createQuery, predicate, this._createTermBind);
|
||||||
let completeCount = 0;
|
|
||||||
for (let i = 0; i < count; ++i) {
|
|
||||||
const inputIndex = i;
|
|
||||||
const term = prefixWildcard ? stringReverse(termList[i]) : termList[i];
|
|
||||||
const query = useWildcard ? IDBKeyRange.bound(term, `${term}\uffff`, false, false) : IDBKeyRange.only(term);
|
|
||||||
|
|
||||||
const onGetAll = (rows) => {
|
|
||||||
for (const row of rows) {
|
|
||||||
if (dictionaries.has(row.dictionary) && !visited.has(row.id)) {
|
|
||||||
visited.add(row.id);
|
|
||||||
results.push(this._createTerm(row, inputIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (++completeCount >= count2) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._db.getAll(index1, query, onGetAll, reject);
|
|
||||||
this._db.getAll(index2, query, onGetAll, reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findTermsExactBulk(termList, readingList, dictionaries) {
|
findTermsExactBulk(termList, dictionaries) {
|
||||||
return new Promise((resolve, reject) => {
|
const predicate = (row, item) => (row.reading === item.reading && dictionaries.has(row.dictionary));
|
||||||
const results = [];
|
return this._findMultiBulk('terms', ['expression'], termList, this._createOnlyQuery3, predicate, this._createTermBind);
|
||||||
const count = termList.length;
|
|
||||||
if (count === 0) {
|
|
||||||
resolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const transaction = this._db.transaction(['terms'], 'readonly');
|
|
||||||
const terms = transaction.objectStore('terms');
|
|
||||||
const index = terms.index('expression');
|
|
||||||
|
|
||||||
let completeCount = 0;
|
|
||||||
for (let i = 0; i < count; ++i) {
|
|
||||||
const inputIndex = i;
|
|
||||||
const reading = readingList[i];
|
|
||||||
const query = IDBKeyRange.only(termList[i]);
|
|
||||||
|
|
||||||
const onGetAll = (rows) => {
|
|
||||||
for (const row of rows) {
|
|
||||||
if (row.reading === reading && dictionaries.has(row.dictionary)) {
|
|
||||||
results.push(this._createTerm(row, inputIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (++completeCount >= count) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._db.getAll(index, query, onGetAll, reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findTermsBySequenceBulk(sequenceList, mainDictionary) {
|
findTermsBySequenceBulk(items) {
|
||||||
return new Promise((resolve, reject) => {
|
const predicate = (row, item) => (row.dictionary === item.dictionary);
|
||||||
const results = [];
|
return this._findMultiBulk('terms', ['sequence'], items, this._createOnlyQuery2, predicate, this._createTermBind);
|
||||||
const count = sequenceList.length;
|
|
||||||
if (count === 0) {
|
|
||||||
resolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const transaction = this._db.transaction(['terms'], 'readonly');
|
|
||||||
const terms = transaction.objectStore('terms');
|
|
||||||
const index = terms.index('sequence');
|
|
||||||
|
|
||||||
let completeCount = 0;
|
|
||||||
for (let i = 0; i < count; ++i) {
|
|
||||||
const inputIndex = i;
|
|
||||||
const query = IDBKeyRange.only(sequenceList[i]);
|
|
||||||
|
|
||||||
const onGetAll = (rows) => {
|
|
||||||
for (const row of rows) {
|
|
||||||
if (row.dictionary === mainDictionary) {
|
|
||||||
results.push(this._createTerm(row, inputIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (++completeCount >= count) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._db.getAll(index, query, onGetAll, reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findTermMetaBulk(termList, dictionaries) {
|
findTermMetaBulk(termList, dictionaries) {
|
||||||
return this._findGenericBulk('termMeta', 'expression', termList, dictionaries, this._createTermMeta.bind(this));
|
const predicate = (row) => dictionaries.has(row.dictionary);
|
||||||
|
return this._findMultiBulk('termMeta', ['expression'], termList, this._createOnlyQuery1, predicate, this._createTermMetaBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
findKanjiBulk(kanjiList, dictionaries) {
|
findKanjiBulk(kanjiList, dictionaries) {
|
||||||
return this._findGenericBulk('kanji', 'character', kanjiList, dictionaries, this._createKanji.bind(this));
|
const predicate = (row) => dictionaries.has(row.dictionary);
|
||||||
|
return this._findMultiBulk('kanji', ['character'], kanjiList, this._createOnlyQuery1, predicate, this._createKanjiBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
findKanjiMetaBulk(kanjiList, dictionaries) {
|
findKanjiMetaBulk(kanjiList, dictionaries) {
|
||||||
return this._findGenericBulk('kanjiMeta', 'character', kanjiList, dictionaries, this._createKanjiMeta.bind(this));
|
const predicate = (row) => dictionaries.has(row.dictionary);
|
||||||
|
return this._findMultiBulk('kanjiMeta', ['character'], kanjiList, this._createOnlyQuery1, predicate, this._createKanjiMetaBind);
|
||||||
}
|
}
|
||||||
|
|
||||||
findTagMetaBulk(items) {
|
findTagMetaBulk(items) {
|
||||||
const predicate = (row, item) => (row.dictionary === item.dictionary);
|
const predicate = (row, item) => (row.dictionary === item.dictionary);
|
||||||
return this._findFirstBulk('tagMeta', 'name', items, predicate);
|
return this._findFirstBulk('tagMeta', 'name', items, this._createOnlyQuery2, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
findTagForTitle(name, title) {
|
findTagForTitle(name, title) {
|
||||||
@ -304,38 +244,9 @@ class DictionaryDatabase {
|
|||||||
return this._db.find('tagMeta', 'name', query, (row) => (row.dictionary === title), null, null);
|
return this._db.find('tagMeta', 'name', query, (row) => (row.dictionary === title), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMedia(targets) {
|
getMedia(items) {
|
||||||
return new Promise((resolve, reject) => {
|
const predicate = (row, item) => (row.dictionary === item.dictionary);
|
||||||
const count = targets.length;
|
return this._findMultiBulk('media', ['path'], items, this._createOnlyQuery4, predicate, this._createMediaBind);
|
||||||
const results = new Array(count).fill(null);
|
|
||||||
if (count === 0) {
|
|
||||||
resolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let completeCount = 0;
|
|
||||||
const transaction = this._db.transaction(['media'], 'readonly');
|
|
||||||
const objectStore = transaction.objectStore('media');
|
|
||||||
const index = objectStore.index('path');
|
|
||||||
|
|
||||||
for (let i = 0; i < count; ++i) {
|
|
||||||
const inputIndex = i;
|
|
||||||
const {path, dictionaryName} = targets[i];
|
|
||||||
const query = IDBKeyRange.only(path);
|
|
||||||
|
|
||||||
const onGetAll = (rows) => {
|
|
||||||
for (const row of rows) {
|
|
||||||
if (row.dictionary !== dictionaryName) { continue; }
|
|
||||||
results[inputIndex] = this._createMedia(row, inputIndex);
|
|
||||||
}
|
|
||||||
if (++completeCount >= count) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._db.getAll(index, query, onGetAll, reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDictionaryInfo() {
|
getDictionaryInfo() {
|
||||||
@ -408,66 +319,67 @@ class DictionaryDatabase {
|
|||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
async _findGenericBulk(objectStoreName, indexName, indexValueList, dictionaries, createResult) {
|
_findMultiBulk(objectStoreName, indexNames, items, createQuery, predicate, createResult) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
const itemCount = items.length;
|
||||||
|
const indexCount = indexNames.length;
|
||||||
const results = [];
|
const results = [];
|
||||||
const count = indexValueList.length;
|
if (itemCount === 0 || indexCount === 0) {
|
||||||
if (count === 0) {
|
|
||||||
resolve(results);
|
resolve(results);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transaction = this._db.transaction([objectStoreName], 'readonly');
|
const transaction = this._db.transaction([objectStoreName], 'readonly');
|
||||||
const terms = transaction.objectStore(objectStoreName);
|
const objectStore = transaction.objectStore(objectStoreName);
|
||||||
const index = terms.index(indexName);
|
const indexList = [];
|
||||||
|
for (const indexName of indexNames) {
|
||||||
|
indexList.push(objectStore.index(indexName));
|
||||||
|
}
|
||||||
let completeCount = 0;
|
let completeCount = 0;
|
||||||
for (let i = 0; i < count; ++i) {
|
const requiredCompleteCount = itemCount * indexCount;
|
||||||
const inputIndex = i;
|
const onGetAll = (rows, {item, itemIndex}) => {
|
||||||
const query = IDBKeyRange.only(indexValueList[i]);
|
for (const row of rows) {
|
||||||
|
if (predicate(row, item)) {
|
||||||
const onGetAll = (rows) => {
|
results.push(createResult(row, itemIndex));
|
||||||
for (const row of rows) {
|
|
||||||
if (dictionaries.has(row.dictionary)) {
|
|
||||||
results.push(createResult(row, inputIndex));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (++completeCount >= count) {
|
}
|
||||||
resolve(results);
|
if (++completeCount >= requiredCompleteCount) {
|
||||||
}
|
resolve(results);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
this._db.getAll(index, query, onGetAll, reject);
|
for (let i = 0; i < itemCount; ++i) {
|
||||||
|
const item = items[i];
|
||||||
|
const query = createQuery(item);
|
||||||
|
for (let j = 0; j < indexCount; ++j) {
|
||||||
|
this._db.getAll(indexList[j], query, onGetAll, reject, {item, itemIndex: i});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_findFirstBulk(objectStoreName, indexName, items, predicate) {
|
_findFirstBulk(objectStoreName, indexName, items, createQuery, predicate) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const count = items.length;
|
const itemCount = items.length;
|
||||||
const results = new Array(count);
|
const results = new Array(itemCount);
|
||||||
if (count === 0) {
|
if (itemCount === 0) {
|
||||||
resolve(results);
|
resolve(results);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transaction = this._db.transaction([objectStoreName], 'readonly');
|
const transaction = this._db.transaction([objectStoreName], 'readonly');
|
||||||
const terms = transaction.objectStore(objectStoreName);
|
const objectStore = transaction.objectStore(objectStoreName);
|
||||||
const index = terms.index(indexName);
|
const index = objectStore.index(indexName);
|
||||||
|
|
||||||
let completeCount = 0;
|
let completeCount = 0;
|
||||||
for (let i = 0; i < count; ++i) {
|
const onFind = (row, itemIndex) => {
|
||||||
const itemIndex = i;
|
results[itemIndex] = row;
|
||||||
|
if (++completeCount >= itemCount) {
|
||||||
|
resolve(results);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (let i = 0; i < itemCount; ++i) {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
const query = IDBKeyRange.only(item.query);
|
const query = createQuery(item);
|
||||||
|
this._db.findFirst(index, query, onFind, reject, i, predicate, item, void 0);
|
||||||
const onFind = (row) => {
|
|
||||||
results[itemIndex] = row;
|
|
||||||
if (++completeCount >= count) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this._db.findFirst(index, query, onFind, reject, predicate, item, void 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,8 @@ class Translator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _addRelatedDefinitions(sequencedDefinitions, unsequencedDefinitions, sequenceList, mainDictionary, enabledDictionaryMap) {
|
async _addRelatedDefinitions(sequencedDefinitions, unsequencedDefinitions, sequenceList, mainDictionary, enabledDictionaryMap) {
|
||||||
const databaseDefinitions = await this._database.findTermsBySequenceBulk(sequenceList, mainDictionary);
|
const items = sequenceList.map((query) => ({query, dictionary: mainDictionary}));
|
||||||
|
const databaseDefinitions = await this._database.findTermsBySequenceBulk(items);
|
||||||
for (const databaseDefinition of databaseDefinitions) {
|
for (const databaseDefinition of databaseDefinitions) {
|
||||||
const {relatedDefinitions, definitionIds} = sequencedDefinitions[databaseDefinition.index];
|
const {relatedDefinitions, definitionIds} = sequencedDefinitions[databaseDefinition.index];
|
||||||
const {id} = databaseDefinition;
|
const {id} = databaseDefinition;
|
||||||
@ -410,8 +411,7 @@ class Translator {
|
|||||||
if (unsequencedDefinitions.length === 0 && secondarySearchDictionaryMap.size === 0) { return; }
|
if (unsequencedDefinitions.length === 0 && secondarySearchDictionaryMap.size === 0) { return; }
|
||||||
|
|
||||||
// Prepare grouping info
|
// Prepare grouping info
|
||||||
const expressionList = [];
|
const termList = [];
|
||||||
const readingList = [];
|
|
||||||
const targetList = [];
|
const targetList = [];
|
||||||
const targetMap = new Map();
|
const targetMap = new Map();
|
||||||
|
|
||||||
@ -431,8 +431,7 @@ class Translator {
|
|||||||
target.sequencedDefinitions.push(sequencedDefinition);
|
target.sequencedDefinitions.push(sequencedDefinition);
|
||||||
if (!definition.isPrimary && !target.searchSecondary) {
|
if (!definition.isPrimary && !target.searchSecondary) {
|
||||||
target.searchSecondary = true;
|
target.searchSecondary = true;
|
||||||
expressionList.push(expression);
|
termList.push({expression, reading});
|
||||||
readingList.push(reading);
|
|
||||||
targetList.push(target);
|
targetList.push(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,14 +455,14 @@ class Translator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search database for additional secondary terms
|
// Search database for additional secondary terms
|
||||||
if (expressionList.length === 0 || secondarySearchDictionaryMap.size === 0) { return; }
|
if (termList.length === 0 || secondarySearchDictionaryMap.size === 0) { return; }
|
||||||
|
|
||||||
const databaseDefinitions = await this._database.findTermsExactBulk(expressionList, readingList, secondarySearchDictionaryMap);
|
const databaseDefinitions = await this._database.findTermsExactBulk(termList, secondarySearchDictionaryMap);
|
||||||
this._sortDatabaseDefinitionsByIndex(databaseDefinitions);
|
this._sortDatabaseDefinitionsByIndex(databaseDefinitions);
|
||||||
|
|
||||||
for (const databaseDefinition of databaseDefinitions) {
|
for (const databaseDefinition of databaseDefinitions) {
|
||||||
const {index, id} = databaseDefinition;
|
const {index, id} = databaseDefinition;
|
||||||
const source = expressionList[index];
|
const source = termList[index].expression;
|
||||||
const target = targetList[index];
|
const target = targetList[index];
|
||||||
for (const {definitionIds, secondaryDefinitions} of target.sequencedDefinitions) {
|
for (const {definitionIds, secondaryDefinitions} of target.sequencedDefinitions) {
|
||||||
if (definitionIds.has(id)) { continue; }
|
if (definitionIds.has(id)) { continue; }
|
||||||
|
@ -26,13 +26,13 @@ class MediaLoader {
|
|||||||
this._loadMediaData = [];
|
this._loadMediaData = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadMedia(path, dictionaryName, onLoad, onUnload) {
|
async loadMedia(path, dictionary, onLoad, onUnload) {
|
||||||
const token = this._token;
|
const token = this._token;
|
||||||
const data = {onUnload, loaded: false};
|
const data = {onUnload, loaded: false};
|
||||||
|
|
||||||
this._loadMediaData.push(data);
|
this._loadMediaData.push(data);
|
||||||
|
|
||||||
const media = await this.getMedia(path, dictionaryName);
|
const media = await this.getMedia(path, dictionary);
|
||||||
if (token !== this._token) { return; }
|
if (token !== this._token) { return; }
|
||||||
|
|
||||||
onLoad(media.url);
|
onLoad(media.url);
|
||||||
@ -59,14 +59,14 @@ class MediaLoader {
|
|||||||
this._token = {};
|
this._token = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMedia(path, dictionaryName) {
|
async getMedia(path, dictionary) {
|
||||||
let cachedData;
|
let cachedData;
|
||||||
let dictionaryCache = this._mediaCache.get(dictionaryName);
|
let dictionaryCache = this._mediaCache.get(dictionary);
|
||||||
if (typeof dictionaryCache !== 'undefined') {
|
if (typeof dictionaryCache !== 'undefined') {
|
||||||
cachedData = dictionaryCache.get(path);
|
cachedData = dictionaryCache.get(path);
|
||||||
} else {
|
} else {
|
||||||
dictionaryCache = new Map();
|
dictionaryCache = new Map();
|
||||||
this._mediaCache.set(dictionaryName, dictionaryCache);
|
this._mediaCache.set(dictionary, dictionaryCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof cachedData === 'undefined') {
|
if (typeof cachedData === 'undefined') {
|
||||||
@ -76,15 +76,15 @@ class MediaLoader {
|
|||||||
url: null
|
url: null
|
||||||
};
|
};
|
||||||
dictionaryCache.set(path, cachedData);
|
dictionaryCache.set(path, cachedData);
|
||||||
cachedData.promise = this._getMediaData(path, dictionaryName, cachedData);
|
cachedData.promise = this._getMediaData(path, dictionary, cachedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedData.promise;
|
return cachedData.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getMediaData(path, dictionaryName, cachedData) {
|
async _getMediaData(path, dictionary, cachedData) {
|
||||||
const token = this._token;
|
const token = this._token;
|
||||||
const data = (await yomichan.api.getMedia([{path, dictionaryName}]))[0];
|
const data = (await yomichan.api.getMedia([{path, dictionary}]))[0];
|
||||||
if (token === this._token && data !== null) {
|
if (token === this._token && data !== null) {
|
||||||
const blob = MediaUtil.createBlobFromBase64Content(data.content, data.mediaType);
|
const blob = MediaUtil.createBlobFromBase64Content(data.content, data.mediaType);
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
|
@ -292,8 +292,11 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
{
|
{
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
termList: ['打', '打つ', '打ち込む'],
|
termList: [
|
||||||
readingList: ['だ', 'うつ', 'うちこむ']
|
{expression: '打', reading: 'だ'},
|
||||||
|
{expression: '打つ', reading: 'うつ'},
|
||||||
|
{expression: '打ち込む', reading: 'うちこむ'}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
expectedResults: {
|
expectedResults: {
|
||||||
@ -313,8 +316,11 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
{
|
{
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
termList: ['打', '打つ', '打ち込む'],
|
termList: [
|
||||||
readingList: ['だ?', 'うつ?', 'うちこむ?']
|
{expression: '打', reading: 'だ?'},
|
||||||
|
{expression: '打つ', reading: 'うつ?'},
|
||||||
|
{expression: '打ち込む', reading: 'うちこむ?'}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
expectedResults: {
|
expectedResults: {
|
||||||
@ -326,8 +332,10 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
{
|
{
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
termList: ['打つ', '打つ'],
|
termList: [
|
||||||
readingList: ['うつ', 'ぶつ']
|
{expression: '打つ', reading: 'うつ'},
|
||||||
|
{expression: '打つ', reading: 'ぶつ'}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
expectedResults: {
|
expectedResults: {
|
||||||
@ -344,8 +352,9 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
{
|
{
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
termList: ['打つ'],
|
termList: [
|
||||||
readingList: ['うちこむ']
|
{expression: '打つ', reading: 'うちこむ'}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
expectedResults: {
|
expectedResults: {
|
||||||
@ -357,8 +366,7 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
{
|
{
|
||||||
inputs: [
|
inputs: [
|
||||||
{
|
{
|
||||||
termList: [],
|
termList: []
|
||||||
readingList: []
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
expectedResults: {
|
expectedResults: {
|
||||||
@ -370,8 +378,8 @@ async function testTindTermsExactBulk1(database, titles) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (const {inputs, expectedResults} of data) {
|
for (const {inputs, expectedResults} of data) {
|
||||||
for (const {termList, readingList} of inputs) {
|
for (const {termList} of inputs) {
|
||||||
const results = await database.findTermsExactBulk(termList, readingList, titles);
|
const results = await database.findTermsExactBulk(termList, titles);
|
||||||
assert.strictEqual(results.length, expectedResults.total);
|
assert.strictEqual(results.length, expectedResults.total);
|
||||||
for (const [expression, count] of expectedResults.expressions) {
|
for (const [expression, count] of expectedResults.expressions) {
|
||||||
assert.strictEqual(countTermsWithExpression(results, expression), count);
|
assert.strictEqual(countTermsWithExpression(results, expression), count);
|
||||||
@ -520,7 +528,7 @@ async function testFindTermsBySequenceBulk1(database, mainDictionary) {
|
|||||||
|
|
||||||
for (const {inputs, expectedResults} of data) {
|
for (const {inputs, expectedResults} of data) {
|
||||||
for (const {sequenceList} of inputs) {
|
for (const {sequenceList} of inputs) {
|
||||||
const results = await database.findTermsBySequenceBulk(sequenceList, mainDictionary);
|
const results = await database.findTermsBySequenceBulk(sequenceList.map((query) => ({query, dictionary: mainDictionary})));
|
||||||
assert.strictEqual(results.length, expectedResults.total);
|
assert.strictEqual(results.length, expectedResults.total);
|
||||||
for (const [expression, count] of expectedResults.expressions) {
|
for (const [expression, count] of expectedResults.expressions) {
|
||||||
assert.strictEqual(countTermsWithExpression(results, expression), count);
|
assert.strictEqual(countTermsWithExpression(results, expression), count);
|
||||||
@ -773,8 +781,8 @@ async function testDatabase2() {
|
|||||||
// Error: not prepared
|
// Error: not prepared
|
||||||
await assert.rejects(async () => await dictionaryDatabase.deleteDictionary(title, {rate: 1000}, () => {}));
|
await assert.rejects(async () => await dictionaryDatabase.deleteDictionary(title, {rate: 1000}, () => {}));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findTermsBulk(['?'], titles, null));
|
await assert.rejects(async () => await dictionaryDatabase.findTermsBulk(['?'], titles, null));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findTermsExactBulk(['?'], ['?'], titles));
|
await assert.rejects(async () => await dictionaryDatabase.findTermsExactBulk([{expression: '?', reading: '?'}], titles));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findTermsBySequenceBulk([1], title));
|
await assert.rejects(async () => await dictionaryDatabase.findTermsBySequenceBulk([{query: 1, dictionary: title}]));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findTermMetaBulk(['?'], titles));
|
await assert.rejects(async () => await dictionaryDatabase.findTermMetaBulk(['?'], titles));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findTermMetaBulk(['?'], titles));
|
await assert.rejects(async () => await dictionaryDatabase.findTermMetaBulk(['?'], titles));
|
||||||
await assert.rejects(async () => await dictionaryDatabase.findKanjiBulk(['?'], titles));
|
await assert.rejects(async () => await dictionaryDatabase.findKanjiBulk(['?'], titles));
|
||||||
|
Loading…
Reference in New Issue
Block a user