8000 Initial support for multi statements / results · mysqljs/mysql@2b2e146 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b2e146

Browse files
committed
Initial support for multi statements / results
1 parent 840596f commit 2b2e146

File tree

5 files changed

+103
-20
lines changed

5 files changed

+103
-20
lines changed

lib/protocol/ResultSet.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = ResultSet;
2+
function ResultSet() {
3+
this.resultSetHeaderPacket = null;
4+
this.fieldPackets = [];
5+
this.eofPackets = [];
6+
this.rows = [];
7+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Manually extracted from mysql-5.5.23/include/mysql_com.h
2+
3+
/**
4+
Is raised when a multi-statement transaction
5+
has been started, either explicitly, by means
6+
of BEGIN or COMMIT AND CHAIN, or
7+
implicitly, by the first transactional
8+
statement, when autocommit=off.
9+
*/
10+
exports.SERVER_STATUS_IN_TRANS = 1;
11+
exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */
12+
exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */
13+
exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16;
14+
exports.SERVER_QUERY_NO_INDEX_USED = 32;
15+
/**
16+
The server was able to fulfill the clients request and opened a
17+
read-only non-scrollable cursor for a query. This flag comes
18+
in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
19+
*/
20+
exports.SERVER_STATUS_CURSOR_EXISTS = 64;
21+
/**
22+
This flag is sent when a read-only cursor is exhausted, in reply to
23+
COM_STMT_FETCH command.
24+
*/
25+
exports.SERVER_STATUS_LAST_ROW_SENT = 128;
26+
exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */
27+
exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512;
28+
/**
29+
Sent to the client if after a prepared statement reprepare
30+
we discovered that the new statement returns a different
31+
number of result set columns.
32+
*/
33+
exports.SERVER_STATUS_METADATA_CHANGED = 1024;
34+
exports.SERVER_QUERY_WAS_SLOW = 2048;
35+
36+
/**
37+
To mark ResultSet containing output parameter values.
38+
*/
39+
exports.SERVER_PS_OUT_PARAMS = 4096;

lib/protocol/packets/EofPacket.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ function EofPacket(options) {
44

55
this.fieldCount = undefined;
66
this.warningCount = options.warningCount;
7-
this.statusFlags = options.statusFlags;
7+
this.serverStatus = options.serverStatus;
88
}
99

1010
EofPacket.prototype.parse = function(parser) {
1111
this.fieldCount = parser.parseUnsignedNumber(1);
1212
this.warningCount = parser.parseUnsignedNumber(2);
13-
this.statusFlags = parser.parseUnsignedNumber(2);
13+
this.serverStatus = parser.parseUnsignedNumber(2);
1414
};
1515

1616
EofPacket.prototype.write = function(writer) {
1717
writer.writeUnsignedNumber(1, 0xfe);
1818
writer.writeUnsignedNumber(2, this.warningCount);
19-
writer.writeUnsignedNumber(2, this.statusFlags);
19+
writer.writeUnsignedNumber(2, this.serverStatus);
2020
};

lib/protocol/sequences/Query.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
var Sequence = require('./Sequence');
2-
var Util = require('util');
3-
var Packets = require('../packets');
1+
var Sequence = require('./Sequence');
2+
var Util = require('util');
3+
var Packets = require('../packets');
4+
var ResultSet = require('../ResultSet');
5+
var ServerStatus = require('../constants/server_status');
46

57
module.exports = Query;
68
Util.inherits(Query, Sequence);
@@ -12,11 +14,8 @@ function Query(options, callback) {
1214
? true
1315
: options.typeCast;
1416

15-
16-
this._resultSetHeaderPacket = null;
17-
this._fieldPackets = [];
18-
this._eofPackets = [];
19-
this._rows = [];
17+
this._resultSet = new ResultSet;
18+
this._resultSets = [];
2019
}
2120

2221
Query.prototype.start = function() {
@@ -35,37 +34,55 @@ Query.prototype.determinePacket = function(firstByte, header) {
3534
return Packets.EofPacket;
3635
}
3736

38-
if (!this._resultSetHeaderPacket) {
37+
if (!this._resultSet.resultSetHeaderPacket) {
3938
return Packets.ResultSetHeaderPacket;
4039
}
4140

42-
return (this._eofPackets.length === 0)
41+
return (this._resultSet.eofPackets.length === 0)
4342
? Packets.FieldPacket
4443
: Packets.RowDataPacket;
4544
};
4645

4746
Query.prototype['ResultSetHeaderPacket'] = function(packet) {
48-
this._resultSetHeaderPacket = packet;
47+
this._resultSet.resultSetHeaderPacket = packet;
4948
};
5049

5150
Query.prototype['FieldPacket'] = function(packet) {
52-
this._fieldPackets.push(packet);
51+
this._resultSet.fieldPackets.push(packet);
5352
};
5453

5554
Query.prototype['EofPacket'] = function(packet) {
56-
this._eofPackets.push(packet);
55+
this._resultSet.eofPackets.push(packet);
56+
57+
if (this._resultSet.eofPackets.length === 2) {
58+
this._resultSets.push(this._resultSet);
5759

58-
if (this._eofPackets.length === 2) {
59-
this.end(null, this._rows);
60+
if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
61+
this._resultSet = new ResultSet();
62+
} else {
63+
this._resultSet = null;
64+
this.end(null, this._results());
65+
}
6066
}
6167
};
6268

69+
Query.prototype._results = function() {
70+
var results = this._resultSets.map(function(resultSet) {
71+
return resultSet.rows;
72+
});
73+
74+
return (results.length > 1)
75+
? results
76+
: results[0];
77+
};
78+
6379
Query.prototype['RowDataPacket'] = function(packet, parser) {
64-
packet.parse(parser, this._fieldPackets, this.typeCast);
80+
packet.parse(parser, this._resultSet.fieldPackets, this.typeCast);
6581

6682
if (this._callback) {
67-
this._rows.push(packet);
83+
this._resultSet.rows.push(packet);
6884
} else {
85+
// @TODO Multiple results
6986
this.emit('row', packet);
7087
}
7188
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var common = require('../common');
2+
var connection = common.createConnection();
3+
var assert = require('assert');
4+
5+
var results;
6+
connection.query('SELECT 1; SELECT 2', function(err, _results) {
7+
if (err) throw err;
8+
9+
results = _results;
10+
});
11+
12+
connection.end();
13+
14+
process.on('exit', function() {
15+
console.log(results);
16+
17+
assert.equal(results.length, 2);
18+
assert.deepEqual(results[0], [{1: 1}]);
19+
assert.deepEqual(results[1], [{2: 2}]);
20+
});

0 commit comments

Comments
 (0)
0