diff options
Diffstat (limited to 'packages/taler-wallet-core/src/util/query.ts')
-rw-r--r-- | packages/taler-wallet-core/src/util/query.ts | 209 |
1 files changed, 31 insertions, 178 deletions
diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts index 19fa0dbfd..90a3cac70 100644 --- a/packages/taler-wallet-core/src/util/query.ts +++ b/packages/taler-wallet-core/src/util/query.ts @@ -490,78 +490,14 @@ type ValidateKeyPath<T, P> = P extends `${infer PX extends keyof T & // foo({x: [0,1,2]}, "x.0"); -export type GetReadOnlyAccess<BoundStores> = { - [P in keyof BoundStores]: BoundStores[P] extends StoreWithIndexes< - infer StoreName, - infer RecordType, - infer IndexMap - > - ? StoreReadOnlyAccessor<RecordType, IndexMap> - : unknown; -}; - export type StoreNames<StoreMap> = StoreMap extends { [P in keyof StoreMap]: StoreWithIndexes<infer SN1, infer SD1, infer IM1>; } ? keyof StoreMap : unknown; -export type DbReadOnlyTransaction< - StoreMap, - Stores extends StoreNames<StoreMap> & string, -> = StoreMap extends { - [P in Stores]: StoreWithIndexes<infer SN1, infer SD1, infer IM1>; -} - ? { - [P in Stores]: StoreMap[P] extends StoreWithIndexes< - infer StoreName, - infer RecordType, - infer IndexMap - > - ? StoreReadOnlyAccessor<RecordType, IndexMap> - : unknown; - } - : unknown; - export type DbReadWriteTransaction< StoreMap, - Stores extends StoreNames<StoreMap> & string, -> = StoreMap extends { - [P in Stores]: StoreWithIndexes<infer SN1, infer SD1, infer IM1>; -} - ? { - [P in Stores]: StoreMap[P] extends StoreWithIndexes< - infer StoreName, - infer RecordType, - infer IndexMap - > - ? StoreReadWriteAccessor<RecordType, IndexMap> - : unknown; - } - : unknown; - -export type GetReadWriteAccess<BoundStores> = { - [P in keyof BoundStores]: BoundStores[P] extends StoreWithIndexes< - infer StoreName, - infer RecordType, - infer IndexMap - > - ? StoreReadWriteAccessor<RecordType, IndexMap> - : unknown; -}; - -type ReadOnlyTransactionFunction<BoundStores, T> = ( - t: GetReadOnlyAccess<BoundStores>, - rawTx: IDBTransaction, -) => Promise<T>; - -type ReadWriteTransactionFunction<BoundStores, T> = ( - t: GetReadWriteAccess<BoundStores>, - rawTx: IDBTransaction, -) => Promise<T>; - -export type DbReadWriteTransactionArr< - StoreMap, StoresArr extends Array<StoreNames<StoreMap>>, > = StoreMap extends { [P in string]: StoreWithIndexes<infer _SN1, infer _SD1, infer _IM1>; @@ -578,7 +514,7 @@ export type DbReadWriteTransactionArr< } : never; -export type DbReadOnlyTransactionArr< +export type DbReadOnlyTransaction< StoreMap, StoresArr extends Array<StoreNames<StoreMap>>, > = StoreMap extends { @@ -596,11 +532,6 @@ export type DbReadOnlyTransactionArr< } : never; -export interface DbTransactionContext<BoundStores> { - runReadWrite<T>(f: ReadWriteTransactionFunction<BoundStores, T>): Promise<T>; - runReadOnly<T>(f: ReadOnlyTransactionFunction<BoundStores, T>): Promise<T>; -} - /** * Convert the type of an array to a union of the contents. * @@ -811,12 +742,6 @@ function makeWriteContext( return ctx; } -type StoreNamesOf<X> = X extends { [x: number]: infer F } - ? F extends { storeName: infer I } - ? I - : never - : never; - /** * Type-safe access to a database with a particular store map. * @@ -832,65 +757,46 @@ export class DbAccess<StoreMap> { return this.db; } - /** - * Run a transaction with all object stores. - */ - mktxAll(): DbTransactionContext<StoreMap> { - const storeNames: string[] = []; + runAllStoresReadWriteTx<T>( + txf: ( + tx: DbReadWriteTransaction<StoreMap, Array<StoreNames<StoreMap>>>, + ) => Promise<T>, + ): Promise<T> { const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } = {}; - for (let i = 0; i < this.db.objectStoreNames.length; i++) { - const sn = this.db.objectStoreNames[i]; + const strStoreNames: string[] = []; + for (const sn of Object.keys(this.stores as any)) { const swi = (this.stores as any)[sn] as StoreWithIndexes<any, any, any>; - if (!swi) { - logger.warn(`store metadata not available (${sn})`); - continue; - } - storeNames.push(sn); - accessibleStores[sn] = swi; + strStoreNames.push(swi.storeName); + accessibleStores[swi.storeName] = swi; } + const tx = this.db.transaction(strStoreNames, "readwrite"); + const writeContext = makeWriteContext(tx, accessibleStores); + return runTx(tx, writeContext, txf); + } - const storeMapKeys = Object.keys(this.stores as any); - for (const storeMapKey of storeMapKeys) { - const swi = (this.stores as any)[storeMapKey] as StoreWithIndexes< - any, - any, - any - >; - if (!accessibleStores[swi.storeName]) { - const version = this.db.version; - throw Error( - `store '${swi.storeName}' required by schema but not in database (minver=${version})`, - ); - } + runAllStoresReadOnlyTx<T>( + txf: ( + tx: DbReadOnlyTransaction<StoreMap, Array<StoreNames<StoreMap>>>, + ) => Promise<T>, + ): Promise<T> { + const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } = + {}; + const strStoreNames: string[] = []; + for (const sn of Object.keys(this.stores as any)) { + const swi = (this.stores as any)[sn] as StoreWithIndexes<any, any, any>; + strStoreNames.push(swi.storeName); + accessibleStores[swi.storeName] = swi; } - - const runReadOnly = <T>( - txf: ReadOnlyTransactionFunction<StoreMap, T>, - ): Promise<T> => { - const tx = this.db.transaction(storeNames, "readonly"); - const readContext = makeReadContext(tx, accessibleStores); - return runTx(tx, readContext, txf); - }; - - const runReadWrite = <T>( - txf: ReadWriteTransactionFunction<StoreMap, T>, - ): Promise<T> => { - const tx = this.db.transaction(storeNames, "readwrite"); - const writeContext = makeWriteContext(tx, accessibleStores); - return runTx(tx, writeContext, txf); - }; - - return { - runReadOnly, - runReadWrite, - }; + const tx = this.db.transaction(strStoreNames, "readonly"); + const writeContext = makeReadContext(tx, accessibleStores); + return runTx(tx, writeContext, txf); } runReadWriteTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>( storeNames: StoreNameArray, txf: ( - tx: DbReadWriteTransactionArr<StoreMap, StoreNameArray>, + tx: DbReadWriteTransaction<StoreMap, StoreNameArray>, ) => Promise<T>, ): Promise<T> { const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } = @@ -908,7 +814,7 @@ export class DbAccess<StoreMap> { runReadOnlyTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>( storeNames: StoreNameArray, - txf: (tx: DbReadOnlyTransactionArr<StoreMap, StoreNameArray>) => Promise<T>, + txf: (tx: DbReadOnlyTransaction<StoreMap, StoreNameArray>) => Promise<T>, ): Promise<T> { const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } = {}; @@ -922,57 +828,4 @@ export class DbAccess<StoreMap> { const readContext = makeReadContext(tx, accessibleStores); return runTx(tx, readContext, txf); } - - /** - * Run a transaction with selected object stores. - * - * The {@link namePicker} must be a function that selects a list of object - * stores from all available object stores. - */ - mktx< - StoreNames extends keyof StoreMap, - Stores extends StoreMap[StoreNames], - StoreList extends Stores[], - BoundStores extends { - [X in StoreNamesOf<StoreList>]: StoreList[number] & { storeName: X }; - }, - >(namePicker: (x: StoreMap) => StoreList): DbTransactionContext<BoundStores> { - const storeNames: string[] = []; - const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } = - {}; - - const storePick = namePicker(this.stores) as any; - if (typeof storePick !== "object" || storePick === null) { - throw Error(); - } - for (const swiPicked of storePick) { - const swi = swiPicked as StoreWithIndexes<any, any, any>; - if (swi.mark !== storeWithIndexesSymbol) { - throw Error("invalid store descriptor returned from selector function"); - } - storeNames.push(swi.storeName); - accessibleStores[swi.storeName] = swi; - } - - const runReadOnly = <T>( - txf: ReadOnlyTransactionFunction<BoundStores, T>, - ): Promise<T> => { - const tx = this.db.transaction(storeNames, "readonly"); - const readContext = makeReadContext(tx, accessibleStores); - return runTx(tx, readContext, txf); - }; - - const runReadWrite = <T>( - txf: ReadWriteTransactionFunction<BoundStores, T>, - ): Promise<T> => { - const tx = this.db.transaction(storeNames, "readwrite"); - const writeContext = makeWriteContext(tx, accessibleStores); - return runTx(tx, writeContext, txf); - }; - - return { - runReadOnly, - runReadWrite, - }; - } } |