Skip to content

Commit 8f5d8e9

Browse files
committed
feat(execute): Send bind parameter dates using MySQL DATETIME type, throw error when passing in undefined parameter
1 parent 518421a commit 8f5d8e9

File tree

3 files changed

+56
-17
lines changed

3 files changed

+56
-17
lines changed

lib/packets/execute.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,25 @@ function Execute(id, parameters, charsetNumber) {
1111
this.encoding = CharsetToEncoding[charsetNumber];
1212
}
1313

14-
var pad = '000000000000';
15-
function leftPad(num, value) {
16-
var s = value.toString();
17-
// if we don't need to pad
18-
if (s.length >= num) {
19-
return s;
20-
}
21-
return (pad + s).slice(-num);
22-
}
23-
24-
function toMysqlDateTime(date) {
25-
return [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-') + ' ' +
26-
[date.getHours(), date.getMinutes(), date.getSeconds()].join(':') + '.' +
27-
leftPad(3, date.getMilliseconds());
28-
}
29-
3014
function isJSON(value) {
3115
return Array.isArray(value) ||
3216
value.constructor === Object ||
3317
(typeof value.toJSON === 'function' && !Buffer.isBuffer(value));
3418
}
3519

20+
function toMysqlDateBuffer(value) {
21+
var bufferValue = Buffer.allocUnsafe(12);
22+
bufferValue.writeUInt8(11, 0);
23+
bufferValue.writeUInt16LE(value.getFullYear(), 1);
24+
bufferValue.writeUInt8(value.getMonth() + 1, 3);
25+
bufferValue.writeUInt8(value.getDate(), 4);
26+
bufferValue.writeUInt8(value.getHours(), 5);
27+
bufferValue.writeUInt8(value.getMinutes(), 6);
28+
bufferValue.writeUInt8(value.getSeconds(), 7);
29+
bufferValue.writeUInt32LE(value.getMilliseconds() * 1000, 8);
30+
return bufferValue;
31+
}
32+
3633
/**
3734
* Converts a value to an object describing type, String/Buffer representation and length
3835
* @param {*} value
@@ -43,6 +40,9 @@ function toParameter(value, encoding) {
4340
var fixed = false;
4441
if (value !== null) {
4542
switch (typeof value) {
43+
case 'undefined':
44+
throw new TypeError('Bind parameters must not contain undefined');
45+
4646
case 'number':
4747
type = Types.DOUBLE;
4848
fixed = true;
@@ -61,7 +61,9 @@ function toParameter(value, encoding) {
6161

6262
case 'object':
6363
if (Object.prototype.toString.call(value) == '[object Date]') {
64-
value = toMysqlDateTime(value);
64+
type = Types.DATETIME;
65+
fixed = true;
66+
value = toMysqlDateBuffer(value);
6567
} else if (isJSON(value)) {
6668
type = Types.JSON;
6769
value = JSON.stringify(value);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var common = require('../../common');
2+
var connection = common.createConnection();
3+
var assert = require('assert');
4+
5+
var date = new Date(2018, 02, 10, 15, 12, 34, 1234)
6+
7+
var rows, fields;
8+
connection.execute('SELECT ? AS result', [date], function(err, _rows, _fields) {
9+
if (err) {
10+
throw err;
11+
}
12+
rows = _rows;
13+
fields = _fields;
14+
connection.end();
15+
});
16+
17+
process.on('exit', function() {
18+
assert.deepEqual(rows, [{ result: date }]);
19+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var common = require('../../common');
2+
var connection = common.createConnection();
3+
var assert = require('assert');
4+
5+
var error = null;
6+
var foo = {};
7+
8+
connection.execute('SELECT ? AS result', [foo.bar], function(err, _rows) { });
9+
10+
// TODO: Needs to be a better way of catching this exception
11+
process.on('uncaughtException', (err) => {
12+
error = err;
13+
process.exit(0);
14+
});
15+
16+
process.on('exit', function() {
17+
assert.equal(error.name, 'TypeError');
18+
});

0 commit comments

Comments
 (0)