import { Client } from 'pg' ; import { PgGodError } from './error' ; export type DbCredential = { user : string ; database : string ; port : number ; host : string ; password : string ; } ; const defaultDbCred = { user : 'postgres' , database : 'postgres' , password : '' , port : 5432 , host : 'localhost' , } ; export type NewDbConfig = { databaseName : string ; errorIfExist ? : boolean ; } ; param newDbConfig param dbCredential throws example export async function createDatabase ( newDbConfig , dbCredential = defaultDbCred ) { const client = new Client ( { ... defaultDbCred , ... dbCredential } ) ; try { await client . connect ( ) ; const existingDb = await client . query ( `
      SELECT datname
      FROM pg_catalog.pg_database
      WHERE lower(datname) = lower('${ newDbConfig . databaseName }');
    ` ) ; if ( existingDb . rowCount > 0 && newDbConfig . errorIfExist ) throw PgGodError . dbAlreadyExist ( ) ; if ( existingDb . rowCount > 0 && ! newDbConfig . errorIfExist ) return ; await client . query ( `CREATE DATABASE "${ newDbConfig . databaseName }";` ) ; } catch ( error ) { throw PgGodError . fromPgError ( error ) ; } finally { await client . end ( ) ; } } export type DropDbConfig = { databaseName : string ; errorIfNonExist ? : boolean ; dropConnections ? : boolean ; } ; param dropDbConfig . databaseName param dropDbConfig . errorIfNonExist param dropDbConfig . dropConnections param dbCredential throws example export async function dropDatabase ( dropDbConfig , dbCredential = defaultDbCred ) { const client = new Client ( { ... defaultDbCred , ... dbCredential } ) ; try { await client . connect ( ) ; const existingDb = await client . query ( `
      SELECT datname
      FROM pg_catalog.pg_database
      WHERE lower(datname) = lower('${ dropDbConfig . databaseName }');
    ` ) ; if ( existingDb . rowCount === 0 && dropDbConfig . errorIfNonExist ) throw PgGodError . dbDoesNotExist ( ) ; if ( existingDb . rowCount === 0 && ! dropDbConfig . errorIfNonExist ) return ; if ( dropDbConfig . dropConnections !== false ) await dropDbOtherUserConnections ( client , dropDbConfig . databaseName ) ; await client . query ( `DROP DATABASE "${ dropDbConfig . databaseName }";` ) ; } catch ( error ) { throw PgGodError . fromPgError ( error ) ; } finally { await client . end ( ) ; } } async function dropDbOtherUserConnections ( client , dbName ) { return client . query ( `
    SELECT
      pg_terminate_backend(pg_stat_activity.pid)
    FROM
      pg_stat_activity
    WHERE
      pg_stat_activity.datname = '${ dbName }'
      AND pid <> pg_backend_pid();
  ` ) ; }