Comparing version 2.10.2 to 2.11.0
@@ -7,2 +7,22 @@ # Changes | ||
## v2.11.0 (2016-06-06) | ||
* Add `POOL_CLOSED` code to "Pool is closed." error | ||
* Add `POOL_CONNLIMIT` code to "No connections available." error #1332 | ||
* Bind underlying connections in pool to same domain as pool #1242 | ||
* Bind underlying socket to same domain as connection #1243 | ||
* Fix allocation errors receiving many result rows #918 #1265 #1324 #1415 | ||
* Fix edge cases constructing long stack traces #1387 | ||
* Fix handshake inactivity timeout on Node.js v4.2.0 #1223 #1236 #1239 #1240 #1241 #1252 | ||
* Fix Query stream to emit close after ending #1349 #1350 | ||
* Fix type cast for BIGINT columns when number is negative #1376 | ||
* Performance improvements for array/object escaping in SqlString #1331 | ||
* Performance improvements for formatting in SqlString #1431 | ||
* Performance improvements for string escaping in SqlString #1390 | ||
* Performance improvements for writing packets to network | ||
* Support Node.js 6.x | ||
* Update `bignumber.js` to 2.3.0 | ||
* Update `readable-stream` to 1.1.14 | ||
* Use the `sqlstring` module for SQL escaping and formatting | ||
## v2.10.2 (2016-01-12) | ||
@@ -9,0 +29,0 @@ |
36
index.js
@@ -5,3 +5,4 @@ var Classes = Object.create(null); | ||
* Create a new Connection instance. | ||
* @param {object} config | ||
* @param {object|string} config Configuration or connection string for new MySQL connection | ||
* @return {Connection} A new MySQL connection | ||
* @public | ||
@@ -18,3 +19,4 @@ */ | ||
* Create a new Pool instance. | ||
* @param {object} config | ||
* @param {object|string} config Configuration or connection string for new MySQL connections | ||
* @return {Pool} A new MySQL pool | ||
* @public | ||
@@ -31,3 +33,4 @@ */ | ||
* Create a new PoolCluster instance. | ||
* @param {object} config | ||
* @param {object} [config] Configuration for pool cluster | ||
* @return {PoolCluster} New MySQL pool cluster | ||
* @public | ||
@@ -43,2 +46,6 @@ */ | ||
* Create a new Query instance. | ||
* @param {string} sql The SQL for the query | ||
* @param {array} [values] Any values to insert into placeholders in sql | ||
* @param {function} [callback] The callback to use when query is complete | ||
* @return {Query} New query object | ||
* @public | ||
@@ -54,5 +61,6 @@ */ | ||
* Escape a value for SQL. | ||
* @param {*} value | ||
* @param {boolean} [stringifyObjects=false] | ||
* @param {string} [timeZone=local] | ||
* @param {*} value The value to escape | ||
* @param {boolean} [stringifyObjects=false] Setting if objects should be stringified | ||
* @param {string} [timeZone=local] Setting for time zone to use for Date conversion | ||
* @return {string} Escaped string value | ||
* @public | ||
@@ -68,4 +76,5 @@ */ | ||
* Escape an identifier for SQL. | ||
* @param {*} value | ||
* @param {boolean} [forbidQualified] | ||
* @param {*} value The value to escape | ||
* @param {boolean} [forbidQualified=false] Setting to treat '.' as part of identifier | ||
* @return {string} Escaped string value | ||
* @public | ||
@@ -81,6 +90,7 @@ */ | ||
* Format SQL and replacement values into a SQL string. | ||
* @param {string} sql | ||
* @param {array} [values] | ||
* @param {boolean} [stringifyObjects=false] | ||
* @param {string} [timeZone=local] | ||
* @param {string} sql The SQL for the query | ||
* @param {array} [values] Any values to insert into placeholders in sql | ||
* @param {boolean} [stringifyObjects=false] Setting if objects should be stringified | ||
* @param {string} [timeZone=local] Setting for time zone to use for Date conversion | ||
* @return {string} Formatted SQL string | ||
* @public | ||
@@ -104,2 +114,4 @@ */ | ||
* Load the given class. | ||
* @param {string} className Name of class to default | ||
* @return {function|object} Class constructor or exports | ||
* @private | ||
@@ -106,0 +118,0 @@ */ |
var Crypto = require('crypto'); | ||
var Events = require('events'); | ||
var Net = require('net'); | ||
@@ -8,9 +9,8 @@ var tls = require('tls'); | ||
var Query = require('./protocol/sequences/Query'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var Util = require('util'); | ||
module.exports = Connection; | ||
Util.inherits(Connection, EventEmitter); | ||
Util.inherits(Connection, Events.EventEmitter); | ||
function Connection(options) { | ||
EventEmitter.call(this); | ||
Events.EventEmitter.call(this); | ||
@@ -27,3 +27,5 @@ this.config = options.config; | ||
function bindToCurrentDomain(callback) { | ||
if (!callback) return; | ||
if (!callback) { | ||
return undefined; | ||
} | ||
@@ -93,2 +95,13 @@ var domain = process.domain; | ||
// Connect socket to connection domain | ||
if (Events.usingDomains) { | ||
if (this._socket.domain) { | ||
this._socket.domain.remove(this._socket); | ||
} | ||
if (this.domain) { | ||
this.domain.add(this._socket); | ||
} | ||
} | ||
var connection = this; | ||
@@ -313,3 +326,3 @@ this._protocol.on('data', function(data) { | ||
} | ||
}) | ||
}); | ||
@@ -316,0 +329,0 @@ // cleartext <-> protocol |
@@ -25,5 +25,8 @@ var mysql = require('../'); | ||
if (this._closed) { | ||
return process.nextTick(function(){ | ||
return cb(new Error('Pool is closed.')); | ||
var err = new Error('Pool is closed.'); | ||
err.code = 'POOL_CLOSED'; | ||
process.nextTick(function () { | ||
cb(err); | ||
}); | ||
return; | ||
} | ||
@@ -36,4 +39,4 @@ | ||
connection = this._freeConnections.shift(); | ||
return this.acquireConnection(connection, cb); | ||
this.acquireConnection(connection, cb); | ||
return; | ||
} | ||
@@ -47,3 +50,3 @@ | ||
return connection.connect({timeout: this.config.acquireTimeout}, function onConnect(err) { | ||
connection.connect({timeout: this.config.acquireTimeout}, function onConnect(err) { | ||
spliceConnection(pool._acquiringConnections, connection); | ||
@@ -53,2 +56,3 @@ | ||
err = new Error('Pool is closed.'); | ||
err.code = 'POOL_CLOSED'; | ||
} | ||
@@ -65,8 +69,12 @@ | ||
}); | ||
return; | ||
} | ||
if (!this.config.waitForConnections) { | ||
return process.nextTick(function(){ | ||
return cb(new Error('No connections available.')); | ||
process.nextTick(function(){ | ||
var err = new Error('No connections available.'); | ||
err.code = 'POOL_CONNLIMIT'; | ||
cb(err); | ||
}); | ||
return; | ||
} | ||
@@ -92,2 +100,3 @@ | ||
err = new Error('Pool is closed.'); | ||
err.code = 'POOL_CLOSED'; | ||
} | ||
@@ -119,3 +128,2 @@ | ||
Pool.prototype.releaseConnection = function releaseConnection(connection) { | ||
var cb; | ||
var pool = this; | ||
@@ -143,14 +151,15 @@ | ||
while (this._closed && this._connectionQueue.length) { | ||
if (this._closed) { | ||
// empty the connection queue | ||
cb = this._connectionQueue.shift(); | ||
process.nextTick(cb.bind(null, new Error('Pool is closed.'))); | ||
this._connectionQueue.splice(0).forEach(function (cb) { | ||
var err = new Error('Pool is closed.'); | ||
err.code = 'POOL_CLOSED'; | ||
process.nextTick(function () { | ||
cb(err); | ||
}); | ||
}); | ||
} else if (this._connectionQueue.length) { | ||
// get connection with next waiting callback | ||
this.getConnection(this._connectionQueue.shift()); | ||
} | ||
if (this._connectionQueue.length) { | ||
cb = this._connectionQueue.shift(); | ||
this.getConnection(cb); | ||
} | ||
}; | ||
@@ -168,22 +177,19 @@ | ||
var calledBack = false; | ||
var waitingClose = this._allConnections.length; | ||
var waitingClose = 0; | ||
function onEnd(err) { | ||
if (calledBack) { | ||
return; | ||
} | ||
if (err || --waitingClose === 0) { | ||
if (!calledBack && (err || --waitingClose <= 0)) { | ||
calledBack = true; | ||
return cb(err); | ||
cb(err); | ||
} | ||
} | ||
if (waitingClose === 0) { | ||
return process.nextTick(cb); | ||
} | ||
while (this._allConnections.length !== 0) { | ||
waitingClose++; | ||
this._purgeConnection(this._allConnections[0], onEnd); | ||
} | ||
if (waitingClose === 0) { | ||
process.nextTick(onEnd); | ||
} | ||
}; | ||
@@ -190,0 +196,0 @@ |
@@ -12,2 +12,5 @@ var Pool = require('./Pool'); | ||
* PoolCluster | ||
* @constructor | ||
* @param {object} [config] The pool cluster configuration | ||
* @public | ||
*/ | ||
@@ -69,3 +72,4 @@ function PoolCluster(config) { | ||
if (this._closed) { | ||
return process.nextTick(cb); | ||
process.nextTick(cb); | ||
return; | ||
} | ||
@@ -77,19 +81,11 @@ | ||
var nodeIds = Object.keys(this._nodes); | ||
var waitingClose = nodeIds.length; | ||
var waitingClose = 0; | ||
function onEnd(err) { | ||
if (calledBack) { | ||
return; | ||
} | ||
if (err || --waitingClose === 0) { | ||
if (!calledBack && (err || --waitingClose <= 0)) { | ||
calledBack = true; | ||
return cb(err); | ||
cb(err); | ||
} | ||
} | ||
if (waitingClose === 0) { | ||
return process.nextTick(cb); | ||
} | ||
for (var i = 0; i < nodeIds.length; i++) { | ||
@@ -99,4 +95,9 @@ var nodeId = nodeIds[i]; | ||
waitingClose++; | ||
node.pool.end(onEnd); | ||
} | ||
if (waitingClose === 0) { | ||
process.nextTick(onEnd); | ||
} | ||
}; | ||
@@ -103,0 +104,0 @@ |
@@ -1,3 +0,4 @@ | ||
var inherits = require('util').inherits; | ||
var inherits = require('util').inherits; | ||
var Connection = require('./Connection'); | ||
var Events = require('events'); | ||
@@ -11,2 +12,13 @@ module.exports = PoolConnection; | ||
// Bind connection to pool domain | ||
if (Events.usingDomains) { | ||
if (this.domain) { | ||
this.domain.remove(this); | ||
} | ||
if (pool.domain) { | ||
pool.domain.add(this); | ||
} | ||
} | ||
// When a fatal error occurs the connection's protocol ends, which will cause | ||
@@ -28,3 +40,3 @@ // the connection to end as well, thus we only need to watch for the end event | ||
if (!pool || pool._closed) { | ||
return; | ||
return undefined; | ||
} | ||
@@ -31,0 +43,0 @@ |
@@ -7,2 +7,7 @@ var PoolSelector = require('./PoolSelector'); | ||
* PoolNamespace | ||
* @constructor | ||
* @param {PoolCluster} cluster The parent cluster for the namespace | ||
* @param {string} pattern The selection pattern to use | ||
* @param {string} selector The selector name to use | ||
* @public | ||
*/ | ||
@@ -31,3 +36,4 @@ function PoolNamespace(cluster, pattern, selector) { | ||
return cb(err); | ||
cb(err); | ||
return; | ||
} | ||
@@ -40,7 +46,9 @@ | ||
if (retry) { | ||
return namespace.getConnection(cb); | ||
namespace.getConnection(cb); | ||
return; | ||
} | ||
if (err) { | ||
return cb(err); | ||
cb(err); | ||
return; | ||
} | ||
@@ -47,0 +55,0 @@ |
@@ -32,2 +32,4 @@ var Types = require('../constants/types'); | ||
} | ||
return undefined; | ||
} |
module.exports = LocalDataFilePacket; | ||
/** | ||
* @param {Buffer} data | ||
* Create a new LocalDataFilePacket | ||
* @constructor | ||
* @param {Buffer} data The data contents of the packet | ||
* @public | ||
*/ | ||
@@ -5,0 +9,0 @@ function LocalDataFilePacket(data) { |
@@ -103,3 +103,3 @@ var Types = require('../constants/types'); | ||
? numberString | ||
: ((supportBigNumbers && (bigNumberStrings || (Number(numberString) > IEEE_754_BINARY_64_PRECISION))) | ||
: ((supportBigNumbers && (bigNumberStrings || (Number(numberString) >= IEEE_754_BINARY_64_PRECISION) || Number(numberString) <= -IEEE_754_BINARY_64_PRECISION)) | ||
? numberString | ||
@@ -106,0 +106,0 @@ : Number(numberString)); |
@@ -1,3 +0,4 @@ | ||
var BIT_16 = Math.pow(2, 16); | ||
var BIT_24 = Math.pow(2, 24); | ||
var BIT_16 = Math.pow(2, 16); | ||
var BIT_24 = Math.pow(2, 24); | ||
var BUFFER_ALLOC_SIZE = Math.pow(2, 8); | ||
// The maximum precision JS Numbers can hold precisely | ||
@@ -10,17 +11,23 @@ // Don't panic: Good enough to represent byte values up to 8192 TB | ||
function PacketWriter() { | ||
this._buffer = new Buffer(0); | ||
this._buffer = null; | ||
this._offset = 0; | ||
} | ||
PacketWriter.prototype.toBuffer = function(parser) { | ||
var packets = Math.floor(this._buffer.length / MAX_PACKET_LENGTH) + 1; | ||
var buffer = this._buffer; | ||
this._buffer = new Buffer(this._buffer.length + packets * 4); | ||
PacketWriter.prototype.toBuffer = function toBuffer(parser) { | ||
if (!this._buffer) { | ||
this._buffer = new Buffer(0); | ||
this._offset = 0; | ||
} | ||
var buffer = this._buffer; | ||
var length = this._offset; | ||
var packets = Math.floor(length / MAX_PACKET_LENGTH) + 1; | ||
this._buffer = new Buffer(length + packets * 4); | ||
this._offset = 0; | ||
for (var packet = 0; packet < packets; packet++) { | ||
this._offset = packet * (MAX_PACKET_LENGTH + 4); | ||
var isLast = (packet + 1 === packets); | ||
var packetLength = (isLast) | ||
? buffer.length % MAX_PACKET_LENGTH | ||
? length % MAX_PACKET_LENGTH | ||
: MAX_PACKET_LENGTH; | ||
@@ -183,5 +190,6 @@ | ||
PacketWriter.prototype._allocate = function(bytes) { | ||
PacketWriter.prototype._allocate = function _allocate(bytes) { | ||
if (!this._buffer) { | ||
this._buffer = new Buffer(bytes); | ||
this._buffer = new Buffer(BUFFER_ALLOC_SIZE); | ||
this._offset = 0; | ||
return; | ||
@@ -195,6 +203,7 @@ } | ||
var newSize = this._buffer.length + Math.max(BUFFER_ALLOC_SIZE, bytes); | ||
var oldBuffer = this._buffer; | ||
this._buffer = new Buffer(oldBuffer.length + bytes); | ||
this._buffer = new Buffer(newSize); | ||
oldBuffer.copy(this._buffer); | ||
}; |
@@ -12,2 +12,3 @@ var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; | ||
this._buffer = new Buffer(0); | ||
this._nextBuffers = []; | ||
this._longPacketBuffers = []; | ||
@@ -25,8 +26,8 @@ this._offset = 0; | ||
Parser.prototype.write = function(buffer) { | ||
this.append(buffer); | ||
Parser.prototype.write = function write(chunk) { | ||
this._nextBuffers.push(chunk); | ||
while (!this._paused) { | ||
if (!this._packetHeader) { | ||
if (this._bytesRemaining() < 4) { | ||
if (!this._combineNextBuffers(4)) { | ||
break; | ||
@@ -55,3 +56,3 @@ } | ||
if (this._bytesRemaining() < this._packetHeader.length) { | ||
if (!this._combineNextBuffers(this._packetHeader.length)) { | ||
break; | ||
@@ -147,3 +148,3 @@ } | ||
Parser.prototype.parseUnsignedNumber = function(bytes) { | ||
Parser.prototype.parseUnsignedNumber = function parseUnsignedNumber(bytes) { | ||
if (bytes === 1) { | ||
@@ -369,6 +370,2 @@ return this._buffer[this._offset++]; | ||
Parser.prototype._bytesRemaining = function() { | ||
return this._buffer.length - this._offset; | ||
}; | ||
Parser.prototype.incrementPacketNumber = function() { | ||
@@ -391,3 +388,19 @@ var currentPacketNumber = this._nextPacketNumber; | ||
Parser.prototype._combineLongPacketBuffers = function() { | ||
Parser.prototype._combineNextBuffers = function _combineNextBuffers(bytes) { | ||
if ((this._buffer.length - this._offset) >= bytes) { | ||
return true; | ||
} | ||
if (!this._nextBuffers.length) { | ||
return false; | ||
} | ||
while (this._nextBuffers.length && (this._buffer.length - this._offset) < bytes) { | ||
this.append(this._nextBuffers.shift()); | ||
} | ||
return (this._buffer.length - this._offset) >= bytes; | ||
}; | ||
Parser.prototype._combineLongPacketBuffers = function _combineLongPacketBuffers() { | ||
if (!this._longPacketBuffers.length) { | ||
@@ -401,3 +414,3 @@ return; | ||
return length + buffer.length; | ||
}, this._bytesRemaining()); | ||
}, (this._buffer.length - this._offset)); | ||
@@ -404,0 +417,0 @@ var combinedBuffer = new Buffer(length); |
@@ -30,2 +30,4 @@ var Sequence = require('./Sequence'); | ||
} | ||
return undefined; | ||
}; | ||
@@ -32,0 +34,0 @@ |
@@ -42,3 +42,3 @@ var Sequence = require('./Sequence'); | ||
} else { | ||
return; | ||
return undefined; | ||
} | ||
@@ -48,3 +48,3 @@ } | ||
if (firstByte === 255) { | ||
return; | ||
return undefined; | ||
} | ||
@@ -202,2 +202,8 @@ | ||
stream.once('end', function() { | ||
process.nextTick(function () { | ||
stream.emit('close'); | ||
}); | ||
}); | ||
this.on('result',function(row,i) { | ||
@@ -213,3 +219,2 @@ if (!stream.push(row)) self._connection.pause(); | ||
this.on('end', function() { | ||
stream.emit('close'); // notify readers that query has completed | ||
stream.push(null); // pushing null, indicating EOF | ||
@@ -216,0 +221,0 @@ }); |
@@ -9,2 +9,4 @@ var Util = require('util'); | ||
var LONG_STACK_DELIMITER = '\n --------------------\n'; | ||
module.exports = Sequence; | ||
@@ -31,3 +33,3 @@ Util.inherits(Sequence, EventEmitter); | ||
this._idleStart = null; | ||
this._idleTimeout = undefined; | ||
this._idleTimeout = -1; | ||
this._repeat = null; | ||
@@ -41,2 +43,3 @@ } | ||
case 0xff: return Packets.ErrorPacket; | ||
default: return undefined; | ||
} | ||
@@ -59,16 +62,2 @@ }; | ||
Sequence.prototype._addLongStackTrace = function _addLongStackTrace(err) { | ||
if (!this._callSite || !this._callSite.stack) { | ||
return; | ||
} | ||
var delimiter = '\n --------------------\n'; | ||
if (err.stack.indexOf(delimiter) > -1) { | ||
return; | ||
} | ||
err.stack += delimiter + this._callSite.stack.replace(/.+\n/, ''); | ||
}; | ||
Sequence.prototype.end = function(err) { | ||
@@ -119,4 +108,25 @@ if (this._ended) { | ||
Sequence.prototype._addLongStackTrace = function _addLongStackTrace(err) { | ||
var callSiteStack = this._callSite && this._callSite.stack; | ||
if (!callSiteStack || typeof callSiteStack !== 'string') { | ||
// No recorded call site | ||
return; | ||
} | ||
if (err.stack.indexOf(LONG_STACK_DELIMITER) !== -1) { | ||
// Error stack already looks long | ||
return; | ||
} | ||
var index = callSiteStack.indexOf('\n'); | ||
if (index !== -1) { | ||
// Append recorded call site | ||
err.stack += LONG_STACK_DELIMITER + callSiteStack.substr(index + 1); | ||
} | ||
}; | ||
Sequence.prototype._onTimeout = function _onTimeout() { | ||
this.emit('timeout'); | ||
}; |
@@ -28,2 +28,4 @@ var Sequence = require('./Sequence'); | ||
} | ||
return undefined; | ||
}; |
@@ -1,162 +0,1 @@ | ||
var SqlString = exports; | ||
SqlString.escapeId = function (val, forbidQualified) { | ||
if (Array.isArray(val)) { | ||
return val.map(function(v) { | ||
return SqlString.escapeId(v, forbidQualified); | ||
}).join(', '); | ||
} | ||
if (forbidQualified) { | ||
return '`' + val.replace(/`/g, '``') + '`'; | ||
} | ||
return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`'; | ||
}; | ||
SqlString.escape = function(val, stringifyObjects, timeZone) { | ||
if (val === undefined || val === null) { | ||
return 'NULL'; | ||
} | ||
switch (typeof val) { | ||
case 'boolean': return (val) ? 'true' : 'false'; | ||
case 'number': return val+''; | ||
} | ||
if (val instanceof Date) { | ||
val = SqlString.dateToString(val, timeZone || 'local'); | ||
} | ||
if (Buffer.isBuffer(val)) { | ||
return SqlString.bufferToString(val); | ||
} | ||
if (Array.isArray(val)) { | ||
return SqlString.arrayToList(val, timeZone); | ||
} | ||
if (typeof val === 'object') { | ||
if (stringifyObjects) { | ||
val = val.toString(); | ||
} else { | ||
return SqlString.objectToValues(val, timeZone); | ||
} | ||
} | ||
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) { | ||
switch(s) { | ||
case "\0": return "\\0"; | ||
case "\n": return "\\n"; | ||
case "\r": return "\\r"; | ||
case "\b": return "\\b"; | ||
case "\t": return "\\t"; | ||
case "\x1a": return "\\Z"; | ||
default: return "\\"+s; | ||
} | ||
}); | ||
return "'"+val+"'"; | ||
}; | ||
SqlString.arrayToList = function(array, timeZone) { | ||
return array.map(function(v) { | ||
if (Array.isArray(v)) return '(' + SqlString.arrayToList(v, timeZone) + ')'; | ||
return SqlString.escape(v, true, timeZone); | ||
}).join(', '); | ||
}; | ||
SqlString.format = function(sql, values, stringifyObjects, timeZone) { | ||
values = values == null ? [] : [].concat(values); | ||
var index = 0; | ||
return sql.replace(/\?\??/g, function(match) { | ||
if (index === values.length) { | ||
return match; | ||
} | ||
var value = values[index++]; | ||
return match === '??' | ||
? SqlString.escapeId(value) | ||
: SqlString.escape(value, stringifyObjects, timeZone); | ||
}); | ||
}; | ||
SqlString.dateToString = function dateToString(date, timeZone) { | ||
var dt = new Date(date); | ||
var year; | ||
var month; | ||
var day; | ||
var hour; | ||
var minute; | ||
var second; | ||
var millisecond; | ||
if (timeZone === 'local') { | ||
year = dt.getFullYear(); | ||
month = dt.getMonth() + 1; | ||
day = dt.getDate(); | ||
hour = dt.getHours(); | ||
minute = dt.getMinutes(); | ||
second = dt.getSeconds(); | ||
millisecond = dt.getMilliseconds(); | ||
} else { | ||
var tz = convertTimezone(timeZone); | ||
if (tz !== false && tz !== 0) { | ||
dt.setTime(dt.getTime() + (tz * 60000)); | ||
} | ||
year = dt.getUTCFullYear(); | ||
month = dt.getUTCMonth() + 1; | ||
day = dt.getUTCDate(); | ||
hour = dt.getUTCHours(); | ||
minute = dt.getUTCMinutes(); | ||
second = dt.getUTCSeconds(); | ||
millisecond = dt.getUTCMilliseconds(); | ||
} | ||
// YYYY-MM-DD HH:mm:ss.mmm | ||
return zeroPad(year, 4) + '-' + zeroPad(month, 2) + '-' + zeroPad(day, 2) + ' ' + | ||
zeroPad(hour, 2) + ':' + zeroPad(minute, 2) + ':' + zeroPad(second, 2) + '.' + | ||
zeroPad(millisecond, 3); | ||
}; | ||
SqlString.bufferToString = function bufferToString(buffer) { | ||
return "X'" + buffer.toString('hex') + "'"; | ||
}; | ||
SqlString.objectToValues = function(object, timeZone) { | ||
var values = []; | ||
for (var key in object) { | ||
var value = object[key]; | ||
if(typeof value === 'function') { | ||
continue; | ||
} | ||
values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone)); | ||
} | ||
return values.join(', '); | ||
}; | ||
function zeroPad(number, length) { | ||
number = number.toString(); | ||
while (number.length < length) { | ||
number = '0' + number; | ||
} | ||
return number; | ||
} | ||
function convertTimezone(tz) { | ||
if (tz === 'Z') { | ||
return 0; | ||
} | ||
var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/); | ||
if (m) { | ||
return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60; | ||
} | ||
return false; | ||
} | ||
module.exports = require('sqlstring'); |
{ | ||
"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.10.2", | ||
"version": "2.11.0", | ||
"license": "MIT", | ||
@@ -10,3 +10,4 @@ "author": "Felix Geisendörfer <felix@debuggable.com> (http://debuggable.com/)", | ||
"Douglas Christopher Wilson <doug@somethingdoug.com>", | ||
"Diogo Resende <dresende@thinkdigital.pt>" | ||
"Diogo Resende <dresende@thinkdigital.pt>", | ||
"Nathan Woltman <nwoltman@outlook.com>" | ||
], | ||
@@ -16,8 +17,10 @@ "homepage": "https://github.com/felixge/node-mysql", | ||
"dependencies": { | ||
"bignumber.js": "2.1.4", | ||
"readable-stream": "~1.1.13" | ||
"bignumber.js": "2.3.0", | ||
"readable-stream": "1.1.14", | ||
"sqlstring": "2.0.1" | ||
}, | ||
"devDependencies": { | ||
"eslint": "1.10.1", | ||
"istanbul": "0.4.2", | ||
"after": "0.8.1", | ||
"eslint": "2.11.1", | ||
"istanbul": "0.4.3", | ||
"require-all": "2.0.0", | ||
@@ -24,0 +27,0 @@ "rimraf": "2.2.8", |
@@ -26,3 +26,3 @@ # mysql | ||
- [PoolCluster](#poolcluster) | ||
- [PoolCluster Option](#poolcluster-option) | ||
- [PoolCluster options](#poolcluster-options) | ||
- [Switching users and altering connection state](#switching-users-and-altering-connection-state) | ||
@@ -315,3 +315,4 @@ - [Server disconnects](#server-disconnects) | ||
user : 'bob', | ||
password : 'secret' | ||
password : 'secret', | ||
database : 'my_db' | ||
}); | ||
@@ -334,3 +335,4 @@ | ||
user : 'bob', | ||
password : 'secret' | ||
password : 'secret', | ||
database : 'my_db' | ||
}); | ||
@@ -375,5 +377,5 @@ | ||
Pools accept all the same options as a connection. When creating a new | ||
connection, the options are simply passed to the connection constructor. In | ||
addition to those options pools accept a few extras: | ||
Pools accept all the same [options as a connection](#connection-options). | ||
When creating a new connection, the options are simply passed to the connection | ||
constructor. In addition to those options pools accept a few extras: | ||
@@ -447,5 +449,5 @@ * `acquireTimeout`: The milliseconds before a timeout occurs during the connection | ||
// add configurations | ||
poolCluster.add(config); // anonymous group | ||
poolCluster.add('MASTER', masterConfig); | ||
// add configurations (the config is a pool config object) | ||
poolCluster.add(config); // add configuration with automatic name | ||
poolCluster.add('MASTER', masterConfig); // add a named configuration | ||
poolCluster.add('SLAVE1', slave1Config); | ||
@@ -485,3 +487,4 @@ poolCluster.add('SLAVE2', slave2Config); | ||
## PoolCluster Option | ||
### PoolCluster options | ||
* `canRetry`: If `true`, `PoolCluster` will attempt to reconnect when connection fails. (Default: `true`) | ||
@@ -630,2 +633,12 @@ * `removeNodeErrorCount`: If connection fails, node's `errorCount` increases. | ||
Multiple placeholders are mapped to values in the same order as passed. For example, | ||
in the following query `foo` equals `a`, `bar` equals `b`, `baz` equals `c`, and | ||
`id` will be `userId`: | ||
```js | ||
connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function(err, results) { | ||
// ... | ||
}); | ||
``` | ||
This looks similar to prepared statements in MySQL, however it really just uses | ||
@@ -764,3 +777,3 @@ the same `connection.escape()` method internally. | ||
consider enabling `supportBigNumbers` option to be able to read the insert id as a | ||
string, otherwise it will throw. | ||
string, otherwise it will throw an error. | ||
@@ -1059,10 +1072,11 @@ This option is also required when fetching big numbers from the database, otherwise | ||
All errors created by this module are instances of the JavaScript [Error][] | ||
object. Additionally they come with two properties: | ||
Most errors created by this module are instances of the JavaScript [Error][] | ||
object. Additionally they typically come with two extra properties: | ||
* `err.code`: Either a [MySQL server error][] (e.g. | ||
`'ER_ACCESS_DENIED_ERROR'`), a node.js error (e.g. `'ECONNREFUSED'`) or an | ||
internal error (e.g. `'PROTOCOL_CONNECTION_LOST'`). | ||
`'ER_ACCESS_DENIED_ERROR'`), a Node.js error (e.g. `'ECONNREFUSED'`) or an | ||
internal error (e.g. `'PROTOCOL_CONNECTION_LOST'`). | ||
* `err.fatal`: Boolean, indicating if this error is terminal to the connection | ||
object. | ||
object. If the error is not from a MySQL protocol operation, this properly | ||
will not be defined. | ||
@@ -1332,3 +1346,5 @@ [Error]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error | ||
Set the environment variables `MYSQL_DATABASE`, `MYSQL_HOST`, `MYSQL_PORT`, | ||
`MYSQL_USER` and `MYSQL_PASSWORD`. Then run `npm test`. | ||
`MYSQL_USER` and `MYSQL_PASSWORD`. `MYSQL_SOCKET` can also be used in place | ||
of `MYSQL_HOST` and `MYSQL_PORT` to connect over a UNIX socket. Then run | ||
`npm test`. | ||
@@ -1350,4 +1366,4 @@ For example, if you have an installation of mysql running on localhost:3306 | ||
[npm-url]: https://npmjs.org/package/mysql | ||
[node-version-image]: http://img.shields.io/node/v/mysql.svg | ||
[node-version-url]: http://nodejs.org/download/ | ||
[node-version-image]: https://img.shields.io/node/v/mysql.svg | ||
[node-version-url]: https://nodejs.org/en/download/ | ||
[travis-image]: https://img.shields.io/travis/felixge/node-mysql/master.svg?label=linux | ||
@@ -1354,0 +1370,0 @@ [travis-url]: https://travis-ci.org/felixge/node-mysql |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
390122
1366
3
9
6559
+ Addedsqlstring@2.0.1
+ Addedbignumber.js@2.3.0(transitive)
+ Addedsqlstring@2.0.1(transitive)
- Removedbignumber.js@2.1.4(transitive)
Updatedbignumber.js@2.3.0
Updatedreadable-stream@1.1.14