gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 03/03: wallet-core: DB improvements


From: gnunet
Subject: [taler-wallet-core] 03/03: wallet-core: DB improvements
Date: Wed, 21 Sep 2022 22:50:52 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 4649469b58b9a4068fa94de07f415f1bbc58794c
Author: Florian Dold <florian@dold.me>
AuthorDate: Wed Sep 21 21:47:00 2022 +0200

    wallet-core: DB improvements
---
 packages/idb-bridge/src/bridge-idb.ts              | 37 +++++++++-----------
 packages/taler-wallet-core/src/db-utils.ts         |  1 +
 packages/taler-wallet-core/src/db.ts               | 23 ++++++++++---
 .../taler-wallet-core/src/operations/recoup.ts     |  4 ++-
 packages/taler-wallet-core/src/util/query.ts       | 40 ++++++++++++++++++----
 5 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/packages/idb-bridge/src/bridge-idb.ts 
b/packages/idb-bridge/src/bridge-idb.ts
index 35cedb1db..128a6900d 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -57,16 +57,17 @@ import {
   TransactionInactiveError,
   VersionError,
 } from "./util/errors.js";
-import { FakeDOMStringList, fakeDOMStringList } from 
"./util/fakeDOMStringList.js";
+import {
+  FakeDOMStringList,
+  fakeDOMStringList,
+} from "./util/fakeDOMStringList.js";
 import FakeEvent from "./util/FakeEvent.js";
 import FakeEventTarget from "./util/FakeEventTarget.js";
 import { makeStoreKeyValue } from "./util/makeStoreKeyValue.js";
 import { normalizeKeyPath } from "./util/normalizeKeyPath.js";
 import { openPromise } from "./util/openPromise.js";
 import queueTask from "./util/queueTask.js";
-import {
-  checkStructuredCloneOrThrow,
-} from "./util/structuredClone.js";
+import { checkStructuredCloneOrThrow } from "./util/structuredClone.js";
 import { validateKeyPath } from "./util/validateKeyPath.js";
 import { valueToKey } from "./util/valueToKey.js";
 
@@ -933,9 +934,8 @@ export class BridgeIDBFactory {
         );
 
         // We need to expose the new version number to the upgrade transaction.
-        db._schema = this.backend.getCurrentTransactionSchema(
-          backendTransaction,
-        );
+        db._schema =
+          this.backend.getCurrentTransactionSchema(backendTransaction);
 
         const transaction = db._internalTransaction(
           [],
@@ -1110,9 +1110,8 @@ export class BridgeIDBIndex implements IDBIndex {
 
     this._backend.renameIndex(btx, this._objectStore.name, oldName, newName);
 
-    this._objectStore._transaction._db._schema = 
this._backend.getCurrentTransactionSchema(
-      btx,
-    );
+    this._objectStore._transaction._db._schema =
+      this._backend.getCurrentTransactionSchema(btx);
 
     this._objectStore._indexesCache.delete(oldName);
     this._objectStore._indexesCache.set(newName, this);
@@ -1629,9 +1628,8 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     }
 
     this._backend.renameObjectStore(btx, oldName, newName);
-    this._transaction._db._schema = this._backend.getCurrentTransactionSchema(
-      btx,
-    );
+    this._transaction._db._schema =
+      this._backend.getCurrentTransactionSchema(btx);
 
     // We don't modify scope, as the scope of the transaction
     // doesn't matter if we're in an upgrade transaction.
@@ -2235,11 +2233,8 @@ export class BridgeIDBRequest extends FakeEventTarget 
implements IDBRequest {
     }
     return this._source;
   }
-  _source:
-    | BridgeIDBCursor
-    | BridgeIDBIndex
-    | BridgeIDBObjectStore
-    | null = null;
+  _source: BridgeIDBCursor | BridgeIDBIndex | BridgeIDBObjectStore | null =
+    null;
   transaction: BridgeIDBTransaction | null = null;
   readyState: "done" | "pending" = "pending";
   onsuccess: EventListener | null = null;
