Skip to content

Commit aedaa59

Browse files
Bluenix2charmander
andauthored
Add support for using promises in Cursor methods (brianc#2554)
* Add similar promise variables to read() and close() as seen in query() * Add testing for promise specific usage * Simplify tests as no real callbacks are involved Removes usage of `done()` since we can end the test when we exit the function Co-Authored-By: Charmander <~@charmander.me> * Switch to let over var Co-authored-by: Charmander <~@charmander.me>
1 parent 9d2c977 commit aedaa59

File tree

2 files changed

+81
-10
lines changed

2 files changed

+81
-10
lines changed

packages/pg-cursor/index.js

+30-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Cursor extends EventEmitter {
1717
this._queue = []
1818
this.state = 'initialized'
1919
this._result = new Result(this._conf.rowMode, this._conf.types)
20+
this._Promise = this._conf.Promise || global.Promise
2021
this._cb = null
2122
this._rows = null
2223
this._portal = null
@@ -198,6 +199,14 @@ class Cursor extends EventEmitter {
198199
}
199200

200201
close(cb) {
202+
let promise
203+
204+
if (!cb) {
205+
promise = new this._Promise((resolve, reject) => {
206+
cb = (err) => (err ? reject(err) : resolve())
207+
})
208+
}
209+
201210
if (!this.connection || this.state === 'done') {
202211
if (cb) {
203212
return setImmediate(cb)
@@ -213,23 +222,34 @@ class Cursor extends EventEmitter {
213222
cb()
214223
})
215224
}
225+
226+
// Return the promise (or undefined)
227+
return promise
216228
}
217229

218230
read(rows, cb) {
219-
if (this.state === 'idle' || this.state === 'submitted') {
220-
return this._getRows(rows, cb)
221-
}
222-
if (this.state === 'busy' || this.state === 'initialized') {
223-
return this._queue.push([rows, cb])
224-
}
225-
if (this.state === 'error') {
226-
return setImmediate(() => cb(this._error))
231+
let promise
232+
233+
if (!cb) {
234+
promise = new this._Promise((resolve, reject) => {
235+
cb = (err, rows) => (err ? reject(err) : resolve(rows))
236+
})
227237
}
228-
if (this.state === 'done') {
229-
return setImmediate(() => cb(null, []))
238+
239+
if (this.state === 'idle' || this.state === 'submitted') {
240+
this._getRows(rows, cb)
241+
} else if (this.state === 'busy' || this.state === 'initialized') {
242+
this._queue.push([rows, cb])
243+
} else if (this.state === 'error') {
244+
setImmediate(() => cb(this._error))
245+
} else if (this.state === 'done') {
246+
setImmediate(() => cb(null, []))
230247
} else {
231248
throw new Error('Unknown state: ' + this.state)
232249
}
250+
251+
// Return the promise (or undefined)
252+
return promise
233253
}
234254
}
235255

packages/pg-cursor/test/promises.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const assert = require('assert')
2+
const Cursor = require('../')
3+
const pg = require('pg')
4+
5+
const text = 'SELECT generate_series as num FROM generate_series(0, 5)'
6+
7+
describe('cursor using promises', function () {
8+
beforeEach(function (done) {
9+
const client = (this.client = new pg.Client())
10+
client.connect(done)
11+
12+
this.pgCursor = function (text, values) {
13+
return client.query(new Cursor(text, values || []))
14+
}
15+
})
16+
17+
afterEach(function () {
18+
this.client.end()
19+
})
20+
21+
it('resolve with result', async function () {
22+
const cursor = this.pgCursor(text)
23+
const res = await cursor.read(6)
24+
assert.strictEqual(res.length, 6)
25+
})
26+
27+
it('reject with error', function (done) {
28+
const cursor = this.pgCursor('select asdfasdf')
29+
cursor.read(1).error((err) => {
30+
assert(err)
31+
done()
32+
})
33+
})
34+
35+
it('read multiple times', async function () {
36+
const cursor = this.pgCursor(text)
37+
let res
38+
39+
res = await cursor.read(2)
40+
assert.strictEqual(res.length, 2)
41+
42+
res = await cursor.read(3)
43+
assert.strictEqual(res.length, 3)
44+
45+
res = await cursor.read(1)
46+
assert.strictEqual(res.length, 1)
47+
48+
res = await cursor.read(1)
49+
assert.strictEqual(res.length, 0)
50+
})
51+
})

0 commit comments

Comments
 (0)