summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-12-19 13:48:37 +0100
committerFlorian Dold <florian.dold@gmail.com>2019-12-19 13:48:37 +0100
commit49e3b3e5b9bbf1ce356ef68f301d50c689ceecb9 (patch)
tree7a0afa6a1920bdb3d60b27f951fa78adba7541ad
parent20ebc44420c76207fa197b7c53201429ffd89bde (diff)
downloadwallet-core-49e3b3e5b9bbf1ce356ef68f301d50c689ceecb9.tar.gz
wallet-core-49e3b3e5b9bbf1ce356ef68f301d50c689ceecb9.tar.bz2
wallet-core-49e3b3e5b9bbf1ce356ef68f301d50c689ceecb9.zip
prepare for schema migrations
-rw-r--r--src/db.ts37
-rw-r--r--src/headless/helpers.ts16
-rw-r--r--src/types/dbTypes.ts35
-rw-r--r--src/types/schemacore.ts58
-rw-r--r--src/util/query.ts26
-rw-r--r--src/webex/wxBackend.ts11
-rw-r--r--tsconfig.json1
7 files changed, 128 insertions, 56 deletions
diff --git a/src/db.ts b/src/db.ts
index e1c5c8f85..da43cf827 100644
--- a/src/db.ts
+++ b/src/db.ts
@@ -1,7 +1,7 @@
import { Stores } from "./types/dbTypes";
-import { openDatabase, Database } from "./util/query";
+import { openDatabase, Database, Store, Index } from "./util/query";
-const TALER_DB_NAME = "taler";
+const TALER_DB_NAME = "taler-wallet";
/**
* Current database version, should be incremented
@@ -9,7 +9,7 @@ const TALER_DB_NAME = "taler";
* In the future we might consider adding migration functions for
* each version increment.
*/
-export const WALLET_DB_VERSION = 28;
+export const WALLET_DB_VERSION = 1;
/**
* Return a promise that resolves
@@ -18,18 +18,41 @@ export const WALLET_DB_VERSION = 28;
export function openTalerDatabase(
idbFactory: IDBFactory,
onVersionChange: () => void,
- onUpgradeUnsupported: (oldVersion: number, newVersion: number) => void,
): Promise<IDBDatabase> {
+ const onUpgradeNeeded = (
+ db: IDBDatabase,
+ oldVersion: number,
+ newVersion: number,
+ ) => {
+ switch (oldVersion) {
+ case 0: // DB does not exist yet
+ for (const n in Stores) {
+ if ((Stores as any)[n] instanceof Store) {
+ const si: Store<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<any, any> = (si as any)[indexName];
+ s.createIndex(ii.indexName, ii.keyPath, ii.options);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ throw Error("unsupported existig DB version");
+ }
+ };
+
return openDatabase(
idbFactory,
TALER_DB_NAME,
WALLET_DB_VERSION,
- Stores,
onVersionChange,
- onUpgradeUnsupported,
+ onUpgradeNeeded,
);
}
export function deleteTalerDatabase(idbFactory: IDBFactory) {
Database.deleteDatabase(idbFactory, TALER_DB_NAME);
-} \ No newline at end of file
+}
diff --git a/src/headless/helpers.ts b/src/headless/helpers.ts
index e65914a01..6832cd4f4 100644
--- a/src/headless/helpers.ts
+++ b/src/headless/helpers.ts
@@ -25,9 +25,7 @@
import { Wallet } from "../wallet";
import { MemoryBackend, BridgeIDBFactory, shimIndexedDB } from "idb-bridge";
import { openTalerDatabase } from "../db";
-import {
- HttpRequestLibrary,
-} from "../util/http";
+import { HttpRequestLibrary } from "../util/http";
import * as amounts from "../util/amounts";
import { Bank } from "./bank";
import fs = require("fs");
@@ -39,7 +37,6 @@ import { Logger } from "../util/logging";
const logger = new Logger("helpers.ts");
-
export interface DefaultNodeWalletArgs {
/**
* Location of the wallet database.
@@ -112,18 +109,9 @@ export async function getDefaultNodeWallet(
throw Error();
};
- const myUnsupportedUpgrade = () => {
- console.error("unsupported database migration");
- throw Error();
- };
-
shimIndexedDB(myBridgeIdbFactory);
- const myDb = await openTalerDatabase(
- myIdbFactory,
- myVersionChange,
- myUnsupportedUpgrade,
- );
+ const myDb = await openTalerDatabase(myIdbFactory, myVersionChange);
//const worker = new SynchronousCryptoWorkerFactory();
//const worker = new NodeCryptoWorkerFactory();
diff --git a/src/types/dbTypes.ts b/src/types/dbTypes.ts
index a289eeb44..f8f9880dd 100644
--- a/src/types/dbTypes.ts
+++ b/src/types/dbTypes.ts
@@ -1366,6 +1366,34 @@ export interface BankWithdrawUriRecord {
reservePub: string;
}
+export const enum ImportPayloadType {
+ CoreSchema = "core-schema",
+}
+
+/**
+ * Record to keep track of data imported into the wallet.
+ */
+export class WalletImportRecord {
+ /**
+ * Unique ID to reference this import record.
+ */
+ walletImportId: string;
+
+ /**
+ * When was the data imported?
+ */
+ timestampImportStarted: Timestamp;
+
+ timestampImportFinished: Timestamp | undefined;
+
+ payloadType: ImportPayloadType;
+
+ /**
+ * The actual data to import.
+ */
+ payload: any;
+}
+
/* tslint:disable:completed-docs */
/**
@@ -1517,6 +1545,12 @@ export namespace Stores {
}
}
+ class WalletImportsStore extends Store<WalletImportRecord> {
+ constructor() {
+ super("walletImports", { keyPath: "walletImportId" });
+ }
+ }
+
export const coins = new CoinsStore();
export const coinsReturns = new Store<CoinsReturnRecord>("coinsReturns", {
keyPath: "contractTermsHash",
@@ -1539,6 +1573,7 @@ export namespace Stores {
export const payEvents = new PayEventsStore();
export const reserveUpdatedEvents = new ReserveUpdatedEventsStore();
export const exchangeUpdatedEvents = new ExchangeUpdatedEventsStore();
+ export const walletImports = new WalletImportsStore();
}
/* tslint:enable:completed-docs */
diff --git a/src/types/schemacore.ts b/src/types/schemacore.ts
new file mode 100644
index 000000000..c709e3d7a
--- /dev/null
+++ b/src/types/schemacore.ts
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2019 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/>
+ */
+
+/**
+ * Core of the wallet's schema, used for painless export, import
+ * and schema migration.
+ *
+ * If this schema is extended, it must be extended in a completely
+ * backwards-compatible way.
+ */
+
+interface CoreCoin {
+ exchangeBaseUrl: string;
+ coinPub: string;
+ coinPriv: string;
+ amountRemaining: string;
+}
+
+interface CorePurchase {
+ noncePub: string;
+ noncePriv: string;
+ paySig: string;
+ contractTerms: any;
+}
+
+interface CoreReserve {
+ reservePub: string;
+ reservePriv: string;
+ exchangeBaseUrl: string;
+}
+
+interface SchemaCore {
+ coins: CoreCoin[];
+ purchases: CorePurchase[];
+
+ /**
+ * Schema version (of full schema) of wallet that exported the core schema.
+ */
+ versionExporter: number;
+
+ /**
+ * Schema version of the database that has been exported to the core schema
+ */
+ versionSourceDatabase: number;
+} \ No newline at end of file
diff --git a/src/util/query.ts b/src/util/query.ts
index 217c0674e..95ef30e1b 100644
--- a/src/util/query.ts
+++ b/src/util/query.ts
@@ -383,9 +383,8 @@ export function openDatabase(
idbFactory: IDBFactory,
databaseName: string,
databaseVersion: number,
- schema: any,
onVersionChange: () => void,
- onUpgradeUnsupported: (oldVersion: number, newVersion: number) => void,
+ onUpgradeNeeded: (db: IDBDatabase, oldVersion: number, newVersion: number) => void,
): Promise<IDBDatabase> {
return new Promise<IDBDatabase>((resolve, reject) => {
const req = idbFactory.open(databaseName, databaseVersion);
@@ -405,31 +404,10 @@ export function openDatabase(
};
req.onupgradeneeded = e => {
const db = req.result;
+ onUpgradeNeeded(db, e.oldVersion, e.newVersion!);
console.log(
`DB: upgrade needed: oldVersion=${e.oldVersion}, newVersion=${e.newVersion}`,
);
- switch (e.oldVersion) {
- case 0: // DB does not exist yet
- for (const n in schema) {
- if (schema[n] instanceof Store) {
- const si: Store<any> = schema[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<any, any> = (si as any)[indexName];
- s.createIndex(ii.indexName, ii.keyPath, ii.options);
- }
- }
- }
- }
- break;
- default:
- if (e.oldVersion !== databaseVersion) {
- onUpgradeUnsupported(e.oldVersion, databaseVersion);
- throw Error("incompatible DB");
- }
- break;
- }
};
});
}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index d5a08b5d7..97774a5c2 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -390,16 +390,6 @@ let outdatedDbVersion: number | undefined;
let walletInit: OpenedPromise<void> = openPromise<void>();
-function handleUpgradeUnsupported(oldDbVersion: number, newDbVersion: number) {
- console.log("DB migration not supported");
- outdatedDbVersion = oldDbVersion;
- chrome.tabs.create({
- url: chrome.extension.getURL("/src/webex/pages/reset-required.html"),
- });
- setBadgeText({ text: "err" });
- chrome.browserAction.setBadgeBackgroundColor({ color: "#F00" });
-}
-
async function reinitWallet() {
if (currentWallet) {
currentWallet.stop();
@@ -412,7 +402,6 @@ async function reinitWallet() {
currentDatabase = await openTalerDatabase(
indexedDB,
reinitWallet,
- handleUpgradeUnsupported,
);
} catch (e) {
console.error("could not open database", e);
diff --git a/tsconfig.json b/tsconfig.json
index 209721e7c..4156247a2 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -67,6 +67,7 @@
"src/types/history.ts",
"src/types/notifications.ts",
"src/types/pending.ts",
+ "src/types/schemacore.ts",
"src/types/talerTypes.ts",
"src/types/types-test.ts",
"src/types/walletTypes.ts",