taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit e9a199544f564e4acc38397c20ffef09ef6548a8
parent 15f2856f1fab6bc115de155c9a97a512ae856f37
Author: Florian Dold <dold@taler.net>
Date:   Thu,  6 Aug 2026 20:33:23 +0200

wallet-cli: drop the file-to-file database conversion

Superseded by the in-place migration: a second file to swap into place is a
step the wallet can take itself, and one the mobile wallets never could.

Issue: https://bugs.taler.net/n/11718

Diffstat:
Mpackages/taler-wallet-cli/src/index.ts | 43-------------------------------------------
Mpackages/taler-wallet-core/src/host-impl.node.ts | 63---------------------------------------------------------------
Mpackages/taler-wallet-core/src/index.node.ts | 5++---
3 files changed, 2 insertions(+), 109 deletions(-)

diff --git a/packages/taler-wallet-cli/src/index.ts b/packages/taler-wallet-cli/src/index.ts @@ -84,7 +84,6 @@ import { import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; import { JsonMessage, runRpcServer } from "@gnu-taler/taler-util/twrpc"; import { - convertWalletDbFile, createNativeWalletHost2, inspectWalletDbPath, nativeCrypto, @@ -2916,48 +2915,6 @@ const advancedCli = walletCli.subcommand("advancedArgs", "advanced", { addApiCommand(advancedCli, "advancedApi", "api"); advancedCli - .subcommand("convertDb", "convert-db", { - help: "Convert a wallet database between storage backends.", - mark: "experimental", - }) - .requiredArgument("source", clk.STRING, { - help: "Existing wallet database file to read.", - }) - .requiredArgument("dest", clk.STRING, { - help: "Fresh file to write the converted database to (must not exist).", - }) - .flag("toIdb", ["--to-indexeddb"], { - help: "Convert native-sqlite to IndexedDB instead of the default IndexedDB to native-sqlite.", - }) - .action(async (args) => { - // The source is never written to; the conversion goes into a fresh file - // and swapping it into place stays an explicit step for the operator. - const direction = args.convertDb.toIdb ? "to-idb" : "to-native"; - const report = await convertWalletDbFile( - args.convertDb.source, - args.convertDb.dest, - direction, - ); - console.log( - j2s({ - direction, - source: args.convertDb.source, - dest: args.convertDb.dest, - totalRecords: report.totalRecords, - copied: report.copied, - }), - ); - console.log(`conversion complete and verified; the original is untouched.`); - console.log( - `to switch the wallet over, move ${args.convertDb.dest} into place` + - ` yourself` + - (direction === "to-native" - ? ` and run the wallet with TALER_WALLET_NATIVE_DB=1.` - : ` and run the wallet without TALER_WALLET_NATIVE_DB.`), - ); - }); - -advancedCli .subcommand("dbMigrationInfo", "db-migration-info", { help: "Show which schema a wallet database file uses.", mark: "experimental", diff --git a/packages/taler-wallet-core/src/host-impl.node.ts b/packages/taler-wallet-core/src/host-impl.node.ts @@ -24,7 +24,6 @@ */ import { BridgeIDBFactory, - createSqliteBackend, createSqliteBackendOverDb, shimIndexedDB, } from "@gnu-taler/idb-bridge"; @@ -42,7 +41,6 @@ import { getSqlite3FilenameFromStoragePath, } from "./host-common.js"; import { openNativeSqliteWalletDb } from "./dbtx-sqlite.js"; -import { convertWalletDb, DbConversionReport } from "./db-converter.js"; import { Wallet } from "./wallet.js"; import { WalletDbHandle } from "./dbtx-handle.js"; import { @@ -174,67 +172,6 @@ export async function rollbackWalletDbMigration(dbPath: string): Promise<void> { * * Extended version that allows getting DB stats. */ -/** - * Convert a wallet database between backends, file to file. - * - * The direction is chosen by `direction`: "to-native" reads an IndexedDB - * emulation file and writes a native sqlite file, "to-idb" the reverse. - * The source is opened read-only in effect (nothing writes to it) and the - * destination must not exist yet: conversion goes into a fresh file, and - * swapping files afterwards is the caller's explicit, reversible step. - */ -export async function convertWalletDbFile( - sourcePath: string, - destPath: string, - direction: "to-native" | "to-idb", -): Promise<DbConversionReport> { - if (fs.existsSync(destPath)) { - throw Error( - `destination ${destPath} already exists; conversion only writes to a` + - ` fresh file`, - ); - } - if (!fs.existsSync(sourcePath)) { - throw Error(`source database ${sourcePath} does not exist`); - } - - const openIdb = async (filename: string) => { - const imp = await createNodeHelperSqlite3Impl(); - const backend = await createSqliteBackend(imp, { filename }); - return new IdbWalletDbHandle(new BridgeIDBFactory(backend)); - }; - const openNative = async (filename: string) => { - const imp = await createNodeHelperSqlite3Impl(); - return new SqliteWalletDbHandle( - await openNativeSqliteWalletDb(await imp.open(filename)), - ); - }; - - const src = - direction === "to-native" - ? await openIdb(sourcePath) - : await openNative(sourcePath); - const dst = - direction === "to-native" - ? await openNative(destPath) - : await openIdb(destPath); - - try { - return await convertWalletDb(src, dst); - } catch (e) { - // A failed conversion must not leave a half-written destination around - // to be mistaken for a converted database. - await dst.close(); - fs.rmSync(destPath, { force: true }); - // WAL side files of a native destination. - fs.rmSync(`${destPath}-wal`, { force: true }); - fs.rmSync(`${destPath}-shm`, { force: true }); - throw e; - } finally { - await src.close(); - } -} - export async function createNativeWalletHost2( args: DefaultNodeWalletArgs = {}, ): Promise<{ diff --git a/packages/taler-wallet-core/src/index.node.ts b/packages/taler-wallet-core/src/index.node.ts @@ -27,9 +27,8 @@ export * from "./crypto/workers/synchronousWorkerFactoryPlain.js"; export * from "./dbtx-bench.js"; export { makeIdbRunner, makeSqliteRunner } from "./dbtx-runners.js"; -// Backend-to-backend database conversion. Node-only: it opens both -// backends' files side by side. -export { convertWalletDbFile } from "./host-impl.node.js"; +// The record-by-record copy between backends, which the in-place migration +// runs. Node-only: the runners spawn the sqlite helper process. export { convertWalletDb } from "./db-converter.js"; export type { DbConversionReport } from "./db-converter.js";