1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16export class IndexedDBHelp { 17 private dbName: string = ''; 18 private dbVersion: number = 1; 19 private db: IDBDatabase | undefined; 20 21 public open(dbName: string, dbVersion: number, storeOptions?: Array<StoreOptions>): Promise<IDBDatabase> { 22 this.dbName = dbName; 23 this.dbVersion = dbVersion; 24 return new Promise((resolve, reject) => { 25 if (this.db && this.db.name === dbName && this.db.version == dbVersion) { 26 resolve(this.db); 27 return; 28 } 29 const idbOpenDBRequest = indexedDB.open(dbName, dbVersion); 30 idbOpenDBRequest.onupgradeneeded = () => { 31 const database: IDBDatabase = idbOpenDBRequest.result; 32 this.db = database; 33 storeOptions?.forEach((option) => { 34 let optionName = option.name; 35 if (database.objectStoreNames.contains(optionName) === false) { 36 if (option.objectStoreParameters) { 37 let objectStore = database.createObjectStore(optionName, option.objectStoreParameters); 38 option.dataItems?.forEach((dataItem) => { 39 if (dataItem.indexParameters) { 40 objectStore.createIndex(dataItem.name, dataItem.keypath, dataItem.indexParameters); 41 } else { 42 objectStore.createIndex(dataItem.name, dataItem.keypath); 43 } 44 }); 45 } else { 46 let objectStore = database.createObjectStore(optionName); 47 option.dataItems?.forEach((dataItem) => { 48 if (dataItem.indexParameters) { 49 objectStore.createIndex(dataItem.name, dataItem.name, dataItem.indexParameters); 50 } else { 51 objectStore.createIndex(dataItem.name, dataItem.name); 52 } 53 }); 54 } 55 } 56 }); 57 resolve(database); 58 }; 59 idbOpenDBRequest.onsuccess = (event) => { 60 const database: IDBDatabase = idbOpenDBRequest.result; 61 this.db = database; 62 resolve(database); 63 }; 64 idbOpenDBRequest.onerror = (event) => { 65 reject(event); 66 }; 67 }); 68 } 69 70 private async transaction(storeName: string): Promise<IDBTransaction> { 71 if (this.db == undefined) { 72 this.db = await this.open(this.dbName, this.dbVersion); 73 } 74 return this.db.transaction([storeName], 'readwrite'); 75 } 76 77 public async getObjectStore(storeName: string): Promise<IDBObjectStore> { 78 let transaction = await this.transaction(storeName); 79 return transaction.objectStore(storeName); 80 } 81 82 public get(storeName: string, query: IDBValidKey | IDBKeyRange, queryIndex?: string) { 83 return new Promise((resolve, reject) => { 84 this.getObjectStore(storeName).then((objectStore: IDBObjectStore) => { 85 let request: IDBRequest<any>; 86 if (queryIndex) { 87 const index = objectStore.index(queryIndex); 88 request = index.getAll(query); 89 } else { 90 request = objectStore.getAll(query); 91 } 92 request.onsuccess = function (event) { 93 // @ts-ignore 94 resolve(event.target.result); 95 }; 96 request.onerror = (event) => { 97 reject(event); 98 }; 99 }); 100 }); 101 } 102 103 public add(storeName: string, value: any, key?: IDBValidKey) { 104 return new Promise((resolve, reject) => { 105 this.getObjectStore(storeName).then((objectStore: IDBObjectStore) => { 106 const request = objectStore.add(value, key); 107 request.onsuccess = function (event) { 108 // @ts-ignore 109 resolve(event.target.result); 110 }; 111 request.onerror = (event) => { 112 reject(event); 113 }; 114 }); 115 }); 116 } 117 118 public delete(storeName: string, query: IDBValidKey | IDBKeyRange) { 119 return new Promise((resolve, reject) => { 120 this.getObjectStore(storeName).then((objectStore: IDBObjectStore) => { 121 const request = objectStore['delete'](query); 122 request.onsuccess = function (event) { 123 // @ts-ignore 124 resolve(event.target.result); 125 }; 126 request.onerror = (event) => { 127 reject(event); 128 }; 129 }); 130 }); 131 } 132 133 public put(storeName: string, value: any, key?: IDBValidKey) { 134 return new Promise((resolve, reject) => { 135 this.getObjectStore(storeName).then((objectStore: IDBObjectStore) => { 136 const request = objectStore.put(value, key); 137 request.onsuccess = function (event) { 138 // @ts-ignore 139 resolve(event.target.result); 140 }; 141 request.onerror = (event) => { 142 reject(event); 143 }; 144 }); 145 }); 146 } 147} 148 149export class StoreOptions { 150 name: string = ''; 151 objectStoreParameters?: IDBObjectStoreParameters; 152 dataItems?: Array<{ name: string; keypath: string[] | string; indexParameters?: IDBIndexParameters }>; 153} 154