Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@goodware/mysql

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@goodware/mysql - npm Package Compare versions

Comparing version 2.0.4 to 2.0.5

90

index.js

@@ -9,3 +9,3 @@ /* eslint-disable no-param-reassign */

/**
/**
* Testing

@@ -17,17 +17,17 @@ *

/**
* To Do
*
* 1. In order for decimals to be returned as numbers instead of strings, add an option and add this code
* conditionally. See
* https://github.com/sidorares/node-mysql2/issues/795
* I tried this when creating a new connection and it didn't work:
* typeCast: (field, next) => {
* if (field.type === "DECIMAL") {
* const value = field.string();
* return (value === null) ? null : Number(value);
* }
* return next();
* }
*/
/**
* To Do
*
* 1. In order for decimals to be returned as numbers instead of strings, add an option and add this code
* conditionally. See
* https://github.com/sidorares/node-mysql2/issues/795
* I tried this when creating a new connection and it didn't work:
* typeCast: (field, next) => {
* if (field.type === "DECIMAL") {
* const value = field.string();
* return (value === null) ? null : Number(value);
* }
* return next();
* }
*/

@@ -57,3 +57,3 @@ /**

keepAliveInitialDelay: Joi.number().integer().min(0).default(10000),
logger: Joi.object(),
logger: Joi.alternatives(Joi.object(), Joi.function()),
// eslint-disable-next-line quotes

@@ -68,7 +68,3 @@ maxConnectDelay: Joi.number()

multipleStatements: Joi.boolean(),
password: Joi.string().when('useIAM', {
is: true,
then: Joi.optional(),
otherwise: Joi.string().required(),
}),
password: Joi.string().allow(''),
port: Joi.number().integer().default(3306),

@@ -83,9 +79,28 @@ queueLimit: Joi.number().integer().min(0).default(0),

useIAM: Joi.boolean(),
user: Joi.string().required(),
user: Joi.string().required().allow(''),
usePool: Joi.boolean(),
});
/**
* @private
* @description This tag is always logged
*/
const logTag = 'mysql';
/**
* @private
* @description Logs a message
* @param {Object | Function} logger
* @param {string []} tags
* @param {Object} message
*/
function log(logger, tags, message) {
if (typeof logger === 'object') {
logger.log(tags, message);
} else {
logger(tags, message);
}
}
/**
* @description Creates mysql2-promise Connections, optionally from a pool. If a database connection can not be acquired

@@ -110,4 +125,6 @@ * due to a timeout specified via the 'connectTimeout' options setting, the methods try again using exponential backoff

* @param {Object} options Database connection options
* @param {Object} [logger]
*/
constructor(options) {
constructor(options, logger) {
if (logger && !options.logger) options = { ...options, logger };
const validation = optionsSchema.validate(options);

@@ -188,9 +205,10 @@ if (validation.error) throw new Error(validation.error.message);

* @description Runs a bogus SQL statement to check the database connection
* @param {Object} [logger]
* @return {Promise} Resolves to true or rejects in case of connection failure
*/
connect() {
connect(logger) {
return this.connectForTask((connection) => {
connection.query('SELECT 1');
return true;
});
}, logger);
}

@@ -204,3 +222,3 @@

* @param {Object} [logger]
* @return {Promise} The value returned by task(), if the database connection is successful
* @return {Promise} Resolves to the value returned by task(), if the database connection is successful
* @throws {Error} The error caught while:

@@ -221,3 +239,3 @@ * 1. connecting to the database

* @param {Object} [logger]
* @return {Promise} The value returned by task(), if the database connection is successful
* @return {Promise} Resolves to the value returned by task(), if the database connection is successful
* @throws {Error} The error caught while:

@@ -239,3 +257,3 @@ * 1. connecting to the database

* @param {Boolean} useTransaction Defaults to true
* @return {Promise} The value returned by task(), if the database connection is successful
* @return {Promise} Resolves to the value returned by task(), if the database connection is successful
* @throws {Error} The error caught while:

@@ -296,3 +314,3 @@ * 1. connecting to the database

if (logger) {
logger.log(['warn', logTag], {
log(logger, ['warn', logTag], {
message: `Rollback transaction on '${this.connectOptions.host}'`,

@@ -307,3 +325,3 @@ host: this.connectOptions.host,

if (logger) {
logger.log(['error', logTag], {
log(logger, ['error', logTag], {
message: `Rollback transaction failed on '${this.connectOptions.host}'`,

@@ -319,3 +337,3 @@ host: this.connectOptions.host,

if (logger) {
logger.log(['error', logTag], {
log(logger, ['error', logTag], {
message: `Destroying connection failed on '${this.connectOptions.host}'`,

@@ -337,3 +355,3 @@ host: this.connectOptions.host,

if (logger) {
logger.log(['error', logTag], {
log(logger, ['error', logTag], {
message: `Dead connection detected on '${this.connectOptions.host}'`,

@@ -349,3 +367,3 @@ host: this.connectOptions.host,

if (logger) {
logger.log(['error', logTag], {
log(logger, ['error', logTag], {
message: `Destroying connection failed on '${this.connectOptions.host}'`,

@@ -388,3 +406,3 @@ host: this.connectOptions.host,

logger.log(['warn', logTag], {
log(logger, ['warn', logTag], {
message: `Waiting ${humanizeDuration(delayMs)} for '${user}@${host}:${port}/${database}' IAM: ${useIAM}`,

@@ -412,3 +430,3 @@ host,

if (logger) {
logger.log(['error', logTag], {
log(logger, ['error', logTag], {
message: `Releasing connection failed on '${this.connectOptions.host}'`,

@@ -415,0 +433,0 @@ host: this.connectOptions.host,

14

package.json
{
"name": "@goodware/mysql",
"version": "2.0.4",
"version": "2.0.5",
"description": "A mysql2-based connection helper",

@@ -23,11 +23,9 @@ "keywords": [

"dependencies": {
"aws-sdk": "^2.773.0",
"docs": "^0.3.2-canary.0",
"humanize-duration": "^3.24.0",
"joi": "^17.2.1",
"mysql2": "^2.2.5"
"aws-sdk": "^2.0.0",
"humanize-duration": "^3.0.0",
"joi": "^17.0.0",
"mysql2": "^2.0.0"
},
"devDependencies": {
"deepmerge": "^4.2.2",
"dotenv": "^8.2.0",
"docs": "^0.3.2-canary.0",
"eslint": "^7.11.0",

@@ -34,0 +32,0 @@ "eslint-config-airbnb-base": "^14.2.0",

@@ -29,6 +29,29 @@ # @goodware/mysql: A mysql2-based connection helper

- If usePool is true, "await stop()" must be called on the MySqlConnector object if you wish to release the connections
in the pool. **Letting these objects merely go out of scope without stopping them will not close the connections.**
in the pool. **Letting these objects go out of scope without stopping them will not close the connections.**
# Example
# Usage
1. Create an instance of the class that is exported by this module
2. Call exectue() or transaction(). These accept a function that accepts a mysql2 connection object. The provided functions usually call query() on the connection object.
3. If you're using connection pooling, call stop() to close all connections. This is necessary if:
a) The app instantiates multiple instances to access the same database server. It is recommended to use a single global instance to avoid this issue.
b) The app hangs when exiting
# Logger
The options provided by the constructor and all other methods accept an optional 'logger' function or object. If an object is provided, it must have the method log():
```js
interface Logger {
/**
* @param tags Typically includes a logging level name, like info or debug.
* @param message An object with at least a message property
*/
log(tags: string[] | string, message: Record<string, unknown>): void;
}
```
# Usage
The following program outputs 'success' to the console.

@@ -48,12 +71,12 @@

const connector = new mysql(config);
const connector = new mysql(config, console.log); // The second parameter is a logger function
async () => {
await connector.execute( async () => {
const [results] = await connection.query(`select 'success' AS column`);
console.log(results[0]).column;
const result = await connector.execute( async (connection) => {
const [results] = await connection.query(`select 'success' AS status`);
return results[0].status;
});
console.log(result);
await connector.stop();
}().then(console.info, console.error);
```

@@ -1,50 +0,10 @@

const deepmerge = require('deepmerge');
const dotenv = require('dotenv');
const pack = require('../package.json');
// Read .env files into process.env
const env = process.env.NODE_ENV || 'dev';
dotenv.config({ path: '.env' });
dotenv.config({ path: `.env-${env}` });
// Default configuration
let config = {
env,
name: pack.name,
version: pack.version,
service: pack.name,
module.exports = {
host: process.env.DB_HOST || '0.0.0.0',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_DATABASE || 'mysql',
region: process.env.DB_AWS_REGION || process.env.AWS_DEFAULT_REGION,
ssl: process.env.DB_SSL,
useIAM: process.env.DB_USE_IAM,
};
// Extra configurations are named after NODE_ENV and merged into config
// Providing .env-{NODE_ENV} file is preferable to editing this file
const configs = {};
// Unit testing
configs.dev = {
db: {
host: process.env.DB_HOST || '0.0.0.0',
port: process.env.DB_PORT || 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
region: process.env.DB_AWS_REGION || process.env.AWS_DEFAULT_REGION,
ssl: process.env.DB_SSL,
useIAM: process.env.DB_USE_IAM,
},
logging: {
categories: {
default: {
console: 'silly',
file: 'silly',
errorFile: 'on',
cloudWatch: 'off',
},
},
},
};
if (env in configs) {
config = deepmerge(config, configs[env], { arrayMerge: (destination, source) => [...destination, ...source] });
}
module.exports = config;

@@ -5,6 +5,24 @@ /* eslint-disable no-console */

function test() {
return new MySqlConnector(config).connect();
class Logger {
// eslint-disable-next-line class-methods-use-this
log(tags, message, extra) {
console.log({ tags, message, extra });
}
}
const logger = new Logger();
const test = async () => {
config.host = '17.1.1.1';
const connector = new MySqlConnector(config, logger.log);
// Test the connection
await connector.connect();
const result = await connector.execute(async (connection) => {
const [results] = await connection.query(`select 'success' AS status`);
return results[0].status;
});
if (result !== 'success') throw new Error('failed');
};
test().then(() => console.log('Successful'), console.error);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc