diff --git a/lib/query.js b/lib/query.js index 81645ef..ed399f4 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); };