Comparing version 1.3.0 to 2.0.0
22
index.js
'use strict' | ||
const Result = require('./pg').Result | ||
const prepare = require('./pg').prepareValue | ||
const Result = require('pg/lib/result.js') | ||
const prepare = require('pg/lib/utils.js').prepareValue | ||
const EventEmitter = require('events').EventEmitter | ||
const util = require('util') | ||
var nextUniqueID = 1 // concept borrowed from org.postgresql.core.v3.QueryExecutorImpl | ||
function Cursor (text, values, config) { | ||
EventEmitter.call(this) | ||
this._conf = config || { } | ||
this._conf = config || {} | ||
this.text = text | ||
@@ -19,2 +21,3 @@ this.values = values ? values.map(prepare) : null | ||
this._rows = null | ||
this._portal = null | ||
} | ||
@@ -26,2 +29,3 @@ | ||
this.connection = connection | ||
this._portal = 'C_' + (nextUniqueID++) | ||
@@ -35,2 +39,3 @@ const con = connection | ||
con.bind({ | ||
portal: this._portal, | ||
values: this.values | ||
@@ -41,3 +46,3 @@ }, true) | ||
type: 'P', | ||
name: '' // use unamed portal | ||
name: this._portal // AWS Redshift requires a portal name | ||
}, true) | ||
@@ -96,3 +101,4 @@ | ||
Cursor.prototype.handleCommandComplete = function () { | ||
Cursor.prototype.handleCommandComplete = function (msg) { | ||
this._result.addCommandComplete(msg) | ||
this.connection.sync() | ||
@@ -140,3 +146,3 @@ } | ||
const msg = { | ||
portal: '', | ||
portal: this._portal, | ||
rows: rows | ||
@@ -152,3 +158,3 @@ } | ||
} | ||
this.connection.stream.once('end', cb) | ||
this.connection.once('end', cb) | ||
this.connection.end() | ||
@@ -161,3 +167,3 @@ } | ||
} | ||
this.connection.close({type: 'P'}) | ||
this.connection.close({ type: 'P' }) | ||
this.connection.sync() | ||
@@ -164,0 +170,0 @@ this.state = 'done' |
{ | ||
"name": "pg-cursor", | ||
"version": "1.3.0", | ||
"version": "2.0.0", | ||
"description": "", | ||
@@ -12,2 +12,6 @@ "main": "index.js", | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/brianc/node-pg-cursor.git" | ||
}, | ||
"author": "Brian M. Carlson", | ||
@@ -14,0 +18,0 @@ "license": "MIT", |
@@ -6,70 +6,2 @@ node-pg-cursor | ||
### why? | ||
Sometimes you need to iterate through a table in chunks. It's extremely inefficient to use hand-crafted `LIMIT` and `OFFSET` queries to do this. | ||
PostgreSQL provides built-in functionality to fetch a "cursor" to your results and page through the cursor efficiently fetching chunks of the results with full MVCC compliance. | ||
This actually ends up pairing very nicely with node's _asyncness_ and handling a lot of data. PostgreSQL is rad. | ||
### example | ||
```js | ||
var Cursor = require('pg-cursor') | ||
var pg = require('pg') | ||
pg.connect(function(err, client, done) { | ||
//imagine some_table has 30,000,000 results where prop > 100 | ||
//lets create a query cursor to efficiently deal with the huge result set | ||
var cursor = client.query(new Cursor('SELECT * FROM some_table WHERE prop > $1', [100])) | ||
//read the first 100 rows from this cursor | ||
cursor.read(100, function(err, rows) { | ||
if(err) { | ||
//cursor error - release the client | ||
//normally you'd do app-specific error handling here | ||
return done(err) | ||
} | ||
//when the cursor is exhausted and all rows have been returned | ||
//all future calls to `cursor#read` will return an empty row array | ||
//so if we received no rows, release the client and be done | ||
if(!rows.length) return done() | ||
//do something with your rows | ||
//when you're ready, read another chunk from | ||
//your result | ||
cursor.read(2000, function(err, rows) { | ||
//I think you get the picture, yeah? | ||
//if you dont...open an issue - I'd love to help you out! | ||
//Also - you probably want to use some sort of async or promise library to deal with paging | ||
//through your cursor results. node-pg-cursor makes no asumptions for you on that front. | ||
}) | ||
}) | ||
}); | ||
``` | ||
### api | ||
#### var Cursor = require('pg-cursor') | ||
#### constructor Cursor(string queryText, array queryParameters) | ||
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, 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)) | ||
Closes the backend portal before itterating through the entire result set. Useful when you want to 'abort' out of a read early but continue to use the same client for other queries after the cursor is finished. | ||
### install | ||
@@ -82,2 +14,4 @@ | ||
### :star: [Documentation](https://node-postgres.com/api/cursor) :star: | ||
### license | ||
@@ -84,0 +18,0 @@ |
@@ -163,2 +163,16 @@ var assert = require('assert') | ||
}) | ||
it('returns rowCount on insert', function (done) { | ||
var pgCursor = this.pgCursor | ||
this.client.query('CREATE TEMPORARY TABLE pg_cursor_test (foo VARCHAR(1), bar VARCHAR(1))') | ||
.then(function () { | ||
var cursor = pgCursor('insert into pg_cursor_test values($1, $2)', ['a', 'b']) | ||
cursor.read(1, function (err, rows, result) { | ||
assert.ifError(err) | ||
assert.equal(rows.length, 0) | ||
assert.equal(result.rowCount, 1) | ||
done() | ||
}) | ||
}).catch(done) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
573
0
18983
13
38