import { ColumnObj , dbDetails , TableDetails , DBList } from './BE_types' ; const { Pool } = require ( 'pg' ) ; const PG_URI = 'postgres://postgres:postgres@localhost:5432' ; let pool = new Pool ( { connectionString : PG_URI } ) ; const getColumnObjects = ( tableName ) : Promise < ColumnObj [ ] > => { const queryString = `
  SELECT cols.column_name,
    cols.data_type,
    cols.character_maximum_length,
    cols.is_nullable,
    kcu.constraint_name,
    cons.constraint_type,
    rel_kcu.table_name AS foreign_table,
    rel_kcu.column_name AS foreign_column
  FROM information_schema.columns cols
  LEFT JOIN information_schema.key_column_usage kcu
    ON cols.column_name = kcu.column_name
    AND cols.table_name = kcu.table_name
  LEFT JOIN information_schema.table_constraints cons
    ON kcu.constraint_name = cons.constraint_name
  LEFT JOIN information_schema.referential_constraints rco
    ON rco.constraint_name = cons.constraint_name
  LEFT JOIN information_schema.key_column_usage rel_kcu
    ON rco.unique_constraint_name = rel_kcu.constraint_name
  WHERE cols.table_name = $1
  ` ; const value = [ tableName ] ; return new Promise ( ( resolve ) => { pool . query ( queryString , value ) . then ( ( result ) => { const columnInfoArray = [ ] ; for ( let i = 0 ; i < result . rows . length ; i += 1 ) { columnInfoArray . push ( result . rows [ i ] ) ; } resolve ( columnInfoArray ) ; } ) ; } ) ; } ; const getDBNames = ( ) : Promise < dbDetails [ ] > => new Promise ( ( resolve , reject ) => { const query = `
      SELECT dbs.datname AS db_name,
             pg_size_pretty(pg_database_size(dbs.datname)) AS db_size
      FROM pg_database dbs
      ORDER BY db_name
    ` ; pool . query ( query ) . then ( ( databases ) => { const dbList = [ ] ; for ( let i = 0 ; i < databases . rows . length ; i += 1 ) { const { db_name } = databases . rows [ i ] ; if ( db_name !== 'postgres' && db_name !== 'template0' && db_name !== 'template1' ) dbList . push ( databases . rows [ i ] ) ; } resolve ( dbList ) ; } ) . catch ( reject ) ; } ) ; const getDBLists = ( ) : Promise < TableDetails [ ] > => new Promise ( ( resolve , reject ) => { const query = `
      SELECT table_catalog, table_schema, table_name, is_insertable_into
      FROM information_schema.tables
      WHERE table_schema = 'public' or table_schema = 'base'
      ORDER BY table_name;
    ` ; const tableList = [ ] ; const promiseArray = [ ] ; pool . query ( query ) . then ( ( tables ) => { for ( let i = 0 ; i < tables . rows . length ; i += 1 ) { tableList . push ( tables . rows [ i ] ) ; promiseArray . push ( getColumnObjects ( tables . rows [ i ] . table_name ) ) ; } Promise . all ( promiseArray ) . then ( ( columnInfo ) => { for ( let i = 0 ; i < columnInfo . length ; i += 1 ) { tableList [ i ] . columns = columnInfo [ i ] ; } resolve ( tableList ) ; } ) . catch ( reject ) ; } ) . catch ( reject ) ; } ) ; interface MyObj { query : ( text : string , params : ( string | number ) [ ] , callback : Function ) => Function ; connectToDB : ( db : string ) => Promise < void > ; getLists : ( ) => Promise < DBList > ; getTableInfo : ( tableName : string ) => Promise < ColumnObj [ ] > ; } ; const myObj = { query : ( text , params , callback ) => pool . query ( text , params , callback ) , connectToDB : async ( db ) => { const newURI = `postgres://postgres:postgres@localhost:5432/${ db }` ; const newPool = new Pool ( { connectionString : newURI } ) ; await pool . end ( ) ; pool = newPool ; } , getLists : ( ) => new Promise ( ( resolve , reject ) => { const listObj = { databaseList : [ ] , tableList : [ ] , } ; Promise . all ( [ getDBNames ( ) , getDBLists ( ) ] ) . then ( ( data ) => { [ listObj . databaseList , listObj . tableList ] = data ; resolve ( listObj ) ; } ) . catch ( reject ) ; } ) , getTableInfo : ( tableName ) => getColumnObjects ( tableName ) , } ; module . exports = myObj ;