gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (cdf5cc58 -> 7e07ad6b)


From: gnunet
Subject: [taler-wallet-core] branch master updated (cdf5cc58 -> 7e07ad6b)
Date: Mon, 16 Nov 2020 14:48:46 +0100

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

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

    from cdf5cc58 only use version in 'make dist'
     new 292160f7 fix tip record creation, migrate DB
     new deaeb17c fix schema upgrade in memoryidb backend
     new 7e07ad6b use index to check existing tip record

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 packages/idb-bridge/src/MemoryBackend.ts         |  8 ----
 packages/taler-wallet-core/src/db.ts             | 56 +++++++++++++++++-------
 packages/taler-wallet-core/src/operations/tip.ts | 16 +++----
 packages/taler-wallet-core/src/types/dbTypes.ts  | 13 ++++--
 packages/taler-wallet-core/src/util/helpers.ts   |  4 ++
 packages/taler-wallet-core/src/util/query.ts     | 28 ++++++++++--
 packages/taler-wallet-core/src/util/taleruri.ts  |  9 ++--
 pnpm-lock.yaml                                   |  2 +-
 8 files changed, 93 insertions(+), 43 deletions(-)

diff --git a/packages/idb-bridge/src/MemoryBackend.ts 
b/packages/idb-bridge/src/MemoryBackend.ts
index e8aec766..531a7f29 100644
--- a/packages/idb-bridge/src/MemoryBackend.ts
+++ b/packages/idb-bridge/src/MemoryBackend.ts
@@ -72,7 +72,6 @@ interface Index {
 
 interface Database {
   committedObjectStores: { [name: string]: ObjectStore };
-  modifiedObjectStores: { [name: string]: ObjectStore };
   committedSchema: Schema;
   /**
    * Was the transaction deleted during the running transaction?
@@ -326,7 +325,6 @@ export class MemoryBackend implements Backend {
         committedObjectStores: objectStores,
         committedSchema: structuredClone(schema),
         connectionCookie: undefined,
-        modifiedObjectStores: {},
         txLevel: TransactionLevel.Disconnected,
         txRestrictObjectStores: undefined,
       };
@@ -448,7 +446,6 @@ export class MemoryBackend implements Backend {
         committedSchema: schema,
         deleted: false,
         committedObjectStores: {},
-        modifiedObjectStores: {},
         txLevel: TransactionLevel.Disconnected,
         connectionCookie: undefined,
         txRestrictObjectStores: undefined,
@@ -782,7 +779,6 @@ export class MemoryBackend implements Backend {
       indexes: {},
     };
     myConn.objectStoreMap[name] = { store: newObjectStore, indexMap: {} };
-    db.modifiedObjectStores[name] = newObjectStore;
   }
 
   createIndex(
@@ -820,9 +816,6 @@ export class MemoryBackend implements Backend {
       originalName: indexName,
     };
     myConn.objectStoreMap[objectStoreName].indexMap[indexName] = newIndex;
-    db.modifiedObjectStores[objectStoreName].modifiedIndexes[
-      indexName
-    ] = newIndex;
     const schema = myConn.modifiedSchema;
     if (!schema) {
       throw Error("no schema in versionchange tx");
@@ -1530,7 +1523,6 @@ export class MemoryBackend implements Backend {
     if (db.txLevel < TransactionLevel.Read) {
       throw Error("only allowed while running a transaction");
     }
-    db.modifiedObjectStores = {};
     db.txLevel = TransactionLevel.Connected;
     db.txRestrictObjectStores = undefined;
     myConn.modifiedSchema = structuredClone(db.committedSchema);
diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index b94fd154..ac3c79e2 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1,6 +1,7 @@
 import { Stores } from "./types/dbTypes";
 import { openDatabase, Database, Store, Index } from "./util/query";
-import { IDBFactory, IDBDatabase } from "idb-bridge";
+import { IDBFactory, IDBDatabase, IDBObjectStore, IDBTransaction } from 
"idb-bridge";
+import { Logger } from './util/logging';
 
 /**
  * Name of the Taler database.  This is effectively the major
@@ -17,7 +18,9 @@ const TALER_DB_NAME = "taler-wallet-prod-v1";
  * backwards-compatible way or object stores and indices
  * are added.
  */
-export const WALLET_DB_MINOR_VERSION = 1;
+export const WALLET_DB_MINOR_VERSION = 2;
+
+const logger = new Logger("db.ts");
 
 /**
  * Return a promise that resolves
@@ -31,24 +34,45 @@ export function openTalerDatabase(
     db: IDBDatabase,
     oldVersion: number,
     newVersion: number,
+    upgradeTransaction: IDBTransaction,
   ): void => {
-    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);
-              }
+    if (oldVersion === 0) {
+      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);
+            }
+          }
+        }
+      }
+      return;
+    }
+    if (oldVersion === newVersion) {
+      return;
+    }
+    logger.info(`upgrading database from ${oldVersion} to ${newVersion}`);
+    for (const n in Stores) {
+      if ((Stores as any)[n] instanceof Store) {
+        const si: Store<any> = (Stores as any)[n];
+        let s: IDBObjectStore;
+        if ((si.storeParams?.versionAdded ?? 1) > oldVersion) {
+          s = db.createObjectStore(si.name, si.storeParams);
+        } else {
+          s = upgradeTransaction.objectStore(si.name);
+        }
+        for (const indexName in si as any) {
+          if ((si as any)[indexName] instanceof Index) {
+            const ii: Index<any, any> = (si as any)[indexName];
+            if ((ii.options?.versionAdded ?? 0) > oldVersion) {
+              s.createIndex(ii.indexName, ii.keyPath, ii.options);
             }
           }
         }
-        break;
-      default:
-        throw Error("unsupported existig DB version");
+      }
     }
   };
 
diff --git a/packages/taler-wallet-core/src/operations/tip.ts 
b/packages/taler-wallet-core/src/operations/tip.ts
index 08f45eb8..1d7386b8 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -46,6 +46,7 @@ import { Logger } from "../util/logging";
 import { checkDbInvariant } from "../util/invariants";
 import { TalerErrorCode } from "../TalerErrorCode";
 import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
+import { j2s } from "../util/helpers";
 
 const logger = new Logger("operations/tip.ts");
 
@@ -68,18 +69,17 @@ export async function prepareTip(
     merchantResp,
     codecForTipPickupGetResponse(),
   );
-  logger.trace(`status ${tipPickupStatus}`);
+  logger.trace(`status ${j2s(tipPickupStatus)}`);
 
   const amount = Amounts.parseOrThrow(tipPickupStatus.tip_amount);
 
-  const merchantOrigin = new URL(res.merchantBaseUrl).origin;
-
-  let tipRecord = await ws.db.get(Stores.tips, [
-    res.merchantTipId,
-    merchantOrigin,
-  ]);
+  let tipRecord = await ws.db.getIndexed(
+    Stores.tips.byMerchantTipIdAndBaseUrl,
+    [res.merchantTipId, res.merchantBaseUrl],
+  );
 
   if (!tipRecord) {
+    logger.trace("new tip, creating tip record");
     await updateExchangeFromUrl(ws, tipPickupStatus.exchange_url);
     const withdrawDetails = await getExchangeWithdrawalInfo(
       ws,
@@ -232,7 +232,7 @@ async function processTipImpl(
   }));
 
   const tipStatusUrl = new URL(
-    `/tips/${tipRecord.merchantTipId}/pickup`,
+    `tips/${tipRecord.merchantTipId}/pickup`,
     tipRecord.merchantBaseUrl,
   );
 
diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts 
b/packages/taler-wallet-core/src/types/dbTypes.ts
index 8f6c22f2..ed3a18ae 100644
--- a/packages/taler-wallet-core/src/types/dbTypes.ts
+++ b/packages/taler-wallet-core/src/types/dbTypes.ts
@@ -361,7 +361,6 @@ export enum DenominationStatus {
   VerifiedBad,
 }
 
-
 /**
  * Denomination record as stored in the wallet's database.
  */
@@ -640,7 +639,7 @@ export interface PlanchetRecord {
   /**
    * Public key of the reserve that this planchet
    * is being withdrawn from.
-   * 
+   *
    * Can be the empty string (non-null/undefined for DB indexing)
    * if this is a tipping reserve.
    */
@@ -1532,7 +1531,6 @@ export enum ImportPayloadType {
   CoreSchema = "core-schema",
 }
 
-
 class ExchangesStore extends Store<ExchangeRecord> {
   constructor() {
     super("exchanges", { keyPath: "baseUrl" });
@@ -1624,6 +1622,15 @@ class TipsStore extends Store<TipRecord> {
   constructor() {
     super("tips", { keyPath: "walletTipId" });
   }
+  // Added in version 2
+  byMerchantTipIdAndBaseUrl = new Index<[string, string], TipRecord>(
+    this,
+    "tipsByMerchantTipIdAndOriginIndex",
+    ["merchantTipId", "merchantBaseUrl"],
+    {
+      versionAdded: 2,
+    }
+  );
 }
 
 class WithdrawalGroupsStore extends Store<WithdrawalGroupRecord> {
diff --git a/packages/taler-wallet-core/src/util/helpers.ts 
b/packages/taler-wallet-core/src/util/helpers.ts
index ae4b0359..570df441 100644
--- a/packages/taler-wallet-core/src/util/helpers.ts
+++ b/packages/taler-wallet-core/src/util/helpers.ts
@@ -146,3 +146,7 @@ export function strcmp(s1: string, s2: string): number {
   }
   return 0;
 }
+
+export function j2s(x: any): string {
+  return JSON.stringify(x, undefined, 2);
+}
\ No newline at end of file
diff --git a/packages/taler-wallet-core/src/util/query.ts 
b/packages/taler-wallet-core/src/util/query.ts
index 6ebc3bbc..f533c4cf 100644
--- a/packages/taler-wallet-core/src/util/query.ts
+++ b/packages/taler-wallet-core/src/util/query.ts
@@ -44,14 +44,25 @@ const logger = new Logger("query.ts");
  */
 export const TransactionAbort = Symbol("transaction_abort");
 
+export interface StoreParams<T> {
+  validator?: (v: T) => T;
+  autoIncrement?: boolean;
+  keyPath?: string | string[] | null;
+
+  /**
+   * Database version that this store was added in, or
+   * undefined if added in the first version.
+   */
+  versionAdded?: number;
+}
+
 /**
  * Definition of an object store.
  */
 export class Store<T> {
   constructor(
     public name: string,
-    public storeParams?: IDBObjectStoreParameters,
-    public validator?: (v: T) => T,
+    public storeParams?: StoreParams<T>,
   ) {}
 }
 
@@ -66,6 +77,12 @@ export interface IndexOptions {
    * Defaults to false.
    */
   multiEntry?: boolean;
+
+  /**
+   * Database version that this store was added in, or
+   * undefined if added in the first version.
+   */
+  versionAdded?: number;
 }
 
 function requestToPromise(req: IDBRequest): Promise<any> {
@@ -425,6 +442,7 @@ export function openDatabase(
     db: IDBDatabase,
     oldVersion: number,
     newVersion: number,
+    upgradeTransaction: IDBTransaction,
   ) => void,
 ): Promise<IDBDatabase> {
   return new Promise<IDBDatabase>((resolve, reject) => {
@@ -449,7 +467,11 @@ export function openDatabase(
       if (!newVersion) {
         throw Error("upgrade needed, but new version unknown");
       }
-      onUpgradeNeeded(db, e.oldVersion, newVersion);
+      const transaction = req.transaction;
+      if (!transaction) {
+        throw Error("no transaction handle available in upgrade handler");
+      }
+      onUpgradeNeeded(db, e.oldVersion, newVersion, transaction);
     };
   });
 }
diff --git a/packages/taler-wallet-core/src/util/taleruri.ts 
b/packages/taler-wallet-core/src/util/taleruri.ts
index 839d0b29..ee055a32 100644
--- a/packages/taler-wallet-core/src/util/taleruri.ts
+++ b/packages/taler-wallet-core/src/util/taleruri.ts
@@ -14,6 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
+import { canonicalizeBaseUrl } from './helpers';
 import { URLSearchParams } from "./url";
 
 export interface PayUriResult {
@@ -59,7 +60,7 @@ export function parseWithdrawUri(s: string): 
WithdrawUriResult | undefined {
   const p = [host, ...pathSegments].join("/");
 
   return {
-    bankIntegrationApiBaseUrl: `${pi.innerProto}://${p}/`,
+    bankIntegrationApiBaseUrl: canonicalizeBaseUrl(`${pi.innerProto}://${p}/`),
     withdrawalOperationId: withdrawId,
   };
 }
@@ -155,7 +156,7 @@ export function parsePayUri(s: string): PayUriResult | 
undefined {
   const orderId = parts[parts.length - 2];
   const pathSegments = parts.slice(1, parts.length - 2);
   const p = [host, ...pathSegments].join("/");
-  const merchantBaseUrl = `${pi.innerProto}://${p}/`;
+  const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
 
   return {
     merchantBaseUrl,
@@ -183,7 +184,7 @@ export function parseTipUri(s: string): TipUriResult | 
undefined {
   const tipId = parts[parts.length - 1];
   const pathSegments = parts.slice(1, parts.length - 1);
   const p = [host, ...pathSegments].join("/");
-  const merchantBaseUrl = `${pi.innerProto}://${p}/`;
+  const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
 
   return {
     merchantBaseUrl,
@@ -210,7 +211,7 @@ export function parseRefundUri(s: string): RefundUriResult 
| undefined {
   const orderId = parts[parts.length - 2];
   const pathSegments = parts.slice(1, parts.length - 2);
   const p = [host, ...pathSegments].join("/");
-  const merchantBaseUrl = `${pi.innerProto}://${p}/`;
+  const merchantBaseUrl = canonicalizeBaseUrl(`${pi.innerProto}://${p}/`);
 
   return {
     merchantBaseUrl,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f8b23685..5bca329c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -233,7 +233,7 @@ importers:
       taler-wallet-core: 'workspace:*'
       tslib: ^2.0.1
       typescript: ^3.9.7
-lockfileVersion: 5.1
+lockfileVersion: 5.2
 packages:
   /@ava/typescript/1.1.1:
     dependencies:

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