Skip to content

Commit

Permalink
Merge pull request #379 from SohumB/feature/nested-raw
Browse files Browse the repository at this point in the history
Allow nested Raw queries
  • Loading branch information
tgriesser committed Aug 14, 2014
2 parents 1bdf35c + c8b003a commit 0330c33
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/raw.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,26 @@ function Raw(sql, bindings) {
this.sql = sql;
this.bindings = _.isArray(bindings) ? bindings :
bindings ? [bindings] : [];

if (_.isString(sql)) {
var replacements = [];
this.bindings = _.reduce(this.bindings, function(accum, param, index) {
var innerBindings = [param];
if (param instanceof Raw) {
var result = this.splicer(param, index);
innerBindings = result.bindings;
replacements.push(result.replacer);
}
return accum.concat(innerBindings);
}.bind(this), []);

// we run this in reverse order, because ? concats earlier in the
// query string will disrupt indices for later ones
this.sql = _.reduce(replacements.reverse(), function(accum, fn) {
return fn(accum);
}, this.sql.split('?')).join('?');
}

this._debug = void 0;
this._transacting = void 0;
}
Expand All @@ -29,6 +49,26 @@ Raw.prototype.toString = function() {
return this.toQuery();
};

// Returns a replacer function that splices into the i'th
// ? in the sql string the inner raw's sql,
// and the bindings associated with it
Raw.prototype.splicer = function(raw, i) {
var obj = raw.toSQL();

// the replacer function assumes that the sql has been
// already sql.split('?') and will be arr.join('?')
var replacer = function(arr) {
arr[i] = arr[i] + obj.sql + arr[i+1];
arr.splice(i+1,1);
return arr;
};

return {
replacer: replacer,
bindings: obj.bindings
};
};

// Returns the raw sql for the query.
Raw.prototype.toSQL = function() {
return {
Expand Down
20 changes: 20 additions & 0 deletions test/unit/query/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,26 @@ module.exports = function(pgclient, mysqlclient, sqlite3client, oracleclient) {
expect(str).to.equal('select "e"."lastname", "e"."salary", (select "avg(salary)" from "employee" where dept_no = e.dept_no) as "avg_sal_dept" from "employee" as "e" where "dept_no" = \'e.dept_no\'');
});

it('supports arbitrarily nested raws', function() {
var chain = sql().select('*').from('places')
.where(raw('ST_DWithin((places.address).xy, ?, ?) AND ST_Distance((places.address).xy, ?) > ? AND ?', [
raw('ST_SetSRID(?,?)', [
raw('ST_MakePoint(?,?)', [-10,10]),
4326
]),
100000,
raw('ST_SetSRID(?,?)', [
raw('ST_MakePoint(?,?)', [-5,5]),
4326
]),
50000,
raw('places.id IN ?', [ [1,2,3] ])
])).toSQL();

expect(chain.sql).to.equal('select * from "places" where ST_DWithin((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?), ?) AND ST_Distance((places.address).xy, ST_SetSRID(ST_MakePoint(?,?),?)) > ? AND places.id IN ?');
expect(chain.bindings).to.eql([-10, 10, 4326, 100000, -5, 5, 4326, 50000, [1,2,3] ]);
});

});

};

0 comments on commit 0330c33

Please sign in to comment.