import type { TransactionConfig } from '@expo/entity'; import { EntityQueryContextProvider, TransactionIsolationLevel } from '@expo/entity'; import type { Knex } from 'knex'; /** * Query context provider for knex (postgres). */ export class PostgresEntityQueryContextProvider extends EntityQueryContextProvider { constructor(private readonly knexInstance: Knex) { super(); } protected getQueryInterface(): any { return this.knexInstance; } protected createTransactionRunner( transactionConfig?: TransactionConfig, ): (transactionScope: (trx: any) => Promise) => Promise { return (transactionScope) => this.knexInstance.transaction( transactionScope, transactionConfig ? PostgresEntityQueryContextProvider.convertTransactionConfig(transactionConfig) : undefined, ); } protected createNestedTransactionRunner( outerQueryInterface: any, ): (transactionScope: (queryInterface: any) => Promise) => Promise { return (transactionScope) => (outerQueryInterface as Knex).transaction(transactionScope); } private static convertTransactionConfig( transactionConfig: TransactionConfig, ): Knex.TransactionConfig { const convertIsolationLevel = ( isolationLevel: TransactionIsolationLevel, ): Knex.IsolationLevels => { switch (isolationLevel) { case TransactionIsolationLevel.READ_COMMITTED: return 'read committed'; case TransactionIsolationLevel.REPEATABLE_READ: return 'repeatable read'; case TransactionIsolationLevel.SERIALIZABLE: return 'serializable'; } }; return { ...(transactionConfig.isolationLevel ? { isolationLevel: convertIsolationLevel(transactionConfig.isolationLevel) } : {}), }; } }