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

mariadb

Package Overview
Dependencies
Maintainers
2
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mariadb - npm Package Compare versions

Comparing version 2.1.5 to 2.2.0

40

CHANGELOG.md
# Change Log
## [2.2.0](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.2.0) (03 Feb. 2020)
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.1.5...2.2.0)
##### CONJS-119 Add an option to detect Server version using a dedicated SELECT @@version
Azure is using a proxy that will return a MySQL handshake not reflecting real server.
A new option `forceVersionCheck` is added to permit issuing a new `SELECT @@Version` command on connection creation,
to retrieve the correct server version. Connector will then act according to that server version.
##### CONJS-20 add query timeout implementation
This option is only permitted for MariaDB server >= 10.1.2, and permits to set a timeout to query operation.
Driver internally use `SET STATEMENT max_statement_time=<timeout> FOR <command>` permitting to cancel operation when timeout is reached,
Implementation of max_statement_time is engine dependent, so there might be some differences: For example, with Galera engine, a commits will ensure replication to other nodes to be done, possibly then exceeded timeout, to ensure proper server state.
##### CONJS-110 fast-authentication improvement:
* add mysql_native_password to fast-authentication path
* plugin 'mysql_native_password' is used by default if default server plugin is unknown
* unexpected packet type during handshake result will throw a good error.
##### CONJS-117 Implement a pool leak detection
A new option `leakDetection` permits to indicate a timeout to log connection borrowed from pool.
When a connection is borrowed from pool and this timeout is reached, a message will be logged to console indicating a possible connection leak.
Another message will tell if the possible logged leak has been released.
A value of 0 (default) meaning Leak detection is disable
Additionally, some error messages have improved:
- Connection timeout now indicate that this correspond to socket failing to establish
- differentiate timeout error when closing pool to standard connection retrieving timeout
misc:
* CONJS-120 Permit values in SQL object to permits compatibility with mysql/mysql2
* CONJS-118 missing import for Error when asking for connection when pool is closed. Thanks to @WayneMDB
* correcting typescript import of @types/node to version >8 thanks to @SimonSchick
* dependencies update
## [2.1.5](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.1.5) (07 Jan. 2020)

@@ -3,0 +43,0 @@ [Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.1.4...2.1.5)

@@ -30,2 +30,15 @@ 'use strict';