@@ -2302,7 +2297,8 @@ export class BridgeIDBRequest extends FakeEventTarget 
implements IDBRequest {
 /** @public */
 export class BridgeIDBOpenDBRequest
   extends BridgeIDBRequest
-  implements IDBOpenDBRequest {
+  implements IDBOpenDBRequest
+{
   public onupgradeneeded: EventListener | null = null;
   public onblocked: EventListener | null = null;
 
@@ -2350,7 +2346,8 @@ function waitMacroQueue(): Promise<void> {
 /** @public */
 export class BridgeIDBTransaction
   extends FakeEventTarget
-  implements IDBTransaction {
+  implements IDBTransaction
+{
   _committed: boolean = false;
   /**
    * A transaction is active as long as new operations can be
diff --git a/packages/taler-wallet-core/src/db-utils.ts 
b/packages/taler-wallet-core/src/db-utils.ts
index b32b3d585..7f4b0de45 100644
--- a/packages/taler-wallet-core/src/db-utils.ts
+++ b/packages/taler-wallet-core/src/db-utils.ts
@@ -60,6 +60,7 @@ function upgradeFromStoreMap(
         const indexDesc: IndexDescriptor = swi.indexMap[indexName];
         s.createIndex(indexDesc.name, indexDesc.keyPath, {
           multiEntry: indexDesc.multiEntry,
+          unique: indexDesc.unique,
         });
       }
     }
diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index 493f1a1d0..8b96dd5be 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -527,6 +527,8 @@ export interface ExchangeRecord {
   /**
    * Public key of the reserve that we're currently using for
    * receiving P2P payments.
+   *
+   * FIXME: Make this a rowId of reserves!
    */
   currentMergeReserveInfo?: MergeReserveInfo;
 }
@@ -569,6 +571,8 @@ export interface PlanchetRecord {
    *
    * Can be the empty string (non-null/undefined for DB indexing)
    * if this is a tipping reserve.
+   *
+   * FIXME: Where is this used?
    */
   reservePub: string;
 
@@ -763,6 +767,8 @@ export interface ProposalDownload {
 
   /**
    * Extracted / parsed data from the contract terms.
+   *
+   * FIXME: Do we need to store *all* that data in duplicate?
    */
   contractData: WalletContractData;
 }
@@ -1762,9 +1768,14 @@ export interface PeerPullPaymentIncomingRecord {
   contractPriv: string;
 }
 
-// FIXME: give this some smaller "row ID" to
-// reference in other records?
+/**
+ * Store for extra information about a reserve.
+ *
+ * Mostly used to store the private key for a reserve and to allow
+ * other records to reference the reserve key pair via a small row ID.
+ */
 export interface ReserveRecord {
+  rowId?: number;
   reservePub: string;
   reservePriv: string;
 }
@@ -1844,9 +1855,12 @@ export const WalletStoresV1 = {
   reserves: describeStore(
     "reserves",
     describeContents<ReserveRecord>({
-      keyPath: "reservePub",
+      keyPath: "rowId",
+      autoIncrement: true,
     }),
-    {},
+    {
+      byReservePub: describeIndex("byReservePub", "reservePub", {}),
+    },
   ),
   config: describeStore(
     "config",
@@ -1956,7 +1970,6 @@ export const WalletStoresV1 = {
       keyPath: "withdrawalGroupId",
     }),
     {
-      byReservePub: describeIndex("byReservePub", "reservePub"),
       byStatus: describeIndex("byStatus", "status"),
       byTalerWithdrawUri: describeIndex(
         "byTalerWithdrawUri",
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts 
b/packages/taler-wallet-core/src/operations/recoup.ts
index 6d899b947..2d92ff8ba 100644
--- a/packages/taler-wallet-core/src/operations/recoup.ts
+++ b/packages/taler-wallet-core/src/operations/recoup.ts
@@ -356,7 +356,9 @@ export async function processRecoupGroupHandler(
           throw Error(`Coin ${coinPub} not found, can't request recoup`);
         }
         if (coin.coinSource.type === CoinSourceType.Withdraw) {
-          const reserve = await tx.reserves.get(coin.coinSource.reservePub);
+          const reserve = await tx.reserves.indexes.byReservePub.get(
+            coin.coinSource.reservePub,
+          );
           if (!reserve) {
             return;
           }
diff --git a/packages/taler-wallet-core/src/util/query.ts 
b/packages/taler-wallet-core/src/util/query.ts
index 3d4ff79cb..71d7b9783 100644
--- a/packages/taler-wallet-core/src/util/query.ts
+++ b/packages/taler-wallet-core/src/util/query.ts
@@ -61,6 +61,13 @@ export interface IndexOptions {
    * undefined if added in the first version.
    */
   versionAdded?: number;
+
+  /**
+   * Does this index enforce unique keys?
+   *
+   * Defaults to false.
+   */
+  unique?: boolean;
 }
 
 function requestToPromise(req: IDBRequest): Promise<any> {
@@ -276,6 +283,7 @@ export interface IndexDescriptor {
   name: string;
   keyPath: IDBKeyPath | IDBKeyPath[];
   multiEntry?: boolean;
+  unique?: boolean;
 }
 
 export interface StoreDescriptor<RecordType> {
@@ -292,7 +300,11 @@ export interface StoreOptions {
 export function describeContents<RecordType = never>(
   options: StoreOptions,
 ): StoreDescriptor<RecordType> {
-  return { keyPath: options.keyPath, _dummy: undefined as any };
+  return {
+    keyPath: options.keyPath,
+    _dummy: undefined as any,
+    autoIncrement: options.autoIncrement,
+  };
 }
 
 export function describeIndex(
@@ -304,6 +316,7 @@ export function describeIndex(
     keyPath,
     name,
     multiEntry: options.multiEntry,
+    unique: options.unique,
   };
 }
 
@@ -339,11 +352,18 @@ export interface StoreReadOnlyAccessor<RecordType, 
IndexMap> {
   indexes: GetIndexReadOnlyAccess<RecordType, IndexMap>;
 }
 
+export interface InsertResponse {
+  /**
+   * Key of the newly inserted (via put/add) record.
+   */
+  key: IDBValidKey;
+}
+
 export interface StoreReadWriteAccessor<RecordType, IndexMap> {
   get(key: IDBValidKey): Promise<RecordType | undefined>;
   iter(query?: IDBValidKey): ResultStream<RecordType>;
-  put(r: RecordType): Promise<void>;
-  add(r: RecordType): Promise<void>;
+  put(r: RecordType): Promise<InsertResponse>;
+  add(r: RecordType): Promise<InsertResponse>;
   delete(key: IDBValidKey): Promise<void>;
   indexes: GetIndexReadWriteAccess<RecordType, IndexMap>;
 }
@@ -577,13 +597,19 @@ function makeWriteContext(
         const req = tx.objectStore(storeName).openCursor(query);
         return new ResultStream<any>(req);
       },
-      add(r) {
+      async add(r) {
         const req = tx.objectStore(storeName).add(r);
-        return requestToPromise(req);
+        const key = await requestToPromise(req);
+        return {
+          key: key,
+        };
       },
-      put(r) {
+      async put(r) {
         const req = tx.objectStore(storeName).put(r);
-        return requestToPromise(req);
+        const key = await requestToPromise(req);
+        return {
+          key: key,
+        };
       },
       delete(k) {
         const req = tx.objectStore(storeName).delete(k);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]