import { URL } from 'url' ; import type { Configuration , ConnectionOptions , DynamicPassword } from '../utils' ; import type { LogContext } from '../logging' ; import type { MetadataStorage } from '../metadata' ; import type { AnyEntity , Dictionary , MaybePromise , Primary } from '../typings' ; import type { Platform } from '../platforms/Platform' ; import type { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster' ; import type { IsolationLevel } from '../enums' ; export abstract class Connection { protected metadata ! : MetadataStorage ; protected platform ! : Platform ; protected readonly options : ConnectionOptions ; protected abstract client : unknown ; protected readonly logger = this . config . getLogger ( ) ; constructor ( protected readonly config , options ? , protected readonly type = 'write' ) { if ( options ) { this . options = options ; } else { const props = [ 'dbName' , 'clientUrl' , 'host' , 'port' , 'user' , 'password' , 'multipleStatements' , 'pool' ] as const ; this . options = props . reduce ( ( o , i ) => { ( o [ i ] as any ) = this . config . get ( i ) ; return o ; } , { } as ConnectionOptions ) ; } } /**
     * Establishes connection to database
     */ abstract connect ( ) ; /**
     * Are we connected to the database
     */ abstract isConnected ( ) ; /**
     * Closes the database connection (aka disconnect)
     */ async close ( force ? ) { Object . keys ( this . options ) . filter ( k => k !== 'name' ) . forEach ( k => delete this . options [ k ] ) ; } /**
     * Returns default client url for given driver (e.g. mongodb://127.0.0.1:27017 for mongodb)
     */ abstract getDefaultClientUrl ( ) ; async transactional < T > ( cb , options ? ) { throw new Error ( `Transactions are not supported by current driver` ) ; } async begin ( options ? ) { throw new Error ( `Transactions are not supported by current driver` ) ; } async commit ( ctx , eventBroadcaster ? ) { throw new Error ( `Transactions are not supported by current driver` ) ; } async rollback ( ctx , eventBroadcaster ? ) { throw new Error ( `Transactions are not supported by current driver` ) ; } abstract execute < T > ( query , params ? , method ? , ctx ? ) ; getConnectionOptions ( ) { const ret = { } ; const url = new URL ( this . options . clientUrl ?? this . config . getClientUrl ( ) ) ; this . options . host = ret . host = this . options . host ?? this . config . get ( 'host' , url . hostname ) ; this . options . port = ret . port = this . options . port ?? this . config . get ( 'port' , + url . port ) ; this . options . user = ret . user = this . options . user ?? this . config . get ( 'user' , url . username ) ; this . options . password = ret . password = this . options . password ?? this . config . get ( 'password' , url . password ) ; this . options . dbName = ret . database = this . options . dbName ?? this . config . get ( 'dbName' , url . pathname . replace ( /^\// , '' ) ) ; return ret ; } getClientUrl ( ) { const options = this . getConnectionOptions ( ) ; const url = new URL ( this . config . getClientUrl ( true ) ) ; return `${ url . protocol }//${ options . user }${ options . password ? ':*****' : '' }@${ options . host }:${ options . port }` ; } setMetadata ( metadata ) { this . metadata = metadata ; } setPlatform ( platform ) { this . platform = platform ; } getPlatform ( ) { return this . platform ; } protected async executeQuery < T > ( query , cb , context ? ) { const now = Date . now ( ) ; try { const res = await cb ( ) ; this . logQuery ( query , { ... context , took : Date . now ( ) - now } ) ; return res ; } catch ( e ) { this . logQuery ( query , { ... context , took : Date . now ( ) - now , level : 'error' } ) ; throw e ; } } protected logQuery ( query , context = { } ) { this . logger . logQuery ( { level : 'info' , connection : { type : this . type , name : this . options . name || this . config . get ( 'name' ) || this . options . host , } , ... context , query , } ) ; } } export interface QueryResult < T extends AnyEntity < T > = { id : number ; } > { affectedRows : number ; insertId : Primary < T > ; row ? : Dictionary ; rows ? : Dictionary [ ] ; insertedIds ? : Primary < T > [ ] ; } export interface ConnectionConfig { host ? : string ; port ? : number ; user ? : string ; password ? : string | ( ( ) => MaybePromise < string > | MaybePromise < DynamicPassword > ) ; database ? : string ; } export type Transaction < T = any > = T ;