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
Show file tree
Hide file tree
Changes from 1 commit
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
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._globalRowsAsArray = 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(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;

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', {
Copy link
Member

Choose a reason for hiding this comment

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

Can these be at least underscore-prefixed? Whatever we add here will shadow any column someone may be trying to query, so need to be careful adding anything new.

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.rowsAsArray = 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.rowsAsArray);

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

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.end(assert.ifError);
});