if (this.opts.timeout) {
const err = Errors.createError(
'Cannot use timeout for Batch statement',
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return;
}
let questionMarkSql = this.sql;

@@ -32,0 +45,0 @@ if (this.opts.namedPlaceholders) {

@@ -28,2 +28,15 @@ 'use strict';

this.info = info;
if (this.opts.timeout) {
const err = Errors.createError(
'Cannot use timeout for Batch statement',
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return;
}
if (this.initialValues.length === 0) this.initialValues = [[]];

@@ -30,0 +43,0 @@ if (this.opts.namedPlaceholders) {

14

lib/cmd/handshake/client-handshake-response.js

@@ -25,13 +25,17 @@ 'use strict';

let authToken;
let authPlugin;
switch (pluginName) {
case 'mysql_native_password':
case '':
authToken = NativePasswordAuth.encryptPassword(pwd, info.seed);
break;
case 'client_ed25519':
authToken = Ed25519PasswordAuth.encryptPassword(pwd, info.seed);
authPlugin = 'client_ed25519';
break;
case 'mysql_clear_password':
authToken = Buffer.from(pwd);
authPlugin = 'mysql_clear_password';
break;
default:
authToken = Buffer.alloc(0);
authToken = NativePasswordAuth.encryptPassword(pwd, info.seed);
authPlugin = 'mysql_native_password';
break;

@@ -38,0 +42,0 @@ }

@@ -110,3 +110,3 @@ 'use strict';

this.throwNewError(
'Unexpected type of packet during handshake phase : ' + packet.log(),
'Unexpected type of packet during handshake phase : ' + marker,
true,

@@ -113,0 +113,0 @@ info,

'use strict';
const Capabilities = require('../../const/capabilities');
const ConnectionInformation = require('../../misc/connection-information');

@@ -63,36 +64,6 @@ /**

}
InitialHandshake.parseVersionString(info);
ConnectionInformation.parseVersionString(info);
}
static parseVersionString(info) {
let car;
let offset = 0;
let type = 0;
let val = 0;
for (; offset < info.serverVersion.raw.length; offset++) {
car = info.serverVersion.raw.charCodeAt(offset);
if (car < 48 || car > 57) {
switch (type) {
case 0:
info.serverVersion.major = val;
break;
case 1:
info.serverVersion.minor = val;
break;
case 2:
info.serverVersion.patch = val;
return;
}
type++;
val = 0;
} else {
val = val * 10 + car - 48;
}
}
//serverVersion finished by number like "5.5.57", assign patchVersion
if (type === 2) info.serverVersion.patch = val;
}
}
module.exports = InitialHandshake;

@@ -29,2 +29,3 @@ 'use strict';

out.writeInt8(0x03);
if (!this.handleTimeout(out, info)) return;
out.writeString(this.sql);

@@ -58,2 +59,3 @@ out.flushBuffer(true);

out.writeInt8(0x03);
if (!this.handleTimeout(out, info)) return;
out.writeString(this.queryParts[0]);

@@ -116,2 +118,45 @@ this.onPacketReceive = this.readResponsePacket;

/**
* If timeout is set, prepend query with SET STATEMENT max_statement_time=xx FOR, or throw an error
* @param out buffer
* @param info server information
* @returns {boolean} false if an error has been thrown
*/
handleTimeout(out, info) {
if (this.opts.timeout) {
if (info.isMariaDB()) {
if (info.hasMinVersion(10, 1, 2)) {
out.writeString('SET STATEMENT max_statement_time=' + this.opts.timeout / 1000 + ' FOR ');
return true;
} else {
const err = Errors.createError(
'Cannot use timeout for MariaDB server before 10.1.2. timeout value: ' +
this.opts.timeout,
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return false;
}
} else {
//not available for MySQL
// max_execution time exist, but only for select, and as hint
const err = Errors.createError(
'Cannot use timeout for MySQL server. timeout value: ' + this.opts.timeout,
false,
info,
'HY000',
Errors.ER_TIMEOUT_NOT_SUPPORTED
);
this.emit('send_end');
this.throwError(err, info);
return false;
}
}
return true;
}
/**
* Validate that parameters exists and are defined.

@@ -118,0 +163,0 @@ *

@@ -95,2 +95,3 @@ 'use strict';

this.opts = {
timeout: cmdOpts.timeout,
typeCast: cmdOpts.typeCast != undefined ? cmdOpts.typeCast : connOpts.typeCast,

@@ -97,0 +98,0 @@ rowsAsArray: cmdOpts.rowsAsArray != undefined ? cmdOpts.rowsAsArray : connOpts.rowsAsArray,

@@ -64,2 +64,3 @@ 'use strict';

this.initSql = opts.initSql;
this.forceVersionCheck = opts.forceVersionCheck || false;
this.maxAllowedPacket = opts.maxAllowedPacket;

@@ -185,2 +186,3 @@ this.metaAsArray = opts.metaAsArray || false;

if (opts.pipelining) opts.pipelining = opts.pipelining == 'true';
if (opts.forceVersionCheck) opts.forceVersionCheck = opts.forceVersionCheck == 'true';
if (opts.rowsAsArray) opts.rowsAsArray = opts.rowsAsArray == 'true';

@@ -187,0 +189,0 @@ if (opts.supportBigNumbers) opts.supportBigNumbers = opts.supportBigNumbers == 'true';

@@ -14,2 +14,4 @@ 'use strict';

if (opts.idleTimeout) opts.idleTimeout = parseInt(opts.idleTimeout);
if (opts.leakDetectionTimeout)
opts.leakDetectionTimeout = parseInt(opts.leakDetectionTimeout);
if (opts.initializationTimeout)

@@ -26,2 +28,3 @@ opts.initializationTimeout = parseInt(opts.initializationTimeout);

this.idleTimeout = opts.idleTimeout || 1800;
this.leakDetectionTimeout = opts.leakDetectionTimeout || 0;
this.initializationTimeout =

@@ -28,0 +31,0 @@ opts.initializationTimeout === undefined ? 30000 : opts.initializationTimeout;

@@ -18,4 +18,2 @@ 'use strict';

const moment = require('moment-timezone');
const Long = require('long');
const Iconv = require('iconv-lite');

@@ -163,6 +161,9 @@ /*commands*/

this.query = (sql, values) => {
let _cmdOpt, _sql;
let _cmdOpt,
_sql,
_values = values;
if (typeof sql === 'object') {
_cmdOpt = sql;
_sql = _cmdOpt.sql;
if (_cmdOpt.values) _values = _cmdOpt.values;
} else {

@@ -173,3 +174,3 @@ _sql = sql;

return new Promise(function(resolve, reject) {
const cmd = new Query(resolve, reject, _cmdOpt, opts, _sql, values);
const cmd = new Query(resolve, reject, _cmdOpt, opts, _sql, _values);
if (opts.trace) Error.captureStackTrace(cmd);

@@ -189,6 +190,9 @@ _addCommand(cmd);

this.batch = (sql, initialValues) => {
let _options, _sql;
let _options,
_sql,
_values = initialValues;
if (typeof sql === 'object') {
_options = sql;
_sql = _options.sql;
if (_options.values) _values = _options.values;
} else {

@@ -198,3 +202,3 @@ _sql = sql;

if (!initialValues) {
if (!_values) {
return Promise.reject(

@@ -211,3 +215,3 @@ Errors.createError(

const vals = Array.isArray(initialValues) ? initialValues : [initialValues];
const vals = Array.isArray(_values) ? _values : [_values];

@@ -235,6 +239,9 @@ return new Promise(function(resolve, reject) {

this.queryStream = (sql, values) => {
let _cmdOpt, _sql;
let _cmdOpt,
_sql,
_values = values;
if (typeof sql === 'object') {
_cmdOpt = sql;
_sql = _cmdOpt.sql;
if (sql.values) _values = sql.values;
} else {

@@ -244,3 +251,3 @@ _sql = sql;

const cmd = new Stream(_cmdOpt, opts, _sql, values, _socket);
const cmd = new Stream(_cmdOpt, opts, _sql, _values, _socket);
if (opts.trace) Error.captureStackTrace(cmd);

@@ -491,7 +498,16 @@ _addCommand(cmd);

this._queryCallback = (sql, values, cb) => {
let _cmdOpts, _sql, _values;
let _cb = cb;
let _cmdOpts,
_sql,
_values = values,
_cb = cb;
if (typeof values === 'function') {
_cb = values;
_values = undefined;
}
if (typeof sql === 'object') {
_cmdOpts = sql;
_sql = _cmdOpts.sql;
if (sql.values) _values = sql.values;
} else {

@@ -501,8 +517,2 @@ _sql = sql;

if (typeof values === 'function') {
_cb = values;
} else if (values !== undefined) {
_values = values;
}
let cmd;

@@ -547,7 +557,16 @@ if (_cb) {

this._batchCallback = (sql, values, cb) => {
let _cmdOpts, _sql, _values;
let _cb = cb;
let _cmdOpts,
_sql,
_values = values,
_cb = cb;
if (typeof values === 'function') {
_cb = values;
_values = undefined;
}
if (typeof sql === 'object') {
_cmdOpts = sql;
_sql = _cmdOpts.sql;
if (sql.values) _values = sql.values;
} else {

@@ -557,6 +576,4 @@ _sql = sql;

if (typeof values === 'function') {
_cb = values;
} else if (values !== undefined) {
_values = Array.isArray(values) ? values : [values];
if (_values !== undefined) {
_values = Array.isArray(_values) ? _values : [_values];
}

@@ -766,2 +783,14 @@

const _checkServerVersion = () => {
if (!opts.forceVersionCheck) {
return Promise.resolve();
}
return this.query('SELECT @@VERSION AS v').then(res => {
info.serverVersion.raw = res[0].v;
info.serverVersion.mariaDb = info.serverVersion.raw.includes('MariaDB');
ConnectionInformation.parseVersionString(info);
return Promise.resolve();
});
};
const _executeInitQuery = () => {

@@ -813,3 +842,8 @@ if (opts.initSql) {

if (opts.connectTimeout) {
_timeout = setTimeout(_connectTimeoutReached, opts.connectTimeout, authFailHandler);
_timeout = setTimeout(
_connectTimeoutReached,
opts.connectTimeout,
authFailHandler,
Date.now()
);
}

@@ -883,2 +917,5 @@

.then(() => {
return _checkServerVersion();
})
.then(() => {
return _executeInitQuery();

@@ -1015,3 +1052,3 @@ })

*/
const _connectTimeoutReached = function(authFailHandler) {
const _connectTimeoutReached = function(authFailHandler, initialConnectionTime) {
_timeout = null;

@@ -1021,3 +1058,5 @@ const handshake = _receiveQueue.peekFront();

Errors.createError(
'Connection timeout',
'Connection timeout: failed to create socket after ' +
(Date.now() - initialConnectionTime) +
'ms',
true,

@@ -1024,0 +1063,0 @@ info,

@@ -0,0 +0,0 @@ 'use strict';

@@ -60,4 +60,38 @@ 'use strict';

}
/**
* Parse raw info to set server major/minor/patch values
* @param info
*/
static parseVersionString(info) {
let car;
let offset = 0;
let type = 0;
let val = 0;
for (; offset < info.serverVersion.raw.length; offset++) {
car = info.serverVersion.raw.charCodeAt(offset);
if (car < 48 || car > 57) {
switch (type) {
case 0:
info.serverVersion.major = val;
break;
case 1:
info.serverVersion.minor = val;
break;
case 2:
info.serverVersion.patch = val;
return;
}
type++;
val = 0;
} else {
val = val * 10 + car - 48;
}
}
//serverVersion finished by number like "5.5.57", assign patchVersion
if (type === 2) info.serverVersion.patch = val;
}
}
module.exports = ConnectionInformation;

@@ -97,2 +97,4 @@ 'use strict';

module.exports.ER_WRONG_AUTO_TIMEZONE = 45036;
module.exports.ER_CLOSING_POOL = 45037;
module.exports.ER_TIMEOUT_NOT_SUPPORTED = 45038;

@@ -99,0 +101,0 @@ const keys = Object.keys(module.exports);

@@ -82,7 +82,7 @@ 'use strict';

const err = Errors.createError(
'retrieve connection from pool timeout',
'pool is ending, connection request aborted',
false,
null,
'HY000',
Errors.ER_GET_CONNECTION_TIMEOUT,
Errors.ER_CLOSING_POOL,
undefined,

@@ -269,2 +269,3 @@ false

.then(() => {
initLeakProcess(conn);
return Promise.resolve(conn);

@@ -280,2 +281,3 @@ })

if (conn.isValid()) {
initLeakProcess(conn);
return Promise.resolve(conn);

@@ -301,3 +303,5 @@ } else {

Errors.createError(
'retrieve connection from pool timeout',
'retrieve connection from pool timeout after ' +
Math.abs(Date.now() - (task.timeout - opts.acquireTimeout)) +
'ms',
false,

@@ -378,2 +382,3 @@ null,

conn.destroy = () => {
removeLeakProcess(conn);
delete activeConnections[conn.threadId];

@@ -389,2 +394,3 @@ initialDestroyFct();

let currConn;
removeLeakProcess(conn);
delete activeConnections[conn.threadId];

@@ -411,2 +417,3 @@ while ((currConn = idleConnections.peekAt(idx))) {

this._releaseConnection = function(conn) {
removeLeakProcess(conn);
conn.lastUse = Date.now();

@@ -508,2 +515,3 @@ delete activeConnections[conn.threadId];

this._discardConnection = conn => {
removeLeakProcess(conn);
delete activeConnections[conn.threadId];

@@ -514,2 +522,30 @@ conn.forceEnd().catch(err => {});

const logLeak = conn => {
console.log(
'Possible connection leak on thread ' +
conn.info.threadId +
' (connection not returned to pool since ' +
(Date.now() - conn.lastUse) +
'ms. Did connection.released() been implemented'
);
conn.leaked = true;
};
const _initLeakProcess = conn => {
conn.lastUse = Date.now();
conn.leaked = false;
conn.leakProcess = setTimeout(logLeak, opts.leakDetectionTimeout, conn);
};
const _removeLeakProcess = conn => {
conn.leakProcess = clearTimeout(conn.leakProcess);
if (conn.leaked) {
console.log(
'Previous possible leak connection with thread ' +
conn.info.threadId +
' was returned to pool'
);
}
};
/**

@@ -525,2 +561,3 @@ * Launch next waiting task request if available connections.

if (conn) {
initLeakProcess(conn);
this.emit('acquire', conn);

@@ -541,3 +578,4 @@ activeConnections[conn.threadId] = conn;

let connectionInCreation = false;
const initLeakProcess = opts.leakDetectionTimeout > 0 ? _initLeakProcess : () => {};
const removeLeakProcess = opts.leakDetectionTimeout > 0 ? _removeLeakProcess : () => {};
const idleConnections = new Queue();

@@ -544,0 +582,0 @@ const activeConnections = {};

@@ -5,2 +5,3 @@ 'use strict';

const ConnectionCallback = require('./connection-callback');
const Errors = require('./misc/errors');
const util = require('util');

@@ -158,9 +159,8 @@

const _queryCallback = function(sql, values, cb) {
let _values, _cb;
let _cb = cb,
_values = values;
if (typeof values === 'function') {
_cb = values;
} else if (values !== undefined) {
_values = values;
_cb = cb;
_values = undefined;
}

@@ -176,9 +176,8 @@

const _batchCallback = function(sql, values, cb) {
let _values, _cb;
let _values = values,
_cb = cb;
if (typeof values === 'function') {
_cb = values;
} else if (values !== undefined) {
_values = values;
_cb = cb;
_values = undefined;
}

@@ -185,0 +184,0 @@

@@ -5,2 +5,3 @@ 'use strict';

const PoolBase = require('./pool-base');
const Errors = require('./misc/errors');
const util = require('util');

@@ -7,0 +8,0 @@

{
"name": "mariadb",
"version": "2.1.5",
"version": "2.2.0",
"description": "fast mariadb/mysql connector.",

@@ -49,5 +49,5 @@ "main": "promise.js",

"@types/geojson": "^7946.0.7",
"@types/node": "^13.1.4",
"@types/node": ">=8.0.0",
"denque": "^1.4.1",
"iconv-lite": "^0.5.0",
"iconv-lite": "^0.5.1",
"long": "^4.0.0",

@@ -57,7 +57,7 @@ "moment-timezone": "^0.5.27"

"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.15.0",
"@typescript-eslint/parser": "^2.15.0",
"@typescript-eslint/eslint-plugin": "^2.18.0",
"@typescript-eslint/parser": "^2.18.0",
"benchmark": "^2.1.4",
"chai": "^4.2.0",
"codecov": "^3.5.0",
"codecov": "^3.6.4",
"colors": "^1.4.0",

@@ -67,10 +67,10 @@ "dom-parser": "^0.1.6",

"eslint": "^6.6.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-markdown": "^1.0.1",
"eslint-plugin-prettier": "^3.1.0",
"mocha": "^7.0.0",
"mocha": "^7.0.1",
"mocha-lcov-reporter": "^1.3.0",
"nyc": "^15.0.0",
"prettier": "^1.19.1",
"typescript": "^3.7.2"
"typescript": "^3.7.5"
},

@@ -77,0 +77,0 @@ "bugs": {

@@ -149,7 +149,7 @@ <p align="center">

[npm-url]:http://npmjs.org/package/mariadb
[appveyor-image]:https://ci.appveyor.com/api/projects/status/bcg7yy4iy9viq08t/branch/master?svg=true
[appveyor-url]:https://ci.appveyor.com/project/rusher/mariadb-connector-nodejs
[appveyor-image]:https://ci.appveyor.com/api/projects/status/558kpv0j1r545pgq/branch/master?svg=true
[appveyor-url]:https://ci.appveyor.com/project/rusher/mariadb-connector-nodejs-w8k25
[licence-image]:https://img.shields.io/badge/license-GNU%20LGPL%20version%202.1-green.svg?style=flat-square
[licence-url]:http://opensource.org/licenses/LGPL-2.1
[codecov-image]:https://codecov.io/gh/MariaDB/mariadb-connector-nodejs/branch/master/graph/badge.svg
[codecov-url]:https://codecov.io/gh/MariaDB/mariadb-connector-nodejs
[codecov-image]:https://codecov.io/gh/mariadb-corporation/mariadb-connector-nodejs/branch/master/graph/badge.svg
[codecov-url]:https://codecov.io/gh/mariadb-corporation/mariadb-connector-nodejs

@@ -0,1 +1,2 @@

/* eslint-disable @typescript-eslint/no-explicit-any */
// Type definitions for mariadb 2.0

@@ -96,2 +97,8 @@ // Project: https://github.com/mariadb-corporation/mariadb-connector-nodejs

/**
* Force server version check by explicitly using SELECT VERSION(), not relying on server initial handshake
* information
*/
forceVersionCheck?: boolean;
/**
* Allows the use of LOAD DATA INFILE statements.

@@ -98,0 +105,0 @@ * Loading data from a file from the client may be a security issue, as a man-in-the-middle proxy server can change

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