Comparing version 1.10.1 to 2.0.0
var pg = require('pg').native | ||
var Native = require('../') | ||
var warmup = function(fn, cb) { | ||
var count = 0; | ||
var max = 10; | ||
var run = function(err) { | ||
if(err) return cb(err); | ||
var warmup = function (fn, cb) { | ||
var count = 0 | ||
var max = 10 | ||
var run = function (err) { | ||
if (err) return cb(err) | ||
if(max >= count++) { | ||
if (max >= count++) { | ||
return fn(run) | ||
@@ -16,30 +16,30 @@ } | ||
} | ||
run(); | ||
run() | ||
} | ||
var native = Native(); | ||
native.connectSync(); | ||
var native = Native() | ||
native.connectSync() | ||
var queryText = 'SELECT generate_series(0, 1000)'; | ||
var client = new pg.Client(); | ||
client.connect(function() { | ||
var pure = function(cb) { | ||
client.query(queryText, function(err) { | ||
if(err) throw err; | ||
cb(err); | ||
}); | ||
var queryText = 'SELECT generate_series(0, 1000)' | ||
var client = new pg.Client() | ||
client.connect(function () { | ||
var pure = function (cb) { | ||
client.query(queryText, function (err) { | ||
if (err) throw err | ||
cb(err) | ||
}) | ||
} | ||
var nativeQuery = function(cb) { | ||
native.query(queryText, function(err) { | ||
if(err) throw err; | ||
cb(err); | ||
}); | ||
var nativeQuery = function (cb) { | ||
native.query(queryText, function (err) { | ||
if (err) throw err | ||
cb(err) | ||
}) | ||
} | ||
var run = function() { | ||
var run = function () { | ||
var start = Date.now() | ||
warmup(pure, function() { | ||
warmup(pure, function () { | ||
console.log('pure done', Date.now() - start) | ||
start = Date.now() | ||
warmup(nativeQuery, function() { | ||
warmup(nativeQuery, function () { | ||
console.log('native done', Date.now() - start) | ||
@@ -50,7 +50,5 @@ }) | ||
setInterval(function() { | ||
setInterval(function () { | ||
run() | ||
}, 500) | ||
}); | ||
}) |
@@ -1,44 +0,38 @@ | ||
var Client = require('../'); | ||
var async = require('async'); | ||
var Client = require('../') | ||
var async = require('async') | ||
var loop = function() { | ||
var client = new Client(); | ||
var loop = function () { | ||
var client = new Client() | ||
var connect = function(cb) { | ||
client.connect(cb); | ||
}; | ||
var connect = function (cb) { | ||
client.connect(cb) | ||
} | ||
var simpleQuery = function(cb) { | ||
client.query('SELECT NOW()', cb); | ||
}; | ||
var simpleQuery = function (cb) { | ||
client.query('SELECT NOW()', cb) | ||
} | ||
var paramsQuery = function(cb) { | ||
client.query('SELECT $1::text as name', ['Brian'], cb); | ||
}; | ||
var paramsQuery = function (cb) { | ||
client.query('SELECT $1::text as name', ['Brian'], cb) | ||
} | ||
var prepared = function(cb) { | ||
client.prepare('test', 'SELECT $1::text as name', 1, function(err) { | ||
if(err) return cb(err); | ||
client.execute('test', ['Brian'], cb); | ||
}); | ||
}; | ||
var prepared = function (cb) { | ||
client.prepare('test', 'SELECT $1::text as name', 1, function (err) { | ||
if (err) return cb(err) | ||
client.execute('test', ['Brian'], cb) | ||
}) | ||
} | ||
var error = function(cb) { | ||
client.query('SELECT ASLKJDASLKJD', function() { | ||
cb(); | ||
}); | ||
}; | ||
var sync = function (cb) { | ||
client.querySync('SELECT NOW()') | ||
client.querySync('SELECT $1::text as name', ['Brian']) | ||
client.prepareSync('boom', 'SELECT $1::text as name', 1) | ||
client.executeSync('boom', ['Brian']) | ||
setImmediate(cb) | ||
} | ||
var sync = function(cb) { | ||
client.querySync('SELECT NOW()'); | ||
client.querySync('SELECT $1::text as name', ['Brian']); | ||
client.prepareSync('boom', 'SELECT $1::text as name', 1); | ||
client.executeSync('boom', ['Brian']); | ||
setImmediate(cb); | ||
}; | ||
var end = function (cb) { | ||
client.end(cb) | ||
} | ||
var end = function(cb) { | ||
client.end(cb); | ||
}; | ||
var ops = [ | ||
@@ -51,14 +45,14 @@ connect, | ||
end | ||
]; | ||
] | ||
var start = Date.now(); | ||
async.series(ops, function(err) { | ||
if(err) throw err; | ||
console.log(Date.now() - start); | ||
setImmediate(loop); | ||
}); | ||
}; | ||
var start = Date.now() | ||
async.series(ops, function (err) { | ||
if (err) throw err | ||
console.log(Date.now() - start) | ||
setImmediate(loop) | ||
}) | ||
} | ||
//on my machine this will consume memory up to about 50 megs of ram | ||
//and then stabalize at that point | ||
loop(); | ||
// on my machine this will consume memory up to about 50 megs of ram | ||
// and then stabalize at that point | ||
loop() |
514
index.js
@@ -1,292 +0,334 @@ | ||
var Libpq = require('libpq'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var util = require('util'); | ||
var assert = require('assert'); | ||
var types = require('pg-types'); | ||
var Libpq = require('libpq') | ||
var EventEmitter = require('events').EventEmitter | ||
var util = require('util') | ||
var assert = require('assert') | ||
var types = require('pg-types') | ||
var buildResult = require('./lib/build-result') | ||
var CopyStream = require('./lib/copy-stream') | ||
var Client = module.exports = function(config) { | ||
if(!(this instanceof Client)) { | ||
return new Client(config); | ||
var Client = module.exports = function (config) { | ||
if (!(this instanceof Client)) { | ||
return new Client(config) | ||
} | ||
config = config || {}; | ||
config = config || {} | ||
EventEmitter.call(this); | ||
this.pq = new Libpq(); | ||
this._reading = false; | ||
this._read = this._read.bind(this); | ||
EventEmitter.call(this) | ||
this.pq = new Libpq() | ||
this._reading = false | ||
this._read = this._read.bind(this) | ||
//allow custom type converstion to be passed in | ||
this._types = config.types || types; | ||
// allow custom type converstion to be passed in | ||
this._types = config.types || types | ||
//allow config to specify returning results | ||
//as an array of values instead of a hash | ||
this.arrayMode = config.arrayMode || false; | ||
var self = this; | ||
// allow config to specify returning results | ||
// as an array of values instead of a hash | ||
this.arrayMode = config.arrayMode || false | ||
this._resultCount = 0 | ||
this._rows = undefined | ||
this._results = undefined | ||
//lazy start the reader if notifications are listened for | ||
//this way if you only run sync queries you wont block | ||
//the event loop artificially | ||
this.on('newListener', function(event) { | ||
if(event != 'notification') return; | ||
self._startReading(); | ||
}); | ||
}; | ||
// lazy start the reader if notifications are listened for | ||
// this way if you only run sync queries you wont block | ||
// the event loop artificially | ||
this.on('newListener', (event) => { | ||
if (event !== 'notification') return | ||
this._startReading() | ||
}) | ||
util.inherits(Client, EventEmitter); | ||
this.on('_queryError', this._onQueryError.bind(this)) | ||
this.on('result', this._onResult.bind(this)) | ||
this.on('readyForQuery', this._onReadyForQuery.bind(this)) | ||
} | ||
Client.prototype.connect = function(params, cb) { | ||
this.pq.connect(params, cb); | ||
}; | ||
util.inherits(Client, EventEmitter) | ||
Client.prototype.connectSync = function(params) { | ||
this.pq.connectSync(params); | ||
}; | ||
Client.prototype.connect = function (params, cb) { | ||
this.pq.connect(params, cb) | ||
} | ||
Client.prototype._parseResults = function(pq, rows) { | ||
var rowCount = pq.ntuples(); | ||
var colCount = pq.nfields(); | ||
for(var i = 0; i < rowCount; i++) { | ||
var row = this.arrayMode ? [] : {}; | ||
rows.push(row); | ||
for(var j = 0; j < colCount; j++) { | ||
var rawValue = pq.getvalue(i, j); | ||
var value = rawValue; | ||
if(rawValue == '') { | ||
if(pq.getisnull(i, j)) { | ||
value = null; | ||
} | ||
} else { | ||
value = this._types.getTypeParser(pq.ftype(j))(rawValue); | ||
} | ||
if(this.arrayMode) { | ||
row.push(value); | ||
} else { | ||
row[pq.fname(j)] = value; | ||
} | ||
} | ||
Client.prototype.connectSync = function (params) { | ||
this.pq.connectSync(params) | ||
} | ||
Client.prototype.query = function (text, values, cb) { | ||
var queryFn | ||
if (typeof values === 'function') { | ||
cb = values | ||
queryFn = function () { return self.pq.sendQuery(text) } | ||
} else { | ||
queryFn = function () { return self.pq.sendQueryParams(text, values) } | ||
} | ||
return rows; | ||
var self = this | ||
self._dispatchQuery(self.pq, queryFn, function (err) { | ||
if (err) return cb(err) | ||
self._awaitResult(cb) | ||
}) | ||
} | ||
Client.prototype.end = function(cb) { | ||
this._stopReading(); | ||
this.pq.finish(); | ||
if(cb) setImmediate(cb); | ||
}; | ||
Client.prototype.prepare = function (statementName, text, nParams, cb) { | ||
var self = this | ||
var fn = function () { | ||
return self.pq.sendPrepare(statementName, text, nParams) | ||
} | ||
Client.prototype._readError = function(message) { | ||
this._stopReading(); | ||
var err = new Error(message || this.pq.errorMessage()); | ||
this.emit('error', err); | ||
}; | ||
self._dispatchQuery(self.pq, fn, function (err) { | ||
if (err) return cb(err) | ||
self._awaitResult(cb) | ||
}) | ||
} | ||
Client.prototype._stopReading = function() { | ||
if(!this._reading) return; | ||
this._reading = false; | ||
this.pq.stopReader(); | ||
this.pq.removeListener('readable', this._read); | ||
}; | ||
Client.prototype.execute = function (statementName, parameters, cb) { | ||
var self = this | ||
//called when libpq is readable | ||
Client.prototype._read = function() { | ||
var pq = this.pq; | ||
//read waiting data from the socket | ||
//e.g. clear the pending 'select' | ||
if(!pq.consumeInput()) { | ||
//if consumeInput returns false | ||
//than a read error has been encountered | ||
return this._readError(); | ||
var fn = function () { | ||
return self.pq.sendQueryPrepared(statementName, parameters) | ||
} | ||
//check if there is still outstanding data | ||
//if so, wait for it all to come in | ||
if(pq.isBusy()) { | ||
return; | ||
self._dispatchQuery(self.pq, fn, function (err, rows) { | ||
if (err) return cb(err) | ||
self._awaitResult(cb) | ||
}) | ||
} | ||
Client.prototype.getCopyStream = function () { | ||
this.pq.setNonBlocking(true) | ||
this._stopReading() | ||
return new CopyStream(this.pq) | ||
} | ||
// cancel a currently executing query | ||
Client.prototype.cancel = function (cb) { | ||
assert(cb, 'Callback is required') | ||
// result is either true or a string containing an error | ||
var result = this.pq.cancel() | ||
return setImmediate(function () { | ||
cb(result === true ? undefined : new Error(result)) | ||
}) | ||
} | ||
Client.prototype.querySync = function (text, values) { | ||
if (values) { | ||
this.pq.execParams(text, values) | ||
} else { | ||
this.pq.exec(text) | ||
} | ||
//load our result object | ||
var rows = [] | ||
while(pq.getResult()) { | ||
if(pq.resultStatus() == 'PGRES_TUPLES_OK') { | ||
this._parseResults(this.pq, rows); | ||
} | ||
if(pq.resultStatus() == 'PGRES_COPY_OUT' || pq.resultStatus() == 'PGRES_COPY_BOTH') break; | ||
throwIfError(this.pq) | ||
const result = buildResult(this.pq, this._types, this.arrayMode) | ||
return result.rows | ||
} | ||
Client.prototype.prepareSync = function (statementName, text, nParams) { | ||
this.pq.prepare(statementName, text, nParams) | ||
throwIfError(this.pq) | ||
} | ||
Client.prototype.executeSync = function (statementName, parameters) { | ||
this.pq.execPrepared(statementName, parameters) | ||
throwIfError(this.pq) | ||
return buildResult(this.pq, this._types, this.arrayMode).rows | ||
} | ||
Client.prototype.escapeLiteral = function (value) { | ||
return this.pq.escapeLiteral(value) | ||
} | ||
Client.prototype.escapeIdentifier = function (value) { | ||
return this.pq.escapeIdentifier(value) | ||
} | ||
// export the version number so we can check it in node-postgres | ||
module.exports.version = require('./package.json').version | ||
Client.prototype.end = function (cb) { | ||
this._stopReading() | ||
this.pq.finish() | ||
if (cb) setImmediate(cb) | ||
} | ||
Client.prototype._readError = function (message) { | ||
var err = new Error(message || this.pq.errorMessage()) | ||
if (this._queryCallback) { | ||
this.emit('_queryError', err) | ||
} else { | ||
this.emit('error', err) | ||
} | ||
} | ||
Client.prototype._stopReading = function () { | ||
if (!this._reading) return | ||
this._reading = false | ||
this.pq.stopReader() | ||
this.pq.removeListener('readable', this._read) | ||
} | ||
var status = pq.resultStatus(); | ||
switch(status) { | ||
Client.prototype._consumeQueryResults = function (pq) { | ||
return buildResult(pq, this._types, this.arrayMode) | ||
} | ||
Client.prototype._emitResult = function (pq) { | ||
var status = pq.resultStatus() | ||
switch (status) { | ||
case 'PGRES_FATAL_ERROR': | ||
return this._readError(); | ||
this._readError() | ||
break | ||
case 'PGRES_TUPLES_OK': | ||
case 'PGRES_COMMAND_OK': | ||
case 'PGRES_TUPLES_OK': | ||
case 'PGRES_EMPTY_QUERY': | ||
const result = this._consumeQueryResults(this.pq) | ||
this.emit('result', result) | ||
break | ||
case 'PGRES_COPY_OUT': | ||
case 'PGRES_COPY_BOTH': | ||
case 'PGRES_EMPTY_QUERY': { | ||
this.emit('result', rows); | ||
break; | ||
case 'PGRES_COPY_BOTH': { | ||
break | ||
} | ||
default: | ||
return this._readError('unrecognized command status: ' + status); | ||
this._readError('unrecognized command status: ' + status) | ||
break | ||
} | ||
return status | ||
} | ||
var notice; | ||
while(notice = this.pq.notifies()) { | ||
this.emit('notification', notice); | ||
// called when libpq is readable | ||
Client.prototype._read = function () { | ||
var pq = this.pq | ||
// read waiting data from the socket | ||
// e.g. clear the pending 'select' | ||
if (!pq.consumeInput()) { | ||
// if consumeInput returns false | ||
// than a read error has been encountered | ||
return this._readError() | ||
} | ||
}; | ||
//ensures the client is reading and | ||
//everything is set up for async io | ||
Client.prototype._startReading = function() { | ||
if(this._reading) return; | ||
this._reading = true; | ||
this.pq.on('readable', this._read); | ||
this.pq.startReader(); | ||
}; | ||
var throwIfError = function(pq) { | ||
var err = pq.resultErrorMessage() || pq.errorMessage(); | ||
if(err) { | ||
throw new Error(err); | ||
// check if there is still outstanding data | ||
// if so, wait for it all to come in | ||
if (pq.isBusy()) { | ||
return | ||
} | ||
} | ||
Client.prototype._awaitResult = function(cb) { | ||
var self = this; | ||
var onError = function(e) { | ||
self.removeListener('error', onError); | ||
self.removeListener('result', onResult); | ||
cb(e); | ||
}; | ||
// load our result object | ||
var onResult = function(rows) { | ||
self.removeListener('error', onError); | ||
self.removeListener('result', onResult); | ||
cb(null, rows); | ||
}; | ||
this.once('error', onError); | ||
this.once('result', onResult); | ||
this._startReading(); | ||
}; | ||
while (pq.getResult()) { | ||
const resultStatus = this._emitResult(this.pq) | ||
//wait for the writable socket to drain | ||
Client.prototype.waitForDrain = function(pq, cb) { | ||
var res = pq.flush(); | ||
//res of 0 is success | ||
if(res === 0) return cb(); | ||
// if the command initiated copy mode we need to break out of the read loop | ||
// so a substream can begin to read copy data | ||
if (resultStatus === 'PGRES_COPY_BOTH' || resultStatus === 'PGRES_COPY_OUT') { | ||
break | ||
} | ||
//res of -1 is failure | ||
if(res === -1) return cb(pq.errorMessage()); | ||
// if reading multiple results, sometimes the following results might cause | ||
// a blocking read. in this scenario yield back off the reader until libpq is readable | ||
if (pq.isBusy()) { | ||
return | ||
} | ||
} | ||
//otherwise outgoing message didn't flush to socket | ||
//wait for it to flush and try again | ||
var self = this | ||
//you cannot read & write on a socket at the same time | ||
return pq.writable(function() { | ||
self.waitForDrain(pq, cb) | ||
}); | ||
}; | ||
this.emit('readyForQuery') | ||
//send an async query to libpq and wait for it to | ||
//finish writing query text to the socket | ||
Client.prototype.dispatchQuery = function(pq, fn, cb) { | ||
this._stopReading(); | ||
var success = pq.setNonBlocking(true); | ||
if(!success) return cb(new Error('Unable to set non-blocking to true')); | ||
var sent = fn(); | ||
if(!sent) return cb(new Error(pq.errorMessage() || 'Something went wrong dispatching the query')); | ||
this.waitForDrain(pq, cb); | ||
}; | ||
var notice = this.pq.notifies() | ||
while (notice) { | ||
this.emit('notification', notice) | ||
notice = this.pq.notifies() | ||
} | ||
} | ||
Client.prototype.query = function(text, values, cb) { | ||
var queryFn; | ||
// ensures the client is reading and | ||
// everything is set up for async io | ||
Client.prototype._startReading = function () { | ||
if (this._reading) return | ||
this._reading = true | ||
this.pq.on('readable', this._read) | ||
this.pq.startReader() | ||
} | ||
if(typeof values == 'function') { | ||
cb = values; | ||
queryFn = function() { return self.pq.sendQuery(text); }; | ||
} else { | ||
queryFn = function() { return self.pq.sendQueryParams(text, values); }; | ||
var throwIfError = function (pq) { | ||
var err = pq.resultErrorMessage() || pq.errorMessage() | ||
if (err) { | ||
throw new Error(err) | ||
} | ||
} | ||
var self = this | ||
Client.prototype._awaitResult = function (cb) { | ||
this._queryCallback = cb | ||
return this._startReading() | ||
} | ||
self.dispatchQuery(self.pq, queryFn, function(err) { | ||
if(err) return cb(err); | ||
// wait for the writable socket to drain | ||
Client.prototype._waitForDrain = function (pq, cb) { | ||
var res = pq.flush() | ||
// res of 0 is success | ||
if (res === 0) return cb() | ||
self._awaitResult(cb) | ||
}); | ||
}; | ||
// res of -1 is failure | ||
if (res === -1) return cb(pq.errorMessage()) | ||
Client.prototype.prepare = function(statementName, text, nParams, cb) { | ||
var self = this; | ||
var fn = function() { | ||
return self.pq.sendPrepare(statementName, text, nParams); | ||
} | ||
// otherwise outgoing message didn't flush to socket | ||
// wait for it to flush and try again | ||
var self = this | ||
// you cannot read & write on a socket at the same time | ||
return pq.writable(function () { | ||
self._waitForDrain(pq, cb) | ||
}) | ||
} | ||
self.dispatchQuery(self.pq, fn, function(err) { | ||
if(err) return cb(err); | ||
self._awaitResult(cb); | ||
}); | ||
}; | ||
// send an async query to libpq and wait for it to | ||
// finish writing query text to the socket | ||
Client.prototype._dispatchQuery = function (pq, fn, cb) { | ||
this._stopReading() | ||
var success = pq.setNonBlocking(true) | ||
if (!success) return cb(new Error('Unable to set non-blocking to true')) | ||
var sent = fn() | ||
if (!sent) return cb(new Error(pq.errorMessage() || 'Something went wrong dispatching the query')) | ||
this._waitForDrain(pq, cb) | ||
} | ||
Client.prototype.execute = function(statementName, parameters, cb) { | ||
var self = this; | ||
Client.prototype._onQueryError = function (err) { | ||
this._queryError = err | ||
} | ||
var fn = function() { | ||
return self.pq.sendQueryPrepared(statementName, parameters); | ||
}; | ||
Client.prototype._onResult = function (result) { | ||
if (this._resultCount === 0) { | ||
this._results = result | ||
this._rows = result.rows | ||
} else if (this._resultCount === 1) { | ||
this._results = [this._results, result] | ||
this._rows = [this._rows, result.rows] | ||
} else { | ||
this._results.push(result) | ||
this._rows.push(result.rows) | ||
} | ||
this._resultCount++ | ||
} | ||
self.dispatchQuery(self.pq, fn, function(err, rows) { | ||
if(err) return cb(err); | ||
self._awaitResult(cb) | ||
}); | ||
}; | ||
Client.prototype._onReadyForQuery = function () { | ||
// remove instance callback | ||
const cb = this._queryCallback | ||
this._queryCallback = undefined | ||
var CopyStream = require('./lib/copy-stream'); | ||
Client.prototype.getCopyStream = function() { | ||
this.pq.setNonBlocking(true); | ||
this._stopReading(); | ||
return new CopyStream(this.pq); | ||
}; | ||
// remove instance query error | ||
const err = this._queryError | ||
this._queryError = undefined | ||
//cancel a currently executing query | ||
Client.prototype.cancel = function(cb) { | ||
assert(cb, 'Callback is required'); | ||
//result is either true or a string containing an error | ||
var result = this.pq.cancel(); | ||
return setImmediate(function() { | ||
cb(result === true ? undefined : new Error(result)); | ||
}); | ||
}; | ||
// remove instance rows | ||
const rows = this._rows | ||
this._rows = undefined | ||
Client.prototype.querySync = function(text, values) { | ||
var queryFn; | ||
var pq = this.pq; | ||
pq[values ? 'execParams' : 'exec'].call(pq, text, values); | ||
throwIfError(this.pq); | ||
return this._parseResults(pq, []); | ||
}; | ||
// remove instance results | ||
const results = this._results | ||
this._results = undefined | ||
Client.prototype.prepareSync = function(statementName, text, nParams) { | ||
this.pq.prepare(statementName, text, nParams); | ||
throwIfError(this.pq); | ||
}; | ||
this._resultCount = 0 | ||
Client.prototype.executeSync = function(statementName, parameters) { | ||
this.pq.execPrepared(statementName, parameters); | ||
throwIfError(this.pq); | ||
return this._parseResults(this.pq, []); | ||
}; | ||
Client.prototype.escapeLiteral = function(value) { | ||
return this.pq.escapeLiteral(value); | ||
}; | ||
Client.prototype.escapeIdentifier = function(value) { | ||
return this.pq.escapeIdentifier(value); | ||
}; | ||
//export the version number so we can check it in node-postgres | ||
module.exports.version = require('./package.json').version | ||
if (cb) { | ||
cb(err, rows || [], results) | ||
} | ||
} |
@@ -1,158 +0,155 @@ | ||
var Duplex = require('stream').Duplex; | ||
var Writable = require('stream').Writable; | ||
var util = require('util'); | ||
var Duplex = require('stream').Duplex | ||
var Writable = require('stream').Writable | ||
var util = require('util') | ||
var CopyStream = module.exports = function(pq, options) { | ||
Duplex.call(this, options); | ||
this.pq = pq; | ||
this._reading = false; | ||
}; | ||
var CopyStream = module.exports = function (pq, options) { | ||
Duplex.call(this, options) | ||
this.pq = pq | ||
this._reading = false | ||
} | ||
util.inherits(CopyStream, Duplex); | ||
util.inherits(CopyStream, Duplex) | ||
//writer methods | ||
CopyStream.prototype._write = function(chunk, encoding, cb) { | ||
var result = this.pq.putCopyData(chunk); | ||
// writer methods | ||
CopyStream.prototype._write = function (chunk, encoding, cb) { | ||
var result = this.pq.putCopyData(chunk) | ||
//sent successfully | ||
if(result === 1) return cb(); | ||
// sent successfully | ||
if (result === 1) return cb() | ||
//error | ||
if(result === -1) return cb(new Error(this.pq.errorMessage())); | ||
// error | ||
if (result === -1) return cb(new Error(this.pq.errorMessage())) | ||
//command would block. wait for writable and call again. | ||
var self = this; | ||
this.pq.writable(function() { | ||
self._write(chunk, encoding, cb); | ||
}); | ||
}; | ||
// command would block. wait for writable and call again. | ||
var self = this | ||
this.pq.writable(function () { | ||
self._write(chunk, encoding, cb) | ||
}) | ||
} | ||
CopyStream.prototype.end = function() { | ||
var args = Array.prototype.slice.call(arguments, 0); | ||
var self = this; | ||
CopyStream.prototype.end = function () { | ||
var args = Array.prototype.slice.call(arguments, 0) | ||
var self = this | ||
var callback = args.pop(); | ||
var callback = args.pop() | ||
if(args.length) { | ||
this.write(args[0]); | ||
if (args.length) { | ||
this.write(args[0]) | ||
} | ||
var result = this.pq.putCopyEnd(); | ||
var result = this.pq.putCopyEnd() | ||
//sent successfully | ||
if(result === 1) { | ||
//consume our results and then call 'end' on the | ||
//"parent" writable class so we can emit 'finish' and | ||
//all that jazz | ||
return consumeResults(this.pq, function(err, res) { | ||
Writable.prototype.end.call(self); | ||
// sent successfully | ||
if (result === 1) { | ||
// consume our results and then call 'end' on the | ||
// "parent" writable class so we can emit 'finish' and | ||
// all that jazz | ||
return consumeResults(this.pq, function (err, res) { | ||
Writable.prototype.end.call(self) | ||
//handle possible passing of callback to end method | ||
if(callback) { | ||
callback(); | ||
// handle possible passing of callback to end method | ||
if (callback) { | ||
callback(err) | ||
} | ||
}); | ||
}) | ||
} | ||
//error | ||
if(result === -1) { | ||
var err = new Error(this.pq.errorMessage()); | ||
return this.emit('error', err); | ||
// error | ||
if (result === -1) { | ||
var err = new Error(this.pq.errorMessage()) | ||
return this.emit('error', err) | ||
} | ||
//command would block. wait for writable and call end again | ||
//don't pass any buffers to end on the second call because | ||
//we already sent them to possible this.write the first time | ||
//we called end | ||
return this.pq.writable(function() { | ||
return self.end.apply(self, callback); | ||
}); | ||
}; | ||
// command would block. wait for writable and call end again | ||
// don't pass any buffers to end on the second call because | ||
// we already sent them to possible this.write the first time | ||
// we called end | ||
return this.pq.writable(function () { | ||
return self.end.apply(self, callback) | ||
}) | ||
} | ||
//reader methods | ||
CopyStream.prototype._consumeBuffer = function(cb) { | ||
var result = this.pq.getCopyData(true); | ||
if(result instanceof Buffer) { | ||
return setImmediate(function() { | ||
cb(null, result); | ||
// reader methods | ||
CopyStream.prototype._consumeBuffer = function (cb) { | ||
var result = this.pq.getCopyData(true) | ||
if (result instanceof Buffer) { | ||
return setImmediate(function () { | ||
cb(null, result) | ||
}) | ||
} | ||
if(result === -1) { | ||
//end of stream | ||
return cb(null, null); | ||
if (result === -1) { | ||
// end of stream | ||
return cb(null, null) | ||
} | ||
if(result === 0) { | ||
var self = this; | ||
this.pq.once('readable', function() { | ||
self.pq.stopReader(); | ||
self.pq.consumeInput(); | ||
self._consumeBuffer(cb); | ||
}); | ||
return this.pq.startReader(); | ||
if (result === 0) { | ||
var self = this | ||
this.pq.once('readable', function () { | ||
self.pq.stopReader() | ||
self.pq.consumeInput() | ||
self._consumeBuffer(cb) | ||
}) | ||
return this.pq.startReader() | ||
} | ||
cb(new Error('Unrecognized read status: ' + result)) | ||
}; | ||
} | ||
CopyStream.prototype._read = function(size) { | ||
if(this._reading) return; | ||
this._reading = true; | ||
//console.log('read begin'); | ||
CopyStream.prototype._read = function (size) { | ||
if (this._reading) return | ||
this._reading = true | ||
// console.log('read begin'); | ||
var self = this | ||
this._consumeBuffer(function(err, buffer) { | ||
self._reading = false; | ||
if(err) { | ||
this._consumeBuffer(function (err, buffer) { | ||
self._reading = false | ||
if (err) { | ||
return self.emit('error', err) | ||
} | ||
if(buffer === false) { | ||
//nothing to read for now, return | ||
return; | ||
if (buffer === false) { | ||
// nothing to read for now, return | ||
return | ||
} | ||
self.push(buffer); | ||
}); | ||
}; | ||
self.push(buffer) | ||
}) | ||
} | ||
var consumeResults = function(pq, cb) { | ||
var consumeResults = function (pq, cb) { | ||
var cleanup = function () { | ||
pq.removeListener('readable', onReadable) | ||
pq.stopReader() | ||
} | ||
var cleanup = function() { | ||
pq.removeListener('readable', onReadable); | ||
pq.stopReader(); | ||
var readError = function (message) { | ||
cleanup() | ||
return cb(new Error(message || pq.errorMessage())) | ||
} | ||
var readError = function(message) { | ||
cleanup(); | ||
return cb(new Error(message || pq.errorMessage())); | ||
}; | ||
var onReadable = function() { | ||
//read waiting data from the socket | ||
//e.g. clear the pending 'select' | ||
if(!pq.consumeInput()) { | ||
return readError(); | ||
var onReadable = function () { | ||
// read waiting data from the socket | ||
// e.g. clear the pending 'select' | ||
if (!pq.consumeInput()) { | ||
return readError() | ||
} | ||
//check if there is still outstanding data | ||
//if so, wait for it all to come in | ||
if(pq.isBusy()) { | ||
return; | ||
// check if there is still outstanding data | ||
// if so, wait for it all to come in | ||
if (pq.isBusy()) { | ||
return | ||
} | ||
//load our result object | ||
pq.getResult(); | ||
// load our result object | ||
pq.getResult() | ||
//"read until results return null" | ||
//or in our case ensure we only have one result | ||
if(pq.getResult() && pq.resultStatus() != 'PGRES_COPY_OUT') { | ||
return readError('Only one result at a time is accepted'); | ||
// "read until results return null" | ||
// or in our case ensure we only have one result | ||
if (pq.getResult() && pq.resultStatus() !== 'PGRES_COPY_OUT') { | ||
return readError('Only one result at a time is accepted') | ||
} | ||
if(pq.resultStatus() == 'PGRES_FATAL_ERROR') { | ||
return readError(); | ||
if (pq.resultStatus() === 'PGRES_FATAL_ERROR') { | ||
return readError() | ||
} | ||
cleanup(); | ||
return cb(null); | ||
}; | ||
pq.on('readable', onReadable); | ||
pq.startReader(); | ||
}; | ||
cleanup() | ||
return cb(null) | ||
} | ||
pq.on('readable', onReadable) | ||
pq.startReader() | ||
} |
{ | ||
"name": "pg-native", | ||
"version": "1.10.1", | ||
"version": "2.0.0", | ||
"description": "A slightly nicer interface to Postgres over node-libpq", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
"test": "mocha && eslint ." | ||
}, | ||
@@ -30,7 +30,13 @@ "repository": { | ||
"devDependencies": { | ||
"generic-pool": "^2.1.1", | ||
"async": "^0.9.0", | ||
"concat-stream": "^1.4.6", | ||
"eslint": "4.2.0", | ||
"eslint-config-standard": "10.2.1", | ||
"eslint-plugin-import": "2.7.0", | ||
"eslint-plugin-node": "5.1.0", | ||
"eslint-plugin-promise": "3.5.0", | ||
"eslint-plugin-standard": "3.0.1", | ||
"generic-pool": "^2.1.1", | ||
"lodash": "^2.4.1", | ||
"mocha": "^1.21.4", | ||
"mocha": "3.4.2", | ||
"okay": "^0.3.0", | ||
@@ -37,0 +43,0 @@ "pg": "*", |
@@ -1,2 +0,2 @@ | ||
#node-pg-native | ||
# node-pg-native | ||
@@ -3,0 +3,0 @@ [![Build Status](https://travis-ci.org/brianc/node-pg-native.svg?branch=master)](https://travis-ci.org/brianc/node-pg-native) |
@@ -1,25 +0,25 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
describe('client with arrayMode', function() { | ||
it('returns result as array', function(done) { | ||
var client = new Client({arrayMode: true}); | ||
client.connectSync(); | ||
client.querySync('CREATE TEMP TABLE blah(name TEXT)'); | ||
describe('client with arrayMode', function () { | ||
it('returns result as array', function (done) { | ||
var client = new Client({arrayMode: true}) | ||
client.connectSync() | ||
client.querySync('CREATE TEMP TABLE blah(name TEXT)') | ||
client.querySync('INSERT INTO blah (name) VALUES ($1)', ['brian']) | ||
client.querySync('INSERT INTO blah (name) VALUES ($1)', ['aaron']) | ||
var rows = client.querySync("SELECT * FROM blah"); | ||
assert.equal(rows.length, 2); | ||
var rows = client.querySync('SELECT * FROM blah') | ||
assert.equal(rows.length, 2) | ||
var row = rows[0] | ||
assert.equal(row.length, 1); | ||
assert.equal(row[0], 'brian'); | ||
assert.equal(rows[1][0], 'aaron'); | ||
assert.equal(row.length, 1) | ||
assert.equal(row[0], 'brian') | ||
assert.equal(rows[1][0], 'aaron') | ||
client.query("SELECT 'brian', null", function(err, res) { | ||
assert.ifError(err); | ||
client.query("SELECT 'brian', null", function (err, res) { | ||
assert.ifError(err) | ||
assert.strictEqual(res[0][0], 'brian') | ||
assert.strictEqual(res[0][1], null) | ||
client.end(done); | ||
}); | ||
}); | ||
}); | ||
client.end(done) | ||
}) | ||
}) | ||
}) |
@@ -1,62 +0,61 @@ | ||
var Client = require('../'); | ||
var ok = require('okay'); | ||
var assert = require('assert'); | ||
var concat = require('concat-stream'); | ||
var Client = require('../') | ||
var ok = require('okay') | ||
var assert = require('assert') | ||
var concat = require('concat-stream') | ||
describe('async workflow', function() { | ||
before(function(done) { | ||
this.client = new Client(); | ||
this.client.connect(done); | ||
}); | ||
describe('async workflow', function () { | ||
before(function (done) { | ||
this.client = new Client() | ||
this.client.connect(done) | ||
}) | ||
var echoParams = function(params, cb) { | ||
this.client.query('SELECT $1::text as first, $2::text as second', params, ok(cb, function(rows) { | ||
checkParams(params, rows); | ||
cb(null, rows); | ||
})); | ||
}; | ||
var echoParams = function (params, cb) { | ||
this.client.query('SELECT $1::text as first, $2::text as second', params, ok(cb, function (rows) { | ||
checkParams(params, rows) | ||
cb(null, rows) | ||
})) | ||
} | ||
var checkParams = function(params, rows) { | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].first, params[0]); | ||
assert.equal(rows[0].second, params[1]); | ||
}; | ||
var checkParams = function (params, rows) { | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].first, params[0]) | ||
assert.equal(rows[0].second, params[1]) | ||
} | ||
it('sends async query', function(done) { | ||
it('sends async query', function (done) { | ||
var params = ['one', 'two'] | ||
echoParams.call(this, params, done); | ||
}); | ||
echoParams.call(this, params, done) | ||
}) | ||
it('sends multiple async queries', function(done) { | ||
var self = this; | ||
var params = ['bang', 'boom']; | ||
echoParams.call(this, params, ok(done, function(rows) { | ||
echoParams.call(self, params, done); | ||
})); | ||
}); | ||
it('sends multiple async queries', function (done) { | ||
var self = this | ||
var params = ['bang', 'boom'] | ||
echoParams.call(this, params, ok(done, function (rows) { | ||
echoParams.call(self, params, done) | ||
})) | ||
}) | ||
it('sends an async query, copies in, copies out, and sends another query', function(done) { | ||
var self = this; | ||
this.client.querySync('CREATE TEMP TABLE test(name text, age int)'); | ||
this.client.query("INSERT INTO test(name, age) VALUES('brian', 32)", ok(done, function() { | ||
self.client.querySync('COPY test FROM stdin'); | ||
console.log('got stream') | ||
var input = self.client.getCopyStream(); | ||
input.write(Buffer('Aaron\t30\n', 'utf8')) | ||
input.end(function() { | ||
self.client.query('SELECT COUNT(*) FROM test', ok(done, function(rows) { | ||
it('sends an async query, copies in, copies out, and sends another query', function (done) { | ||
var self = this | ||
this.client.querySync('CREATE TEMP TABLE test(name text, age int)') | ||
this.client.query("INSERT INTO test(name, age) VALUES('brian', 32)", ok(done, function () { | ||
self.client.querySync('COPY test FROM stdin') | ||
var input = self.client.getCopyStream() | ||
input.write(Buffer.from('Aaron\t30\n', 'utf8')) | ||
input.end(function () { | ||
self.client.query('SELECT COUNT(*) FROM test', ok(done, function (rows) { | ||
assert.equal(rows.length, 1) | ||
self.client.query('COPY test TO stdout', ok(done, function() { | ||
var output = self.client.getCopyStream(); | ||
self.client.query('COPY test TO stdout', ok(done, function () { | ||
var output = self.client.getCopyStream() | ||
//pump the stream | ||
output.read(); | ||
output.pipe(concat(function(err, res) { | ||
done(); | ||
})); | ||
})); | ||
})); | ||
}); | ||
})); | ||
}); | ||
}); | ||
// pump the stream | ||
output.read() | ||
output.pipe(concat(function (res) { | ||
done() | ||
})) | ||
})) | ||
})) | ||
}) | ||
})) | ||
}) | ||
}) |
@@ -1,32 +0,32 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var ok = require('okay'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
describe('cancel query', function() { | ||
it('works', function(done) { | ||
var client = new Client(); | ||
client.connectSync(); | ||
client.query('SELECT pg_sleep(100);', function(err) { | ||
done(); | ||
}); | ||
client.cancel(function(err) { | ||
assert.ifError(err); | ||
}); | ||
}); | ||
describe('cancel query', function () { | ||
it('works', function (done) { | ||
var client = new Client() | ||
client.connectSync() | ||
client.query('SELECT pg_sleep(100);', function (err) { | ||
assert(err instanceof Error) | ||
client.end(done) | ||
}) | ||
client.cancel(function (err) { | ||
assert.ifError(err) | ||
}) | ||
}) | ||
it('does not raise error if no active query', function(done) { | ||
var client = new Client(); | ||
client.connectSync(); | ||
client.cancel(function(err) { | ||
assert.ifError(err); | ||
done(); | ||
}); | ||
}); | ||
it('does not raise error if no active query', function (done) { | ||
var client = new Client() | ||
client.connectSync() | ||
client.cancel(function (err) { | ||
assert.ifError(err) | ||
done() | ||
}) | ||
}) | ||
it('raises error if client is not connected', function(done) { | ||
new Client().cancel(function(err) { | ||
assert(err, 'should raise an error when not connected'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('raises error if client is not connected', function (done) { | ||
new Client().cancel(function (err) { | ||
assert(err, 'should raise an error when not connected') | ||
done() | ||
}) | ||
}) | ||
}) |
@@ -1,25 +0,25 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
describe('connection error', function() { | ||
it('doesnt segfault', function(done) { | ||
var client = new Client(); | ||
client.connect('asldgsdgasgdasdg', function(err) { | ||
assert(err); | ||
//calling error on a closed client was segfaulting | ||
client.end(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('connection error', function () { | ||
it('doesnt segfault', function (done) { | ||
var client = new Client() | ||
client.connect('asldgsdgasgdasdg', function (err) { | ||
assert(err) | ||
// calling error on a closed client was segfaulting | ||
client.end() | ||
done() | ||
}) | ||
}) | ||
}) | ||
describe('reading while not connected', function() { | ||
it('does not seg fault but does throw execption', function() { | ||
var client = new Client(); | ||
assert.throws(function() { | ||
client.on('notification', function(msg) { | ||
describe('reading while not connected', function () { | ||
it('does not seg fault but does throw execption', function () { | ||
var client = new Client() | ||
assert.throws(function () { | ||
client.on('notification', function (msg) { | ||
}); | ||
}) | ||
}) | ||
}); | ||
}); | ||
}) | ||
}) |
@@ -1,47 +0,47 @@ | ||
var assert = require('assert'); | ||
var Client = require('../'); | ||
var assert = require('assert') | ||
var Client = require('../') | ||
describe('COPY FROM', function() { | ||
before(function(done) { | ||
describe('COPY FROM', function () { | ||
before(function (done) { | ||
this.client = Client() | ||
this.client.connect(done); | ||
}); | ||
this.client.connect(done) | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('works', function(done) { | ||
var client = this.client; | ||
this.client.querySync('CREATE TEMP TABLE blah(name text, age int)'); | ||
this.client.querySync('COPY blah FROM stdin'); | ||
var stream = this.client.getCopyStream(); | ||
stream.write(Buffer('Brian\t32\n', 'utf8')); | ||
stream.write(Buffer('Aaron\t30\n', 'utf8')); | ||
stream.write(Buffer('Shelley\t28\n', 'utf8')); | ||
stream.end(); | ||
it('works', function (done) { | ||
var client = this.client | ||
this.client.querySync('CREATE TEMP TABLE blah(name text, age int)') | ||
this.client.querySync('COPY blah FROM stdin') | ||
var stream = this.client.getCopyStream() | ||
stream.write(Buffer.from('Brian\t32\n', 'utf8')) | ||
stream.write(Buffer.from('Aaron\t30\n', 'utf8')) | ||
stream.write(Buffer.from('Shelley\t28\n', 'utf8')) | ||
stream.end() | ||
stream.once('finish', function() { | ||
var rows = client.querySync('SELECT COUNT(*) FROM blah'); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].count, 3); | ||
done(); | ||
}); | ||
}); | ||
stream.once('finish', function () { | ||
var rows = client.querySync('SELECT COUNT(*) FROM blah') | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].count, 3) | ||
done() | ||
}) | ||
}) | ||
it('works with a callback passed to end', function(done) { | ||
var client = this.client; | ||
this.client.querySync('CREATE TEMP TABLE boom(name text, age int)'); | ||
this.client.querySync('COPY boom FROM stdin'); | ||
var stream = this.client.getCopyStream(); | ||
stream.write(Buffer('Brian\t32\n', 'utf8')); | ||
stream.write(Buffer('Aaron\t30\n', 'utf8'), function() { | ||
stream.end(Buffer('Shelley\t28\n', 'utf8'), function() { | ||
it('works with a callback passed to end', function (done) { | ||
var client = this.client | ||
this.client.querySync('CREATE TEMP TABLE boom(name text, age int)') | ||
this.client.querySync('COPY boom FROM stdin') | ||
var stream = this.client.getCopyStream() | ||
stream.write(Buffer.from('Brian\t32\n', 'utf8')) | ||
stream.write(Buffer.from('Aaron\t30\n', 'utf8'), function () { | ||
stream.end(Buffer.from('Shelley\t28\n', 'utf8'), function () { | ||
var rows = client.querySync('SELECT COUNT(*) FROM boom') | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].count, 3); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].count, 3) | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) |
@@ -1,33 +0,33 @@ | ||
var assert = require('assert'); | ||
var Client = require('../'); | ||
var assert = require('assert') | ||
var Client = require('../') | ||
var concat = require('concat-stream') | ||
var _ = require('lodash') | ||
describe('COPY TO', function() { | ||
before(function(done) { | ||
describe('COPY TO', function () { | ||
before(function (done) { | ||
this.client = Client() | ||
this.client.connect(done); | ||
}); | ||
this.client.connect(done) | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('works - basic check', function(done) { | ||
it('works - basic check', function (done) { | ||
var limit = 1000 | ||
var qText = 'COPY (SELECT * FROM generate_series(0, ' + (limit - 1) + ')) TO stdout' | ||
var self = this | ||
this.client.query(qText, function(err) { | ||
if(err) return done(err); | ||
var stream = self.client.getCopyStream(); | ||
//pump the stream for node v0.11.x | ||
stream.read(); | ||
stream.pipe(concat(function(buff) { | ||
this.client.query(qText, function (err) { | ||
if (err) return done(err) | ||
var stream = self.client.getCopyStream() | ||
// pump the stream for node v0.11.x | ||
stream.read() | ||
stream.pipe(concat(function (buff) { | ||
var res = buff.toString('utf8') | ||
var expected = _.range(0, limit).join('\n') + '\n' | ||
assert.equal(res, expected) | ||
done(); | ||
})); | ||
}); | ||
}); | ||
}); | ||
done() | ||
})) | ||
}) | ||
}) | ||
}) |
@@ -1,32 +0,24 @@ | ||
var Client = require('../'); | ||
var ok = require('okay'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var ok = require('okay') | ||
var assert = require('assert') | ||
var types = { | ||
getTypeParser: function(oid) { | ||
return function(text) { | ||
return "blah"; | ||
}; | ||
} | ||
}; | ||
describe('Custom type parser', function() { | ||
it('is used by client', function(done) { | ||
describe('Custom type parser', function () { | ||
it('is used by client', function (done) { | ||
var client = new Client({ | ||
types: { | ||
getTypeParser: function() { | ||
return function() { | ||
return 'blah'; | ||
getTypeParser: function () { | ||
return function () { | ||
return 'blah' | ||
} | ||
} | ||
} | ||
}); | ||
client.connectSync(); | ||
var rows = client.querySync('SELECT NOW() AS when'); | ||
assert.equal(rows[0].when, 'blah'); | ||
client.query('SELECT NOW() as when', ok(function(rows) { | ||
assert.equal(rows[0].when, 'blah'); | ||
client.end(done); | ||
})); | ||
}); | ||
}); | ||
}) | ||
client.connectSync() | ||
var rows = client.querySync('SELECT NOW() AS when') | ||
assert.equal(rows[0].when, 'blah') | ||
client.query('SELECT NOW() as when', ok(function (rows) { | ||
assert.equal(rows[0].when, 'blah') | ||
client.end(done) | ||
})) | ||
}) | ||
}) |
@@ -1,32 +0,32 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
var checkDomain = function(domain, when) { | ||
assert(process.domain, 'Domain was lost after ' + when); | ||
assert.strictEqual(process.domain, domain, 'Domain switched after ' + when); | ||
var checkDomain = function (domain, when) { | ||
assert(process.domain, 'Domain was lost after ' + when) | ||
assert.strictEqual(process.domain, domain, 'Domain switched after ' + when) | ||
} | ||
describe('domains', function(done) { | ||
it('remains bound after a query', function(done) { | ||
var domain = require('domain').create(); | ||
domain.run(function() { | ||
var client = new Client(); | ||
client.connect((function() { | ||
checkDomain(domain, 'connection'); | ||
client.query('SELECT NOW()', (function() { | ||
checkDomain(domain, 'query'); | ||
client.prepare('testing', 'SELECT NOW()', 0, (function() { | ||
checkDomain(domain, 'prepare'); | ||
client.execute('testing', [], (function() { | ||
checkDomain(domain, 'execute'); | ||
client.end(function() { | ||
checkDomain(domain, 'end'); | ||
done(); | ||
}); | ||
})); | ||
})); | ||
})); | ||
})); | ||
}); | ||
}); | ||
}); | ||
describe('domains', function (done) { | ||
it('remains bound after a query', function (done) { | ||
var domain = require('domain').create() // eslint-disable-line | ||
domain.run(function () { | ||
var client = new Client() | ||
client.connect(function () { | ||
checkDomain(domain, 'connection') | ||
client.query('SELECT NOW()', function () { | ||
checkDomain(domain, 'query') | ||
client.prepare('testing', 'SELECT NOW()', 0, function () { | ||
checkDomain(domain, 'prepare') | ||
client.execute('testing', [], function () { | ||
checkDomain(domain, 'execute') | ||
client.end(function () { | ||
checkDomain(domain, 'end') | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
var Client = require('../') | ||
var assert = require('assert') | ||
var async = require('async') | ||
describe('huge async query', function() { | ||
before(function(done) { | ||
this.client = Client(); | ||
this.client.connect(done); | ||
}); | ||
describe('huge async query', function () { | ||
before(function (done) { | ||
this.client = Client() | ||
this.client.connect(done) | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('works', function(done) { | ||
var params = ['']; | ||
var len = 100000; | ||
for(var i = 0; i < len; i++) { | ||
params[0] += 'A'; | ||
it('works', function (done) { | ||
var params = [''] | ||
var len = 100000 | ||
for (var i = 0; i < len; i++) { | ||
params[0] += 'A' | ||
} | ||
var qText = "SELECT '" + params[0] + "'::text as my_text"; | ||
var start = Date.now(); | ||
this.client.query(qText, function(err, rows) { | ||
if(err) return done(err); | ||
assert.equal(rows[0].my_text.length, len); | ||
done(); | ||
}); | ||
var end = Date.now(); | ||
}); | ||
}); | ||
var qText = "SELECT '" + params[0] + "'::text as my_text" | ||
this.client.query(qText, function (err, rows) { | ||
if (err) return done(err) | ||
assert.equal(rows[0].my_text.length, len) | ||
done() | ||
}) | ||
}) | ||
}) |
var Client = require('../') | ||
var assert = require('assert') | ||
describe('connection', function() { | ||
it('works', function(done) { | ||
Client().connect(done); | ||
}); | ||
describe('connection', function () { | ||
it('works', function (done) { | ||
Client().connect(done) | ||
}) | ||
it('connects with args', function(done) { | ||
Client().connect('host=localhost', done); | ||
}); | ||
it('connects with args', function (done) { | ||
Client().connect('host=localhost', done) | ||
}) | ||
it('errors out with bad connection args', function(done) { | ||
Client().connect('host=asldkfjasdf', function(err) { | ||
assert(err, 'should raise an error for bad host'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors out with bad connection args', function (done) { | ||
Client().connect('host=asldkfjasdf', function (err) { | ||
assert(err, 'should raise an error for bad host') | ||
done() | ||
}) | ||
}) | ||
}) | ||
describe('connectSync', function() { | ||
it('works without args', function() { | ||
Client().connectSync(); | ||
}); | ||
describe('connectSync', function () { | ||
it('works without args', function () { | ||
Client().connectSync() | ||
}) | ||
it('works with args', function() { | ||
it('works with args', function () { | ||
var args = 'host=' + (process.env.PGHOST || 'localhost') | ||
Client().connectSync(args); | ||
}); | ||
Client().connectSync(args) | ||
}) | ||
it('throws if bad host', function() { | ||
assert.throws(function() { | ||
Client().connectSync('host=laksdjfdsf'); | ||
}); | ||
}); | ||
}); | ||
it('throws if bad host', function () { | ||
assert.throws(function () { | ||
Client().connectSync('host=laksdjfdsf') | ||
}) | ||
}) | ||
}) |
@@ -1,26 +0,26 @@ | ||
var Client = require('../'); | ||
var async = require('async'); | ||
var ok = require('okay'); | ||
var Client = require('../') | ||
var async = require('async') | ||
var ok = require('okay') | ||
var execute = function(x, done) { | ||
var client = new Client(); | ||
var execute = function (x, done) { | ||
var client = new Client() | ||
client.connectSync() | ||
var query = function(n, cb) { | ||
client.query('SELECT $1::int as num', [n], function(err) { | ||
var query = function (n, cb) { | ||
client.query('SELECT $1::int as num', [n], function (err) { | ||
cb(err) | ||
}); | ||
}; | ||
return async.timesSeries(5, query, ok(done, function() { | ||
client.end(); | ||
}) | ||
} | ||
return async.timesSeries(5, query, ok(done, function () { | ||
client.end() | ||
done() | ||
})); | ||
})) | ||
} | ||
describe('Load tests', function() { | ||
it('single client and many queries', function(done) { | ||
async.times(1, execute, done); | ||
}); | ||
describe('Load tests', function () { | ||
it('single client and many queries', function (done) { | ||
async.times(1, execute, done) | ||
}) | ||
it('multiple client and many queries', function(done) { | ||
async.times(20, execute, done); | ||
}); | ||
}); | ||
it('multiple client and many queries', function (done) { | ||
async.times(20, execute, done) | ||
}) | ||
}) |
@@ -1,50 +0,48 @@ | ||
var Client = require('../'); | ||
var async = require('async'); | ||
var ok = require('okay'); | ||
var Client = require('../') | ||
var async = require('async') | ||
var ok = require('okay') | ||
var bytes = require('crypto').pseudoRandomBytes | ||
describe('many connections', function() { | ||
describe('many connections', function () { | ||
describe('async', function () { | ||
var test = function (count, times) { | ||
it('connecting ' + count + ' clients ' + times, function (done) { | ||
this.timeout(200000) | ||
describe('async', function() { | ||
var test = function(count, times) { | ||
it('connecting ' + count + ' clients ' + times, function(done) { | ||
this.timeout(200000); | ||
var connectClient = function(n, cb) { | ||
var client = new Client(); | ||
client.connect(ok(cb, function() { | ||
bytes(1000, ok(cb, function(chunk) { | ||
client.query('SELECT $1::text as txt', [chunk.toString('base64')], ok(cb, function(rows) { | ||
client.end(cb); | ||
})); | ||
})); | ||
})); | ||
var connectClient = function (n, cb) { | ||
var client = new Client() | ||
client.connect(ok(cb, function () { | ||
bytes(1000, ok(cb, function (chunk) { | ||
client.query('SELECT $1::text as txt', [chunk.toString('base64')], ok(cb, function (rows) { | ||
client.end(cb) | ||
})) | ||
})) | ||
})) | ||
} | ||
var run = function(n, cb) { | ||
async.times(count, connectClient, cb); | ||
var run = function (n, cb) { | ||
async.times(count, connectClient, cb) | ||
} | ||
async.timesSeries(times, run, done); | ||
async.timesSeries(times, run, done) | ||
}) | ||
} | ||
}); | ||
}; | ||
test(1, 1); | ||
test(1, 1); | ||
test(1, 1); | ||
test(5, 5); | ||
test(5, 5); | ||
test(5, 5); | ||
test(5, 5); | ||
test(10, 10); | ||
test(10, 10); | ||
test(10, 10); | ||
test(20, 20); | ||
test(20, 20); | ||
test(20, 20); | ||
test(30, 10); | ||
test(30, 10); | ||
test(30, 10); | ||
}); | ||
}); | ||
test(1, 1) | ||
test(1, 1) | ||
test(1, 1) | ||
test(5, 5) | ||
test(5, 5) | ||
test(5, 5) | ||
test(5, 5) | ||
test(10, 10) | ||
test(10, 10) | ||
test(10, 10) | ||
test(20, 20) | ||
test(20, 20) | ||
test(20, 20) | ||
test(30, 10) | ||
test(30, 10) | ||
test(30, 10) | ||
}) | ||
}) |
@@ -1,29 +0,26 @@ | ||
var Client = require('../'); | ||
var async = require('async'); | ||
var ok = require('okay'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var async = require('async') | ||
var assert = require('assert') | ||
describe('many errors', function() { | ||
it('functions properly without segfault', function(done) { | ||
var throwError = function(n, cb) { | ||
describe('many errors', function () { | ||
it('functions properly without segfault', function (done) { | ||
var throwError = function (n, cb) { | ||
var client = new Client() | ||
client.connectSync() | ||
var doIt = function(n, cb) { | ||
client.query('select asdfiasdf', function(err) { | ||
assert(err, 'bad query should emit an error'); | ||
cb(null); | ||
}); | ||
}; | ||
var doIt = function (n, cb) { | ||
client.query('select asdfiasdf', function (err) { | ||
assert(err, 'bad query should emit an error') | ||
cb(null) | ||
}) | ||
} | ||
async.timesSeries(10, doIt, function(err) { | ||
if(err) return cb(err); | ||
client.end(cb); | ||
}); | ||
}; | ||
async.timesSeries(10, doIt, function (err) { | ||
if (err) return cb(err) | ||
client.end(cb) | ||
}) | ||
} | ||
async.times(10, throwError, done); | ||
}); | ||
}); | ||
async.times(10, throwError, done) | ||
}) | ||
}) |
@@ -1,6 +0,6 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
describe('multiple commands in a single query', function() { | ||
before(function(done) { | ||
describe('multiple commands in a single query', function () { | ||
before(function (done) { | ||
this.client = new Client() | ||
@@ -10,27 +10,33 @@ this.client.connect(done) | ||
after(function(done) { | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('all execute to completion', function(done) { | ||
this.client.query("SELECT '10'::int as num; SELECT 'brian'::text as name", function(err, rows) { | ||
assert.ifError(err); | ||
assert.equal(rows.length, 2, 'should return two rows'); | ||
assert.equal(rows[0].num, '10'); | ||
assert.equal(rows[1].name, 'brian'); | ||
done(); | ||
}); | ||
}); | ||
it('all execute to completion', function (done) { | ||
this.client.query("SELECT '10'::int as num; SELECT 'brian'::text as name", function (err, rows) { | ||
assert.ifError(err) | ||
assert.equal(rows.length, 2, 'should return two sets rows') | ||
assert.equal(rows[0][0].num, '10') | ||
assert.equal(rows[1][0].name, 'brian') | ||
done() | ||
}) | ||
}) | ||
it('inserts and reads at once', function(done) { | ||
var txt = 'CREATE TEMP TABLE boom(age int);'; | ||
txt += 'INSERT INTO boom(age) VALUES(10);'; | ||
txt += 'SELECT * FROM boom;'; | ||
this.client.query(txt, function(err, rows) { | ||
assert.ifError(err); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].age, 10); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('inserts and reads at once', function (done) { | ||
var txt = 'CREATE TEMP TABLE boom(age int);' | ||
txt += 'INSERT INTO boom(age) VALUES(10);' | ||
txt += 'SELECT * FROM boom;' | ||
this.client.query(txt, function (err, rows, results) { | ||
assert.ifError(err) | ||
assert.equal(rows.length, 3) | ||
assert.equal(rows[0].length, 0) | ||
assert.equal(rows[1].length, 0) | ||
assert.equal(rows[2][0].age, 10) | ||
assert.equal(results[0].command, 'CREATE') | ||
assert.equal(results[1].command, 'INSERT') | ||
assert.equal(results[2].command, 'SELECT') | ||
done() | ||
}) | ||
}) | ||
}) |
var Client = require('../') | ||
var ok = require('okay') | ||
var notify = function(channel, payload) { | ||
var client = new Client(); | ||
client.connectSync(); | ||
client.querySync("NOTIFY " + channel + ", '" + payload + "'"); | ||
client.end(); | ||
}; | ||
var notify = function (channel, payload) { | ||
var client = new Client() | ||
client.connectSync() | ||
client.querySync('NOTIFY ' + channel + ", '" + payload + "'") | ||
client.end() | ||
} | ||
describe('simple LISTEN/NOTIFY', function() { | ||
before(function(done) { | ||
var client = this.client = new Client(); | ||
client.connect(done); | ||
}); | ||
describe('simple LISTEN/NOTIFY', function () { | ||
before(function (done) { | ||
var client = this.client = new Client() | ||
client.connect(done) | ||
}) | ||
it('works', function(done) { | ||
var client = this.client; | ||
client.querySync('LISTEN boom'); | ||
client.on('notification', function(msg) { | ||
done(); | ||
}); | ||
it('works', function (done) { | ||
var client = this.client | ||
client.querySync('LISTEN boom') | ||
client.on('notification', function (msg) { | ||
done() | ||
}) | ||
notify('boom', 'sup') | ||
}); | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
}) | ||
describe('async LISTEN/NOTIFY', function() { | ||
before(function(done) { | ||
var client = this.client = new Client(); | ||
client.connect(done); | ||
}); | ||
if (!process.env.TRAVIS_CI) { | ||
describe('async LISTEN/NOTIFY', function () { | ||
before(function (done) { | ||
var client = this.client = new Client() | ||
client.connect(done) | ||
}) | ||
it('works', function(done) { | ||
var client = this.client; | ||
var count = 0; | ||
var check = function() { | ||
count++; | ||
if(count >= 3) return done(); | ||
} | ||
client.on('notification', check); | ||
client.query('LISTEN test', ok(done, function() { | ||
notify('test', 'bot'); | ||
client.query('SELECT pg_sleep(.05)', ok(done, function() { | ||
check(); | ||
})); | ||
notify('test', 'bot'); | ||
})); | ||
}); | ||
it('works', function (done) { | ||
var client = this.client | ||
var count = 0 | ||
var check = function () { | ||
count++ | ||
if (count >= 2) return done() | ||
} | ||
client.on('notification', check) | ||
client.query('LISTEN test', ok(done, function () { | ||
notify('test', 'bot') | ||
client.query('SELECT pg_sleep(.05)', ok(done, function () { | ||
check() | ||
})) | ||
notify('test', 'bot') | ||
})) | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
}) | ||
} |
@@ -1,57 +0,56 @@ | ||
var Client = require('../'); | ||
var ok = require('okay'); | ||
var async = require('async'); | ||
var Client = require('../') | ||
var ok = require('okay') | ||
var async = require('async') | ||
describe('async prepare', function() { | ||
var run = function(n, cb) { | ||
var client = new Client(); | ||
client.connectSync(); | ||
describe('async prepare', function () { | ||
var run = function (n, cb) { | ||
var client = new Client() | ||
client.connectSync() | ||
var exec = function(x, done) { | ||
var exec = function (x, done) { | ||
client.prepare('get_now' + x, 'SELECT NOW()', 0, done) | ||
}; | ||
} | ||
async.timesSeries(10, exec, ok(cb, function() { | ||
client.end(cb); | ||
})); | ||
}; | ||
async.timesSeries(10, exec, ok(cb, function () { | ||
client.end(cb) | ||
})) | ||
} | ||
var t = function(n) { | ||
it('works for ' + n + ' clients', function(done) { | ||
async.times(n, run, function(err) { | ||
done(err); | ||
}); | ||
}); | ||
}; | ||
var t = function (n) { | ||
it('works for ' + n + ' clients', function (done) { | ||
async.times(n, run, function (err) { | ||
done(err) | ||
}) | ||
}) | ||
} | ||
for(var i = 0; i < 10; i++) { | ||
t(i); | ||
for (var i = 0; i < 10; i++) { | ||
t(i) | ||
} | ||
}); | ||
}) | ||
describe('async execute', function() { | ||
var run = function(n, cb) { | ||
var client = new Client(); | ||
client.connectSync(); | ||
client.prepareSync('get_now', 'SELECT NOW()', 0); | ||
var exec = function(x, cb) { | ||
client.execute('get_now', [], cb); | ||
}; | ||
async.timesSeries(10, exec, ok(cb, function() { | ||
client.end(cb); | ||
})); | ||
}; | ||
describe('async execute', function () { | ||
var run = function (n, cb) { | ||
var client = new Client() | ||
client.connectSync() | ||
client.prepareSync('get_now', 'SELECT NOW()', 0) | ||
var exec = function (x, cb) { | ||
client.execute('get_now', [], cb) | ||
} | ||
async.timesSeries(10, exec, ok(cb, function () { | ||
client.end(cb) | ||
})) | ||
} | ||
var t = function (n) { | ||
it('works for ' + n + ' clients', function (done) { | ||
async.times(n, run, function (err) { | ||
done(err) | ||
}) | ||
}) | ||
} | ||
var t = function(n) { | ||
it('works for ' + n + ' clients', function(done) { | ||
async.times(n, run, function(err) { | ||
done(err); | ||
}); | ||
}); | ||
}; | ||
for(var i = 0; i < 10; i++) { | ||
t(i); | ||
for (var i = 0; i < 10; i++) { | ||
t(i) | ||
} | ||
}); | ||
}) |
@@ -1,89 +0,103 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var async = require('async'); | ||
var ok = require('okay'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
var async = require('async') | ||
var ok = require('okay') | ||
describe('async query', function() { | ||
before(function(done) { | ||
this.client = Client(); | ||
this.client.connect(function(err) { | ||
if(err) return done(err); | ||
return done(); | ||
}); | ||
}); | ||
describe('async query', function () { | ||
before(function (done) { | ||
this.client = Client() | ||
this.client.connect(done) | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('simple query works', function(done) { | ||
var runQuery = function(n, done) { | ||
this.client.query('SELECT NOW() AS the_time', function(err, rows) { | ||
if(err) return done(err); | ||
assert.equal(rows[0].the_time.getFullYear(), new Date().getFullYear()); | ||
return done(); | ||
}); | ||
}.bind(this); | ||
it('can execute many prepared statements on a client', function (done) { | ||
async.timesSeries(20, (i, cb) => { | ||
this.client.query('SELECT $1::text as name', ['brianc'], cb) | ||
}, done) | ||
}) | ||
it('simple query works', function (done) { | ||
var runQuery = function (n, done) { | ||
this.client.query('SELECT NOW() AS the_time', function (err, rows) { | ||
if (err) return done(err) | ||
assert.equal(rows[0].the_time.getFullYear(), new Date().getFullYear()) | ||
return done() | ||
}) | ||
}.bind(this) | ||
async.timesSeries(3, runQuery, done) | ||
}); | ||
}) | ||
it('parameters work', function(done) { | ||
var runQuery = function(n, done) { | ||
this.client.query('SELECT $1::text AS name', ['Brian'], done); | ||
}.bind(this); | ||
it('parameters work', function (done) { | ||
var runQuery = function (n, done) { | ||
this.client.query('SELECT $1::text AS name', ['Brian'], done) | ||
}.bind(this) | ||
async.timesSeries(3, runQuery, done) | ||
}); | ||
}) | ||
it('prepared, named statements work', function(done) { | ||
var client = this.client; | ||
client.prepare('test', 'SELECT $1::text as name', 1, function(err) { | ||
if(err) return done(err); | ||
client.execute('test', ['Brian'], ok(done, function(rows) { | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].name, 'Brian'); | ||
client.execute('test', ['Aaron'], ok(done, function(rows) { | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].name, 'Aaron'); | ||
done(); | ||
})); | ||
})); | ||
}); | ||
}); | ||
it('prepared, named statements work', function (done) { | ||
var client = this.client | ||
client.prepare('test', 'SELECT $1::text as name', 1, function (err) { | ||
if (err) return done(err) | ||
client.execute('test', ['Brian'], ok(done, function (rows) { | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].name, 'Brian') | ||
client.execute('test', ['Aaron'], ok(done, function (rows) { | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].name, 'Aaron') | ||
done() | ||
})) | ||
})) | ||
}) | ||
}) | ||
it('returns error if prepare fails', function(done) { | ||
this.client.prepare('test', 'SELECT AWWW YEAH', 0, function(err) { | ||
assert(err, 'Should have returned an error'); | ||
done(); | ||
}); | ||
}); | ||
it('returns error if prepare fails', function (done) { | ||
this.client.prepare('test', 'SELECT AWWW YEAH', 0, function (err) { | ||
assert(err, 'Should have returned an error') | ||
done() | ||
}) | ||
}) | ||
it('returns an error if execute fails', function(done) { | ||
this.client.execute('test', [], function(err) { | ||
assert(err, 'Should have returned an error'); | ||
done(); | ||
}); | ||
}); | ||
it('returns an error if execute fails', function (done) { | ||
this.client.execute('test', [], function (err) { | ||
assert(err, 'Should have returned an error') | ||
done() | ||
}) | ||
}) | ||
it('returns an error if there was a query error', function(done) { | ||
var runErrorQuery = function(n, done) { | ||
this.client.query('SELECT ALKJSFDSLFKJ', function(err) { | ||
assert(err instanceof Error, 'Should return an error instance'); | ||
done(); | ||
}); | ||
}.bind(this); | ||
async.timesSeries(3, runErrorQuery, done); | ||
}); | ||
it('returns an error if there was a query error', function (done) { | ||
var runErrorQuery = function (n, done) { | ||
this.client.query('SELECT ALKJSFDSLFKJ', function (err) { | ||
assert(err instanceof Error, 'Should return an error instance') | ||
done() | ||
}) | ||
}.bind(this) | ||
async.timesSeries(3, runErrorQuery, done) | ||
}) | ||
it('is still usable after an error', function(done) { | ||
this.client.query('SELECT NOW()', done); | ||
}); | ||
it('is still usable after an error', function (done) { | ||
const runErrorQuery = (_, cb) => { | ||
this.client.query('SELECT LKJSDJFLSDKFJ', (err) => { | ||
assert(err instanceof Error, 'Should return an error instance') | ||
cb(null, err) | ||
}) | ||
} | ||
async.timesSeries(3, runErrorQuery, (err, res) => { | ||
assert(!err) | ||
assert.equal(res.length, 3) | ||
this.client.query('SELECT NOW()', done) | ||
}) | ||
}) | ||
it('supports empty query', function(done) { | ||
this.client.query('', function(err, rows) { | ||
assert.ifError(err); | ||
assert(rows, 'should return rows'); | ||
assert.equal(rows.length, 0, 'should return no rows'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('supports empty query', function (done) { | ||
this.client.query('', function (err, rows) { | ||
assert.ifError(err) | ||
assert(Array.isArray(rows)) | ||
console.log('rows', rows) | ||
assert(rows.length === 0) | ||
done() | ||
}) | ||
}) | ||
}) |
var Client = require('../') | ||
var assert = require('assert') | ||
describe('query sync', function(done) { | ||
before(function() { | ||
this.client = Client(); | ||
this.client.connectSync(); | ||
}); | ||
describe('query sync', function (done) { | ||
before(function () { | ||
this.client = Client() | ||
this.client.connectSync() | ||
}) | ||
after(function(done) { | ||
this.client.end(done); | ||
}); | ||
after(function (done) { | ||
this.client.end(done) | ||
}) | ||
it('simple query works', function() { | ||
var rows = this.client.querySync('SELECT NOW() AS the_time'); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].the_time.getFullYear(), new Date().getFullYear()); | ||
}); | ||
it('simple query works', function () { | ||
var rows = this.client.querySync('SELECT NOW() AS the_time') | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].the_time.getFullYear(), new Date().getFullYear()) | ||
}) | ||
it('parameterized query works', function() { | ||
var rows = this.client.querySync('SELECT $1::text AS name', ['Brian']); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].name, 'Brian'); | ||
}); | ||
it('parameterized query works', function () { | ||
var rows = this.client.querySync('SELECT $1::text AS name', ['Brian']) | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].name, 'Brian') | ||
}) | ||
it('prepared statement works', function() { | ||
this.client.prepareSync('test', 'SELECT $1::text as name', 1); | ||
it('prepared statement works', function () { | ||
this.client.prepareSync('test', 'SELECT $1::text as name', 1) | ||
var rows = this.client.executeSync('test', ['Brian']); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].name, 'Brian'); | ||
var rows = this.client.executeSync('test', ['Brian']) | ||
assert.equal(rows.length, 1) | ||
assert.equal(rows[0].name, 'Brian') | ||
var rows = this.client.executeSync('test', ['Aaron']); | ||
assert.equal(rows.length, 1); | ||
assert.equal(rows[0].name, 'Aaron'); | ||
}); | ||
var rows2 = this.client.executeSync('test', ['Aaron']) | ||
assert.equal(rows2.length, 1) | ||
assert.equal(rows2[0].name, 'Aaron') | ||
}) | ||
it('prepare throws exception on error', function() { | ||
assert.throws(function() { | ||
this.client.prepareSync('blah', 'I LIKE TO PARTY!!!', 0); | ||
}.bind(this)); | ||
}); | ||
it('prepare throws exception on error', function () { | ||
assert.throws(function () { | ||
this.client.prepareSync('blah', 'I LIKE TO PARTY!!!', 0) | ||
}.bind(this)) | ||
}) | ||
it('throws exception on executing improperly', function() { | ||
assert.throws(function() { | ||
//wrong number of parameters | ||
this.client.executeSync('test', []); | ||
}); | ||
it('throws exception on executing improperly', function () { | ||
assert.throws(function () { | ||
// wrong number of parameters | ||
this.client.executeSync('test', []) | ||
}) | ||
}) | ||
it('throws exception on error', function() { | ||
assert.throws(function() { | ||
this.client.querySync('SELECT ASLKJASLKJF'); | ||
it('throws exception on error', function () { | ||
assert.throws(function () { | ||
this.client.querySync('SELECT ASLKJASLKJF') | ||
}.bind(this)) | ||
}); | ||
}) | ||
it('is still usable after an error', function() { | ||
var rows = this.client.querySync('SELECT NOW()'); | ||
assert(rows, 'should have returned rows'); | ||
assert.equal(rows.length, 1); | ||
}); | ||
it('is still usable after an error', function () { | ||
var rows = this.client.querySync('SELECT NOW()') | ||
assert(rows, 'should have returned rows') | ||
assert.equal(rows.length, 1) | ||
}) | ||
it('supports empty query', function() { | ||
var rows = this.client.querySync(''); | ||
assert(rows, 'should return rows'); | ||
assert.equal(rows.length, 0, 'should return no rows'); | ||
}); | ||
}); | ||
it('supports empty query', function () { | ||
var rows = this.client.querySync('') | ||
assert(rows, 'should return rows') | ||
assert.equal(rows.length, 0, 'should return no rows') | ||
}) | ||
}) |
@@ -1,11 +0,11 @@ | ||
var Client = require('../'); | ||
var assert = require('assert'); | ||
var semver = require('semver'); | ||
var Client = require('../') | ||
var assert = require('assert') | ||
var semver = require('semver') | ||
describe('version', function() { | ||
it('is exported', function() { | ||
assert(Client.version); | ||
assert.equal(require('../package.json').version, Client.version); | ||
assert(semver.gt(Client.version, '1.4.0')); | ||
}); | ||
}); | ||
describe('version', function () { | ||
it('is exported', function () { | ||
assert(Client.version) | ||
assert.equal(require('../package.json').version, Client.version) | ||
assert(semver.gt(Client.version, '1.4.0')) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
50486
32
1280
14
2
1