diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-06-28 17:24:06 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-28 17:24:06 -0400 | 
| commit | 441c23bf3be1bc4f14e17ec3956a8c90b1a674e8 (patch) | |
| tree | 2ff8aef4f401f333df2d487814b741a005ca35d3 /ext/bg/js/database.js | |
| parent | 7590055d4e809ab857b2d491dab256e66f1b34b6 (diff) | |
Rename Database to DictionaryDatabase (#633)
Diffstat (limited to 'ext/bg/js/database.js')
| -rw-r--r-- | ext/bg/js/database.js | 474 | 
1 files changed, 0 insertions, 474 deletions
diff --git a/ext/bg/js/database.js b/ext/bg/js/database.js deleted file mode 100644 index 47f1ebdd..00000000 --- a/ext/bg/js/database.js +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) 2016-2020  Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ - -/* global - * GenericDatabase - * dictFieldSplit - */ - -class Database { -    constructor() { -        this._db = new GenericDatabase(); -        this._dbName = 'dict'; -        this._schemas = new Map(); -    } - -    // Public - -    async prepare() { -        await this._db.open( -            this._dbName, -            60, -            [ -                { -                    version: 20, -                    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: 30, -                    stores: { -                        termMeta: { -                            primaryKey: {autoIncrement: true}, -                            indices: ['dictionary', 'expression'] -                        }, -                        kanjiMeta: { -                            primaryKey: {autoIncrement: true}, -                            indices: ['dictionary', 'character'] -                        }, -                        tagMeta: { -                            primaryKey: {autoIncrement: true}, -                            indices: ['dictionary', 'name'] -                        } -                    } -                }, -                { -                    version: 40, -                    stores: { -                        terms: { -                            primaryKey: {keyPath: 'id', autoIncrement: true}, -                            indices: ['dictionary', 'expression', 'reading', 'sequence'] -                        } -                    } -                }, -                { -                    version: 50, -                    stores: { -                        terms: { -                            primaryKey: {keyPath: 'id', autoIncrement: true}, -                            indices: ['dictionary', 'expression', 'reading', 'sequence', 'expressionReverse', 'readingReverse'] -                        } -                    } -                }, -                { -                    version: 60, -                    stores: { -                        media: { -                            primaryKey: {keyPath: 'id', autoIncrement: true}, -                            indices: ['dictionary', 'path'] -                        } -                    } -                } -            ] -        ); -    } - -    async close() { -        this._db.close(); -    } - -    isPrepared() { -        return this._db.isOpen(); -    } - -    async purge() { -        if (this._db.isOpening()) { -            throw new Error('Cannot purge database while opening'); -        } -        if (this._db.isOpen()) { -            this._db.close(); -        } -        await GenericDatabase.deleteDatabase(this._dbName); -        await this.prepare(); -    } - -    async deleteDictionary(dictionaryName, progressSettings, onProgress) { -        const targets = [ -            ['dictionaries', 'title'], -            ['kanji', 'dictionary'], -            ['kanjiMeta', 'dictionary'], -            ['terms', 'dictionary'], -            ['termMeta', 'dictionary'], -            ['tagMeta', 'dictionary'], -            ['media', 'dictionary'] -        ]; - -        const {rate} = progressSettings; -        const progressData = { -            count: 0, -            processed: 0, -            storeCount: targets.length, -            storesProcesed: 0 -        }; - -        const filterKeys = (keys) => { -            ++progressData.storesProcesed; -            progressData.count += keys.length; -            onProgress(progressData); -            return keys; -        }; -        const onProgress2 = () => { -            const processed = progressData.processed + 1; -            progressData.processed = processed; -            if ((processed % rate) === 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); -        } -        await Promise.all(promises); -    } - -    findTermsBulk(termList, dictionaries, wildcard) { -        return new Promise((resolve, reject) => { -            const results = []; -            const count = termList.length; -            if (count === 0) { -                resolve(results); -                return; -            } - -            const visited = new Set(); -            const useWildcard = !!wildcard; -            const prefixWildcard = wildcard === 'prefix'; - -            const transaction = this._db.transaction(['terms'], 'readonly'); -            const terms = transaction.objectStore('terms'); -            const index1 = terms.index(prefixWildcard ? 'expressionReverse' : 'expression'); -            const index2 = terms.index(prefixWildcard ? 'readingReverse' : 'reading'); - -            const count2 = count * 2; -            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) { -        return new Promise((resolve, reject) => { -            const results = []; -            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) { -        return new Promise((resolve, reject) => { -            const results = []; -            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) { -        return this._findGenericBulk('termMeta', 'expression', termList, dictionaries, this._createTermMeta.bind(this)); -    } - -    findKanjiBulk(kanjiList, dictionaries) { -        return this._findGenericBulk('kanji', 'character', kanjiList, dictionaries, this._createKanji.bind(this)); -    } - -    findKanjiMetaBulk(kanjiList, dictionaries) { -        return this._findGenericBulk('kanjiMeta', 'character', kanjiList, dictionaries, this._createKanjiMeta.bind(this)); -    } - -    findTagForTitle(name, title) { -        const query = IDBKeyRange.only(name); -        return this._db.find('tagMeta', 'name', query, (row) => (row.dictionary === title), null); -    } - -    getMedia(targets) { -        return new Promise((resolve, reject) => { -            const count = targets.length; -            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() { -        return new Promise((resolve, reject) => { -            const transaction = this._db.transaction(['dictionaries'], 'readonly'); -            const objectStore = transaction.objectStore('dictionaries'); -            this._db.getAll(objectStore, null, resolve, reject); -        }); -    } - -    getDictionaryCounts(dictionaryNames, getTotal) { -        return new Promise((resolve, reject) => { -            const targets = [ -                ['kanji', 'dictionary'], -                ['kanjiMeta', 'dictionary'], -                ['terms', 'dictionary'], -                ['termMeta', 'dictionary'], -                ['tagMeta', 'dictionary'], -                ['media', 'dictionary'] -            ]; -            const objectStoreNames = targets.map(([objectStoreName]) => objectStoreName); -            const transaction = this._db.transaction(objectStoreNames, 'readonly'); -            const databaseTargets = targets.map(([objectStoreName, indexName]) => { -                const objectStore = transaction.objectStore(objectStoreName); -                const index = objectStore.index(indexName); -                return {objectStore, index}; -            }); - -            const countTargets = []; -            if (getTotal) { -                for (const {objectStore} of databaseTargets) { -                    countTargets.push([objectStore, null]); -                } -            } -            for (const dictionaryName of dictionaryNames) { -                const query = IDBKeyRange.only(dictionaryName); -                for (const {index} of databaseTargets) { -                    countTargets.push([index, query]); -                } -            } - -            const onCountComplete = (results) => { -                const resultCount = results.length; -                const targetCount = targets.length; -                const counts = []; -                for (let i = 0; i < resultCount; i += targetCount) { -                    const countGroup = {}; -                    for (let j = 0; j < targetCount; ++j) { -                        countGroup[targets[j][0]] = results[i + j]; -                    } -                    counts.push(countGroup); -                } -                const total = getTotal ? counts.shift() : null; -                resolve({total, counts}); -            }; - -            this._db.bulkCount(countTargets, onCountComplete, reject); -        }); -    } - -    async dictionaryExists(title) { -        const query = IDBKeyRange.only(title); -        const result = await this._db.find('dictionaries', 'title', query); -        return typeof result !== 'undefined'; -    } - -    bulkAdd(objectStoreName, items, start, count) { -        return this._db.bulkAdd(objectStoreName, items, start, count); -    } - -    // Private - -    async _findGenericBulk(objectStoreName, indexName, indexValueList, dictionaries, createResult) { -        return new Promise((resolve, reject) => { -            const results = []; -            const count = indexValueList.length; -            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 inputIndex = i; -                const query = IDBKeyRange.only(indexValueList[i]); - -                const onGetAll = (rows) => { -                    for (const row of rows) { -                        if (dictionaries.has(row.dictionary)) { -                            results.push(createResult(row, inputIndex)); -                        } -                    } -                    if (++completeCount >= count) { -                        resolve(results); -                    } -                }; - -                this._db.getAll(index, query, onGetAll, reject); -            } -        }); -    } - -    _createTerm(row, index) { -        return { -            index, -            expression: row.expression, -            reading: row.reading, -            definitionTags: dictFieldSplit(row.definitionTags || row.tags || ''), -            termTags: dictFieldSplit(row.termTags || ''), -            rules: dictFieldSplit(row.rules), -            glossary: row.glossary, -            score: row.score, -            dictionary: row.dictionary, -            id: row.id, -            sequence: typeof row.sequence === 'undefined' ? -1 : row.sequence -        }; -    } - -    _createKanji(row, index) { -        return { -            index, -            character: row.character, -            onyomi: dictFieldSplit(row.onyomi), -            kunyomi: dictFieldSplit(row.kunyomi), -            tags: dictFieldSplit(row.tags), -            glossary: row.meanings, -            stats: row.stats, -            dictionary: row.dictionary -        }; -    } - -    _createTermMeta({expression, mode, data, dictionary}, index) { -        return {expression, mode, data, dictionary, index}; -    } - -    _createKanjiMeta({character, mode, data, dictionary}, index) { -        return {character, mode, data, dictionary, index}; -    } - -    _createMedia(row, index) { -        return Object.assign({}, row, {index}); -    } -}  |