Socket
Socket
Sign inDemoInstall

mysql

Package Overview
Dependencies
Maintainers
9
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mysql - npm Package Compare versions

Comparing version 2.5.5 to 2.6.0

lib/PoolNamespace.js

12

Changes.md

@@ -7,2 +7,14 @@ # Changes

## v2.6.0 (2015-03-24)
* Add `poolCluster.remove` to remove pools from the cluster #1006 #1007
* Add optional callback to `poolCluster.end`
* Add `restoreNodeTimeout` option to `PoolCluster` #880 #906
* Fix LOAD DATA INFILE handling in multiple statements #1036
* Fix `poolCluster.add` to throw if `PoolCluster` has been closed
* Fix `poolCluster.add` to throw if `id` already defined
* Fix un-catchable error from `PoolCluster` when MySQL server offline #1033
* Improve speed formatting SQL #1019
* Support io.js
## v2.5.5 (2015-02-23)

@@ -9,0 +21,0 @@

318

lib/PoolCluster.js

@@ -1,5 +0,7 @@

var Pool = require('./Pool');
var PoolConfig = require('./PoolConfig');
var Util = require('util');
var EventEmitter = require('events').EventEmitter;
var Pool = require('./Pool');
var PoolConfig = require('./PoolConfig');
var PoolNamespace = require('./PoolNamespace');
var PoolSelector = require('./PoolSelector');
var Util = require('util');
var EventEmitter = require('events').EventEmitter;

@@ -16,11 +18,11 @@ module.exports = PoolCluster;

this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry;
this._defaultSelector = config.defaultSelector || 'RR';
this._removeNodeErrorCount = config.removeNodeErrorCount || 5;
this._defaultSelector = config.defaultSelector || 'RR';
this._restoreNodeTimeout = config.restoreNodeTimeout || 0;
this._closed = false;
this._findCaches = Object.create(null);
this._lastId = 0;
this._nodes = {};
this._serviceableNodeIds = [];
this._namespaces = {};
this._findCaches = {};
this._namespaces = Object.create(null);
this._nodes = Object.create(null);
}

@@ -30,2 +32,71 @@

