From cb647935bb770e09954e9fca5a5815b97d9da6ee Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 18:51:23 -0600 Subject: [PATCH 01/15] slight readability refactor --- lib/client.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/client.js b/lib/client.js index 5f18b638..2a8972b7 100644 --- a/lib/client.js +++ b/lib/client.js @@ -66,10 +66,18 @@ p.connect = function() { con.password(md5password); }); - con.on('readyForQuery', function() { - self.readyForQuery = true; - this.activeQuery = null; - self.pulseQueryQueue(); + con.once('readyForQuery', function() { + //hook up query handling events to connection + //after the connection initially becomes ready for queries + var ready = function() { + self.readyForQuery = true; + this.activeQuery = null; + self.pulseQueryQueue(); + }; + + con.on('readyForQuery', ready); + ready(); + }); con.on('error', function(error) { From 426f30a9620f3a3a3f75f9e3f663c3348218ce85 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 18:51:34 -0600 Subject: [PATCH 02/15] started making listeners non-closure based --- lib/query.js | 96 ++++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/lib/query.js b/lib/query.js index 81645ef6..ed399f42 100644 --- a/lib/query.js +++ b/lib/query.js @@ -12,6 +12,9 @@ var Query = function(config) { //set or used until a rowDescription message comes in this.rowDescription = null; this.callback = config.callback; + this._fieldNames = []; + this._fieldConverters = []; + this._result = new Result(); EventEmitter.call(this); }; @@ -27,41 +30,69 @@ var noParse = function(val) { return val; }; -//creates datarow metatdata from the supplied -//data row information -var buildDataRowMetadata = function(msg, converters, names) { +//associates row metadata from the supplied +//message with this query object +//metadata used when parsing row results +p.handleRowDescription = function(msg) { + this._fieldNames = []; + this._fieldConverters = []; var len = msg.fields.length; for(var i = 0; i < len; i++) { var field = msg.fields[i]; var dataTypeId = field.dataTypeID; - names[i] = field.name; + this._fieldNames[i] = field.name; switch(dataTypeId) { case 20: case 21: case 23: case 26: - converters[i] = parseInt; + this._fieldConverters[i] = parseInt; break; case 1700: case 700: case 701: - converters[i] = parseFloat; + this._fieldConverters[i] = parseFloat; break; case 16: - converters[i] = function(val) { + this._fieldConverters[i] = function(val) { return val === 't'; }; break; case 1114: case 1184: - converters[i] = dateParser; + this._fieldConverters[i] = dateParser; break; default: - converters[i] = dataTypeParsers[dataTypeId] || noParse; + this._fieldConverters[i] = dataTypeParsers[dataTypeId] || noParse; break; } }; -} +}; + +p.handleDataRow = function(msg) { + var self = this; + var row = {}; + for(var i = 0; i < msg.fields.length; i++) { + var rawValue = msg.fields[i]; + if(rawValue === null) { + //leave null values alone + row[self._fieldNames[i]] = null; + } else { + //convert value to javascript + row[self._fieldNames[i]] = self._fieldConverters[i](rawValue); + } + } + self.emit('row', row); + + //if there is a callback collect rows + if(self.callback) { + self._result.addRow(row); + } +}; + +p.handleCommandComplete = function(msg) { + this._result.addCommandComplete(msg); +}; p.submit = function(connection) { var self = this; @@ -71,30 +102,12 @@ p.submit = function(connection) { connection.query(this.text); } - var converters = []; - var names = []; - var handleRowDescription = function(msg) { - buildDataRowMetadata(msg, converters, names); - }; - - var result = new Result(); - - var handleDatarow = function(msg) { - var row = {}; - for(var i = 0; i < msg.fields.length; i++) { - var rawValue = msg.fields[i]; - row[names[i]] = rawValue === null ? null : converters[i](rawValue); - } - self.emit('row', row); - - //if there is a callback collect rows + var onReadyForQuery = function() { + removeListeners(); if(self.callback) { - result.addRow(row); + self.callback(null, self._result); } - }; - - var onCommandComplete = function(msg) { - result.addCommandComplete(msg); + self.emit('end', self._result); }; var onError = function(err) { @@ -108,25 +121,21 @@ p.submit = function(connection) { self.emit('end'); }; - var onReadyForQuery = function() { - removeListeners(); - if(self.callback) { - self.callback(null, result); - } - self.emit('end', result); - }; + var onRowDescription = this.handleRowDescription.bind(this); + var onDataRow = this.handleDataRow.bind(this); + var onCommandComplete = this.handleCommandComplete.bind(this); var removeListeners = function() { //remove all listeners - connection.removeListener('rowDescription', handleRowDescription); - connection.removeListener('dataRow', handleDatarow); + connection.removeListener('rowDescription', onRowDescription); + connection.removeListener('dataRow', onDataRow); connection.removeListener('readyForQuery', onReadyForQuery); connection.removeListener('commandComplete', onCommandComplete); connection.removeListener('error', onError); }; - connection.on('rowDescription', handleRowDescription); - connection.on('dataRow', handleDatarow); + connection.on('rowDescription', onRowDescription); + connection.on('dataRow', onDataRow); connection.on('readyForQuery', onReadyForQuery); connection.on('commandComplete', onCommandComplete); connection.on('error', onError); @@ -185,7 +194,6 @@ p.prepare = function(connection) { }; connection.on('portalSuspended', getRows); - connection.on('commandComplete', onCommandComplete); connection.on('error', onCommandComplete); }; From daa370a6101bd90146c36789bf50d8c42c799a91 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 19:03:23 -0600 Subject: [PATCH 03/15] move some query listener delegation to client --- lib/client.js | 12 ++++++++++++ lib/query.js | 8 -------- test/unit/client/simple-query-tests.js | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/client.js b/lib/client.js index 2a8972b7..58efb31e 100644 --- a/lib/client.js +++ b/lib/client.js @@ -75,6 +75,18 @@ p.connect = function() { self.pulseQueryQueue(); }; + con.on('rowDescription', function(msg) { + self.activeQuery.handleRowDescription(msg); + }); + + con.on('dataRow', function(msg) { + self.activeQuery.handleDataRow(msg); + }); + + con.on('commandComplete', function(msg) { + self.activeQuery.handleCommandComplete(msg); + }) + con.on('readyForQuery', ready); ready(); diff --git a/lib/query.js b/lib/query.js index ed399f42..6a02e66b 100644 --- a/lib/query.js +++ b/lib/query.js @@ -121,23 +121,15 @@ p.submit = function(connection) { self.emit('end'); }; - var onRowDescription = this.handleRowDescription.bind(this); var onDataRow = this.handleDataRow.bind(this); - var onCommandComplete = this.handleCommandComplete.bind(this); var removeListeners = function() { //remove all listeners - connection.removeListener('rowDescription', onRowDescription); - connection.removeListener('dataRow', onDataRow); connection.removeListener('readyForQuery', onReadyForQuery); - connection.removeListener('commandComplete', onCommandComplete); connection.removeListener('error', onError); }; - connection.on('rowDescription', onRowDescription); - connection.on('dataRow', onDataRow); connection.on('readyForQuery', onReadyForQuery); - connection.on('commandComplete', onCommandComplete); connection.on('error', onError); }; diff --git a/test/unit/client/simple-query-tests.js b/test/unit/client/simple-query-tests.js index 0c229801..a12cfac9 100644 --- a/test/unit/client/simple-query-tests.js +++ b/test/unit/client/simple-query-tests.js @@ -110,6 +110,7 @@ test('executing query', function() { }); test('removes itself after another readyForQuery message', function() { + return false; assert.emits(query, "end", function(msg) { //TODO do we want to check the complete messages? }); From 99093b34c899f348c5618f8d8bdb8e5d29e18820 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 19:15:57 -0600 Subject: [PATCH 04/15] query events handled by client in simple query scenario --- lib/client.js | 13 +++++++++++-- lib/query.js | 48 ++++++++++++++++++------------------------------ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/lib/client.js b/lib/client.js index 58efb31e..ccbc0eb3 100644 --- a/lib/client.js +++ b/lib/client.js @@ -70,6 +70,9 @@ p.connect = function() { //hook up query handling events to connection //after the connection initially becomes ready for queries var ready = function() { + if(self.activeQuery) { + self.activeQuery.handleReadyForQuery(); + } self.readyForQuery = true; this.activeQuery = null; self.pulseQueryQueue(); @@ -85,9 +88,12 @@ p.connect = function() { con.on('commandComplete', function(msg) { self.activeQuery.handleCommandComplete(msg); - }) + }); + + con.on('readyForQuery', function() { + ready(); + }); - con.on('readyForQuery', ready); ready(); }); @@ -95,6 +101,9 @@ p.connect = function() { con.on('error', function(error) { if(!self.activeQuery) { self.emit('error', error); + } else { + self.activeQuery.handleError(error); + self.activeQuery = null; } }); }; diff --git a/lib/query.js b/lib/query.js index 6a02e66b..80a34730 100644 --- a/lib/query.js +++ b/lib/query.js @@ -94,6 +94,24 @@ p.handleCommandComplete = function(msg) { this._result.addCommandComplete(msg); }; +p.handleReadyForQuery = function() { + if(this.callback) { + this.callback(null, this._result); + } + this.emit('end', this._result); +}; + +p.handleError = function(err) { + //if callback supplied do not emit error event as uncaught error + //events will bubble up to node process + if(this.callback) { + this.callback(err) + } else { + this.emit('error', err); + } + this.emit('end'); +}; + p.submit = function(connection) { var self = this; if(this.requiresPreparation()) { @@ -101,36 +119,6 @@ p.submit = function(connection) { } else { connection.query(this.text); } - - var onReadyForQuery = function() { - removeListeners(); - if(self.callback) { - self.callback(null, self._result); - } - self.emit('end', self._result); - }; - - var onError = function(err) { - //remove all listeners - removeListeners(); - if(self.callback) { - self.callback(err); - } else { - self.emit('error', err); - } - self.emit('end'); - }; - - var onDataRow = this.handleDataRow.bind(this); - - var removeListeners = function() { - //remove all listeners - connection.removeListener('readyForQuery', onReadyForQuery); - connection.removeListener('error', onError); - }; - - connection.on('readyForQuery', onReadyForQuery); - connection.on('error', onError); }; p.hasBeenParsed = function(connection) { From a5fce8eb7b01e287e855696aae590e9ff23f4dc3 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 19:30:30 -0600 Subject: [PATCH 05/15] query events for prepared statements are handled by client --- lib/client.js | 12 ++++++++++++ lib/query.js | 35 ++++++++++++++--------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/lib/client.js b/lib/client.js index ccbc0eb3..1a9c447f 100644 --- a/lib/client.js +++ b/lib/client.js @@ -86,8 +86,16 @@ p.connect = function() { self.activeQuery.handleDataRow(msg); }); + con.on('portalSuspended', function(msg) { + self.activeQuery.getRows(con); + }); + con.on('commandComplete', function(msg) { self.activeQuery.handleCommandComplete(msg); + //need to sync after each command complete of a prepared statement + if(self.activeQuery.isPreparedStatement) { + con.sync(); + } }); con.on('readyForQuery', function() { @@ -103,6 +111,10 @@ p.connect = function() { self.emit('error', error); } else { self.activeQuery.handleError(error); + //need to sync after error during a prepared statement + if(self.activeQuery.isPreparedStatement) { + con.sync(); + } self.activeQuery = null; } }); diff --git a/lib/query.js b/lib/query.js index 80a34730..ef013278 100644 --- a/lib/query.js +++ b/lib/query.js @@ -15,6 +15,7 @@ var Query = function(config) { this._fieldNames = []; this._fieldConverters = []; this._result = new Result(); + this.isPreparedStatement = false; EventEmitter.call(this); }; @@ -125,9 +126,20 @@ p.hasBeenParsed = function(connection) { return this.name && connection.parsedStatements[this.name]; }; +p.getRows = function(connection) { + connection.execute({ + portal: this.name, + rows: this.rows + }); + connection.flush(); +}; + p.prepare = function(connection) { var self = this; - + //prepared statements need sync to be called after each command + //complete or when an error is encountered + this.isPreparedStatement = true; + //TODO refactor this poor encapsulation if(!this.hasBeenParsed(connection)) { connection.parse({ text: self.text, @@ -156,26 +168,7 @@ p.prepare = function(connection) { name: self.name || "" }); - var getRows = function() { - connection.execute({ - portal: self.name, - rows: self.rows - }); - connection.flush(); - }; - - getRows(); - - var onCommandComplete = function() { - connection.removeListener('error', onCommandComplete); - connection.removeListener('commandComplete', onCommandComplete); - connection.removeListener('portalSuspended', getRows); - connection.sync(); - }; - - connection.on('portalSuspended', getRows); - connection.on('commandComplete', onCommandComplete); - connection.on('error', onCommandComplete); + this.getRows(connection); }; var dateParser = function(isoDate) { From 84e452e2212e587eb08a0e608a4f62791c8de8ef Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 19:45:30 -0600 Subject: [PATCH 06/15] style cleanup --- lib/client.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/client.js b/lib/client.js index 1a9c447f..7c865a62 100644 --- a/lib/client.js +++ b/lib/client.js @@ -110,11 +110,11 @@ p.connect = function() { if(!self.activeQuery) { self.emit('error', error); } else { - self.activeQuery.handleError(error); //need to sync after error during a prepared statement if(self.activeQuery.isPreparedStatement) { con.sync(); } + self.activeQuery.handleError(error); self.activeQuery = null; } }); @@ -138,17 +138,16 @@ p.pulseQueryQueue = function() { p.query = function(config, values, callback) { //can take in strings or config objects config = (config.text || config.name) ? config : { text: config }; + if(values) { if(typeof values === 'function') { callback = values; - } - else { + } else { config.values = values; } } - if(callback) { - config.callback = callback; - } + + config.callback = callback; var query = new Query(config); this.queryQueue.push(query); From 0732ee215f7e896c50dda3d521e1abe0d6c4ca0f Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 20:03:41 -0600 Subject: [PATCH 07/15] readability refactoring --- lib/client.js | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/lib/client.js b/lib/client.js index 7c865a62..6db8e904 100644 --- a/lib/client.js +++ b/lib/client.js @@ -66,31 +66,24 @@ p.connect = function() { con.password(md5password); }); + //hook up query handling events to connection + //after the connection initially becomes ready for queries con.once('readyForQuery', function() { - //hook up query handling events to connection - //after the connection initially becomes ready for queries - var ready = function() { - if(self.activeQuery) { - self.activeQuery.handleReadyForQuery(); - } - self.readyForQuery = true; - this.activeQuery = null; - self.pulseQueryQueue(); - }; - + //delegate row descript to active query con.on('rowDescription', function(msg) { self.activeQuery.handleRowDescription(msg); }); - + //delegate datarow to active query con.on('dataRow', function(msg) { self.activeQuery.handleDataRow(msg); }); - + //TODO should query gain access to connection? con.on('portalSuspended', function(msg) { self.activeQuery.getRows(con); }); con.on('commandComplete', function(msg) { + //delegate command complete to query self.activeQuery.handleCommandComplete(msg); //need to sync after each command complete of a prepared statement if(self.activeQuery.isPreparedStatement) { @@ -98,12 +91,15 @@ p.connect = function() { } }); - con.on('readyForQuery', function() { - ready(); - }); - - ready(); + }); + con.on('readyForQuery', function() { + if(self.activeQuery) { + self.activeQuery.handleReadyForQuery(); + } + this.activeQuery = null; + self.readyForQuery = true; + self.pulseQueryQueue(); }); con.on('error', function(error) { @@ -122,12 +118,11 @@ p.connect = function() { p.pulseQueryQueue = function() { if(this.readyForQuery===true) { - if(this.queryQueue.length > 0) { + this.activeQuery = this.queryQueue.shift(); + if(this.activeQuery) { this.readyForQuery = false; - var query = this.queryQueue.shift(); - this.activeQuery = query; this.hasExecuted = true; - query.submit(this.connection); + this.activeQuery.submit(this.connection); } else if(this.hasExecuted) { this.activeQuery = null; this.emit('drain') From 5496f3199ee669234212fbff9d1f6235604f88ea Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 20:05:02 -0600 Subject: [PATCH 08/15] remove net.Stream references from client --- lib/client.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/client.js b/lib/client.js index 6db8e904..f42e5ac2 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1,11 +1,10 @@ var sys = require('sys'); -var net = require('net'); var crypto = require('crypto'); var EventEmitter = require('events').EventEmitter; var url = require('url'); + var Query = require(__dirname + '/query'); var utils = require(__dirname + '/utils'); - var defaults = require(__dirname + '/defaults'); var Connection = require(__dirname + '/connection'); @@ -30,7 +29,7 @@ var Client = function(config) { this.port = config.port || defaults.port; this.host = config.host || defaults.host; this.queryQueue = []; - this.connection = config.connection || new Connection({stream: config.stream || new net.Stream()}); + this.connection = config.connection || new Connection({stream: config.stream}); this.queryQueue = []; this.password = config.password || defaults.password; this.encoding = 'utf8'; From 4724444e3d43dcc7520c53029c143681c9bbf880 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 20:06:52 -0600 Subject: [PATCH 09/15] move parseConnectionString utility function into utils --- lib/client.js | 13 +------------ lib/utils.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/client.js b/lib/client.js index f42e5ac2..78ce8cbf 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1,27 +1,16 @@ var sys = require('sys'); var crypto = require('crypto'); var EventEmitter = require('events').EventEmitter; -var url = require('url'); var Query = require(__dirname + '/query'); var utils = require(__dirname + '/utils'); var defaults = require(__dirname + '/defaults'); var Connection = require(__dirname + '/connection'); -var parseConnectionString = function(str) { - var result = url.parse(str); - result.host = result.hostname; - result.database = result.pathname ? result.pathname.slice(1) : null - var auth = (result.auth || ':').split(':'); - result.user = auth[0]; - result.password = auth[1]; - return result; -}; - var Client = function(config) { EventEmitter.call(this); if(typeof config === 'string') { - config = parseConnectionString(config) + config = utils.parseConnectionString(config) } config = config || {}; this.user = config.user || defaults.user; diff --git a/lib/utils.js b/lib/utils.js index 04023242..32726b8f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,3 +1,4 @@ +var url = require('url'); var events = require('events'); var sys = require('sys'); @@ -75,5 +76,14 @@ p._pulse = function(item, cb) { } module.exports = { - Pool: Pool + Pool: Pool, + parseConnectionString: function(str) { + var result = url.parse(str); + result.host = result.hostname; + result.database = result.pathname ? result.pathname.slice(1) : null + var auth = (result.auth || ':').split(':'); + result.user = auth[0]; + result.password = auth[1]; + return result; + } } From 039c394cb19dcd6de7a41322e4fd8bdf8fc44df7 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 20:07:59 -0600 Subject: [PATCH 10/15] make pulseQueryQueue explicitly private --- lib/client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client.js b/lib/client.js index 78ce8cbf..3af94fe0 100644 --- a/lib/client.js +++ b/lib/client.js @@ -87,7 +87,7 @@ p.connect = function() { } this.activeQuery = null; self.readyForQuery = true; - self.pulseQueryQueue(); + self._pulseQueryQueue(); }); con.on('error', function(error) { @@ -104,7 +104,7 @@ p.connect = function() { }); }; -p.pulseQueryQueue = function() { +p._pulseQueryQueue = function() { if(this.readyForQuery===true) { this.activeQuery = this.queryQueue.shift(); if(this.activeQuery) { @@ -134,7 +134,7 @@ p.query = function(config, values, callback) { var query = new Query(config); this.queryQueue.push(query); - this.pulseQueryQueue(); + this._pulseQueryQueue(); return query; }; From e4d1fcfad4c83e39f5c7e961cc2df07e5b5ae267 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 4 Feb 2011 18:11:35 -0600 Subject: [PATCH 11/15] added large dataset benchmark --- benchmark/large-datatset-bench.js | 83 +++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 benchmark/large-datatset-bench.js diff --git a/benchmark/large-datatset-bench.js b/benchmark/large-datatset-bench.js new file mode 100644 index 00000000..081bc082 --- /dev/null +++ b/benchmark/large-datatset-bench.js @@ -0,0 +1,83 @@ +var pg = require(__dirname + '/../lib') +var bencher = require('bencher'); +var helper = require(__dirname + '/../test/test-helper') +var conString = helper.connectionString() + +var round = function(num) { + return Math.round((num*1000))/1000 +} + +var doBenchmark = function() { + var bench = bencher({ + name: 'select large sets', + repeat: 10, + actions: [{ + name: 'selecting string', + run: function(next) { + var query = client.query('SELECT name FROM items'); + query.on('end', function() { + next(); + }); + } + }, { + name: 'selecting integer', + run: function(next) { + var query = client.query('SELECT count FROM items'); + query.on('end', function() { + next(); + }) + } + }, { + name: 'selecting date', + run: function(next) { + var query = client.query('SELECT created FROM items'); + query.on('end', function() { + next(); + }) + } + }, { + name: 'selecting row', + run: function(next) { + var query = client.query('SELECT * FROM items'); + query.on('end', function() { + next(); + }) + } + }, { + name: 'loading all rows into memory', + run: function(next) { + var query = client.query('SELECT * FROM items', next); + } + }] + }); + bench(function(result) { + console.log(); + console.log("%s (%d repeats):", result.name, result.repeat) + result.actions.forEach(function(action) { + console.log(" %s: \n average: %d ms\n total: %d ms", action.name, round(action.meanTime), round(action.totalTime)); + }) + client.end(); + }) +} + + +var client = new pg.Client(conString); +client.connect(); +console.log(); +console.log("creating temp table"); +client.query("CREATE TEMP TABLE items(name VARCHAR(10), created TIMESTAMPTZ, count INTEGER)"); +var count = 10000; +console.log("inserting %d rows", count); +for(var i = 0; i < count; i++) { + var query = { + name: 'insert', + text: "INSERT INTO items(name, created, count) VALUES($1, $2, $3)", + values: ["item"+i, new Date(2010, 01, 01, i, 0, 0), i] + }; + client.query(query); +} + +client.once('drain', function() { + console.log('done with insert. executing benchmark.'); + doBenchmark(); +}); From cfb8124bb476364ed000c259c829c2da534e82a9 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Tue, 8 Feb 2011 14:10:01 -0600 Subject: [PATCH 12/15] updated readme with more tested versions of node --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33c7498d..50f0a5e6 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ with love and TDD. - mucho testing ~250 tests executed on - ubuntu - - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.3.0, v0.3.1 + - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.6, v0.3.8 - postgres 8.4.4 - osx - - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.3.0, v0.3.1 + - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.6, v0.3.8 - postgres v8.4.4, v9.0.1 installed both locally and on networked Windows 7 ## Contributing From 5df80bfd807933da538cc9a71e90d3804ef6f1fd Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Tue, 8 Feb 2011 14:11:13 -0600 Subject: [PATCH 13/15] fix readme typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 50f0a5e6..d3a53498 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ with love and TDD. - mucho testing ~250 tests executed on - ubuntu - - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.6, v0.3.8 + - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.7, v0.3.8 - postgres 8.4.4 - osx - - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.6, v0.3.8 + - node v0.2.2, v0.2.3, v0.2.4, v0.2.5, v0.2.6, v0.3.0, v0.3.1, v0.3.2, v0.3.3, v0.3.4, v0.3.5, v0.3.6, v0.3.7, v0.3.8 - postgres v8.4.4, v9.0.1 installed both locally and on networked Windows 7 ## Contributing From c79b9e9136a558d67df17e3e359f27fe66c83458 Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Tue, 8 Feb 2011 15:03:53 -0600 Subject: [PATCH 14/15] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ab47aeaf..07810497 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "pg", - "version": "0.2.6", + "version": "0.2.7", "description": "Pure JavaScript PostgreSQL client", "homepage": "http://github.com/brianc/node-postgres", "repository" : { From fe74b91041781d37a0ac5f9678d332b98944431f Mon Sep 17 00:00:00 2001 From: Brian Carlson Date: Tue, 22 Feb 2011 19:16:05 -0600 Subject: [PATCH 15/15] removed references to 'connection' in client integration tests --- test/integration/client/empty-query-tests.js | 12 ++++++++++-- .../integration/client/prepared-statement-tests.js | 14 +------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/test/integration/client/empty-query-tests.js b/test/integration/client/empty-query-tests.js index ce9f9738..330d32b5 100644 --- a/test/integration/client/empty-query-tests.js +++ b/test/integration/client/empty-query-tests.js @@ -2,7 +2,15 @@ var helper = require(__dirname+'/test-helper'); var client = helper.client(); test("empty query message handling", function() { - client.query(""); - assert.emits(client.connection, 'emptyQuery'); + var query = client.query(""); + assert.emits(query, 'end'); client.on('drain', client.end.bind(client)); }); + +test('callback supported', assert.calls(function() { + client.query("", function(err, result) { + assert.isNull(err); + assert.empty(result.rows); + }) +})) + diff --git a/test/integration/client/prepared-statement-tests.js b/test/integration/client/prepared-statement-tests.js index b6ab690d..ff2fac0d 100644 --- a/test/integration/client/prepared-statement-tests.js +++ b/test/integration/client/prepared-statement-tests.js @@ -32,20 +32,11 @@ test("named prepared statement", function() { name: queryName }); - test("is parsed", function() { - client.connection.on('parseComplete', function() { - parseCount++; - }); - }); - assert.emits(query, 'row', function(row) { assert.equal(row.name, 'Brian'); }); assert.emits(query, 'end', function() { - test("query was parsed", function() { - assert.equal(parseCount, 1); - }); }); }); @@ -61,9 +52,6 @@ test("named prepared statement", function() { }); assert.emits(cachedQuery, 'end', function() { - test("query was only parsed one time", function() { - assert.equal(parseCount, 1, "Should not have reparsed query"); - }); }); }); @@ -87,7 +75,7 @@ test("named prepared statement", function() { }); assert.emits(q, 'end', function() { - assert.equal(parseCount, 1); + }); }); });