summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-09-05 20:00:08 -0400
committerGitHub <noreply@github.com>2021-09-05 20:00:08 -0400
commit97a80276f6ce5834ab1b9ad12309df4f6f2f3ec5 (patch)
tree28aa37aa95832cd51d55011ded62dfdbb649703e
parentf68ad1f843607d4ba1ad216fe16305c420cee8d6 (diff)
Database readwrite transaction updates (#1932)
* Add _readWriteTransaction helper * Improve deleteDictionary order * Make onProgress event optional * Simplify progress rate parameter
-rw-r--r--ext/js/data/database.js21
-rw-r--r--ext/js/language/dictionary-database.js53
-rw-r--r--ext/js/language/dictionary-worker-handler.js2
-rw-r--r--test/test-database.js4
4 files changed, 49 insertions, 31 deletions
diff --git a/ext/js/data/database.js b/ext/js/data/database.js
index 224233a8..cc4f39f9 100644
--- a/ext/js/data/database.js
+++ b/ext/js/data/database.js
@@ -76,9 +76,7 @@ class Database {
return;
}
- const transaction = this.transaction([objectStoreName], 'readwrite');
- transaction.onerror = (e) => reject(e.target.error);
- transaction.oncomplete = () => resolve();
+ const transaction = this._readWriteTransaction([objectStoreName], resolve, reject);
const objectStore = transaction.objectStore(objectStoreName);
for (let i = start, ii = start + count; i < ii; ++i) {
objectStore.add(items[i]);
@@ -161,9 +159,7 @@ class Database {
delete(objectStoreName, key) {
return new Promise((resolve, reject) => {
- const transaction = this.transaction([objectStoreName], 'readwrite');
- transaction.onerror = (e) => reject(e.target.error);
- transaction.oncomplete = () => resolve();
+ const transaction = this._readWriteTransaction([objectStoreName], resolve, reject);
const objectStore = transaction.objectStore(objectStoreName);
objectStore.delete(key);
transaction.commit();
@@ -172,10 +168,7 @@ class Database {
bulkDelete(objectStoreName, indexName, query, filterKeys=null, onProgress=null) {
return new Promise((resolve, reject) => {
- const transaction = this.transaction([objectStoreName], 'readwrite');
- transaction.onerror = (e) => reject(e.target.error);
- transaction.oncomplete = () => resolve();
-
+ const transaction = this._readWriteTransaction([objectStoreName], resolve, reject);
const objectStore = transaction.objectStore(objectStoreName);
const objectStoreOrIndex = indexName !== null ? objectStore.index(indexName) : objectStore;
@@ -317,4 +310,12 @@ class Database {
}
}
}
+
+ _readWriteTransaction(storeNames, resolve, reject) {
+ const transaction = this.transaction(storeNames, 'readwrite');
+ transaction.onerror = (e) => reject(e.target.error);
+ transaction.onabort = () => reject(new Error('Transaction aborted'));
+ transaction.oncomplete = () => resolve();
+ return transaction;
+ }
}
diff --git a/ext/js/language/dictionary-database.js b/ext/js/language/dictionary-database.js
index 6b235fb6..50435c51 100644
--- a/ext/js/language/dictionary-database.js
+++ b/ext/js/language/dictionary-database.js
@@ -139,22 +139,37 @@ class DictionaryDatabase {
return result;
}
- async deleteDictionary(dictionaryName, progressSettings, onProgress) {
- const targets = [
- ['dictionaries', 'title'],
- ['kanji', 'dictionary'],
- ['kanjiMeta', 'dictionary'],
- ['terms', 'dictionary'],
- ['termMeta', 'dictionary'],
- ['tagMeta', 'dictionary'],
- ['media', 'dictionary']
+ async deleteDictionary(dictionaryName, progressRate, onProgress) {
+ if (typeof progressRate !== 'number') {
+ progressRate = 1;
+ }
+ if (typeof onProgress !== 'function') {
+ onProgress = () => {};
+ }
+
+ const targetGroups = [
+ [
+ ['kanji', 'dictionary'],
+ ['kanjiMeta', 'dictionary'],
+ ['terms', 'dictionary'],
+ ['termMeta', 'dictionary'],
+ ['tagMeta', 'dictionary'],
+ ['media', 'dictionary']
+ ],
+ [
+ ['dictionaries', 'title']
+ ]
];
- const {rate} = progressSettings;
+ let storeCount = 0;
+ for (const targets of targetGroups) {
+ storeCount += targets.length;
+ }
+
const progressData = {
count: 0,
processed: 0,
- storeCount: targets.length,
+ storeCount,
storesProcesed: 0
};
@@ -167,18 +182,20 @@ class DictionaryDatabase {
const onProgress2 = () => {
const processed = progressData.processed + 1;
progressData.processed = processed;
- if ((processed % rate) === 0 || processed === progressData.count) {
+ if ((processed % progressRate) === 0 || processed === progressData.count) {
onProgress(progressData);
}
};
- const promises = [];
- for (const [objectStoreName, indexName] of targets) {
- const query = IDBKeyRange.only(dictionaryName);
- const promise = this._db.bulkDelete(objectStoreName, indexName, query, filterKeys, onProgress2);
- promises.push(promise);
+ for (const targets of targetGroups) {
+ const promises = [];
+ for (const [objectStoreName, indexName] of targets) {
+ const query = IDBKeyRange.only(dictionaryName);
+ const promise = this._db.bulkDelete(objectStoreName, indexName, query, filterKeys, onProgress2);
+ promises.push(promise);
+ }
+ await Promise.all(promises);
}
- await Promise.all(promises);
}
findTermsBulk(termList, dictionaries, wildcard) {
diff --git a/ext/js/language/dictionary-worker-handler.js b/ext/js/language/dictionary-worker-handler.js
index 3ce744f9..8aa6a265 100644
--- a/ext/js/language/dictionary-worker-handler.js
+++ b/ext/js/language/dictionary-worker-handler.js
@@ -84,7 +84,7 @@ class DictionaryWorkerHandler {
async _deleteDictionary({dictionaryTitle}, onProgress) {
const dictionaryDatabase = await this._getPreparedDictionaryDatabase();
try {
- return await dictionaryDatabase.deleteDictionary(dictionaryTitle, {rate: 1000}, onProgress);
+ return await dictionaryDatabase.deleteDictionary(dictionaryTitle, 1000, onProgress);
} finally {
dictionaryDatabase.close();
}
diff --git a/test/test-database.js b/test/test-database.js
index e855f07f..a87a3f72 100644
--- a/test/test-database.js
+++ b/test/test-database.js
@@ -122,7 +122,7 @@ async function testDatabase1() {
let progressEvent = false;
await dictionaryDatabase.deleteDictionary(
title,
- {rate: 1000},
+ 1000,
() => {
progressEvent = true;
}
@@ -788,7 +788,7 @@ async function testDatabase2() {
const dictionaryDatabase = new DictionaryDatabase();
// Error: not prepared
- await assert.rejects(async () => await dictionaryDatabase.deleteDictionary(title, {rate: 1000}, () => {}));
+ await assert.rejects(async () => await dictionaryDatabase.deleteDictionary(title, 1000));
await assert.rejects(async () => await dictionaryDatabase.findTermsBulk(['?'], titles, null));
await assert.rejects(async () => await dictionaryDatabase.findTermsExactBulk([{term: '?', reading: '?'}], titles));
await assert.rejects(async () => await dictionaryDatabase.findTermsBySequenceBulk([{query: 1, dictionary: title}]));