gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: idb: implement missing method


From: gnunet
Subject: [taler-wallet-core] branch master updated: idb: implement missing methods
Date: Tue, 23 Feb 2021 20:16:16 +0100

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 9c85f627 idb: implement missing methods
9c85f627 is described below

commit 9c85f6277bf85606eb4fbbca47f1a1b5404d2a2e
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Feb 23 20:16:10 2021 +0100

    idb: implement missing methods
---
 packages/idb-bridge/src/MemoryBackend.ts     |  39 ++++
 packages/idb-bridge/src/backend-interface.ts |   5 +
 packages/idb-bridge/src/bridge-idb.ts        | 299 ++++++++++++++++++++++++++-
 pnpm-lock.yaml                               |  55 ++++-
 4 files changed, 387 insertions(+), 11 deletions(-)

diff --git a/packages/idb-bridge/src/MemoryBackend.ts 
b/packages/idb-bridge/src/MemoryBackend.ts
index 2317fb16..68f60f75 100644
--- a/packages/idb-bridge/src/MemoryBackend.ts
+++ b/packages/idb-bridge/src/MemoryBackend.ts
@@ -860,6 +860,45 @@ export class MemoryBackend implements Backend {
     });
   }
 
+  async clearObjectStore(
+    btx: DatabaseTransaction,
+    objectStoreName: string,
+  ): Promise<void> {
+    const myConn = this.requireConnectionFromTransaction(btx);
+    const db = this.databases[myConn.dbName];
+    if (!db) {
+      throw Error("db not found");
+    }
+    if (db.txLevel < TransactionLevel.Write) {
+      throw Error("only allowed in write transaction");
+    }
+    if (
+      db.txRestrictObjectStores &&
+      !db.txRestrictObjectStores.includes(objectStoreName)
+    ) {
+      throw Error(
+        `Not allowed to access store '${objectStoreName}', transaction is over 
${JSON.stringify(
+          db.txRestrictObjectStores,
+        )}`,
+      );
+    }
+
+    const schema = myConn.modifiedSchema;
+    const objectStoreMapEntry = myConn.objectStoreMap[objectStoreName];
+
+    objectStoreMapEntry.store.modifiedData = new BTree([], compareKeys);
+
+    for (const indexName of Object.keys(
+      schema.objectStores[objectStoreName].indexes,
+    )) {
+      const index = myConn.objectStoreMap[objectStoreName].indexMap[indexName];
+      if (!index) {
+        throw Error("index referenced by object store does not exist");
+      }
+      index.modifiedData = new BTree([], compareKeys);
+    }
+  }
+
   async deleteRecord(
     btx: DatabaseTransaction,
     objectStoreName: string,
diff --git a/packages/idb-bridge/src/backend-interface.ts 
b/packages/idb-bridge/src/backend-interface.ts
index 3d295384..5ca70c8a 100644
--- a/packages/idb-bridge/src/backend-interface.ts
+++ b/packages/idb-bridge/src/backend-interface.ts
@@ -216,4 +216,9 @@ export interface Backend {
     btx: DatabaseTransaction,
     storeReq: RecordStoreRequest,
   ): Promise<RecordStoreResponse>;
+
+  clearObjectStore(
+    btx: DatabaseTransaction,
+    objectStoreName: string,
+  ): Promise<void>
 }