PoolCluster.prototype.add = function add(id, config) {
if (this._closed) {
throw new Error('PoolCluster is closed.');
}
var nodeId = typeof id === 'object'
? 'CLUSTER::' + (++this._lastId)
: String(id);
if (this._nodes[nodeId] !== undefined) {
throw new Error('Node ID "' + nodeId + '" is already defined in PoolCluster.');
}
var poolConfig = typeof id !== 'object'
? new PoolConfig(config)
: new PoolConfig(id);
this._nodes[nodeId] = {
id : nodeId,
errorCount : 0,
pool : new Pool({config: poolConfig}),
_offlineUntil : 0
};
this._clearFindCaches();
};
PoolCluster.prototype.end = function end(callback) {
var cb = callback !== undefined
? callback
: _cb;
if (typeof cb !== 'function') {
throw TypeError('callback argument must be a function')
}
if (this._closed) {
return process.nextTick(cb);
}
this._closed = true;
var calledBack = false;
var nodeIds = Object.keys(this._nodes);
var waitingClose = nodeIds.length;
function onEnd(err) {
if (calledBack) {
return;
}
if (err || --waitingClose === 0) {
calledBack = true;
return cb(err);
}
}
if (waitingClose === 0) {
return process.nextTick(cb);
}
for (var i = 0; i < nodeIds.length; i++) {
var nodeId = nodeIds[i];
var node = this._nodes[nodeId];
node.pool.end(onEnd);
}
};
PoolCluster.prototype.of = function(pattern, selector) {

@@ -36,3 +107,3 @@ pattern = pattern || '*';

selector = selector.toUpperCase();
if (typeof Selector[selector] === 'undefined') {
if (typeof PoolSelector[selector] === 'undefined') {
selector = this._defaultSelector;

@@ -50,18 +121,11 @@ }

PoolCluster.prototype.add = function(id, config) {
if (typeof id === 'object') {
config = id;
id = 'CLUSTER::' + (++this._lastId);
}
PoolCluster.prototype.remove = function remove(pattern) {
var foundNodeIds = this._findNodeIds(pattern, true);
if (typeof this._nodes[id] === 'undefined') {
this._nodes[id] = {
id: id,
errorCount: 0,
pool: new Pool({config: new PoolConfig(config)})
};
for (var i = 0; i < foundNodeIds.length; i++) {
var node = this._getNode(foundNodeIds[i]);
this._serviceableNodeIds.push(id);
this._clearFindCaches();
if (node) {
this._removeNode(node);
}
}

@@ -87,65 +151,86 @@ };

PoolCluster.prototype.end = function() {
if (this._closed) {
return;
PoolCluster.prototype._clearFindCaches = function _clearFindCaches() {
this._findCaches = Object.create(null);
};
PoolCluster.prototype._decreaseErrorCount = function _decreaseErrorCount(node) {
var errorCount = node.errorCount;
if (errorCount > this._removeNodeErrorCount) {
errorCount = this._removeNodeErrorCount;
}
this._closed = true;
if (errorCount < 1) {
errorCount = 1;
}
for (var id in this._nodes) {
this._nodes[id].pool.end();
node.errorCount = errorCount - 1;
if (node._offlineUntil) {
node._offlineUntil = 0;
this.emit('online', node.id);
}
};
PoolCluster.prototype._findNodeIds = function(pattern) {
if (typeof this._findCaches[pattern] !== 'undefined') {
return this._findCaches[pattern];
}
PoolCluster.prototype._findNodeIds = function _findNodeIds(pattern, includeOffline) {
var currentTime = 0;
var foundNodeIds = this._findCaches[pattern];
var foundNodeIds;
if (foundNodeIds === undefined) {
var nodeIds = Object.keys(this._nodes);
var wildcard = pattern.substr(-1) === '*';
var keyword = wildcard
? pattern.substr(0, pattern.length - 1)
: pattern;
if (pattern === '*') { // all
foundNodeIds = this._serviceableNodeIds;
} else if (this._serviceableNodeIds.indexOf(pattern) != -1) { // one
foundNodeIds = [pattern];
} else if (pattern[pattern.length - 1] === '*') {
// wild matching
var keyword = pattern.substring(pattern.length - 1, 0);
if (wildcard) {
foundNodeIds = keyword.length !== 0
? nodeIds.filter(function (id) { return id.substr(0, keyword.length) === keyword; })
: nodeIds;
} else {
var index = nodeIds.indexOf(keyword);
foundNodeIds = nodeIds.slice(index, index + 1);
}
foundNodeIds = this._serviceableNodeIds.filter(function (id) {
return id.indexOf(keyword) === 0;
});
} else {
foundNodeIds = [];
this._findCaches[pattern] = foundNodeIds;
}
this._findCaches[pattern] = foundNodeIds;
if (includeOffline) {
return foundNodeIds;
}
return foundNodeIds;
return foundNodeIds.filter(function (nodeId) {
var node = this._getNode(nodeId);
if (!node._offlineUntil) {
return true;
}
if (!currentTime) {
currentTime = getMonotonicMilliseconds();
}
return node._offlineUntil <= currentTime;
}, this);
};
PoolCluster.prototype._getNode = function(id) {
PoolCluster.prototype._getNode = function _getNode(id) {
return this._nodes[id] || null;
};
PoolCluster.prototype._increaseErrorCount = function(node) {
if (++node.errorCount >= this._removeNodeErrorCount) {
var index = this._serviceableNodeIds.indexOf(node.id);
if (index !== -1) {
this._serviceableNodeIds.splice(index, 1);
delete this._nodes[node.id];
PoolCluster.prototype._increaseErrorCount = function _increaseErrorCount(node) {
var errorCount = ++node.errorCount;
this._clearFindCaches();
if (this._removeNodeErrorCount > errorCount) {
return;
}
node.pool.end();
this.emit('remove', node.id);
}
if (this._restoreNodeTimeout > 0) {
node._offlineUntil = getMonotonicMilliseconds() + this._restoreNodeTimeout;
this.emit('offline', node.id);
return;
}
};
PoolCluster.prototype._decreaseErrorCount = function(node) {
if (node.errorCount > 0) {
--node.errorCount;
}
this._removeNode(node);
this.emit('remove', node.id);
};

@@ -171,92 +256,29 @@

PoolCluster.prototype._clearFindCaches = function() {
this._findCaches = {};
};
PoolCluster.prototype._removeNode = function _removeNode(node) {
delete this._nodes[node.id];
/**
* PoolNamespace
*/
function PoolNamespace(cluster, pattern, selector) {
this._cluster = cluster;
this._pattern = pattern;
this._selector = new Selector[selector]();
}
this._clearFindCaches();
PoolNamespace.prototype.getConnection = function(cb) {
var clusterNode = this._getClusterNode();
var cluster = this._cluster;
var namespace = this;
if (clusterNode === null) {
var err = new Error('Pool does not exist.')
err.code = 'POOL_NOEXIST';
return cb(err);
}
cluster._getConnection(clusterNode, function(err, connection) {
var retry = err && cluster._canRetry
&& cluster._findNodeIds(namespace._pattern).length !== 0;
if (retry) {
return namespace.getConnection(cb);
}
if (err) {
return cb(err);
}
cb(null, connection);
});
node.pool.end(_noop);
};
PoolNamespace.prototype._getClusterNode = function _getClusterNode() {
var foundNodeIds = this._cluster._findNodeIds(this._pattern);
var nodeId;
function getMonotonicMilliseconds() {
var ms;
switch (foundNodeIds.length) {
case 0:
nodeId = null;
break;
case 1:
nodeId = foundNodeIds[0];
break;
default:
nodeId = this._selector(foundNodeIds);
break;
if (typeof process.hrtime === 'function') {
ms = process.hrtime();
ms = ms[0] * 1e3 + ms[1] * 1e-6;
} else {
ms = process.uptime() * 1000;
}
return nodeId !== null
? this._cluster._getNode(nodeId)
: null;
};
return Math.floor(ms);
}
/**
* Selector
*/
var Selector = {};
function _cb(err) {
if (err) {
throw err;
}
}
Selector.RR = function () {
var index = 0;
return function(clusterIds) {
if (index >= clusterIds.length) {
index = 0;
}
var clusterId = clusterIds[index++];
return clusterId;
};
};
Selector.RANDOM = function () {
return function(clusterIds) {
return clusterIds[Math.floor(Math.random() * clusterIds.length)];
};
};
Selector.ORDER = function () {
return function(clusterIds) {
return clusterIds[0];
};
};
function _noop() {}

@@ -77,2 +77,3 @@ var Sequence = require('./Sequence');

this._index++;
this._resultSet = null;
this._handleFinalResultPacket(packet);

@@ -79,0 +80,0 @@ }

@@ -70,11 +70,13 @@ var SqlString = exports;

var index = 0;
return sql.replace(/\?\??/g, function(match) {
if (!values.length) {
if (index === values.length) {
return match;
}
if (match == "??") {
return SqlString.escapeId(values.shift());
}
return SqlString.escape(values.shift(), stringifyObjects, timeZone);
var value = values[index++];
return match === '??'
? SqlString.escapeId(value)
: SqlString.escape(value, stringifyObjects, timeZone);
});

@@ -81,0 +83,0 @@ };

{
"name": "mysql",
"description": "A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.",
"version": "2.5.5",
"version": "2.6.0",
"license": "MIT",

@@ -20,3 +20,3 @@ "author": "Felix Geisendörfer <felix@debuggable.com> (http://debuggable.com/)",

"devDependencies": {
"istanbul": "0.3.5",
"istanbul": "0.3.8",
"rimraf": "2.2.8",

@@ -27,2 +27,9 @@ "mkdirp": "0.5.0",

},
"files": [
"lib/",
"Changes.md",
"License",
"Readme.md",
"index.js"
],
"engines": {

@@ -29,0 +36,0 @@ "node": ">= 0.6"

@@ -29,2 +29,3 @@ # mysql

- [Server disconnects](#server-disconnects)
- [Performing queries](#performing-queries)
- [Escaping query values](#escaping-query-values)

@@ -223,3 +224,3 @@ - [Escaping query identifiers](#escaping-query-identifiers)

* `multipleStatements`: Allow multiple mysql statements per query. Be careful
with this, it exposes you to SQL injection attacks. (Default: `false`)
with this, it could increase the scope of SQL injection attacks. (Default: `false`)
* `flags`: List of connection flags to use other than the default ones. It is

@@ -443,2 +444,3 @@ also possible to blacklist default ones. For more information, check

// add configurations
poolCluster.add(config); // anonymous group

@@ -449,2 +451,6 @@ poolCluster.add('MASTER', masterConfig);

// remove configurations
poolCluster.remove('SLAVE2'); // By nodeId
poolCluster.remove('SLAVE*'); // By target group : SLAVE1-2
// Target Group : ALL(anonymous, MASTER, SLAVE1-2), Selector : round-robin(default)

@@ -471,4 +477,6 @@ poolCluster.getConnection(function (err, connection) {});

// destroy
poolCluster.end();
// close all connections
poolCluster.end(function (err) {
// all connections in the pool cluster have ended
});
```

@@ -480,2 +488,5 @@

When `errorCount` is greater than `removeNodeErrorCount`, remove a node in the `PoolCluster`. (Default: `5`)
* `restoreNodeTimeout`: If connection fails, specifies the number of milliseconds
before another connection attempt will be made. If set to `0`, then node will bd
removed instead and never re-used. (Default: `0`)
* `defaultSelector`: The default selector. (Default: `RR`)

@@ -533,2 +544,47 @@ * `RR`: Select one alternately. (Round-Robin)

## Performing queries
In the MySQL library library, the most basic way to perform a query is to call
the `.query()` method on an object (like on a `Connection`, `Pool`, `PoolNamespace`
or other similar objects).
The simplest form on query comes as `.query(sqlString, callback)`, where a string
of a MySQL query is the first argument and the second is a callback:
```js
connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
```
The second form `.query(sqlString, parameters, callback)` comes when using
placeholders (see [escaping query values](#escaping-query-values)):
```js
connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
```
The third form `.query(options, callback)` comes when using various advanced
options on the query, like [escaping query values](#escaping-query-values),
[joins with overlapping column names](#joins-with-overlapping-column-names),
[timeouts](#timeout), and [type casting](#type-casting).
```js
connection.query({
sql: 'SELECT * FROM `books` WHERE `author` = ?',
timeout: 40000, // 40s
values: ['David']
}, function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
});
```
## Escaping query values

@@ -566,3 +622,3 @@

* Numbers are left untouched
* Booleans are converted to `true` / `false` strings
* Booleans are converted to `true` / `false`
* Date objects are converted to `'YYYY-mm-dd HH:ii:ss'` strings

@@ -778,2 +834,7 @@ * Buffers are converted to hex strings, e.g. `X'0fa5'`

confirming the success of a INSERT/UPDATE query.
* It is very important not to leave the result paused too long, or you may
encounter `Error: Connection lost: The server closed the connection.`
The time limit for this is determined by the
[net_write_timeout setting](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_net_write_timeout)
on your MySQL server.

@@ -780,0 +841,0 @@ Additionally you may be interested to know that it is currently not possible to

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