text: // @flow
  
  import pg from 'pg';
  import serializeError from 'serialize-error';
  import {
    parse as parseConnectionString
  } from 'pg-connection-string';
  import {
    createUlid
  } from '../utilities';
  import type {
    ClientConfigurationType,
    DatabasePoolType,
    DatabaseConfigurationType
  } from '../types';
  import Logger from '../Logger';
  import bindPool from '../binders/bindPool';
  
  // @see https://github.com/facebook/flow/issues/2977#issuecomment-390613203
  const defaultClientConfiguration = Object.freeze({});
  
  export default (
    connectionConfiguration: DatabaseConfigurationType,
    clientConfiguration: ClientConfigurationType = defaultClientConfiguration
  ): DatabasePoolType => {
    const poolLog = Logger.child({
      poolId: createUlid()
    });
  
    const pool = new pg.Pool(typeof connectionConfiguration === 'string' ? parseConnectionString(connectionConfiguration) : connectionConfiguration);
  
    pool.on('error', (error) => {
      poolLog.error({
        error: serializeError(error)
      }, 'client connection error');
    });
  
    pool.on('connect', (client) => {
      poolLog.info({
        processId: client.processID,
        stats: {
          idleConnectionCount: pool.idleCount,
          totalConnectionCount: pool.totalCount,
          waitingRequestCount: pool.waitingCount
        }
      }, 'created a new client connection');
    });
  
    pool.on('acquire', (client) => {
      poolLog.info({
        processId: client.processID,
        stats: {
          idleConnectionCount: pool.idleCount,
          totalConnectionCount: pool.totalCount,
          waitingRequestCount: pool.waitingCount
        }
      }, 'client is checked out from the pool');
    });
  
    pool.on('remove', (client) => {
      poolLog.info({
        processId: client.processID,
        stats: {
          idleConnectionCount: pool.idleCount,
          totalConnectionCount: pool.totalCount,
          waitingRequestCount: pool.waitingCount
        }
      }, 'client connection is closed and removed from the client pool');
    });
  
    return bindPool(poolLog, pool, clientConfiguration);
  };
  