node-pg-migrate-custom
Version:
Postgresql database migration management tool for node.js
91 lines (89 loc) • 3.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("util");
const pg_1 = require("pg");
var ConnectionStatus;
(function (ConnectionStatus) {
ConnectionStatus["DISCONNECTED"] = "DISCONNECTED";
ConnectionStatus["CONNECTED"] = "CONNECTED";
ConnectionStatus["ERROR"] = "ERROR";
})(ConnectionStatus || (ConnectionStatus = {}));
const db = (connection, logger = console) => {
const isExternalClient = typeof connection === 'object' && 'query' in connection && typeof connection.query === 'function';
let connectionStatus = ConnectionStatus.DISCONNECTED;
const client = isExternalClient ? connection : new pg_1.Client(connection);
const beforeCloseListeners = [];
const createConnection = () => new Promise((resolve, reject) => {
if (isExternalClient || connectionStatus === ConnectionStatus.CONNECTED) {
resolve();
}
else if (connectionStatus === ConnectionStatus.ERROR) {
reject(new Error('Connection already failed, do not try to connect again'));
}
else {
client.connect((err) => {
if (err) {
connectionStatus = ConnectionStatus.ERROR;
logger.error(`could not connect to postgres: ${util_1.inspect(err)}`);
return reject(err);
}
connectionStatus = ConnectionStatus.CONNECTED;
return resolve();
});
}
});
const query = async (queryTextOrConfig, values) => {
await createConnection();
try {
return await client.query(queryTextOrConfig, values);
}
catch (err) {
const { message, position } = err;
const string = typeof queryTextOrConfig === 'string' ? queryTextOrConfig : queryTextOrConfig.text;
if (message && position >= 1) {
const endLineWrapIndexOf = string.indexOf('\n', position);
const endLineWrapPos = endLineWrapIndexOf >= 0 ? endLineWrapIndexOf : string.length;
const stringStart = string.substring(0, endLineWrapPos);
const stringEnd = string.substr(endLineWrapPos);
const startLineWrapPos = stringStart.lastIndexOf('\n') + 1;
const padding = ' '.repeat(position - startLineWrapPos - 1);
logger.error(`Error executing:
${stringStart}
${padding}^^^^${stringEnd}
${message}
`);
}
else {
logger.error(`Error executing:
${string}
${err}
`);
}
throw err;
}
};
const select = async (queryTextOrConfig, values) => {
const { rows } = await query(queryTextOrConfig, values);
return rows;
};
const column = async (columnName, queryTextOrConfig, values) => {
const rows = await select(queryTextOrConfig, values);
return rows.map((r) => r[columnName]);
};
return {
createConnection,
query,
select,
column,
connected: () => connectionStatus === ConnectionStatus.CONNECTED,
addBeforeCloseListener: (listener) => beforeCloseListeners.push(listener),
close: async () => {
await beforeCloseListeners.reduce((promise, listener) => promise.then(listener).catch((err) => logger.error(err.stack || err)), Promise.resolve());
if (!isExternalClient) {
connectionStatus = ConnectionStatus.DISCONNECTED;
client.end();
}
},
};
};
exports.default = db;
;