Skip to content

Commit 313bd02

Browse files
committed
support for custom typeCast #338
1 parent 7fcbc81 commit 313bd02

File tree

4 files changed

+80
-16
lines changed

4 files changed

+80
-16
lines changed

lib/commands/query.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Query.prototype.row = function (packet)
194194
return this.done();
195195
}
196196

197-
var row = new this._rowParser(packet);
197+
var row = new this._rowParser(packet, this._fields[this._resultIndex], this.options);
198198
if (this.onResult) {
199199
this._rows[this._resultIndex].push(row);
200200
} else {

lib/compile_text_parser.js

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,37 @@ for (var t in Types) {
88
typeNames[Types[t]] = t;
99
}
1010

11+
1112
function compile (fields, options, config) {
1213

14+
// node-mysql typeCast compatibility wrapper
15+
// see https://github.com/mysqljs/mysql/blob/96fdd0566b654436624e2375c7b6604b1f50f825/lib/protocol/packets/Field.js
16+
function wrap(field, type, packet) {
17+
return {
18+
type: type,
19+
length: field.columnLength,
20+
db: field.schema,
21+
table: field.table,
22+
name: field.name,
23+
string: function() { return packet.readLengthCodedString(); },
24+
buffer: function () { return this.parser.parseLengthCodedBuffer(); },
25+
geometry: function () { return this.parser.parseGeometryValue(); }
26+
};
27+
};
28+
1329
var result = [];
1430
var i = 0;
1531
var lvalue = '';
1632

17-
result.push('(function() { return function TextRow(packet) {');
33+
result.push('(function() { return function TextRow(packet, fields, options) {');
1834
if (options.rowsAsArray) {
1935
result.push(' var result = new Array(' + fields.length + ')');
2036
}
2137

38+
if (typeof options.typeCast === 'function') {
39+
result.push(' var wrap = ' + wrap.toString());
40+
}
41+
2242
var resultTables = {};
2343
var resultTablesArray = [];
2444

@@ -48,7 +68,14 @@ function compile (fields, options, config) {
4868
} else {
4969
lvalue = ' this[' + srcEscape(fields[i].name) + ']';
5070
}
51-
result.push(lvalue + ' = ' + readCodeFor(fields[i].columnType, fields[i].characterSet, config));
71+
var readCode = readCodeFor(fields[i].columnType, fields[i].characterSet, config);
72+
if (typeof options.typeCast === 'function') {
73+
result.push(lvalue + ' = options.typeCast(wrap(fields[' + i + '], ' + srcEscape(typeNames[fields[i].columnType]) + ', packet), function() { return ' + readCode + ';})');
74+
} else if (options.typeCast === false) {
75+
result.push(lvalue + ' = packet.readLengthCodedBuffer();');
76+
} else {
77+
result.push(lvalue + ' = ' + readCode);
78+
}
5279
}
5380

5481
if (options.rowsAsArray) {
@@ -59,6 +86,7 @@ function compile (fields, options, config) {
5986
var src = result.join('\n');
6087
if (config.debug) {
6188
console.log(' Compiled text protocol row parser:\n\n');
89+
console.log(src);
6290
var cardinal = require('cardinal');
6391
console.log(cardinal.highlight(src) + '\n\n');
6492
}
@@ -72,45 +100,45 @@ function readCodeFor (type, charset, config) {
72100
case Types.LONG:
73101
case Types.INT24:
74102
case Types.YEAR:
75-
return 'packet.parseLengthCodedInt();';
103+
return 'packet.parseLengthCodedInt()';
76104
case Types.LONGLONG:
77105
if (config.supportBigNumbers && config.bigNumberStrings) {
78-
return 'packet.parseLengthCodedIntString();';
106+
return 'packet.parseLengthCodedIntString()';
79107
}
80-
return 'packet.parseLengthCodedInt();';
108+
return 'packet.parseLengthCodedInt()';
81109
case Types.FLOAT:
82110
case Types.DOUBLE:
83-
return 'packet.parseLengthCodedFloat();';
111+
return 'packet.parseLengthCodedFloat()';
84112
case Types.NULL:
85-
return 'null; packet.skip(1);';
113+
return 'null; packet.skip(1)';
86114
case Types.DECIMAL:
87115
case Types.NEWDECIMAL:
88116
if (config.decimalNumbers) {
89-
return 'packet.parseLengthCodedFloat();';
117+
return 'packet.parseLengthCodedFloat()';
90118
}
91-
return 'packet.readLengthCodedString(); //' + type + ' ' + charset;
119+
return 'packet.readLengthCodedString()';
92120
case Types.DATE:
93121
if (config.dateStrings) {
94122
return 'packet.readLengthCodedString()';
95123
}
96-
return 'packet.parseDate();';
124+
return 'packet.parseDate()';
97125
case Types.DATETIME:
98126
case Types.TIMESTAMP:
99127
if (config.dateStrings) {
100128
return 'packet.readLengthCodedString()';
101129
}
102-
return 'packet.parseDateTime();';
130+
return 'packet.parseDateTime()';
103131
case Types.TIME:
104132
return 'packet.readLengthCodedString()';
105133
case Types.GEOMETRY:
106-
return 'packet.parseGeometryValue();';
134+
return 'packet.parseGeometryValue()';
107135
case Types.JSON:
108-
return 'JSON.parse(packet.readLengthCodedString());';
136+
return 'JSON.parse(packet.readLengthCodedString())';
109137
default:
110138
if (charset == Charsets.BINARY) {
111-
return 'packet.readLengthCodedBuffer();';
139+
return 'packet.readLengthCodedBuffer()';
112140
} else {
113-
return 'packet.readLengthCodedString(); //' + type + ' ' + charset;
141+
return 'packet.readLengthCodedString()';
114142
}
115143
}
116144
}

lib/packets/column_definition.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ addString('table');
6161
addString('orgTable');
6262
addString('orgName');
6363

64+
// node-mysql compatibility: alias "db" to "schema"
65+
Object.defineProperty(ColumnDefinition.prototype, 'db', {get: function () {
66+
var start = this._schemaStart;
67+
var end = start._shemaLength;
68+
return this._buf.utf8Slice(start, end);
69+
}});
70+
71+
6472
ColumnDefinition.prototype.inspect = function () {
6573
return {
6674
catalog : this.catalog,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
var common = require('../../common');
2+
var connection = common.createConnection();
3+
var assert = require('assert');
4+
5+
connection.query({
6+
sql: 'select "foo uppercase" as foo',
7+
typeCast: function (field, next) {
8+
if (field.type == 'VAR_STRING') {
9+
return field.string().toUpperCase();
10+
}
11+
return next();
12+
}
13+
}, function(err, res) {
14+
assert.ifError(err);
15+
assert.equal(res[0].foo, 'FOO UPPERCASE')
16+
});
17+
18+
19+
connection.query({
20+
sql: 'select "foobar" as foo',
21+
typeCast: false
22+
}, function(err, res) {
23+
assert.ifError(err);
24+
assert(Buffer.isBuffer(res[0].foo));
25+
assert.equal(res[0].foo.toString('utf8'), 'foobar');
26+
});
27+
28+
connection.end();

0 commit comments

Comments
 (0)