import { DMMF } from '@prisma/client/runtime/dmmf-types' ; import { DataSource } from '@prisma/generator-helper' ; import _ from 'lodash' ; import pg from 'pg' ; import url from 'url' ; import { migrateLift , getTmpPrismaSchemaPath } from '../lift' ; import { InternalPool } from '../pool' ; import { Pool , DBInstance } from '../../types' ; param dmmf export function getPostgreSQLPool ( dmmf , cwd ) { return class extends PostgreSQLPool { constructor ( options ) { super ( dmmf , { tmpPrismaSchemaPath : getTmpPrismaSchemaPath , ... options } , cwd ) ; } } ; } export interface PostgreSQLConnection { host : string ; port : number ; user : string ; password ? : string ; database : string ; schema : string ; } export interface PostgreSQLPoolOptions { connection : ( id : string ) => PostgreSQLConnection ; pool ? : { max ? : number ; } ; tmpPrismaSchemaPath ? : ( id : string ) => string ; } class PostgreSQLPool extends InternalPool { private dmmf : DMMF . Document ; private projectDir : string ; private getConnection : ( id : string ) => PostgreSQLConnection ; private getTmpPrismaSchemaPath : ( id : string ) => string ; constructor ( dmmf , options , cwd ) { super ( { max : _ . get ( options , [ 'pool' , 'max' ] , Infinity ) } ) ; this . dmmf = dmmf ; this . projectDir = cwd ; this . getConnection = options . connection ; this . getTmpPrismaSchemaPath = options . tmpPrismaSchemaPath ! ; } /**
     * Creates a DB isntance.
     */ async createDBInstance ( id ) { const connection = this . getConnection ( id ) ; const tmpPrismaSchemaPath = this . getTmpPrismaSchemaPath ( id ) ; const url = readPostgreSQLUrl ( connection ) ; const datasources = [ { name : 'db' , connectorType : 'postgresql' , url : { value : url , fromEnvVar : null , } , config : { } , } , ] ; const { datamodel } = await migrateLift ( { id , datasources , projectDir : this . projectDir , tmpPrismaSchemaPath , dmmf : this . dmmf , } ) ; const instance = { url : url , cwd : this . projectDir , datamodel : datamodel , } ; return instance ; } /**
     * Delets DB instance.
     */ async deleteDBInstance ( instance ) { const connection = parsePostgreSQLUrl ( instance . url ) ; const client = await getPostgreSQLClient ( connection ) ; try { await client . query ( `DROP SCHEMA IF EXISTS "${ connection . schema }" CASCADE;` ) ; } catch ( err ) { throw err ; } } } /**
 * Helper functions.
 */ param options function readPostgreSQLUrl ( connection ) { return `postgres://${ connection . user }:${ connection . password }@${ connection . host }:${ connection . port }/${ connection . database }?schema=${ connection . schema }` ; } param url function parsePostgreSQLUrl ( urlStr ) { const { query , auth , port : rawPort , hostname : host , pathname } = url . parse ( urlStr , true ) ; const port = parseInt ( rawPort ! , 10 ) ; const [ , user , password ] = auth ! . match ( /(\w+):(\w+)/ ) ! ; const [ , database ] = pathname ! . match ( /\/(\w+)/ ) ! ; if ( typeof query . schema !== 'string' ) { throw new Error ( `Unsupported schema type: ${ typeof query . schema }` ) ; } const schema = query . schema ; return { user , password , host : host ! , port , database , schema , } ; } param connection async function getPostgreSQLClient ( connection ) { const client = new pg . Client ( { host : connection . host , port : connection . port , user : connection . user , password : connection . password , database : connection . database , } ) ; try { await client . connect ( ) ; return client ; } catch ( err ) { throw err ; } }