Database improvements to data persistency (#1893)

* Fix function check

* Rename arguments of getAll, getAllKeys, and their private functions

* Simplify bulkAdd

* Simplify delete

* Simplify bulkDelete

* Remove persistData
This commit is contained in:
toasted-nutbread 2021-08-13 18:35:31 -04:00 committed by GitHub
parent 9facacfb23
commit cd78d56fee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 73 deletions

View File

@ -76,38 +76,30 @@ class Database {
return; return;
} }
const end = start + count;
let completedCount = 0;
const onError = (e) => reject(e.target.error);
const onSuccess = () => {
if (++completedCount >= count) {
resolve();
}
};
const transaction = this.transaction([objectStoreName], 'readwrite'); const transaction = this.transaction([objectStoreName], 'readwrite');
transaction.onerror = (e) => reject(e.target.error);
transaction.oncomplete = () => resolve();
const objectStore = transaction.objectStore(objectStoreName); const objectStore = transaction.objectStore(objectStoreName);
for (let i = start; i < end; ++i) { for (let i = start, ii = start + count; i < ii; ++i) {
const request = objectStore.add(items[i]); objectStore.add(items[i]);
request.onerror = onError;
request.onsuccess = onSuccess;
} }
transaction.commit();
}); });
} }
getAll(objectStoreOrIndex, query, resolve, reject, data) { getAll(objectStoreOrIndex, query, onSuccess, onError, data) {
if (typeof objectStoreOrIndex.getAll === 'function') { if (typeof objectStoreOrIndex.getAll === 'function') {
this._getAllFast(objectStoreOrIndex, query, resolve, reject, data); this._getAllFast(objectStoreOrIndex, query, onSuccess, onError, data);
} else { } else {
this._getAllUsingCursor(objectStoreOrIndex, query, resolve, reject, data); this._getAllUsingCursor(objectStoreOrIndex, query, onSuccess, onError, data);
} }
} }
getAllKeys(objectStoreOrIndex, query, resolve, reject) { getAllKeys(objectStoreOrIndex, query, onSuccess, onError) {
if (typeof objectStoreOrIndex.getAll === 'function') { if (typeof objectStoreOrIndex.getAllKeys === 'function') {
this._getAllKeysFast(objectStoreOrIndex, query, resolve, reject); this._getAllKeysFast(objectStoreOrIndex, query, onSuccess, onError);
} else { } else {
this._getAllKeysUsingCursor(objectStoreOrIndex, query, resolve, reject); this._getAllKeysUsingCursor(objectStoreOrIndex, query, onSuccess, onError);
} }
} }
@ -170,16 +162,20 @@ class Database {
delete(objectStoreName, key) { delete(objectStoreName, key) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const transaction = this.transaction([objectStoreName], 'readwrite'); const transaction = this.transaction([objectStoreName], 'readwrite');
transaction.onerror = (e) => reject(e.target.error);
transaction.oncomplete = () => resolve();
const objectStore = transaction.objectStore(objectStoreName); const objectStore = transaction.objectStore(objectStoreName);
const request = objectStore.delete(key); objectStore.delete(key);
request.onerror = (e) => reject(e.target.error); transaction.commit();
request.onsuccess = () => resolve();
}); });
} }
bulkDelete(objectStoreName, indexName, query, filterKeys=null, onProgress=null) { bulkDelete(objectStoreName, indexName, query, filterKeys=null, onProgress=null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const transaction = this.transaction([objectStoreName], 'readwrite'); const transaction = this.transaction([objectStoreName], 'readwrite');
transaction.onerror = (e) => reject(e.target.error);
transaction.oncomplete = () => resolve();
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;
@ -188,7 +184,8 @@ class Database {
if (typeof filterKeys === 'function') { if (typeof filterKeys === 'function') {
keys = filterKeys(keys); keys = filterKeys(keys);
} }
this._bulkDeleteInternal(objectStore, keys, onProgress, resolve, reject); this._bulkDeleteInternal(objectStore, keys, onProgress);
transaction.commit();
} catch (e) { } catch (e) {
reject(e); reject(e);
} }
@ -198,16 +195,6 @@ class Database {
}); });
} }
persistData(objectStoreName) {
return new Promise((resolve, reject) => {
const transaction = this.transaction([objectStoreName], 'readonly');
const objectStore = transaction.objectStore(objectStoreName);
const cursor = objectStore.openCursor();
cursor.onerror = (e) => reject(e.target.error);
cursor.onsuccess = () => resolve();
});
}
static deleteDatabase(databaseName) { static deleteDatabase(databaseName) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const request = indexedDB.deleteDatabase(databaseName); const request = indexedDB.deleteDatabase(databaseName);
@ -266,77 +253,68 @@ class Database {
return false; return false;
} }
_getAllFast(objectStoreOrIndex, query, resolve, reject, data) { _getAllFast(objectStoreOrIndex, query, onSuccess, onReject, data) {
const request = objectStoreOrIndex.getAll(query); const request = objectStoreOrIndex.getAll(query);
request.onerror = (e) => reject(e.target.error, data); request.onerror = (e) => onReject(e.target.error, data);
request.onsuccess = (e) => resolve(e.target.result, data); request.onsuccess = (e) => onSuccess(e.target.result, data);
} }
_getAllUsingCursor(objectStoreOrIndex, query, resolve, reject, data) { _getAllUsingCursor(objectStoreOrIndex, query, onSuccess, onReject, data) {
const results = []; const results = [];
const request = objectStoreOrIndex.openCursor(query, 'next'); const request = objectStoreOrIndex.openCursor(query, 'next');
request.onerror = (e) => reject(e.target.error, data); request.onerror = (e) => onReject(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, data); onSuccess(results, data);
} }
}; };
} }
_getAllKeysFast(objectStoreOrIndex, query, resolve, reject) { _getAllKeysFast(objectStoreOrIndex, query, onSuccess, onError) {
const request = objectStoreOrIndex.getAllKeys(query); const request = objectStoreOrIndex.getAllKeys(query);
request.onerror = (e) => reject(e.target.error); request.onerror = (e) => onError(e.target.error);
request.onsuccess = (e) => resolve(e.target.result); request.onsuccess = (e) => onSuccess(e.target.result);
} }
_getAllKeysUsingCursor(objectStoreOrIndex, query, resolve, reject) { _getAllKeysUsingCursor(objectStoreOrIndex, query, onSuccess, onError) {
const results = []; const results = [];
const request = objectStoreOrIndex.openKeyCursor(query, 'next'); const request = objectStoreOrIndex.openKeyCursor(query, 'next');
request.onerror = (e) => reject(e.target.error); request.onerror = (e) => onError(e.target.error);
request.onsuccess = (e) => { request.onsuccess = (e) => {
const cursor = e.target.result; const cursor = e.target.result;
if (cursor) { if (cursor) {
results.push(cursor.primaryKey); results.push(cursor.primaryKey);
cursor.continue(); cursor.continue();
} else { } else {
resolve(results); onSuccess(results);
} }
}; };
} }
_bulkDeleteInternal(objectStore, keys, onProgress, resolve, reject) { _bulkDeleteInternal(objectStore, keys, onProgress) {
const count = keys.length; const count = keys.length;
if (count === 0) { if (count === 0) { return; }
resolve();
return;
}
let completedCount = 0; let completedCount = 0;
const hasProgress = (typeof onProgress === 'function');
const onError = (e) => reject(e.target.error);
const onSuccess = () => { const onSuccess = () => {
++completedCount; ++completedCount;
if (hasProgress) {
try { try {
onProgress(completedCount, count); onProgress(completedCount, count);
} catch (e) { } catch (e) {
// NOP // NOP
} }
}
if (completedCount >= count) {
resolve();
}
}; };
const hasProgress = (typeof onProgress === 'function');
for (const key of keys) { for (const key of keys) {
const request = objectStore.delete(key); const request = objectStore.delete(key);
request.onerror = onError; if (hasProgress) {
request.onsuccess = onSuccess; request.onsuccess = onSuccess;
} }
} }
}
} }

View File

@ -317,10 +317,6 @@ class DictionaryDatabase {
return this._db.bulkAdd(objectStoreName, items, start, count); return this._db.bulkAdd(objectStoreName, items, start, count);
} }
persistData(objectStoreName) {
return this._db.persistData(objectStoreName);
}
// Private // Private
_findMultiBulk(objectStoreName, indexNames, items, createQuery, predicate, createResult) { _findMultiBulk(objectStoreName, indexNames, items, createQuery, predicate, createResult) {

View File

@ -149,10 +149,6 @@ class DictionaryImporter {
this._progressData.index += count; this._progressData.index += count;
this._progress(); this._progress();
} }
// This function is required in order to make the added data persist after the worker is terminated.
// https://bugs.chromium.org/p/chromium/issues/detail?id=1237686
await dictionaryDatabase.persistData(objectStoreName);
}; };
await bulkAdd('terms', termList); await bulkAdd('terms', termList);