From f6f0abb19fa0fd1c03453cea47718ca2f13a4198 Mon Sep 17 00:00:00 2001 From: Jeffrey Yang Date: Tue, 26 Mar 2013 10:06:30 -0400 Subject: [PATCH 1/2] Backport better serialization of parameter values. --- lib/native/query.js | 34 +++++++++++++++++----------------- lib/query.js | 20 ++++++++++++++++---- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/native/query.js b/lib/native/query.js index 4473100be..f1d49a309 100644 --- a/lib/native/query.js +++ b/lib/native/query.js @@ -3,6 +3,22 @@ var util = require('util'); var types = require(__dirname + "/../types"); +var prepareValue = function(val, stringifyNull) { + if(typeof val === 'undefined') { + return stringifyNull ? "NULL" : null; + } + if (Array.isArray(val)) { + // convert a JS array to a postgres array literal + // uses comma separator so won't work for types like box that use + // a different array separator. + return "{" + val.map(function(v) { return prepareValue(v, true); }).join(",") + "}"; + } + if(val instanceof Date || val instanceof Object) { + return JSON.stringify(val); + } + return val === null ? (stringifyNull ? "NULL" : null) : val.toString(); +}; + //event emitter proxy var NativeQuery = function(text, values, callback) { //TODO there are better ways to detect overloads @@ -30,23 +46,7 @@ var NativeQuery = function(text, values, callback) { } //normalize values if(this.values) { - for(var i = 0, len = this.values.length; i < len; i++) { - var item = this.values[i]; - switch(typeof item) { - case 'undefined': - this.values[i] = null; - break; - case 'object': - this.values[i] = item === null ? null : JSON.stringify(item); - break; - case 'string': - //value already string - break; - default: - //numbers - this.values[i] = item.toString(); - } - } + this.values = this.values.map(function(o,i,a) { return prepareValue(o, false); }); } EventEmitter.call(this); diff --git a/lib/query.js b/lib/query.js index c7fadeec9..e23aae1c8 100644 --- a/lib/query.js +++ b/lib/query.js @@ -28,6 +28,21 @@ p.requiresPreparation = function() { return (this.values || 0).length > 0 || this.name || this.rows || this.binary; }; +var prepareValue = function(val, stringifyNull) { + if(typeof val === 'undefined') { + return stringifyNull ? "NULL" : null; + } + if (Array.isArray(val)) { + // convert a JS array to a postgres array literal + // uses comma separator so won't work for types like box that use + // a different array separator. + return "{" + val.map(function(v) { return prepareValue(v, true); }).join(",") + "}"; + } + if(val instanceof Date || val instanceof Object) { + return JSON.stringify(val); + } + return val === null ? (stringifyNull ? "NULL" : null) : val.toString(); +}; var noParse = function(val) { return val; @@ -127,11 +142,8 @@ p.prepare = function(connection) { connection.parsedStatements[this.name] = true; } - //TODO is there some better way to prepare values for the database? if(self.values) { - self.values = self.values.map(function(val) { - return (val instanceof Date) ? JSON.stringify(val) : val; - }); + self.values = self.values.map(function(val) { return prepareValue(o, false); }); } //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY From bd9a2c71164b42761c77955b2c7bc07d9b993bb0 Mon Sep 17 00:00:00 2001 From: Jeffrey Yang Date: Mon, 8 Apr 2013 15:47:58 -0400 Subject: [PATCH 2/2] Fix native query prepareValue call --- lib/query.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/query.js b/lib/query.js index e23aae1c8..8b263aea1 100644 --- a/lib/query.js +++ b/lib/query.js @@ -143,7 +143,7 @@ p.prepare = function(connection) { } if(self.values) { - self.values = self.values.map(function(val) { return prepareValue(o, false); }); + self.values = self.values.map(function(val) { return prepareValue(val, false); }); } //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY