aboutsummaryrefslogtreecommitdiff
path: root/src/query.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/query.ts')
-rw-r--r--src/query.ts78
1 files changed, 60 insertions, 18 deletions
diff --git a/src/query.ts b/src/query.ts
index f510da55d..5726bcaa6 100644
--- a/src/query.ts
+++ b/src/query.ts
@@ -1,5 +1,3 @@
-import { openPromise } from "./promiseUtils";
-
/*
This file is part of TALER
(C) 2016 GNUnet e.V.
@@ -23,6 +21,12 @@ import { openPromise } from "./promiseUtils";
*/
/**
+ * Imports.
+ */
+import { openPromise } from "./promiseUtils";
+
+
+/**
* Result of an inner join.
*/
export interface JoinResult<L, R> {
@@ -63,27 +67,48 @@ export interface IndexOptions {
}
function requestToPromise(req: IDBRequest): Promise<any> {
+ const stack = Error("Failed request was started here.")
return new Promise((resolve, reject) => {
req.onsuccess = () => {
resolve(req.result);
};
req.onerror = () => {
+ console.log("error in DB request", req.error);
reject(req.error);
+ console.log("Request failed:", stack);
};
});
}
-export function oneShotGet<T>(
+function transactionToPromise(tx: IDBTransaction): Promise<void> {
+ const stack = Error("Failed transaction was started here.");
+ return new Promise((resolve, reject) => {
+ tx.onabort = () => {
+ reject(TransactionAbort);
+ };
+ tx.oncomplete = () => {
+ resolve();
+ };
+ tx.onerror = () => {
+ console.error("Transaction failed:", stack);
+ reject(tx.error);
+ };
+ });
+}
+
+export async function oneShotGet<T>(
db: IDBDatabase,
store: Store<T>,
key: any,
): Promise<T | undefined> {
const tx = db.transaction([store.name], "readonly");
const req = tx.objectStore(store.name).get(key);
- return requestToPromise(req);
+ const v = await requestToPromise(req)
+ await transactionToPromise(tx);
+ return v;
}
-export function oneShotGetIndexed<S extends IDBValidKey, T>(
+export async function oneShotGetIndexed<S extends IDBValidKey, T>(
db: IDBDatabase,
index: Index<S, T>,
key: any,
@@ -93,10 +118,12 @@ export function oneShotGetIndexed<S extends IDBValidKey, T>(
.objectStore(index.storeName)
.index(index.indexName)
.get(key);
- return requestToPromise(req);
+ const v = await requestToPromise(req);
+ await transactionToPromise(tx);
+ return v;
}
-export function oneShotPut<T>(
+export async function oneShotPut<T>(
db: IDBDatabase,
store: Store<T>,
value: T,
@@ -104,7 +131,9 @@ export function oneShotPut<T>(
): Promise<any> {
const tx = db.transaction([store.name], "readwrite");
const req = tx.objectStore(store.name).put(value, key);
- return requestToPromise(req);
+ const v = await requestToPromise(req);
+ await transactionToPromise(tx);
+ return v;
}
function applyMutation<T>(
@@ -115,7 +144,7 @@ function applyMutation<T>(
req.onsuccess = () => {
const cursor = req.result;
if (cursor) {
- const val = cursor.value();
+ const val = cursor.value;
const modVal = f(val);
if (modVal !== undefined && modVal !== null) {
const req2: IDBRequest = cursor.update(modVal);
@@ -138,7 +167,7 @@ function applyMutation<T>(
});
}
-export function oneShotMutate<T>(
+export async function oneShotMutate<T>(
db: IDBDatabase,
store: Store<T>,
key: any,
@@ -146,7 +175,8 @@ export function oneShotMutate<T>(
): Promise<void> {
const tx = db.transaction([store.name], "readwrite");
const req = tx.objectStore(store.name).openCursor(key);
- return applyMutation(req, f);
+ await applyMutation(req, f);
+ await transactionToPromise(tx);
}
type CursorResult<T> = CursorEmptyResult<T> | CursorValueResult<T>;
@@ -326,15 +356,12 @@ export function runWithWriteTransaction<T>(
stores: Store<any>[],
f: (t: TransactionHandle) => Promise<T>,
): Promise<T> {
+ const stack = Error("Failed transaction was started here.");
return new Promise((resolve, reject) => {
const storeName = stores.map(x => x.name);
const tx = db.transaction(storeName, "readwrite");
let funResult: any = undefined;
let gotFunResult: boolean = false;
- tx.onerror = () => {
- console.error("error in transaction:", tx.error);
- reject(tx.error);
- };
tx.oncomplete = () => {
// This is a fatal error: The transaction completed *before*
// the transaction function returned. Likely, the transaction
@@ -350,15 +377,30 @@ export function runWithWriteTransaction<T>(
}
resolve(funResult);
};
+ tx.onerror = () => {
+ console.error("error in transaction");
+ };
tx.onabort = () => {
- console.error("aborted transaction");
- reject(AbortTransaction);
+ if (tx.error) {
+ console.error("Transaction aborted with error:", tx.error);
+ } else {
+ console.log("Trasaction aborted (no error)");
+ }
+ reject(TransactionAbort);
};
const th = new TransactionHandle(tx);
const resP = f(th);
resP.then(result => {
gotFunResult = true;
funResult = result;
+ }).catch((e) => {
+ if (e == TransactionAbort) {
+ console.info("aborting transaction");
+ } else {
+ tx.abort();
+ console.error("Transaction failed:", e);
+ console.error(stack);
+ }
});
});
}
@@ -401,4 +443,4 @@ export class Index<S extends IDBValidKey, T> {
/**
* Exception that should be thrown by client code to abort a transaction.
*/
-export const AbortTransaction = Symbol("abort_transaction");
+export const TransactionAbort = Symbol("transaction_abort");