import IEngine from '../IEngine' ; import * as pg from 'pg' ; import IExec from '../IExec' ; export default class EnginePostgres implements IEngine , IExec < pg . Client > { private readonly url ? : string ; private connectionInProgress ? : Promise < pg . Client > ; private _client ? : pg . Client ; constructor ( url ? ) { this . url = url ; } async connect ( ) { await this . ensureConnection ( ) ; } isConnected ( ) { return Boolean ( this . _client ) ; } async close ( ) { if ( ! this . _client ) { return Promise . resolve ( ) ; } await this . _client . end ( ) ; this . _client = undefined ; } async drop ( ) { await this . exec ( client => { return Promise . all ( [ client . query ( 'TRUNCATE channel CASCADE' ) , client . query ( 'TRUNCATE payment CASCADE' ) , client . query ( 'TRUNCATE token CASCADE' ) ] ) ; } ) ; } async exec < B > ( fn ) { let client = await this . ensureConnection ( ) ; return fn ( client ) ; } async ensureConnection ( ) { if ( this . _client ) { return this . _client ; } if ( this . connectionInProgress ) { return this . connectionInProgress ; } const connectionString = { connectionString : this . url } ; const client = new pg . Client ( connectionString ) ; this . connectionInProgress = client . connect ( ) . then ( ( ) => { this . _client = client ; return client ; } ) ; return this . connectionInProgress ; } }