eip-cloud-services
Version:
Houses a collection of helpers for connecting with Cloud services.
126 lines (111 loc) • 4.32 kB
JavaScript
const mysql = require ( 'mysql' );
const fs = require ( 'fs' );
let config = {};
const configDirPath = `${ process.cwd ()}/config`;
if ( fs.existsSync ( configDirPath ) && fs.statSync ( configDirPath ).isDirectory () ) {
config = require ( 'config' ); // require the config directory if it exists
}
// Replace single pool with pools object to store multiple connection pools
const pools = {};
/**
* Creates or retrieves a MySQL connection pool based on a given pool identifier.
* If the pool does not exist, it creates a new one with the configuration settings.
*
* @param {string} [poolId='main'] - The identifier for the MySQL connection pool. Defaults to 'main'.
* @returns {Object} The MySQL connection pool.
*/
function getPool (poolId = 'main') {
console.log(`Getting MySQL connection pool for poolId: ${poolId}`);
if (!pools[poolId]) {
// Support custom config per poolId if available
const poolConfig = config.mysql[poolId] || config.mysql;
pools[poolId] = mysql.createPool({
connectionLimit: poolConfig.connectionLimit,
host: poolConfig.host,
user: poolConfig.user,
password: poolConfig.password,
database: poolConfig.database || undefined,
multipleStatements: poolConfig.multipleStatements || true
});
}
return pools[poolId];
}
const newQuery = ( connection, query ) => new Promise ( ( resolve, reject ) => {
connection.query ( query, ( error, results, fields ) => {
connection.release ();
if ( error ) {
const MAX_ERROR_LENGTH = 500;
const MAX_QUERY_LENGTH = 300;
const shortError = (error?.stack || error?.message || String(error)).slice(0, MAX_ERROR_LENGTH);
const shortQuery = query.slice(0, MAX_QUERY_LENGTH);
console.error("Query Error:", shortError);
console.error("Truncated Query:", shortQuery);
reject(`There was a problem with query: ${shortError}`);
}
else {
resolve ( results );
}
} );
} );
/**
* Deletes a MySQL connection pool.
* @param {string} poolId - The identifier of the pool to delete.
* @returns {Promise<void>} - A promise that resolves once the pool is closed and deleted.
*/
exports.deletePool = (poolId) => new Promise((resolve) => {
if (pools[poolId]) {
pools[poolId].end(() => {
delete pools[poolId];
resolve();
});
} else {
resolve();
}
});
exports.getPool = getPool;
/**
* Gets a MySQL connection from a specified pool.
* @param {string} [poolId='main'] - The identifier for the MySQL connection pool.
* @returns {Promise<Object>} - A promise that resolves with a MySQL connection.
*/
exports.getConnection = (poolId = 'main') => new Promise((resolve, reject) => {
getPool(poolId).getConnection((error, connection) => {
if (error) {
console.log(error);
console.error('There was a problem getting a new database connection.');
reject('There was a problem getting a new database connection.');
} else {
resolve(connection);
}
});
});
/**
* Executes a query using a connection from a specified pool.
* @param {string} queryString - The SQL query to execute.
* @param {string} [poolId='main'] - The identifier for the MySQL connection pool.
* @returns {Promise<Object>} - A promise that resolves with the query results.
*/
exports.query = (queryString, poolId = 'main') => new Promise((resolve, reject) => {
if (!queryString.endsWith(';')) {
queryString += ';';
}
this.getConnection(poolId)
.then(connection => newQuery(connection, queryString))
.then(resolve)
.catch(reject);
});
/**
* Gracefully closes all MySQL connection pools.
* @returns {Promise<void>} - A promise that resolves once all pools are closed.
*/
exports.kill = () => new Promise(resolve => {
const closePromises = Object.keys(pools).map(poolId =>
new Promise(poolResolve => {
pools[poolId].end(() => {
delete pools[poolId];
poolResolve();
});
})
);
Promise.all(closePromises).then(() => resolve());
});