Skip to content
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

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

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions lib/ConnectionConfig.js
Original file line number Diff line number Diff line change
@@ -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) {
9 changes: 9 additions & 0 deletions lib/protocol/Parser.js
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ function Parser(options) {
this._nextPacketNumber = 0;
this._encoding = 'utf-8';
this._paused = false;
this._globalRowsAsArray = options.config && options.config.rowsAsArray;
}

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

Parser.prototype.setArrayRowMode = function(rowsAsArray) {
this._isArrayRowMode = typeof rowsAsArray === 'undefined' ? this._globalRowsAsArray : rowsAsArray;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you hoist this to prevent the hidden class change this is triggering?

};

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

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

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

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

Object.defineProperty(RowDataPacket.prototype, '_typeCast', {
configurable : true,
enumerable : false,
@@ -25,6 +33,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;
@@ -39,7 +52,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] || {};
11 changes: 8 additions & 3 deletions lib/protocol/sequences/Query.js
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ function Query(options, callback) {
? true
: options.typeCast;
this.nestTables = options.nestTables || false;
this.rowsAsArray = options.rowsAsArray;

this._resultSet = null;
this._results = [];
@@ -36,7 +37,9 @@ Query.prototype.determinePacket = function determinePacket(byte, parser) {
switch (byte) {
case 0x00: return Packets.OkPacket;
case 0xff: return Packets.ErrorPacket;
default: return Packets.ResultSetHeaderPacket;
default:
parser.setArrayRowMode(this.rowsAsArray);
return Packets.ResultSetHeaderPacket;
}
}

@@ -140,10 +143,12 @@ Query.prototype._handleFinalResultPacket = function(packet) {
Query.prototype['RowDataPacket'] = function(packet, parser, connection) {
packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection);

var row = packet._getValue();

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);
}
};

31 changes: 31 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,31 @@
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}]);
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test that verifies the connection is reset back to the mode from the connection config here?

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

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