Skip to content

Added an option to return resultsets as an array type. #1633

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ issue [#501](https://github.com/mysqljs/mysql/issues/501). (Default: `false`)
also possible to blacklist default ones. For more information, check
[Connection Flags](#connection-flags).
* `ssl`: object with ssl parameters or a string containing name of ssl profile. See [SSL options](#ssl-options).
* `rowsAsArray`: If `true`, resultsets return as an array type instead of an object. (Default: `false`)


In addition to passing these options as an object, you can also use a url
Expand Down
2 changes: 2 additions & 0 deletions lib/ConnectionConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ function ConnectionConfig(options) {
// Set the client flags
var defaultFlags = ConnectionConfig.getDefaultFlags(options);
this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags);

this.rowsAsArray = options.rowsAsArray || false;
}

ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) {
Expand Down
9 changes: 9 additions & 0 deletions lib/protocol/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function Parser(options) {
this._nextPacketNumber = 0;
this._encoding = 'utf-8';
this._paused = false;
this._rowsAsArray = options.config && options.config.rowsAsArray;
}

Parser.prototype.write = function write(chunk) {
Expand Down Expand Up @@ -410,6 +411,14 @@ Parser.prototype.packetLength = function packetLength() {
return this._packetHeader.length + this._longPacketBuffers.size;
};

Parser.prototype.setArrayRowMode = function(isArrayRowMode) {
this._isArrayRowMode = typeof isArrayRowMode === 'undefined' ? this._rowsAsArray : isArrayRowMode;
};

Parser.prototype.isArrayRowMode = function() {
return this._isArrayRowMode;
};

Parser.prototype._combineNextBuffers = function _combineNextBuffers(bytes) {
var length = this._buffer.length - this._offset;

Expand Down
25 changes: 24 additions & 1 deletion lib/protocol/packets/RowDataPacket.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ Object.defineProperty(RowDataPacket.prototype, 'parse', {
value : parse
});

Object.defineProperty(RowDataPacket.prototype, 'isArray', {
configurable : true,
enumerable : false,
value : function() {
return typeof this._row !== 'undefined';
}
});

Object.defineProperty(RowDataPacket.prototype, 'getArrayValue', {
configurable : true,
enumerable : false,
value : function() {
return this._row;
}
});

Object.defineProperty(RowDataPacket.prototype, '_typeCast', {
configurable : true,
enumerable : false,
Expand All @@ -25,6 +41,11 @@ function parse(parser, fieldPackets, typeCast, nestTables, connection) {
return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings);
};

var isArrayRowMode = parser.isArrayRowMode();
if (isArrayRowMode) {
this._row = [];
}

for (var i = 0; i < fieldPackets.length; i++) {
var fieldPacket = fieldPackets[i];
var value;
Expand All @@ -39,7 +60,9 @@ function parse(parser, fieldPackets, typeCast, nestTables, connection) {
: parser.parseLengthCodedString() );
}

if (typeof nestTables === 'string' && nestTables.length) {
if (isArrayRowMode) {
this._row.push(value);
} else if (typeof nestTables === 'string' && nestTables.length) {
this[fieldPacket.table + nestTables + fieldPacket.name] = value;
} else if (nestTables) {
this[fieldPacket.table] = this[fieldPacket.table] || {};
Expand Down
9 changes: 7 additions & 2 deletions lib/protocol/sequences/Query.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function Query(options, callback) {
? true
: options.typeCast;
this.nestTables = options.nestTables || false;
this.isArrayRowMode = options.rowsAsArray;

this._resultSet = null;
this._results = [];
Expand Down Expand Up @@ -138,12 +139,16 @@ Query.prototype._handleFinalResultPacket = function(packet) {
};

Query.prototype['RowDataPacket'] = function(packet, parser, connection) {
parser.setArrayRowMode(this.isArrayRowMode);

packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection);

var row = packet.isArray() ? packet.getArrayValue() : packet;

if (this._callback) {
this._resultSet.rows.push(packet);
this._resultSet.rows.push(row);
} else {
this.emit('result', packet, this._index);
this.emit('result', row, this._index);
}
};

Expand Down
26 changes: 26 additions & 0 deletions test/integration/connection/test-query-rows-as-array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var assert = require('assert');
var common = require('../../common');

common.getTestConnection({ rowsAsArray: true }, function (err, connection) {
assert.ifError(err);

connection.query('SELECT 1', function (err, rows) {
assert.ifError(err);
assert.deepEqual(rows, [[1]]);
});

connection.query({ sql: 'SELECT ?' }, [ 1 ], function (err, rows) {
assert.ifError(err);
assert.deepEqual(rows, [[1]]);
});

connection.query({
sql: 'SELECT ?',
rowsAsArray: false
}, [ 1 ], function (err, rows) {
assert.ifError(err);
assert.deepEqual(rows, [{1: 1}]);
});

connection.end(assert.ifError);
});