import { Sequelize } from 'sequelize'; import config from 'lib/Config'; import { Log } from 'lib/Log'; type SequelDBClientState = { connection?: Sequelize; connecting?: Promise; connected: boolean; }; const log = Log.child({ module: 'DB', }); if (!config.postgresql.database) throw new Error('No database specified to connect to. Aborting...'); const state: SequelDBClientState = { connection: undefined, connecting: undefined, get connected() { return this.connection !== undefined; }, }; export const client = new Sequelize(config.postgresql.database, config.postgresql.user, config.postgresql.pass, { host: config.postgresql.host, port: config.postgresql.port, dialect: 'postgres', logging: log.trace.bind(log), }); export const connect = (): Promise => new Promise((resolve, reject) => { if (state.connected) { resolve(); return; } if (!state.connecting) { state.connecting = new Promise((iresolve, ireject) => { client.authenticate().then(iresolve).catch(ireject); }); } state.connecting.then(resolve).catch(reject); }); export const disconnect = () => { if (state.connection) { return state.connection .close() .then(() => { state.connected = false; log.debug('Closed connection...'); }) .catch((err) => { log.error('Failed to close connection', err); }); } }; /** Create the initial connection */ connect().catch((err) => { log.error('Failed to establish connection', err); throw new Error('Failed to establish connection'); }); // eslint-disable-next-line @typescript-eslint/no-misused-promises process.on('SIGINT', disconnect); // eslint-disable-next-line @typescript-eslint/no-misused-promises process.on('SIGTERM', disconnect);