From 9e459aa0036ddcb1884a66649f72b95f3dc28b53 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 12 Aug 2021 11:39:19 -0700 Subject: [PATCH] Allow queries on keys (docs say this works) --- src/matrix/storage/idb/QueryTarget.ts | 56 ++++++++++++++------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/matrix/storage/idb/QueryTarget.ts b/src/matrix/storage/idb/QueryTarget.ts index 5d2d5bb4..cb25657b 100644 --- a/src/matrix/storage/idb/QueryTarget.ts +++ b/src/matrix/storage/idb/QueryTarget.ts @@ -18,13 +18,15 @@ import {iterateCursor, reqAsPromise} from "./utils"; type Reducer = (acc: B, val: A) => B +type IDBQuery = IDBValidKey | IDBKeyRange + interface QueryTargetInterface { - openCursor: (range?: IDBKeyRange | null , direction?: IDBCursorDirection) => IDBRequest - openKeyCursor: (range?: IDBKeyRange, direction?: IDBCursorDirection) => IDBRequest + openCursor: (range?: IDBQuery | null , direction?: IDBCursorDirection) => IDBRequest + openKeyCursor: (range?: IDBQuery, direction?: IDBCursorDirection) => IDBRequest supports: (method: string) => boolean keyPath: string | string[] - get: (key: IDBValidKey) => IDBRequest - getKey: (key: IDBValidKey) => IDBRequest + get: (key: IDBQuery) => IDBRequest + getKey: (key: IDBQuery) => IDBRequest } export class QueryTarget { @@ -34,7 +36,7 @@ export class QueryTarget { this._target = target; } - _openCursor(range?: IDBKeyRange, direction?: IDBCursorDirection) { + _openCursor(range?: IDBQuery, direction?: IDBCursorDirection) { if (range && direction) { return this._target.openCursor(range, direction); } else if (range) { @@ -50,11 +52,11 @@ export class QueryTarget { return this._target.supports(methodName); } - get(key: IDBValidKey): Promise { + get(key: IDBQuery): Promise { return reqAsPromise(this._target.get(key)); } - getKey(key: IDBValidKey): Promise { + getKey(key: IDBQuery): Promise { if (this._target.supports("getKey")) { return reqAsPromise(this._target.getKey(key)); } else { @@ -70,31 +72,31 @@ export class QueryTarget { } } - reduce(range: IDBKeyRange, reducer: Reducer, initialValue: B): Promise { + reduce(range: IDBQuery, reducer: Reducer, initialValue: B): Promise { return this._reduce(range, reducer, initialValue, "next"); } - reduceReverse(range: IDBKeyRange, reducer: Reducer, initialValue: B): Promise { + reduceReverse(range: IDBQuery, reducer: Reducer, initialValue: B): Promise { return this._reduce(range, reducer, initialValue, "prev"); } - selectLimit(range: IDBKeyRange, amount: number): Promise { + selectLimit(range: IDBQuery, amount: number): Promise { return this._selectLimit(range, amount, "next"); } - selectLimitReverse(range: IDBKeyRange, amount: number): Promise { + selectLimitReverse(range: IDBQuery, amount: number): Promise { return this._selectLimit(range, amount, "prev"); } - selectWhile(range: IDBKeyRange, predicate: (v: T) => boolean): Promise { + selectWhile(range: IDBQuery, predicate: (v: T) => boolean): Promise { return this._selectWhile(range, predicate, "next"); } - selectWhileReverse(range: IDBKeyRange, predicate: (v: T) => boolean): Promise { + selectWhileReverse(range: IDBQuery, predicate: (v: T) => boolean): Promise { return this._selectWhile(range, predicate, "prev"); } - async selectAll(range?: IDBKeyRange, direction?: IDBCursorDirection): Promise { + async selectAll(range?: IDBQuery, direction?: IDBCursorDirection): Promise { const cursor = this._openCursor(range, direction); const results: T[] = []; await iterateCursor(cursor, (value) => { @@ -104,23 +106,23 @@ export class QueryTarget { return results; } - selectFirst(range: IDBKeyRange): Promise { + selectFirst(range: IDBQuery): Promise { return this._find(range, () => true, "next"); } - selectLast(range: IDBKeyRange): Promise { + selectLast(range: IDBQuery): Promise { return this._find(range, () => true, "prev"); } - find(range: IDBKeyRange, predicate: (v: T) => boolean): Promise { + find(range: IDBQuery, predicate: (v: T) => boolean): Promise { return this._find(range, predicate, "next"); } - findReverse(range: IDBKeyRange, predicate: (v : T) => boolean): Promise { + findReverse(range: IDBQuery, predicate: (v : T) => boolean): Promise { return this._find(range, predicate, "prev"); } - async findMaxKey(range: IDBKeyRange): Promise { + async findMaxKey(range: IDBQuery): Promise { const cursor = this._target.openKeyCursor(range, "prev"); let maxKey; await iterateCursor(cursor, (_, key) => { @@ -131,14 +133,14 @@ export class QueryTarget { } - async iterateValues(range: IDBKeyRange, callback: (val: T, key: IDBValidKey, cur: IDBCursorWithValue) => boolean) { + async iterateValues(range: IDBQuery, callback: (val: T, key: IDBValidKey, cur: IDBCursorWithValue) => boolean) { const cursor = this._target.openCursor(range, "next"); await iterateCursor(cursor, (value, key, cur) => { return {done: callback(value, key, cur)}; }); } - async iterateKeys(range: IDBKeyRange, callback: (key: IDBValidKey, cur: IDBCursor) => boolean) { + async iterateKeys(range: IDBQuery, callback: (key: IDBValidKey, cur: IDBCursor) => boolean) { const cursor = this._target.openKeyCursor(range, "next"); await iterateCursor(cursor, (_, key, cur) => { return {done: callback(key, cur)}; @@ -184,7 +186,7 @@ export class QueryTarget { } } - _reduce(range: IDBKeyRange, reducer: (reduced: B, value: T) => B, initialValue: B, direction: IDBCursorDirection): Promise { + _reduce(range: IDBQuery, reducer: (reduced: B, value: T) => B, initialValue: B, direction: IDBCursorDirection): Promise { let reducedValue = initialValue; const cursor = this._openCursor(range, direction); return iterateCursor(cursor, (value) => { @@ -193,13 +195,13 @@ export class QueryTarget { }); } - _selectLimit(range: IDBKeyRange, amount: number, direction: IDBCursorDirection): Promise { + _selectLimit(range: IDBQuery, amount: number, direction: IDBCursorDirection): Promise { return this._selectUntil(range, (results) => { return results.length === amount; }, direction); } - async _selectUntil(range: IDBKeyRange, predicate: (vs: T[], v: T) => boolean, direction: IDBCursorDirection): Promise { + async _selectUntil(range: IDBQuery, predicate: (vs: T[], v: T) => boolean, direction: IDBCursorDirection): Promise { const cursor = this._openCursor(range, direction); const results: T[] = []; await iterateCursor(cursor, (value) => { @@ -210,7 +212,7 @@ export class QueryTarget { } // allows you to fetch one too much that won't get added when the predicate fails - async _selectWhile(range: IDBKeyRange, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise { + async _selectWhile(range: IDBQuery, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise { const cursor = this._openCursor(range, direction); const results: T[] = []; await iterateCursor(cursor, (value) => { @@ -223,7 +225,7 @@ export class QueryTarget { return results; } - async iterateWhile(range: IDBKeyRange, predicate: (v: T) => boolean) { + async iterateWhile(range: IDBQuery, predicate: (v: T) => boolean) { const cursor = this._openCursor(range, "next"); await iterateCursor(cursor, (value) => { const passesPredicate = predicate(value); @@ -231,7 +233,7 @@ export class QueryTarget { }); } - async _find(range: IDBKeyRange, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise { + async _find(range: IDBQuery, predicate: (v: T) => boolean, direction: IDBCursorDirection): Promise { const cursor = this._openCursor(range, direction); let result; const found = await iterateCursor(cursor, (value) => {