Search code examples
node.jspostgresqlnode-postgres

Every second time I run the config file it doesn't work


I'm using node.js w/ PSQL, along with express and node-postgres. I've got a file called config.js. The intention is to have it delete the database then recreate it along with the tables every time it is run. This works every second time, returning an error the other half of the time, and not re-creating the database.

(node:11300) UnhandledPromiseRejectionWarning: error: database "abc" does not exist

Anyone know what's up? Please tell me if I need to include the full error message, I didn't as it didn't seem very useful.

Code:

const { Pool, Client } = require('pg')

let dbName = "abc"

let tables = [{
    name: "users",
    content: "id SERIAL, username VARCHAR, email VARCHAR, passcode VARCHAR"
}]

let pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'postgres',
    password: 'postgres',
    port: 5432
})

deleteDb()
createDbAndTables()

function deleteDb() {
    pool.query("DROP DATABASE IF EXISTS abc", (err, res) => {

        if (err) {

            console.log(err)
        } else {

            console.log("deleted db " + dbName)
        }
    })
}

function createDbAndTables() {
    pool.query("CREATE DATABASE abc", (err, res) => {

        console.log("created db " + dbName)

        const client = new Client({
            host: 'localhost',
            port: 5432,
            user: 'postgres',
            password: 'postgres',
            database: dbName,
        })

        client.connect()

        for (let i = 0; i < tables.length; i++) {

            let table = tables[i]

            client.query("CREATE TABLE " + table.name + "(" + table.content + ")", (err, res) => {
                if (err) {

                    console.log(err)
                } else {

                    console.log("created table " + table.name)
                }
                if (i == tables.length) {

                    client.end()
                }
            })
        }
        pool.end()
    })
}

If there are things I'm doing wrong or optimizations that could be made, I'd also love to hear them. Thanks for the help in advance!


Solution

  • Here is a very quick and dirty way to make sure both of your functions deleteDb and createDbAndTables run in sequence:

    const { Pool, Client } = require('pg');
    
    let dbName = 'abc';
    
    let tables = [
      {
        name: 'users',
        content: 'id SERIAL, username VARCHAR, email VARCHAR, passcode VARCHAR',
      },
    ];
    
    let pool = new Pool({
      user: 'postgres',
      host: 'localhost',
      database: 'postgres',
      password: 'postgres',
      port: 5432,
    });
    
    deleteDb().then(() => {
      createDbAndTables();
    });
    
    function deleteDb() {
      return new Promise((resolve, reject) => {
        pool.query('DROP DATABASE IF EXISTS abc', (err, res) => {
          if (err) {
            reject(err);
          } else {
            resolve('deleted db ' + dbName);
          }
        });
      });
    }
    
    function createDbAndTables() {
      pool.query('CREATE DATABASE abc', (err, res) => {
        console.log('created db ' + dbName);
    
        const client = new Client({
          host: 'localhost',
          port: 5432,
          user: 'postgres',
          password: 'postgres',
          database: dbName,
        });
    
        client.connect();
    
        for (let i = 0; i < tables.length; i++) {
          let table = tables[i];
          client.query(
            'CREATE TABLE ' + table.name + '(' + table.content + ')',
            (err, res) => {
              if (err) {
                console.log(err);
              } else {
                console.log('created table ' + table.name);
              }
              if (i == tables.length) {
                client.end();
              }
            }
          );
        }
        pool.end();
      });
    }
    

    Note I only made one of them a promise but you will likely have to do it with both if you want to run things after. I also didn't use async / await as I assume this is not run inside a fucntion and you don't have the latest node running for simplicity.