Merge remote-tracking branch 'brianc/master'

This commit is contained in:
Rick Bergfalk 2017-08-04 16:58:34 -04:00
commit 6072bcea8e
6 changed files with 72 additions and 13 deletions

View File

@ -1,6 +1,13 @@
language: node_js
dist: trusty
sudo: false
node_js:
- "0.10"
- "0.11"
- "6"
env:
- PGUSER=postgres
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- psql -c 'create database travis;' -U postgres | true

View File

@ -59,12 +59,13 @@ pg.connect(function(err, client, done) {
Creates an instance of a query cursor. Pass this instance to node-postgres [`client#query`](https://github.com/brianc/node-postgres/wiki/Client#wiki-method-query-parameterized)
#### cursor#read(int rowCount, function callback(Error err, Array rows)
#### cursor#read(int rowCount, function callback(Error err, Array rows, Result result)
Read `rowCount` rows from the cursor instance. The `callback` will be called when the rows are available, loaded into memory, parsed, and converted to JavaScript types.
If the cursor has read to the end of the result sets all subsequent calls to `cursor#read` will return a 0 length array of rows. I'm open to other ways to signal the end of a cursor, but this has worked out well for me so far.
`result` is a special [https://github.com/brianc/node-postgres/wiki/Query#result-object](Result) object that can be used to accumulate rows.
#### cursor#close(function callback(Error err))

View File

@ -1,7 +1,11 @@
var Result = require('./pg').Result
var prepare = require('./pg').prepareValue
var EventEmitter = require('events').EventEmitter;
var util = require('util');
function Cursor (text, values) {
EventEmitter.call(this);
var Cursor = function(text, values) {
this.text = text
this.values = values ? values.map(prepare) : null
this.connection = null
@ -12,6 +16,8 @@ var Cursor = function(text, values) {
this._rows = null
}
util.inherits(Cursor, EventEmitter)
Cursor.prototype.submit = function(connection) {
this.connection = connection
@ -58,6 +64,7 @@ Cursor.prototype.handleRowDescription = function(msg) {
Cursor.prototype.handleDataRow = function(msg) {
var row = this._result.parseRow(msg.fields)
this.emit('row', row, this._result)
this._rows.push(row)
}
@ -70,7 +77,8 @@ Cursor.prototype._sendRows = function() {
//within the call to this callback
this._cb = null
if(cb) {
cb(null, this._rows)
this._result.rows = this._rows
cb(null, this._rows, this._result)
}
this._rows = []
}.bind(this))
@ -86,6 +94,7 @@ Cursor.prototype.handlePortalSuspended = function() {
Cursor.prototype.handleReadyForQuery = function() {
this._sendRows()
this.emit('end', this._result)
this.state = 'done'
}
@ -106,6 +115,11 @@ Cursor.prototype.handleError = function(msg) {
for(var i = 0; i < this._queue.length; i++) {
this._queue.pop()[1](msg)
}
if (this.eventNames().indexOf('error') >= 0) {
//only dispatch error events if we have a listener
this.emit('error', msg)
}
//call sync to keep this connection from hanging
this.connection.sync()
}

View File

@ -1,6 +1,6 @@
{
"name": "pg-cursor",
"version": "1.0.0",
"version": "1.2.0",
"description": "",
"main": "index.js",
"directories": {

11
pg.js
View File

@ -1,13 +1,10 @@
var path = require('path')
var pgPath;
//support both pg & pg.js
//this will eventually go away when i break native bindings
//out into their own module
try {
pgPath = path.dirname(require.resolve('pg'))
module.exports.Result = require('pg/lib/result.js')
module.exports.prepareValue = require('pg/lib/utils.js').prepareValue
} catch(e) {
pgPath = path.dirname(require.resolve('pg.js')) + '/lib'
module.exports.Result = require('pg.js/lib/result.js')
module.exports.prepareValue = require('pg.js/lib/utils.js').prepareValue
}
module.exports.Result = require(path.join(pgPath, 'result.js'))
module.exports.prepareValue = require(path.join(pgPath, 'utils.js')).prepareValue

View File

@ -116,4 +116,44 @@ describe('cursor', function() {
})
})
})
it('returns result along with rows', function(done) {
var cursor = this.pgCursor(text)
cursor.read(1, function(err, rows, result) {
assert.ifError(err)
assert.equal(rows.length, 1)
assert.strictEqual(rows, result.rows)
assert.deepEqual(result.fields.map(f => f.name), ['num'])
done()
})
})
it('emits row events', function(done) {
var cursor = this.pgCursor(text)
cursor.read(10)
cursor.on('row', (row, result) => result.addRow(row))
cursor.on('end', (result) => {
assert.equal(result.rows.length, 6)
done()
})
})
it('emits row events when cursor is closed manually', function(done) {
var cursor = this.pgCursor(text)
cursor.on('row', (row, result) => result.addRow(row))
cursor.on('end', (result) => {
assert.equal(result.rows.length, 3)
done()
})
cursor.read(3, () => cursor.close())
})
it('emits error events', function(done) {
var cursor = this.pgCursor('select asdfasdf')
cursor.on('error', function(err) {
assert(err)
done()
})
})
})