Skip to content

Commit 28b330c

Browse files
committed
Add JS driver support for multiple results
1 parent 8798e50 commit 28b330c

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

lib/query.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ var Query = function (config, values, callback) {
2929
// use unique portal name each time
3030
this.portal = config.portal || ''
3131
this.callback = config.callback
32+
this._rowMode = config.rowMode
3233
if (process.domain && config.callback) {
3334
this.callback = process.domain.bind(config.callback)
3435
}
35-
this._result = new Result(config.rowMode, config.types)
36+
this._result = new Result(this._rowMode, this.types)
37+
38+
// potential for multiple results
39+
this._results = this._result
3640
this.isPreparedStatement = false
3741
this._canceledDueToError = false
3842
this._promise = null
@@ -54,10 +58,24 @@ Query.prototype.requiresPreparation = function () {
5458
return this.values.length > 0
5559
}
5660

61+
Query.prototype._checkForMultirow = function () {
62+
// if we already have a result with a command property
63+
// then we've already executed one query in a multi-statement simple query
64+
// turn our results into an array of results
65+
if (this._result.command) {
66+
if (!Array.isArray(this._results)) {
67+
this._results = [this._result]
68+
}
69+
this._result = new Result(this._rowMode, this.types)
70+
this._results.push(this._result)
71+
}
72+
}
73+
5774
// associates row metadata from the supplied
5875
// message with this query object
5976
// metadata used when parsing row results
6077
Query.prototype.handleRowDescription = function (msg) {
78+
this._checkForMultirow()
6179
this._result.addFields(msg.fields)
6280
this._accumulateRows = this.callback || !this.listeners('row').length
6381
}
@@ -83,6 +101,7 @@ Query.prototype.handleDataRow = function (msg) {
83101
}
84102

85103
Query.prototype.handleCommandComplete = function (msg, con) {
104+
this._checkForMultirow()
86105
this._result.addCommandComplete(msg)
87106
// need to sync after each command complete of a prepared statement
88107
if (this.isPreparedStatement) {
@@ -104,9 +123,9 @@ Query.prototype.handleReadyForQuery = function (con) {
104123
return this.handleError(this._canceledDueToError, con)
105124
}
106125
if (this.callback) {
107-
this.callback(null, this._result)
126+
this.callback(null, this._results)
108127
}
109-
this.emit('end', this._result)
128+
this.emit('end', this._results)
110129
}
111130

112131
Query.prototype.handleError = function (err, connection) {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'use strict'
2+
const assert = require('assert')
3+
const co = require('co')
4+
5+
const helper = require('./test-helper')
6+
7+
const suite = new helper.Suite('multiple result sets')
8+
9+
suite.test('two select results work', co.wrap(function * () {
10+
const client = new helper.Client()
11+
yield client.connect()
12+
13+
const results = yield client.query(`SELECT 'foo'::text as name; SELECT 'bar'::text as baz`)
14+
assert(Array.isArray(results))
15+
16+
assert.equal(results[0].fields[0].name, 'name')
17+
assert.deepEqual(results[0].rows, [{ name: 'foo' }])
18+
19+
assert.equal(results[1].fields[0].name, 'baz')
20+
assert.deepEqual(results[1].rows, [{ baz: 'bar' }])
21+
22+
return client.end()
23+
}))
24+
25+
suite.test('multiple selects work', co.wrap(function * () {
26+
const client = new helper.Client()
27+
yield client.connect()
28+
29+
const text = `
30+
SELECT * FROM generate_series(2, 4) as foo;
31+
SELECT * FROM generate_series(8, 10) as bar;
32+
SELECT * FROM generate_series(20, 22) as baz;
33+
`
34+
35+
const results = yield client.query(text)
36+
assert(Array.isArray(results))
37+
38+
assert.equal(results[0].fields[0].name, 'foo')
39+
assert.deepEqual(results[0].rows, [{ foo: 2 }, { foo: 3 }, { foo: 4 }])
40+
41+
assert.equal(results[1].fields[0].name, 'bar')
42+
assert.deepEqual(results[1].rows, [{ bar: 8 }, { bar: 9 }, { bar: 10 }])
43+
44+
assert.equal(results[2].fields[0].name, 'baz')
45+
assert.deepEqual(results[2].rows, [{ baz: 20 }, { baz: 21 }, { baz: 22 }])
46+
47+
assert.equal(results.length, 3)
48+
49+
return client.end()
50+
}))
51+
52+
suite.test('mixed queries and statements', co.wrap(function * () {
53+
const client = new helper.Client()
54+
yield client.connect()
55+
56+
const text = `
57+
CREATE TEMP TABLE weather(type text);
58+
INSERT INTO weather(type) VALUES ('rain');
59+
SELECT * FROM weather;
60+
`
61+
62+
const results = yield client.query(text)
63+
assert(Array.isArray(results))
64+
assert.equal(results[0].command, 'CREATE')
65+
assert.equal(results[1].command, 'INSERT')
66+
assert.equal(results[2].command, 'SELECT')
67+
68+
return client.end()
69+
}))

0 commit comments

Comments
 (0)