wallet-core: implement exportDb API call

This commit is contained in:
Florian Dold 2021-12-01 18:16:40 +01:00
parent b0c2a73146
commit 668ffa7302
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 57 additions and 5 deletions

View File

@ -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<any> {
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();
}
});
}
});
}

View File

@ -488,9 +488,12 @@ function makeReadContext(
return new ResultStream<any>(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<any>(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<StoreMap> {
constructor(private db: IDBDatabase, private stores: StoreMap) {}
idbHandle(): IDBDatabase {
return this.db;
}
mktx<
PickerType extends (x: StoreMap) => unknown,
BoundStores extends GetPickerType<PickerType, StoreMap>

View File

@ -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<

View File

@ -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,