inceptum
Version:
hipages take on the foundational library for enterprise-grade apps written in NodeJS
95 lines • 4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DBClient = void 0;
const LogManager_1 = require("../log/LogManager");
const ConnectionPool_1 = require("./ConnectionPool");
const LOGGER = LogManager_1.LogManager.getLogger(__filename);
class DBClient {
constructor(clientConfiguration) {
this.clientConfiguration = clientConfiguration;
}
/**
* Runs a function in a transaction. The function must receive one parameter that will be of class
* {MysqlTransaction} and that you need to use to run all queries in this transaction
*
* @param {boolean} readonly Whether the transaction needs to be readonly or not
* @param {Function} func A function that returns a promise that will execute all the queries wanted in this transaction
* @returns {Promise} A promise that will execute the whole transaction
*/
async runInTransaction(readonly, func) {
const dbTransaction = this.getNewDBTransaction(readonly, this.getPoolForReadonly(readonly));
try {
await dbTransaction.begin();
const resp = await func(dbTransaction);
return resp;
}
catch (err) {
LOGGER.error(err, 'There was an error running in transaction');
dbTransaction.markError(err);
throw err;
}
finally {
await dbTransaction.end();
}
}
getPoolForReadonly(readonly) {
if (readonly && this.slavePool) {
return this.slavePool;
}
return this.masterPool;
}
/**
* Shorthand for a single readonly query
* @param sql query to run
* @param binds binds
*/
async read(sql, ...binds) {
return this.executeSql(true, sql, ...binds);
}
/**
* Shorthand to run a single sql.
* Easy to mock
* @param readonly
* @param sql
* @param binds
*/
async executeSql(readonly, sql, ...binds) {
return this.runInTransaction(readonly, (client) => client.query(sql, ...binds));
}
async initialise() {
const defaultConnectionConfig = this.getDefaultConnectionConfig();
if (this.clientConfiguration.master) {
// tslint:disable-next-line:prefer-object-spread
const fullMasterConfig = Object.assign({}, defaultConnectionConfig, this.clientConfiguration.master.connectionConfig);
this.masterPool = new ConnectionPool_1.InstrumentedConnectionPool(this.getConnectionFactory(`${this.clientConfiguration.name}_master`, fullMasterConfig), this.clientConfiguration.master, this.clientConfiguration.name, false);
await this.masterPool.start();
}
if (this.clientConfiguration.slave) {
// tslint:disable-next-line:prefer-object-spread
const fullSlaveConfig = Object.assign({}, defaultConnectionConfig, this.clientConfiguration.slave.connectionConfig);
this.slavePool = new ConnectionPool_1.InstrumentedConnectionPool(this.getConnectionFactory(`${this.clientConfiguration.name}_slave`, fullSlaveConfig), this.clientConfiguration.slave, this.clientConfiguration.name, true);
await this.slavePool.start();
}
if (!this.masterPool && !this.slavePool) {
throw new Error(`MysqlClient ${this.name} has no connections configured for either master or slave`);
}
}
async stop() {
if (this.masterPool) {
await this.masterPool.stop();
}
if (this.slavePool) {
await this.slavePool.stop();
}
}
async ping(readonly) {
LOGGER.trace('Doing ping');
const pool = this.getPoolForReadonly(readonly);
const dbTransaction = this.getNewDBTransaction(true, pool);
await dbTransaction.runQueryWithoutTransaction(this.getPingQuery());
}
}
exports.DBClient = DBClient;
DBClient.startMethod = 'initialise';
DBClient.stopMethod = 'stop';
//# sourceMappingURL=DBClient.js.map