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