From 668ffa7302d9f1629848c250904fd269979bb8b0 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 1 Dec 2021 18:16:40 +0100 Subject: wallet-core: implement exportDb API call --- packages/taler-wallet-core/src/db.ts | 31 ++++++++++++++++++++++ packages/taler-wallet-core/src/util/query.ts | 18 ++++++++++--- packages/taler-wallet-core/src/wallet-api-types.ts | 5 ++++ packages/taler-wallet-core/src/wallet.ts | 8 +++++- 4 files changed, 57 insertions(+), 5 deletions(-) (limited to 'packages/taler-wallet-core') diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 2d818f1db..4296d0503 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -41,6 +41,7 @@ import { } from "@gnu-taler/taler-util"; import { RetryInfo } from "./util/retries.js"; import { PayCoinSelection } from "./util/coinSelection.js"; +import { Event, IDBDatabase } from "@gnu-taler/idb-bridge"; /** * Name of the Taler database. This is effectively the major @@ -1773,3 +1774,33 @@ export const walletMetadataStore = { {}, ), }; + +export function exportDb(db: IDBDatabase): Promise { + const dump = { + name: db.name, + stores: {} as { [s: string]: any }, + version: db.version, + }; + + return new Promise((resolve, reject) => { + const tx = db.transaction(Array.from(db.objectStoreNames)); + tx.addEventListener("complete", () => { + resolve(dump); + }); + // tslint:disable-next-line:prefer-for-of + for (let i = 0; i < db.objectStoreNames.length; i++) { + const name = db.objectStoreNames[i]; + const storeDump = {} as { [s: string]: any }; + dump.stores[name] = storeDump; + tx.objectStore(name) + .openCursor() + .addEventListener("success", (e: Event) => { + const cursor = (e.target as any).result; + if (cursor) { + storeDump[cursor.key] = cursor.value; + cursor.continue(); + } + }); + } + }); +} diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts index a95cbf1ff..2d0fc077e 100644 --- a/packages/taler-wallet-core/src/util/query.ts +++ b/packages/taler-wallet-core/src/util/query.ts @@ -488,9 +488,12 @@ function makeReadContext( return new ResultStream(req); }, getAll(query, count) { - const req = tx.objectStore(storeName).index(indexName).getAll(query, count); + const req = tx + .objectStore(storeName) + .index(indexName) + .getAll(query, count); return requestToPromise(req); - } + }, }; } ctx[storeAlias] = { @@ -534,9 +537,12 @@ function makeWriteContext( return new ResultStream(req); }, getAll(query, count) { - const req = tx.objectStore(storeName).index(indexName).getAll(query, count); + const req = tx + .objectStore(storeName) + .index(indexName) + .getAll(query, count); return requestToPromise(req); - } + }, }; } ctx[storeAlias] = { @@ -574,6 +580,10 @@ function makeWriteContext( export class DbAccess { constructor(private db: IDBDatabase, private stores: StoreMap) {} + idbHandle(): IDBDatabase { + return this.db; + } + mktx< PickerType extends (x: StoreMap) => unknown, BoundStores extends GetPickerType diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 991c03ee2..445c0539a 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -115,6 +115,7 @@ export enum WalletApiOperation { SetWalletDeviceId = "setWalletDeviceId", ExportBackupPlain = "exportBackupPlain", WithdrawFakebank = "withdrawFakebank", + ExportDb = "exportDb", } export type WalletOperations = { @@ -270,6 +271,10 @@ export type WalletOperations = { request: TestPayArgs; response: {}; }; + [WalletApiOperation.ExportDb]: { + request: {}; + response: any; + }; }; export type RequestType< diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 7233af3af..04213ddc9 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -123,6 +123,7 @@ import { import { AuditorTrustRecord, CoinSourceType, + exportDb, ReserveRecordStatus, WalletStoresV1, } from "./db.js"; @@ -183,6 +184,7 @@ import { readSuccessResponseJsonOrThrow, } from "./util/http.js"; import { getMerchantInfo } from "./operations/merchants.js"; +import { Event, IDBDatabase } from "@gnu-taler/idb-bridge"; const builtinAuditors: AuditorTrustRecord[] = [ { @@ -953,6 +955,10 @@ async function dispatchRequestInternal( logger.info(`started fakebank withdrawal: ${j2s(fbResp)}`); return {}; } + case "exportDb": { + const dbDump = await exportDb(ws.db.idbHandle()); + return dbDump; + } } throw OperationFailedError.fromCode( TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN, @@ -997,7 +1003,7 @@ export async function handleCoreApiRequest( try { logger.error("Caught unexpected exception:"); logger.error(e.stack); - } catch (e) { } + } catch (e) {} return { type: "error", operation, -- cgit v1.2.3