From 368724d4f4b9123a4bdeb6da2e737ccc197ab214 Mon Sep 17 00:00:00 2001 From: brianc Date: Tue, 26 Oct 2010 23:57:36 -0500 Subject: [PATCH] integer datatype coercion in result set --- lib/client.js | 58 ++++++++++++++++++------- test/unit/client/typed-query-results.js | 51 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 test/unit/client/typed-query-results.js diff --git a/lib/client.js b/lib/client.js index c4bd9df6..6f83d801 100644 --- a/lib/client.js +++ b/lib/client.js @@ -92,6 +92,9 @@ Client.md5 = function(string) { var Query = function(config) { this.text = config.text; + //for code clarity purposes we'll declare this here though it's not + //set or used until a rowDescription message comes in + this.rowDescription = null; EventEmitter.call(this); }; sys.inherits(Query, EventEmitter);p @@ -101,10 +104,10 @@ p.submit = function(connection) { var self = this; connection.query(this.text); var handleRowDescription = function(msg) { - + self.onRowDescription(msg); }; var handleDatarow = function(msg) { - self.emit('row', msg); + self.onDataRow(msg); }; connection.on('rowDescription', handleRowDescription); connection.on('dataRow', handleDatarow); @@ -116,6 +119,31 @@ p.submit = function(connection) { }); }; +p.onRowDescription = function(msg) { + var typeIds = msg.fields.map(function(field) { + return field.dataTypeID; + }); + var noParse = function(val) { + return val; + }; + + this.converters = typeIds.map(function(typeId) { + return Client.dataTypeParser[typeId] || noParse; + }); +}; + +//handles the raw 'dataRow' event from the connection does type coercion +p.onDataRow = function(msg) { + var fields = msg.fields; + var converters = this.converters || []; + var len = msg.fields.length; + for(var i = 0; i < len; i++) { + fields[i] = this.converters[i] (fields[i]); + } + msg.fields = fields; + this.emit('row', msg); +}; + // var intParser = { @@ -143,19 +171,19 @@ p.submit = function(connection) { // } // }; -// Client.dataTypes = { -// 20: intParser, -// 21: intParser, -// 23: intParser, -// 26: intParser, -// 1700: floatParser, -// 700: floatParser, -// 701: floatParser, -// 1083: timeParser, -// 1266: timeParser, -// 1114: dateParser, -// 1184: dateParser -// }; +Client.dataTypeParser = { + 20: parseInt, + 21: parseInt, + 23: parseInt, + 26: parseInt + // 1700: floatParser, + // 700: floatParser, + // 701: floatParser, + // 1083: timeParser, + // 1266: timeParser, + // 1114: dateParser, + // 1184: dateParser +}; // p.processRowDescription = function(description) { // this.fields = description.fields; diff --git a/test/unit/client/typed-query-results.js b/test/unit/client/typed-query-results.js new file mode 100644 index 00000000..f97987da --- /dev/null +++ b/test/unit/client/typed-query-results.js @@ -0,0 +1,51 @@ +var helper = require(__dirname + '/test-helper'); +//http://www.postgresql.org/docs/8.4/static/datatype.html +test('typed results', function() { + var client = helper.client(); + var con = client.connection; + con.emit('readyForQuery'); + var query = client.query("the bums lost"); + + + assert.raises(query, 'row', function(row) { + var testParses = function(name, index, expected) { + test('parses ' + name, function() { + assert.strictEqual(row.fields[index], expected); + }); + }; + testParses('string', 0, 'bang'); + testParses('integer / int4', 1, 1394); + testParses('smallInt / int2', 2, 4); + testParses('bigint / int8', 3, 1234567890); + testParses('oid', 4, 1234); + }); + + con.emit('rowDescription', { + fieldCount: 2, + fields: [{ + name: 'string/varchar', //note: field name has NO influence on type parsing... + dataTypeID: 1043 + },{ + name: 'integer/int4', + dataTypeID: 23 //int4, integer + },{ + name: 'smallint/int2', + dataTypeID: 21 + },{ + name: 'bigint/int8', + dataTypeID: 20 + },{ + name: 'oid', + dataTypeID: 26 + }] + }); + + assert.ok(con.emit('dataRow', {fields:[ + 'bang', //varchar + '1394', //integer + '4', //smallint + '1234567890', //bigint (yes, i know, this isn't 8 bytes) + '1234' //oid + ]})); + +});