import { CompiledQuery } from '../query-compiler/compiled-query.js' ; import { Log } from '../util/log.js' ; import { performanceNow } from '../util/performance-now.js' ; import { DatabaseConnection , QueryResult } from './database-connection.js' ; import { Driver , TransactionSettings } from './driver.js' ; /**
 * A small wrapper around  Driver that makes sure the driver is
 * initialized before it is used, only initialized and destroyed
 * once etc.
  export class RuntimeDriver implements Driver { readonly #driver : Driver ; readonly #log : Log ; #initPromise ? : Promise < void > ; #destroyPromise ? : Promise < void > ; #connections = new WeakSet < DatabaseConnection > ( ) ; constructor ( driver , log ) { this . #driver = driver ; this . #log = log ; } async init ( ) { if ( ! this . #initPromise ) { this . #initPromise = this . #driver . init ( ) . catch ( ( err ) => { this . #initPromise = undefined ; return Promise . reject ( err ) ; } ) ; } await this . #initPromise ; } async acquireConnection ( ) { await this . init ( ) ; const connection = await this . #driver . acquireConnection ( ) ; if ( ! this . #connections . has ( connection ) ) { if ( this . #needsLogging ( ) ) { this . #addLogging ( connection ) ; } this . #connections . add ( connection ) ; } return connection ; } async releaseConnection ( connection ) { await this . #driver . releaseConnection ( connection ) ; } beginTransaction ( connection , settings ) { return this . #driver . beginTransaction ( connection , settings ) ; } commitTransaction ( connection ) { return this . #driver . commitTransaction ( connection ) ; } rollbackTransaction ( connection ) { return this . #driver . rollbackTransaction ( connection ) ; } async destroy ( ) { if ( ! this . #initPromise ) { return ; } await this . #initPromise ; if ( ! this . #destroyPromise ) { this . #destroyPromise = this . #driver . destroy ( ) . catch ( ( err ) => { this . #destroyPromise = undefined ; return Promise . reject ( err ) ; } ) ; } await this . #destroyPromise ; } #needsLogging ( ) { return ( this . #log . isLevelEnabled ( 'query' ) || this . #log . isLevelEnabled ( 'error' ) ) ; } #addLogging ( connection ) { const executeQuery = connection . executeQuery ; connection . executeQuery = async ( compiledQuery ) : Promise < QueryResult < any > > => { const startTime = performanceNow ( ) ; try { return await executeQuery . call ( connection , compiledQuery ) ; } catch ( error ) { this . #logError ( error ) ; throw error ; } finally { this . #logQuery ( compiledQuery , startTime ) ; } } ; } #logError ( error ) { this . #log . error ( ( ) => ( { level : 'error' , error , } ) ) ; } #logQuery ( compiledQuery , startTime ) { this . #log . query ( ( ) => ( { level : 'query' , query : compiledQuery , queryDurationMillis : this . #calculateDurationMillis ( startTime ) , } ) ) ; } #calculateDurationMillis ( startTime ) { return performanceNow ( ) - startTime ; } }