aboutsummaryrefslogtreecommitdiff
path: root/extension/background/query.ts
diff options
context:
space:
mode:
Diffstat (limited to 'extension/background/query.ts')
-rw-r--r--extension/background/query.ts283
1 files changed, 0 insertions, 283 deletions
diff --git a/extension/background/query.ts b/extension/background/query.ts
deleted file mode 100644
index 61847a74d..000000000
--- a/extension/background/query.ts
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- This file is part of TALER
- (C) 2016 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
- */
-
-/// <reference path="../decl/chrome/chrome.d.ts" />
-
-
-/**
- * Database query abstractions.
- * @module Query
- * @author Florian Dold
- */
-
-"use strict";
-
-
-function Query(db) {
- return new QueryRoot(db);
-}
-
-
-abstract class QueryStreamBase {
- abstract subscribe(f: (isDone: boolean, value: any) => void);
-
- root: QueryRoot;
-
- constructor(root: QueryRoot) {
- this.root = root;
- }
-
- indexJoin(storeName: string, indexName: string, key: any): QueryStreamBase {
- // join on the source relation's key, which may be
- // a path or a transformer function
- this.root.stores.add(storeName);
- return new QueryStreamIndexJoin(this, storeName, indexName, key);
- }
-
- filter(f: (any) => boolean): QueryStreamBase {
- return new QueryStreamFilter(this, f);
- }
-
- reduce(f, acc?): Promise<any> {
- let leakedResolve;
- let p = new Promise((resolve, reject) => {
- leakedResolve = resolve;
- });
-
- this.subscribe((isDone, value) => {
- if (isDone) {
- leakedResolve(acc);
- return;
- }
- acc = f(value, acc);
- });
-
- return Promise.resolve().then(() => this.root.finish().then(() => p));
- }
-}
-
-
-class QueryStreamFilter extends QueryStreamBase {
- s: QueryStreamBase;
- filterFn;
-
- constructor(s: QueryStreamBase, filterFn) {
- super(s.root);
- this.s = s;
- this.filterFn = filterFn;
- }
-
- subscribe(f) {
- this.s.subscribe((isDone, value) => {
- if (isDone) {
- f(true, undefined);
- return;
- }
- if (this.filterFn(value)) {
- f(false, value)
- }
- });
- }
-}
-
-
-class QueryStreamIndexJoin extends QueryStreamBase {
- s: QueryStreamBase;
- storeName;
- key;
- indexName;
-
- constructor(s, storeName: string, indexName: string, key: any) {
- super(s.root);
- this.s = s;
- this.storeName = storeName;
- this.key = key;
- this.indexName = indexName;
- }
-
- subscribe(f) {
- this.s.subscribe((isDone, value) => {
- if (isDone) {
- f(true, undefined);
- return;
- }
- let s = this.root.tx.objectStore(this.storeName).index(this.indexName);
- let req = s.openCursor(IDBKeyRange.only(this.key(value)));
- req.onsuccess = () => {
- let cursor = req.result;
- if (cursor) {
- f(false, [value, cursor.value]);
- cursor.continue();
- } else {
- f(true, undefined);
- }
- }
- });
- }
-
-}
-
-
-class IterQueryStream extends QueryStreamBase {
- private qr: QueryRoot;
- private storeName;
- private options;
-
- constructor(qr, storeName, options?) {
- super(qr);
- this.qr = qr;
- this.options = options;
- this.storeName = storeName;
- }
-
- subscribe(f) {
- function doIt() {
- let s;
- if (this.options && this.options.indexName) {
- s = this.qr.tx.objectStore(this.storeName)
- .index(this.options.indexName);
- } else {
- s = this.qr.tx.objectStore(this.storeName);
- }
- let kr = undefined;
- if (this.options && ("only" in this.options)) {
- kr = IDBKeyRange.only(this.options.only);
- }
- let req = s.openCursor(kr);
- req.onsuccess = (e) => {
- let cursor: IDBCursorWithValue = req.result;
- if (cursor) {
- f(false, cursor.value);
- cursor.continue();
- } else {
- f(true, undefined);
- }
- }
- }
-
- this.qr.work.push(doIt.bind(this));
- }
-}
-
-
-class QueryRoot {
- work = [];
- db: IDBDatabase;
- tx: IDBTransaction;
- stores = new Set();
- kickoffPromise;
-
- constructor(db) {
- this.db = db;
- }
-
- iter(storeName): QueryStreamBase {
- this.stores.add(storeName);
- return new IterQueryStream(this, storeName);
- }
-
- iterOnly(storeName, key): QueryStreamBase {
- this.stores.add(storeName);
- return new IterQueryStream(this, storeName, {only: key});
- }
-
- iterIndex(storeName, indexName, key) {
- this.stores.add(storeName);
- return new IterQueryStream(this, storeName, {indexName: indexName});
- }
-
- put(storeName, val): QueryRoot {
- this.stores.add(storeName);
- function doPut() {
- this.tx.objectStore(storeName).put(val);
- }
-
- this.work.push(doPut.bind(this));
- return this;
- }
-
- putAll(storeName, iterable): QueryRoot {
- this.stores.add(storeName);
- function doPutAll() {
- for (let obj of iterable) {
- this.tx.objectStore(storeName).put(obj);
- }
- }
-
- this.work.push(doPutAll.bind(this));
- return this;
- }
-
- add(storeName, val): QueryRoot {
- this.stores.add(storeName);
- function doAdd() {
- this.tx.objectStore(storeName).add(val);
- }
-
- this.work.push(doAdd.bind(this));
- return this;
- }
-
- get(storeName, key): Promise<any> {
- this.stores.add(storeName);
- let leakedResolve;
- let p = new Promise((resolve, reject) => {
- leakedResolve = resolve;
- });
- if (!leakedResolve) {
- // According to ES6 spec (paragraph 25.4.3.1), this can't happen.
- throw Error("assertion failed");
- }
- function doGet() {
- let req = this.tx.objectStore(storeName).get(key);
- req.onsuccess = (r) => {
- leakedResolve(req.result);
- };
- }
-
- this.work.push(doGet.bind(this));
- return Promise.resolve().then(() => {
- return this.finish().then(() => p);
- });
- }
-
- finish(): Promise<void> {
- if (this.kickoffPromise) {
- return this.kickoffPromise;
- }
- this.kickoffPromise = new Promise((resolve, reject) => {
-
- this.tx = this.db.transaction(Array.from(this.stores), "readwrite");
- this.tx.oncomplete = () => {
- resolve();
- };
- for (let w of this.work) {
- w();
- }
- });
- return this.kickoffPromise;
- }
-
- delete(storeName: string, key): QueryRoot {
- this.stores.add(storeName);
- function doDelete() {
- this.tx.objectStore(storeName).delete(key);
- }
-
- this.work.push(doDelete.bind(this));
- return this;
- }
-} \ No newline at end of file