aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-08-19 13:56:00 +0200
committerFlorian Dold <florian@dold.me>2021-08-19 13:56:00 +0200
commitdefc393d6e320f6cc76df059a94936a7b88571a1 (patch)
tree7492672ac537505f9f14c689151e46d2625ef902 /packages
parent3ce740d87dc51c2f9a330d3e12237ba1fdd5f2e7 (diff)
add missing file
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-wallet-core/src/db-utils.ts154
1 files changed, 154 insertions, 0 deletions
diff --git a/packages/taler-wallet-core/src/db-utils.ts b/packages/taler-wallet-core/src/db-utils.ts
new file mode 100644
index 000000000..424d12b84
--- /dev/null
+++ b/packages/taler-wallet-core/src/db-utils.ts
@@ -0,0 +1,154 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler 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, or (at your option) any later version.
+
+ GNU Taler 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
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
+import { IDBDatabase, IDBFactory, IDBTransaction } from "@gnu-taler/idb-bridge";
+import { Logger } from "@gnu-taler/taler-util";
+import {
+ CURRENT_DB_CONFIG_KEY,
+ TALER_DB_NAME,
+ TALER_META_DB_NAME,
+ walletMetadataStore,
+ WalletStoresV1,
+ WALLET_DB_MINOR_VERSION,
+} from "./db.js";
+import {
+ DbAccess,
+ IndexDescriptor,
+ openDatabase,
+ StoreDescriptor,
+ StoreWithIndexes,
+} from "./util/query.js";
+
+const logger = new Logger("db-utils.ts");
+
+function upgradeFromStoreMap(
+ storeMap: any,
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+): void {
+ if (oldVersion === 0) {
+ for (const n in storeMap) {
+ const swi: StoreWithIndexes<StoreDescriptor<unknown>, any> = storeMap[n];
+ const storeDesc: StoreDescriptor<unknown> = swi.store;
+ const s = db.createObjectStore(storeDesc.name, {
+ autoIncrement: storeDesc.autoIncrement,
+ keyPath: storeDesc.keyPath,
+ });
+ for (const indexName in swi.indexMap as any) {
+ const indexDesc: IndexDescriptor = swi.indexMap[indexName];
+ s.createIndex(indexDesc.name, indexDesc.keyPath, {
+ multiEntry: indexDesc.multiEntry,
+ });
+ }
+ }
+ return;
+ }
+ if (oldVersion === newVersion) {
+ return;
+ }
+ logger.info(`upgrading database from ${oldVersion} to ${newVersion}`);
+ throw Error("upgrade not supported");
+}
+
+function onTalerDbUpgradeNeeded(
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+) {
+ upgradeFromStoreMap(
+ WalletStoresV1,
+ db,
+ oldVersion,
+ newVersion,
+ upgradeTransaction,
+ );
+}
+
+function onMetaDbUpgradeNeeded(
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+) {
+ upgradeFromStoreMap(
+ walletMetadataStore,
+ db,
+ oldVersion,
+ newVersion,
+ upgradeTransaction,
+ );
+}
+
+/**
+ * Return a promise that resolves
+ * to the taler wallet db.
+ */
+export async function openTalerDatabase(
+ idbFactory: IDBFactory,
+ onVersionChange: () => void,
+): Promise<DbAccess<typeof WalletStoresV1>> {
+ const metaDbHandle = await openDatabase(
+ idbFactory,
+ TALER_META_DB_NAME,
+ 1,
+ () => {},
+ onMetaDbUpgradeNeeded,
+ );
+
+ const metaDb = new DbAccess(metaDbHandle, walletMetadataStore);
+ let currentMainVersion: string | undefined;
+ await metaDb
+ .mktx((x) => ({
+ metaConfig: x.metaConfig,
+ }))
+ .runReadWrite(async (tx) => {
+ const dbVersionRecord = await tx.metaConfig.get(CURRENT_DB_CONFIG_KEY);
+ if (!dbVersionRecord) {
+ currentMainVersion = TALER_DB_NAME;
+ await tx.metaConfig.put({
+ key: CURRENT_DB_CONFIG_KEY,
+ value: TALER_DB_NAME,
+ });
+ } else {
+ currentMainVersion = dbVersionRecord.value;
+ }
+ });
+
+ if (currentMainVersion !== TALER_DB_NAME) {
+ // In the future, the migration logic will be implemented here.
+ throw Error(`migration from database ${currentMainVersion} not supported`);
+ }
+
+ const mainDbHandle = await openDatabase(
+ idbFactory,
+ TALER_DB_NAME,
+ WALLET_DB_MINOR_VERSION,
+ onVersionChange,
+ onTalerDbUpgradeNeeded,
+ );
+
+ return new DbAccess(mainDbHandle, WalletStoresV1);
+}
+
+export function deleteTalerDatabase(idbFactory: IDBFactory): void {
+ idbFactory.deleteDatabase(TALER_DB_NAME);
+}