diff options
-rw-r--r-- | ext/bg/js/database.js | 111 |
1 files changed, 96 insertions, 15 deletions
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js index e5245582..9810328f 100644 --- a/ext/bg/js/database.js +++ b/ext/bg/js/database.js @@ -27,23 +27,63 @@ class Database { throw new Error('Database already initialized'); } - this.db = new Dexie('dict'); - this.db.version(2).stores({ - terms: '++id,dictionary,expression,reading', - kanji: '++,dictionary,character', - tagMeta: '++,dictionary', - dictionaries: '++,title,version' - }); - this.db.version(3).stores({ - termMeta: '++,dictionary,expression', - kanjiMeta: '++,dictionary,character', - tagMeta: '++,dictionary,name' - }); - this.db.version(4).stores({ - terms: '++id,dictionary,expression,reading,sequence' + const idb = await Database.open('dict', 4, (db, transaction, oldVersion) => { + Database.upgrade(db, transaction, oldVersion, [ + { + version: 2, + stores: { + terms: { + primaryKey: {keyPath: 'id', autoIncrement: true}, + indices: ['dictionary', 'expression', 'reading'] + }, + kanji: { + primaryKey: {autoIncrement: true}, + indices: ['dictionary', 'character'] + }, + tagMeta: { + primaryKey: {autoIncrement: true}, + indices: ['dictionary'] + }, + dictionaries: { + primaryKey: {autoIncrement: true}, + indices: ['title', 'version'] + } + } + }, + { + version: 3, + stores: { + termMeta: { + primaryKey: {autoIncrement: true}, + indices: ['dictionary', 'expression'] + }, + kanjiMeta: { + primaryKey: {autoIncrement: true}, + indices: ['dictionary', 'character'] + }, + tagMeta: { + primaryKey: {autoIncrement: true}, + indices: ['dictionary', 'name'] + } + } + }, + { + version: 4, + stores: { + terms: { + primaryKey: {keyPath: 'id', autoIncrement: true}, + indices: ['dictionary', 'expression', 'reading', 'sequence'] + } + } + } + ]); }); - await this.db.open(); + this.db = { + backendDB: () => idb, + close: () => {}, // Not implemented + delete: () => {} // Not implemented + }; } async purge() { @@ -734,4 +774,45 @@ class Database { } }); } + + static open(name, version, onUpgradeNeeded) { + return new Promise((resolve, reject) => { + const request = window.indexedDB.open(name, version * 10); + + request.onupgradeneeded = (event) => { + try { + request.transaction.onerror = (e) => reject(e); + onUpgradeNeeded(request.result, request.transaction, event.oldVersion / 10, event.newVersion / 10); + } catch (e) { + reject(e); + } + }; + + request.onerror = (e) => reject(e); + request.onsuccess = () => resolve(request.result); + }); + } + + static upgrade(db, transaction, oldVersion, upgrades) { + for (const {version, stores} of upgrades) { + if (oldVersion >= version) { continue; } + + const objectStoreNames = Object.keys(stores); + for (const objectStoreName of objectStoreNames) { + const {primaryKey, indices} = stores[objectStoreName]; + + const objectStore = ( + transaction.objectStoreNames.contains(objectStoreName) ? + transaction.objectStore(objectStoreName) : + db.createObjectStore(objectStoreName, primaryKey) + ); + + for (const indexName of indices) { + if (objectStore.indexNames.contains(indexName)) { continue; } + + objectStore.createIndex(indexName, indexName, {}); + } + } + } + } } |