diff --git a/packages/idb-bridge/src/bridge-idb.ts 
b/packages/idb-bridge/src/bridge-idb.ts
index 744ad1ae..3c168674 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -1234,11 +1234,48 @@ export class BridgeIDBIndex implements IDBIndex {
     query?: BridgeIDBKeyRange | IDBValidKey,
     count?: number,
   ): IDBRequest<any[]> {
-    throw Error("not implemented");
+    this._confirmIndexExists();
+    this._confirmActiveTransaction();
+    if (this._deleted) {
+      throw new InvalidStateError();
+    }
+
+    if (!(query instanceof BridgeIDBKeyRange)) {
+      query = BridgeIDBKeyRange._valueToKeyRange(query);
+    }
+
+    if (count === undefined) {
+      count = -1;
+    }
+
+    const getReq: RecordGetRequest = {
+      direction: "next",
+      indexName: this._name,
+      limit: count,
+      range: query,
+      objectStoreName: this._objectStore._name,
+      resultLevel: ResultLevel.Full,
+    };
+
+    const operation = async () => {
+      const { btx } = this._confirmStartedBackendTransaction();
+      const result = await this._backend.getRecords(btx, getReq);
+      const values = result.values;
+      if (!values) {
+        throw Error("invariant violated");
+      }
+      return values.map((x) => structuredRevive(x));
+    };
+
+    return this._objectStore._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
   // 
http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBIndex-getKey-IDBRequest-any-key
   public getKey(key: BridgeIDBKeyRange | IDBValidKey) {
+    this._confirmIndexExists();
     this._confirmActiveTransaction();
 
     if (!(key instanceof BridgeIDBKeyRange)) {
@@ -1278,11 +1315,45 @@ export class BridgeIDBIndex implements IDBIndex {
     query?: BridgeIDBKeyRange | IDBValidKey,
     count?: number,
   ): IDBRequest<IDBValidKey[]> {
-    throw Error("not implemented");
+    this._confirmIndexExists();
+    this._confirmActiveTransaction();
+
+    if (!(query instanceof BridgeIDBKeyRange)) {
+      query = BridgeIDBKeyRange._valueToKeyRange(query);
+    }
+
+    if (count === undefined) {
+      count = -1;
+    }
+
+    const getReq: RecordGetRequest = {
+      direction: "next",
+      indexName: this._name,
+      limit: count,
+      range: query,
+      objectStoreName: this._objectStore._name,
+      resultLevel: ResultLevel.OnlyKeys,
+    };
+
+    const operation = async () => {
+      const { btx } = this._confirmStartedBackendTransaction();
+      const result = await this._backend.getRecords(btx, getReq);
+      const primaryKeys = result.primaryKeys;
+      if (!primaryKeys) {
+        throw Error("invariant violated");
+      }
+      return primaryKeys;
+    };
+
+    return this._objectStore._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
   // 
http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBIndex-count-IDBRequest-any-key
   public count(key: BridgeIDBKeyRange | IDBValidKey | null | undefined) {
+    this._confirmIndexExists();
     this._confirmActiveTransaction();
 
     if (key === null) {
@@ -1718,14 +1789,147 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     query?: BridgeIDBKeyRange | IDBValidKey,
     count?: number,
   ): IDBRequest<any[]> {
-    throw Error("not implemented");
+    if (BridgeIDBFactory.enableTracing) {
+      console.log(`getting from object store ${this._name} key ${query}`);
+    }
+
+    if (arguments.length === 0) {
+      throw new TypeError();
+    }
+
+    if (!this._transaction._active) {
+      throw new TransactionInactiveError();
+    }
+
+    if (this._deleted) {
+      throw new InvalidStateError(
+        "tried to call 'delete' on a deleted object store",
+      );
+    }
+
+    if (count === undefined) {
+      count = -1;
+    }
+
+    let keyRange: BridgeIDBKeyRange;
+
+    if (query instanceof BridgeIDBKeyRange) {
+      keyRange = query;
+    } else {
+      try {
+        keyRange = BridgeIDBKeyRange.only(valueToKey(query));
+      } catch (e) {
+        throw new DataError(
+          `invalid key (type ${typeof query}) for object store 
'${this._name}'`,
+        );
+      }
+    }
+
+    const recordRequest: RecordGetRequest = {
+      objectStoreName: this._name,
+      indexName: undefined,
+      lastIndexPosition: undefined,
+      lastObjectStorePosition: undefined,
+      direction: "next",
+      limit: count,
+      resultLevel: ResultLevel.Full,
+      range: keyRange,
+    };
+
+    const operation = async () => {
+      if (BridgeIDBFactory.enableTracing) {
+        console.log("running getAll operation:", recordRequest);
+      }
+      const { btx } = this._confirmStartedBackendTransaction();
+      const result = await this._backend.getRecords(btx, recordRequest);
+
+      if (BridgeIDBFactory.enableTracing) {
+        console.log("get operation result count:", result.count);
+      }
+      const values = result.values;
+      if (!values) {
+        throw Error("invariant violated");
+      }
+      return values.map((x) => structuredRevive(x));
+    };
+
+    return this._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
   // http://w3c.github.io/IndexedDB/#dom-idbobjectstore-getkey
   public getKey(
-    key?: BridgeIDBKeyRange | IDBValidKey,
+    query?: BridgeIDBKeyRange | IDBValidKey,
   ): IDBRequest<IDBValidKey | undefined> {
-    throw Error("not implemented");
+    if (arguments.length === 0) {
+      throw new TypeError();
+    }
+
+    if (!this._transaction._active) {
+      throw new TransactionInactiveError();
+    }
+
+    if (this._deleted) {
+      throw new InvalidStateError(
+        "tried to call 'delete' on a deleted object store",
+      );
+    }
+
+    let keyRange: BridgeIDBKeyRange;
+
+    if (query instanceof BridgeIDBKeyRange) {
+      keyRange = query;
+    } else {
+      try {
+        keyRange = BridgeIDBKeyRange.only(valueToKey(query));
+      } catch (e) {
+        throw new DataError(
+          `invalid key (type ${typeof query}) for object store 
'${this._name}'`,
+        );
+      }
+    }
+
+    const recordRequest: RecordGetRequest = {
+      objectStoreName: this._name,
+      indexName: undefined,
+      lastIndexPosition: undefined,
+      lastObjectStorePosition: undefined,
+      direction: "next",
+      limit: 1,
+      resultLevel: ResultLevel.OnlyKeys,
+      range: keyRange,
+    };
+
+    const operation = async () => {
+      if (BridgeIDBFactory.enableTracing) {
+        console.log("running get operation:", recordRequest);
+      }
+      const { btx } = this._confirmStartedBackendTransaction();
+      const result = await this._backend.getRecords(btx, recordRequest);
+
+      if (BridgeIDBFactory.enableTracing) {
+        console.log("get operation result count:", result.count);
+      }
+
+      if (result.count === 0) {
+        return undefined;
+      }
+      const primaryKeys = result.primaryKeys;
+      if (!primaryKeys) {
+        throw Error("invariant violated");
+      }
+      if (primaryKeys.length !== 1) {
+        throw Error("invariant violated");
+      }
+      return structuredRevive(primaryKeys[0]);
+    };
+
+    return this._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
   // http://w3c.github.io/IndexedDB/#dom-idbobjectstore-getallkeys
@@ -1733,11 +1937,86 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     query?: BridgeIDBKeyRange | IDBValidKey,
     count?: number,
   ): IDBRequest<any[]> {
-    throw Error("not implemented");
+    if (arguments.length === 0) {
+      throw new TypeError();
+    }
+
+    if (!this._transaction._active) {
+      throw new TransactionInactiveError();
+    }
+
+    if (this._deleted) {
+      throw new InvalidStateError(
+        "tried to call 'delete' on a deleted object store",
+      );
+    }
+
+    if (count === undefined) {
+      count = -1;
+    }
+
+    let keyRange: BridgeIDBKeyRange;
+
+    if (query instanceof BridgeIDBKeyRange) {
+      keyRange = query;
+    } else {
+      try {
+        keyRange = BridgeIDBKeyRange.only(valueToKey(query));
+      } catch (e) {
+        throw new DataError(
+          `invalid key (type ${typeof query}) for object store 
'${this._name}'`,
+        );
+      }
+    }
+
+    const recordRequest: RecordGetRequest = {
+      objectStoreName: this._name,
+      indexName: undefined,
+      lastIndexPosition: undefined,
+      lastObjectStorePosition: undefined,
+      direction: "next",
+      limit: count,
+      resultLevel: ResultLevel.OnlyKeys,
+      range: keyRange,
+    };
+
+    const operation = async () => {
+      const { btx } = this._confirmStartedBackendTransaction();
+      const result = await this._backend.getRecords(btx, recordRequest);
+
+      const primaryKeys = result.primaryKeys;
+      if (!primaryKeys) {
+        throw Error("invariant violated");
+      }
+      return primaryKeys.map((x) => structuredRevive(x));
+    };
+
+    return this._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
-  public clear(): IDBRequest<undefined> {
-    throw Error("not implemented");
+  public clear(): IDBRequest {
+    if (!this._transaction._active) {
+      throw new TransactionInactiveError();
+    }
+
+    if (this._deleted) {
+      throw new InvalidStateError(
+        "tried to call 'delete' on a deleted object store",
+      );
+    }
+
+    const operation = async () => {
+      const { btx } = this._confirmStartedBackendTransaction();
+      await this._backend.clearObjectStore(btx, this._name);
+    };
+
+    return this._transaction._execRequestAsync({
+      operation,
+      source: this,
+    });
   }
 
   public openCursor(
@@ -2228,12 +2507,12 @@ export class BridgeIDBTransaction
     if (this._db._upgradeTransaction) {
       for (const os of this._usedObjectStores) {
         if (os._justCreated) {
-          os._deleted = true
+          os._deleted = true;
         }
       }
       for (const ind of this._usedIndexes) {
         if (ind._justCreated) {
-          ind._deleted = true
+          ind._deleted = true;
         }
       }
     }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 70a45839..be4eac3a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7,6 +7,9 @@ importers:
       typeson: 5.18.2
       typeson-registry: 1.0.0-alpha.38
     devDependencies:
+      '@rollup/plugin-commonjs': 17.1.0_rollup@2.37.1
+      '@rollup/plugin-json': 4.1.0_rollup@2.37.1
+      '@rollup/plugin-node-resolve': 11.2.0_rollup@2.37.1
       '@types/node': 14.14.22
       ava: 3.15.0
       esm: 3.2.25
@@ -15,6 +18,9 @@ importers:
       rollup: 2.37.1
       typescript: 4.1.3
     specifiers:
+      '@rollup/plugin-commonjs': ^17.1.0
+      '@rollup/plugin-json': ^4.1.0
+      '@rollup/plugin-node-resolve': ^11.2.0
       '@types/node': ^14.14.22
       ava: ^3.15.0
       esm: ^3.2.25
@@ -520,6 +526,23 @@ packages:
       rollup: ^2.30.0
     resolution:
       integrity: 
sha512-/omBIJG1nHQc+bgkYDuLpb/V08QyutP9amOrJRUSlYJZP+b/68gM//D8sxJe3Yry2QnYIr3QjR3x4AlxJEN3GA==
+  /@rollup/plugin-commonjs/17.1.0_rollup@2.37.1:
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@2.37.1
+      commondir: 1.0.1
+      estree-walker: 2.0.2
+      glob: 7.1.6
+      is-reference: 1.2.1
+      magic-string: 0.25.7
+      resolve: 1.20.0
+      rollup: 2.37.1
+    dev: true
+    engines:
+      node: '>= 8.0.0'
+    peerDependencies:
+      rollup: ^2.30.0
+    resolution:
+      integrity: 
sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==
   /@rollup/plugin-json/4.1.0_rollup@2.37.1:
     dependencies:
       '@rollup/pluginutils': 3.1.0_rollup@2.37.1
@@ -545,6 +568,22 @@ packages:
       rollup: ^1.20.0||^2.0.0
     resolution:
       integrity: 
sha512-ouBBppRdWJKCllDXGzJ7ZIkYbaq+5TmyP0smt1vdJCFfoZhLi31vhpmjLhyo8lreHf4RoeSNllaWrvSqHpHRog==
+  /@rollup/plugin-node-resolve/11.2.0_rollup@2.37.1:
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@2.37.1
+      '@types/resolve': 1.17.1
+      builtin-modules: 3.2.0
+      deepmerge: 4.2.2
+      is-module: 1.0.0
+      resolve: 1.20.0
+      rollup: 2.37.1
+    dev: true
+    engines:
+      node: '>= 10.0.0'
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
+    resolution:
+      integrity: 
sha512-qHjNIKYt5pCcn+5RUBQxK8krhRvf1HnyVgUCcFFcweDS7fhkOLZeYh0mhHK6Ery8/bb9tvN/ubPzmfF0qjDCTA==
   /@rollup/plugin-replace/2.3.4_rollup@2.37.1:
     dependencies:
       '@rollup/pluginutils': 3.1.0_rollup@2.37.1
@@ -684,6 +723,10 @@ packages:
   /@types/node/14.14.22:
     resolution:
       integrity: 
sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
+  /@types/node/14.14.31:
+    dev: true
+    resolution:
+      integrity: 
sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
   /@types/normalize-package-data/2.4.0:
     dev: true
     resolution:
@@ -707,7 +750,7 @@ packages:
       integrity: 
sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==
   /@types/resolve/1.17.1:
     dependencies:
-      '@types/node': 14.14.22
+      '@types/node': 14.14.31
     dev: true
     resolution:
       integrity: 
sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==
@@ -3296,6 +3339,7 @@ packages:
     resolution:
       integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA=
   /lodash.sortby/4.7.0:
+    dev: false
     resolution:
       integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
   /lodash/4.17.20:
@@ -4239,6 +4283,13 @@ packages:
     dev: true
     resolution:
       integrity: 
sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
+  /resolve/1.20.0:
+    dependencies:
+      is-core-module: 2.2.0
+      path-parse: 1.0.6
+    dev: true
+    resolution:
+      integrity: 
sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
   /responselike/1.0.2:
     dependencies:
       lowercase-keys: 1.0.1
@@ -4781,6 +4832,7 @@ packages:
   /tr46/2.0.2:
     dependencies:
       punycode: 2.1.1
+    dev: false
     engines:
       node: '>=8'
     resolution:
@@ -5015,6 +5067,7 @@ packages:
     resolution:
       integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
   /webidl-conversions/6.1.0:
+    dev: false
     engines:
       node: '>=10.4'
     resolution:

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