diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-11-30 04:07:36 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-12-01 03:00:09 +0100 |
commit | b8ccc7c990a1542cf80578b41972f9a5b0870af9 (patch) | |
tree | 6f16319f9ce3133c4c4617129a516e692cfc3ac1 /src/query.ts | |
parent | bc2c4aff8e657c7d5709433f137299491b98d257 (diff) |
partial implementation of tipping
Diffstat (limited to 'src/query.ts')
-rw-r--r-- | src/query.ts | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/src/query.ts b/src/query.ts index 653e91a1b..554f937a5 100644 --- a/src/query.ts +++ b/src/query.ts @@ -51,6 +51,20 @@ export class Store<T> { /** + * Options for an index. + */ +export interface IndexOptions { + /** + * If true and the path resolves to an array, create an index entry for + * each member of the array (instead of one index entry containing the full array). + * + * Defaults to false. + */ + multiEntry?: boolean; +} + + +/** * Definition of an index. */ export class Index<S extends IDBValidKey, T> { @@ -59,7 +73,16 @@ export class Index<S extends IDBValidKey, T> { */ storeName: string; - constructor(s: Store<T>, public indexName: string, public keyPath: string | string[]) { + /** + * Options to use for the index. + */ + options: IndexOptions; + + constructor(s: Store<T>, public indexName: string, public keyPath: string | string[], options?: IndexOptions) { + const defaultOptions = { + multiEntry: false, + }; + this.options = { ...defaultOptions, ...(options || {}) }; this.storeName = s.name; } @@ -671,26 +694,33 @@ export class QueryRoot { /** - * Get, modify and store an element inside a transaction. + * Update objects inside a transaction. + * + * If the mutation function throws AbortTransaction, the whole transaction will be aborted. + * If the mutation function returns undefined or null, no modification will be made. */ mutate<T>(store: Store<T>, key: any, f: (v: T|undefined) => T|undefined): QueryRoot { this.checkFinished(); const doPut = (tx: IDBTransaction) => { - const reqGet = tx.objectStore(store.name).get(key); - reqGet.onsuccess = () => { - const r = reqGet.result; - let m: T|undefined; - try { - m = f(r); - } catch (e) { - if (e === AbortTransaction) { - tx.abort(); - return; + const req = tx.objectStore(store.name).openCursor(IDBKeyRange.only(key)); + req.onsuccess = () => { + const cursor = req.result; + if (cursor) { + const value = cursor.value; + let modifiedValue: T|undefined; + try { + modifiedValue = f(value); + } catch (e) { + if (e === AbortTransaction) { + tx.abort(); + return; + } + throw e; } - throw e; - } - if (m !== undefined && m !== null) { - tx.objectStore(store.name).put(m); + if (modifiedValue !== undefined && modifiedValue !== null) { + cursor.update(modifiedValue); + } + cursor.continue(); } }; }; @@ -702,8 +732,6 @@ export class QueryRoot { /** * Add all object from an iterable to the given object store. - * Fails if the object's key is already present - * in the object store. */ putAll<T>(store: Store<T>, iterable: T[]): QueryRoot { this.checkFinished(); @@ -822,13 +850,13 @@ export class QueryRoot { /** * Delete an object by from the given object store. */ - delete(storeName: string, key: any): QueryRoot { + delete<T>(store: Store<T>, key: any): QueryRoot { this.checkFinished(); const doDelete = (tx: IDBTransaction) => { - tx.objectStore(storeName).delete(key); + tx.objectStore(store.name).delete(key); }; this.scheduleFinish(); - this.addWork(doDelete, storeName, true); + this.addWork(doDelete, store.name, true); return this; } |