eip-cloud-services 1.1.12 → 1.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/mysql.js +86 -32
  3. package/src/redis.js +19 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eip-cloud-services",
3
- "version": "1.1.12",
3
+ "version": "1.1.14",
4
4
  "description": "Houses a collection of helpers for connecting with Cloud services.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/mysql.js CHANGED
@@ -6,21 +6,33 @@ if ( fs.existsSync ( configDirPath ) && fs.statSync ( configDirPath ).isDirector
6
6
  config = require ( 'config' ); // require the config directory if it exists
7
7
  }
8
8
 
9
- let pool = null;
9
+ // Replace single pool with pools object to store multiple connection pools
10
+ const pools = {};
10
11
 
11
- function getPool () {
12
- if ( !pool ) {
13
- pool = mysql.createPool ( {
14
- connectionLimit: config.mysql.connectionLimit,
15
- host: config.mysql.host,
16
- user: config.mysql.user,
17
- password: config.mysql.password,
18
- database: config.mysql.database || undefined,
19
- multipleStatements: config.mysql.multipleStatements || true
20
- } );
12
+ /**
13
+ * Creates or retrieves a MySQL connection pool based on a given pool identifier.
14
+ * If the pool does not exist, it creates a new one with the configuration settings.
15
+ *
16
+ * @param {string} [poolId='main'] - The identifier for the MySQL connection pool. Defaults to 'main'.
17
+ * @returns {Object} The MySQL connection pool.
18
+ */
19
+ function getPool (poolId = 'main') {
20
+ console.log(`Getting MySQL connection pool for poolId: ${poolId}`);
21
+ if (!pools[poolId]) {
22
+ // Support custom config per poolId if available
23
+ const poolConfig = config.mysql[poolId] || config.mysql;
24
+
25
+ pools[poolId] = mysql.createPool({
26
+ connectionLimit: poolConfig.connectionLimit,
27
+ host: poolConfig.host,
28
+ user: poolConfig.user,
29
+ password: poolConfig.password,
30
+ database: poolConfig.database || undefined,
31
+ multipleStatements: poolConfig.multipleStatements || true
32
+ });
21
33
  }
22
34
 
23
- return pool;
35
+ return pools[poolId];
24
36
  }
25
37
 
26
38
  const newQuery = ( connection, query ) => new Promise ( ( resolve, reject ) => {
@@ -44,29 +56,71 @@ const newQuery = ( connection, query ) => new Promise ( ( resolve, reject ) => {
44
56
  } );
45
57
  } );
46
58
 
59
+ /**
60
+ * Deletes a MySQL connection pool.
61
+ * @param {string} poolId - The identifier of the pool to delete.
62
+ * @returns {Promise<void>} - A promise that resolves once the pool is closed and deleted.
63
+ */
64
+ exports.deletePool = (poolId) => new Promise((resolve) => {
65
+ if (pools[poolId]) {
66
+ pools[poolId].end(() => {
67
+ delete pools[poolId];
68
+ resolve();
69
+ });
70
+ } else {
71
+ resolve();
72
+ }
73
+ });
74
+
47
75
  exports.getPool = getPool;
48
- exports.getConnection = () => new Promise ( ( resolve, reject ) => {
49
- getPool ().getConnection ( ( error, connection ) => {
50
- if ( error ) {
51
- console.log ( error );
52
- console.error ( 'There was a problem getting a new database connection.' );
53
- reject ( 'There was a problem getting a new database connection.' );
54
- }
55
- else {
56
- resolve ( connection );
76
+
77
+ /**
78
+ * Gets a MySQL connection from a specified pool.
79
+ * @param {string} [poolId='main'] - The identifier for the MySQL connection pool.
80
+ * @returns {Promise<Object>} - A promise that resolves with a MySQL connection.
81
+ */
82
+ exports.getConnection = (poolId = 'main') => new Promise((resolve, reject) => {
83
+ getPool(poolId).getConnection((error, connection) => {
84
+ if (error) {
85
+ console.log(error);
86
+ console.error('There was a problem getting a new database connection.');
87
+ reject('There was a problem getting a new database connection.');
88
+ } else {
89
+ resolve(connection);
57
90
  }
58
- } );
59
- } );
91
+ });
92
+ });
60
93
 
61
- exports.query = queryString => new Promise ( ( resolve, reject ) => {
62
- if ( !queryString.endsWith ( ';' ) ){
94
+ /**
95
+ * Executes a query using a connection from a specified pool.
96
+ * @param {string} queryString - The SQL query to execute.
97
+ * @param {string} [poolId='main'] - The identifier for the MySQL connection pool.
98
+ * @returns {Promise<Object>} - A promise that resolves with the query results.
99
+ */
100
+ exports.query = (queryString, poolId = 'main') => new Promise((resolve, reject) => {
101
+ if (!queryString.endsWith(';')) {
63
102
  queryString += ';';
64
103
  }
65
- this.getConnection ().then ( connection => newQuery ( connection, queryString ) ).then ( resolve ).catch ( reject );
66
- } );
104
+
105
+ this.getConnection(poolId)
106
+ .then(connection => newQuery(connection, queryString))
107
+ .then(resolve)
108
+ .catch(reject);
109
+ });
67
110
 
68
- exports.kill = () => new Promise ( resolve => {
69
- pool.end ( () => {
70
- resolve ();
71
- } );
72
- } );
111
+ /**
112
+ * Gracefully closes all MySQL connection pools.
113
+ * @returns {Promise<void>} - A promise that resolves once all pools are closed.
114
+ */
115
+ exports.kill = () => new Promise(resolve => {
116
+ const closePromises = Object.keys(pools).map(poolId =>
117
+ new Promise(poolResolve => {
118
+ pools[poolId].end(() => {
119
+ delete pools[poolId];
120
+ poolResolve();
121
+ });
122
+ })
123
+ );
124
+
125
+ Promise.all(closePromises).then(() => resolve());
126
+ });
package/src/redis.js CHANGED
@@ -248,26 +248,32 @@ exports.multiGet = async ( keys ) => {
248
248
  * @param {*} value - The value to set for the key.
249
249
  * @param {string} [ex] - Optional EX parameter to set expiration in seconds.
250
250
  * @param {number} [px] - Optional PX parameter to set expiration in milliseconds.
251
+ * @param {boolean}[nx] – NX flag → “only set if key does not exist”
251
252
  * @returns {Promise} - A promise that resolves with the result of the SET command.
252
253
  *
253
254
  * @description This method sets the value for the specified key in Redis.
254
255
  * If the value is an object or array, it will be automatically converted to a JSON string before storing.
255
256
  * Optionally, you can set an expiration time for the key using the `ex` parameter in seconds or the `px` parameter in milliseconds.
256
257
  */
257
- exports.set = async ( key, value, ex, px ) => {
258
+ exports.set = async ( key, value, ex, px, nx ) => {
258
259
  try {
259
- if ( typeof key === 'string' ) {
260
- const client = await getClient ();
261
-
262
- // Automatically convert objects or arrays to JSON strings
263
- const serializedValue = ( typeof value === 'object' && value !== null ) ? JSON.stringify ( value ) : value;
264
- const fullKey = ( !config?.redis?.prefix || key.startsWith ( config?.redis?.prefix ) ) ? key : config?.redis?.prefix + key;
265
-
266
- // Use the set method directly with optional EX and PX parameters
267
- return await client.set ( fullKey, serializedValue, ...( ex ? [ 'EX', ex ] : [] ), ...( px ? [ 'PX', px ] : [] ) );
268
- }
269
-
270
- throw new Error ( `redis.set expects a string key, instead the type provided was: ${typeof key}` );
260
+ if (typeof key !== 'string')
261
+ throw new Error(`redis.set expects a string key, got ${typeof key}`);
262
+
263
+ const client = await getClient();
264
+
265
+
266
+ const fullKey = (!config?.redis?.prefix || key.startsWith(config.redis.prefix)) ? key : config.redis.prefix + key;
267
+ const serialised = (typeof value === 'object' && value !== null) ? JSON.stringify(value) : value;
268
+
269
+ const args = [];
270
+ if (nx) args.push('NX');
271
+ if (ex !== undefined && px !== undefined)
272
+ throw new Error('redis.set: cannot specify both EX and PX');
273
+ if (ex !== undefined) args.push('EX', ex);
274
+ if (px !== undefined) args.push('PX', px);
275
+
276
+ return await client.set(fullKey, serialised, ...args);
271
277
  }
272
278
  catch ( error ) {
273
279
  console.log ( 'REDIS LIB ERROR [set]', error );