diff --git a/lib/query.js b/lib/query.js index e303df5e..02ed2258 100644 --- a/lib/query.js +++ b/lib/query.js @@ -27,6 +27,42 @@ var noParse = function(val) { return val; }; +//creates datarow metatdata from the supplied +//data row information +var buildDataRowMetadata = function(msg, converters, names) { + 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; + switch(dataTypeId) { + case 20: + case 21: + case 23: + case 26: + converters[i] = parseInt; + break; + case 1700: + case 700: + case 701: + converters[i] = parseFloat; + break; + case 16: + converters[i] = function(val) { + return val === 't'; + }; + break; + case 1114: + case 1184: + converters[i] = dateParser; + break; + default: + converters[i] = dataTypeParsers[dataTypeId] || noParse; + break; + } + }; +} + p.submit = function(connection) { var self = this; if(this.requiresPreparation()) { @@ -34,16 +70,15 @@ p.submit = function(connection) { } else { connection.query(this.text); } + var converters = []; var names = []; + var handleRowDescription = function(msg) { + buildDataRowMetadata(msg, converters, names); + }; var result = new Result(); - var handleRowDescription = function(msg) { - for(var i = 0; i < msg.fields.length; i++) { - converters[i] = dataTypeParsers[msg.fields[i].dataTypeID] || noParse; - names[i] = msg.fields[i].name; - }; - }; + var handleDatarow = function(msg) { var row = {}; for(var i = 0; i < msg.fields.length; i++) { @@ -64,11 +99,7 @@ p.submit = function(connection) { var onError = function(err) { //remove all listeners - connection.removeListener('rowDescription', handleDatarow); - connection.removeListener('dataRow', handleDatarow); - connection.removeListener('error', onError); - connection.removeListener('readyForQuery', onReadyForQuery); - connection.removeListener('commandComplete', onCommandComplete); + removeListeners(); if(self.callback) { self.callback(err); } else { @@ -78,17 +109,20 @@ p.submit = function(connection) { }; var onReadyForQuery = function() { + removeListeners(); + if(self.callback) { + self.callback(null, result); + } + self.emit('end', result); + }; + + var removeListeners = function() { //remove all listeners connection.removeListener('rowDescription', handleRowDescription); connection.removeListener('dataRow', handleDatarow); connection.removeListener('readyForQuery', onReadyForQuery); connection.removeListener('error', onError); connection.removeListener('commandComplete', onCommandComplete); - if(self.callback) { - self.callback(null, result); - rows = []; - } - self.emit('end', result); }; connection.on('rowDescription', handleRowDescription); @@ -106,12 +140,12 @@ p.prepare = function(connection) { var self = this; if(!this.hasBeenParsed(connection)) { - connection.parsedStatements[this.name] = true; connection.parse({ text: self.text, name: self.name, types: self.types }); + connection.parsedStatements[this.name] = true; } //TODO is there some btter way to prepare values for the database? @@ -143,7 +177,6 @@ p.prepare = function(connection) { getRows(); - //TODO support EmptyQueryResponse, ErrorResponse, and PortalSuspended var onCommandComplete = function() { connection.removeListener('error', onCommandComplete); connection.removeListener('commandComplete', onCommandComplete); @@ -209,25 +242,13 @@ var dateParser = function(isoDate) { Query.dateParser = dateParser; var dataTypeParsers = { - 20: parseInt, - 21: parseInt, - 23: parseInt, - 26: parseInt, - 1700: parseFloat, - 700: parseFloat, - 701: parseFloat, - 16: function(dbVal) { //boolean - return dbVal === 't'; - }, - 1114: dateParser, - 1184: dateParser }; +//TODO document this public method Query.registerParser = function(typeOid, parseFunction) { dataTypeParsers[typeOid] = parseFunction; }; - //parses integer arrays Query.registerParser(1007, function(val) { return JSON.parse(val.replace("{","[").replace("}","]"));