summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/db.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/db.ts')
-rw-r--r--packages/taler-wallet-core/src/db.ts182
1 files changed, 124 insertions, 58 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index b13abac57..aed2ce5cb 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1,5 +1,11 @@
-import { Stores } from "./types/dbTypes";
-import { openDatabase, Database, Store, Index } from "./util/query";
+import { MetaStores, Stores } from "./types/dbTypes";
+import {
+ openDatabase,
+ Database,
+ Store,
+ Index,
+ AnyStoreMap,
+} from "./util/query";
import {
IDBFactory,
IDBDatabase,
@@ -14,7 +20,11 @@ import { Logger } from "./util/logging";
* for all previous versions must be written, which should be
* avoided.
*/
-const TALER_DB_NAME = "taler-wallet-prod-v1";
+const TALER_DB_NAME = "taler-wallet-main-v2";
+
+const TALER_META_DB_NAME = "taler-wallet-meta";
+
+const CURRENT_DB_CONFIG_KEY = "currentMainDbName";
/**
* Current database minor version, should be incremented
@@ -23,78 +33,134 @@ const TALER_DB_NAME = "taler-wallet-prod-v1";
* backwards-compatible way or object stores and indices
* are added.
*/
-export const WALLET_DB_MINOR_VERSION = 3;
+export const WALLET_DB_MINOR_VERSION = 1;
const logger = new Logger("db.ts");
-/**
- * Return a promise that resolves
- * to the taler wallet db.
- */
-export function openTalerDatabase(
- idbFactory: IDBFactory,
- onVersionChange: () => void,
-): Promise<IDBDatabase> {
- const onUpgradeNeeded = (
- db: IDBDatabase,
- oldVersion: number,
- newVersion: number,
- upgradeTransaction: IDBTransaction,
- ): void => {
- if (oldVersion === 0) {
- for (const n in Stores) {
- if ((Stores as any)[n] instanceof Store) {
- const si: Store<string, any> = (Stores as any)[n];
- const s = db.createObjectStore(si.name, si.storeParams);
- for (const indexName in si as any) {
- if ((si as any)[indexName] instanceof Index) {
- const ii: Index<string, string, any, any> = (si as any)[
- indexName
- ];
- s.createIndex(ii.indexName, ii.keyPath, ii.options);
- }
+function upgradeFromStoreMap(
+ storeMap: AnyStoreMap,
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+): void {
+ if (oldVersion === 0) {
+ for (const n in storeMap) {
+ if ((storeMap as any)[n] instanceof Store) {
+ const si: Store<string, any> = (storeMap as any)[n];
+ const s = db.createObjectStore(si.name, si.storeParams);
+ for (const indexName in si as any) {
+ if ((si as any)[indexName] instanceof Index) {
+ const ii: Index<string, string, any, any> = (si as any)[indexName];
+ s.createIndex(ii.indexName, ii.keyPath, ii.options);
}
}
}
- return;
- }
- if (oldVersion === newVersion) {
- return;
}
- logger.info(`upgrading database from ${oldVersion} to ${newVersion}`);
- for (const n in Stores) {
- if ((Stores as any)[n] instanceof Store) {
- const si: Store<string, any> = (Stores as any)[n];
- let s: IDBObjectStore;
- const storeVersionAdded = si.storeParams?.versionAdded ?? 1;
- if (storeVersionAdded > oldVersion) {
- s = db.createObjectStore(si.name, si.storeParams);
- } else {
- s = upgradeTransaction.objectStore(si.name);
- }
- for (const indexName in si as any) {
- if ((si as any)[indexName] instanceof Index) {
- const ii: Index<string, string, any, any> = (si as any)[indexName];
- const indexVersionAdded = ii.options?.versionAdded ?? 0;
- if (
- indexVersionAdded > oldVersion ||
- storeVersionAdded > oldVersion
- ) {
- s.createIndex(ii.indexName, ii.keyPath, ii.options);
- }
+ return;
+ }
+ if (oldVersion === newVersion) {
+ return;
+ }
+ logger.info(`upgrading database from ${oldVersion} to ${newVersion}`);
+ for (const n in Stores) {
+ if ((Stores as any)[n] instanceof Store) {
+ const si: Store<string, any> = (Stores as any)[n];
+ let s: IDBObjectStore;
+ const storeVersionAdded = si.storeParams?.versionAdded ?? 1;
+ if (storeVersionAdded > oldVersion) {
+ s = db.createObjectStore(si.name, si.storeParams);
+ } else {
+ s = upgradeTransaction.objectStore(si.name);
+ }
+ for (const indexName in si as any) {
+ if ((si as any)[indexName] instanceof Index) {
+ const ii: Index<string, string, any, any> = (si as any)[indexName];
+ const indexVersionAdded = ii.options?.versionAdded ?? 0;
+ if (
+ indexVersionAdded > oldVersion ||
+ storeVersionAdded > oldVersion
+ ) {
+ s.createIndex(ii.indexName, ii.keyPath, ii.options);
}
}
}
}
- };
+ }
+}
- return openDatabase(
+function onTalerDbUpgradeNeeded(
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+) {
+ upgradeFromStoreMap(Stores, db, oldVersion, newVersion, upgradeTransaction);
+}
+
+function onMetaDbUpgradeNeeded(
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ upgradeTransaction: IDBTransaction,
+) {
+ upgradeFromStoreMap(
+ MetaStores,
+ db,
+ oldVersion,
+ newVersion,
+ upgradeTransaction,
+ );
+}
+
+/**
+ * Return a promise that resolves
+ * to the taler wallet db.
+ */
+export async function openTalerDatabase(
+ idbFactory: IDBFactory,
+ onVersionChange: () => void,
+): Promise<Database<typeof Stores>> {
+ const metaDbHandle = await openDatabase(
+ idbFactory,
+ TALER_META_DB_NAME,
+ 1,
+ () => {},
+ onMetaDbUpgradeNeeded,
+ );
+
+ const metaDb = new Database(metaDbHandle, MetaStores);
+ let currentMainVersion: string | undefined;
+ await metaDb.runWithWriteTransaction([MetaStores.metaConfig], async (tx) => {
+ const dbVersionRecord = await tx.get(
+ MetaStores.metaConfig,
+ CURRENT_DB_CONFIG_KEY,
+ );
+ if (!dbVersionRecord) {
+ currentMainVersion = TALER_DB_NAME;
+ await tx.put(MetaStores.metaConfig, {
+ key: CURRENT_DB_CONFIG_KEY,
+ value: TALER_DB_NAME,
+ });
+ } else {
+ currentMainVersion = dbVersionRecord.key;
+ }
+ });
+
+ 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,
- onUpgradeNeeded,
+ onTalerDbUpgradeNeeded,
);
+
+ return new Database(mainDbHandle, Stores);
}
export function deleteTalerDatabase(idbFactory: IDBFactory): void {