From face20501cee4c2c1cb1d143d354f14226ed768b Mon Sep 17 00:00:00 2001 From: Ian Miles Ownbey Date: Thu, 1 Aug 2013 13:12:39 -0400 Subject: [PATCH 1/3] Added support for strings in where clauses --- index.js | 55 +++++++++++++++++++++++++++++++++----------------- test/select.js | 10 +++++++++ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index f6b0bf3..54c797f 100644 --- a/index.js +++ b/index.js @@ -34,12 +34,8 @@ UPDATE.prototype = { }, WHERE: function(where,conjunction) { assert(this.text.indexOf('SET') >= 0); - if (conjunction === undefined) { - conjunction = 'AND'; - } - assert(conjunction == 'AND' || conjunction == 'OR'); - this.text += ' WHERE ' + get_where_clause(where, this.values, conjunction); - return this; + this.text += generate_where_clause(arguments, this.values); + return this }, RETURNING: function(returning) { assert(this.text.indexOf('SET') >= 0); @@ -79,14 +75,11 @@ SELECT.prototype = { this.text += ' FROM ' + table; return this; }, - WHERE: function(where,conjunction) { + // where,conjunction + WHERE: function() { assert(this.text.indexOf('FROM') >= 0); - if (conjunction === undefined) { - conjunction = 'AND'; - } - assert(conjunction == AND || conjunction == OR); - this.text += ' WHERE ' + get_where_clause(where, this.values, conjunction); - return this; + this.text += generate_where_clause(arguments, this.values); + return this }, ORDER_BY: function(what,direction) { assert(this.text.indexOf('FROM') >= 0); @@ -151,12 +144,8 @@ function DELETE(table) { DELETE.prototype = { WHERE: function(where,conjunction) { - if (conjunction === undefined) { - conjunction = 'AND'; - } - assert(conjunction == AND || conjunction == OR); - this.text += ' WHERE ' + get_where_clause(where, this.values, conjunction); - return this; + this.text += generate_where_clause(arguments, this.values); + return this }, LIMIT: function(count) { assert(this.text.indexOf('WHERE') >= 0); @@ -191,6 +180,34 @@ function get_set_clause(set, values) { }).join(', '); } +// (iano): Because the rest of these functions are some weird combination +// of functional and destructive I have allowed myself to be completely +// destructive here. [dealwithit] +function generate_where_clause(args, values) { + var clause; + if (args[0] !== null && typeof args[0] == 'object') { + clause = where_clause_from_object(args[0], args[1], values); + } else if (typeof args[0] == 'string') { + clause = where_clause_from_string(args[0], args[1] || [], values); + } + return ' WHERE ' + clause +}; + +function where_clause_from_object(where, conjunction, values) { + if (conjunction === undefined) { + conjunction = 'AND'; + } + assert(conjunction == AND || conjunction == OR); + return get_where_clause(where, values, conjunction); +}; + +function where_clause_from_string(str, new_values, values) { + return str.replace("?", function () { + values.push(new_values.shift()); + return "$" + values.length; + }); +}; + // used in UPDATE, SELECT and DELETE // can handle where objects like so: // { foo: [1,2,3,4], bar: NOT_NULL, baz: null } diff --git a/test/select.js b/test/select.js index ec55cb5..cf88fe7 100644 --- a/test/select.js +++ b/test/select.js @@ -134,6 +134,16 @@ describe('SELECT', function(){ sql.values.should.have.length(0); }); }); + describe('#().FROM(table).WHERE("id < ?", 3).ORDER_BY(col,ASC)', function(){ + it('should return an object with placeholders and populated values', function(){ + var sql = SELECT().FROM('foo').WHERE("id < ?", [3]) + sql.should.have.text; + sql.should.have.values; + sql.text.should.equal('SELECT * FROM foo WHERE id < $1') + sql.values.should.be.an.instanceOf(Array) + sql.values.should.eql([3]); + }); + }); describe('#().FROM(table).WHERE(where_null,OR).ORDER_BY(col,ASC).LIMIT(10).OFFSET(10)', function(){ it('should return an object with placeholders and populated values', function(){ var sql = SELECT().FROM('foo').WHERE({ a: NULL, b: NOT_NULL },OR).ORDER_BY('bar','ASC').LIMIT(10).OFFSET(10); From 91debab1ae24529dd5fcbf80bc674c65610d9f22 Mon Sep 17 00:00:00 2001 From: Ian Miles Ownbey Date: Thu, 1 Aug 2013 15:39:47 -0400 Subject: [PATCH 2/3] Clean things up a bit --- index.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index 54c797f..00a9dd4 100644 --- a/index.js +++ b/index.js @@ -198,20 +198,6 @@ function where_clause_from_object(where, conjunction, values) { conjunction = 'AND'; } assert(conjunction == AND || conjunction == OR); - return get_where_clause(where, values, conjunction); -}; - -function where_clause_from_string(str, new_values, values) { - return str.replace("?", function () { - values.push(new_values.shift()); - return "$" + values.length; - }); -}; - -// used in UPDATE, SELECT and DELETE -// can handle where objects like so: -// { foo: [1,2,3,4], bar: NOT_NULL, baz: null } -function get_where_clause(where, values, conjunction){ return Object.keys(where).map(function column_to_where(c,i) { var value = where[c]; if (Array.isArray(value)) { @@ -228,6 +214,19 @@ function get_where_clause(where, values, conjunction){ return c + ' = $' + values.length; } }).join(' ' + conjunction + ' '); +}; + +function where_clause_from_string(str, new_values, values) { + return str.replace("?", function () { + values.push(new_values.shift()); + return "$" + values.length; + }); +}; + +// used in UPDATE, SELECT and DELETE +// can handle where objects like so: +// { foo: [1,2,3,4], bar: NOT_NULL, baz: null } +function get_where_clause(where, values, conjunction){ } module.exports = { From e28c0704b0382dbccac3bc4ddbab2a0d6b416948 Mon Sep 17 00:00:00 2001 From: Hursh Agrawal Date: Fri, 2 Aug 2013 13:05:00 -0400 Subject: [PATCH 3/3] fixed array and null insertion into string where --- index.js | 19 ++++++++++++++++--- test/select.js | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 00a9dd4..e4b3056 100644 --- a/index.js +++ b/index.js @@ -217,9 +217,22 @@ function where_clause_from_object(where, conjunction, values) { }; function where_clause_from_string(str, new_values, values) { - return str.replace("?", function () { - values.push(new_values.shift()); - return "$" + values.length; + return str.replace(/\?/g, function () { + var value = new_values.shift(); + + if (Array.isArray(value)) { + return '(' + value.map(function(v) { + values.push(v); + return '$' + values.length; + }).join(', ') + ')'; + } else if (value === null) { + return 'NULL'; + } else if (value === NOT_NULL) { + return 'NOT NULL'; + } else { + values.push(value); + return '$' + values.length; + } }); }; diff --git a/test/select.js b/test/select.js index cf88fe7..7bac59d 100644 --- a/test/select.js +++ b/test/select.js @@ -134,14 +134,24 @@ describe('SELECT', function(){ sql.values.should.have.length(0); }); }); - describe('#().FROM(table).WHERE("id < ?", 3).ORDER_BY(col,ASC)', function(){ + describe('#().FROM(table).WHERE("(id < ?) AND (bar = ?)", [3, 5]).ORDER_BY(col,ASC)', function(){ it('should return an object with placeholders and populated values', function(){ - var sql = SELECT().FROM('foo').WHERE("id < ?", [3]) + var sql = SELECT().FROM('foo').WHERE("(id < ?) AND (bar = ?)", [3, 5]) sql.should.have.text; sql.should.have.values; - sql.text.should.equal('SELECT * FROM foo WHERE id < $1') + sql.text.should.equal('SELECT * FROM foo WHERE (id < $1) AND (bar = $2)') sql.values.should.be.an.instanceOf(Array) - sql.values.should.eql([3]); + sql.values.should.eql([3, 5]); + }); + }); + describe('#().FROM(table).WHERE("id IN ?", [[3, 5, 6]]).ORDER_BY(col,ASC)', function(){ + it('should return an object with placeholders and populated values', function(){ + var sql = SELECT().FROM('foo').WHERE("id IN ?", [[3, 5]]) + sql.should.have.text; + sql.should.have.values; + sql.text.should.equal('SELECT * FROM foo WHERE id IN ($1, $2)') + sql.values.should.be.an.instanceOf(Array) + sql.values.should.eql([3, 5]); }); }); describe('#().FROM(table).WHERE(where_null,OR).ORDER_BY(col,ASC).LIMIT(10).OFFSET(10)', function(){