knex/lib/raw.js

85 lines
2.2 KiB
JavaScript
Raw Normal View History

2013-09-13 16:58:38 -04:00
// Raw
// -------
2014-04-15 13:10:32 -04:00
var _ = require('lodash');
var inherits = require('inherits');
var EventEmitter = require('events').EventEmitter;
function Raw(sql, bindings) {
if (sql && sql.toSQL) {
2014-06-09 15:26:48 -04:00
var output = sql.toSQL();
sql = output.sql;
bindings = output.bindings;
2014-04-15 13:10:32 -04:00
}
this.sql = sql;
2014-04-15 13:10:32 -04:00
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 don't need to care about replacements adding more '?'s
// and disrupting the indices, because we split first, join later
this.sql = _.reduce(replacements, function(accum, fn) {
return fn(accum);
}, this.sql.split('?')).join('?');
}
this._debug = void 0;
this._transacting = void 0;
}
inherits(Raw, EventEmitter);
// Wraps the current sql with `before` and `after`.
Raw.prototype.wrap = function(before, after) {
this.sql = before + this.sql + after;
return this;
};
// Calls `toString` on the Knex object.
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.
2014-04-09 10:11:41 -04:00
Raw.prototype.toSQL = function() {
return {
sql: this.sql,
2014-04-09 10:11:41 -04:00
method: 'raw',
bindings: this.bindings
};
};
// Allow the `Raw` object to be utilized with full access to the relevant
// promise API.
require('./interface')(Raw);
module.exports = Raw;