knex/lib/raw.js

141 lines
3.4 KiB
JavaScript
Raw Normal View History

2013-09-13 16:58:38 -04:00
// Raw
// -------
2015-05-09 14:01:19 -04:00
'use strict';
2015-05-09 13:58:18 -04:00
var inherits = require('inherits');
var EventEmitter = require('events').EventEmitter;
var assign = require('lodash/object/assign');
var reduce = require('lodash/collection/reduce');
function Raw(client) {
2015-05-09 13:58:18 -04:00
this.client = client;
2015-05-09 13:58:18 -04:00
this.sql = '';
this.bindings = [];
this._cached = undefined;
// Todo: Deprecate
2015-05-09 13:58:18 -04:00
this._wrappedBefore = undefined;
this._wrappedAfter = undefined;
this._debug = client && client.options && client.options.debug;
}
2015-05-09 13:58:18 -04:00
inherits(Raw, EventEmitter);
assign(Raw.prototype, {
2015-05-09 13:58:18 -04:00
set: function set(sql, bindings) {
this._cached = undefined;
this.sql = sql;
this.bindings = bindings;
return this;
},
// Wraps the current sql with `before` and `after`.
2015-05-09 13:58:18 -04:00
wrap: function wrap(before, after) {
this._cached = undefined;
this._wrappedBefore = before;
this._wrappedAfter = after;
return this;
},
// Calls `toString` on the Knex object.
2015-05-09 13:58:18 -04:00
toString: function toString() {
return this.toQuery();
},
// Returns the raw sql for the query.
2015-05-09 13:58:18 -04:00
toSQL: function toSQL() {
if (this._cached) return this._cached;
if (Array.isArray(this.bindings)) {
2015-05-09 13:58:18 -04:00
this._cached = replaceRawArrBindings(this);
} else if (this.bindings && typeof this.bindings === 'object') {
2015-05-09 13:58:18 -04:00
this._cached = replaceKeyBindings(this);
} else {
this._cached = {
method: 'raw',
sql: this.sql,
bindings: this.bindings
2015-05-09 13:58:18 -04:00
};
}
if (this._wrappedBefore) {
2015-05-09 13:58:18 -04:00
this._cached.sql = this._wrappedBefore + this._cached.sql;
}
if (this._wrappedAfter) {
2015-05-09 13:58:18 -04:00
this._cached.sql = this._cached.sql + this._wrappedAfter;
}
2015-05-09 13:58:18 -04:00
this._cached.options = reduce(this._options, assign, {});
return this._cached;
}
2015-05-09 13:58:18 -04:00
});
function replaceRawArrBindings(raw) {
2015-05-09 13:58:18 -04:00
var expectedBindings = raw.bindings.length;
var values = raw.bindings;
var client = raw.client;
var index = 0;
var bindings = [];
var sql = raw.sql.replace(/\?\??/g, function (match) {
var value = values[index++];
if (value && typeof value.toSQL === 'function') {
2015-05-09 13:58:18 -04:00
var bindingSQL = value.toSQL();
bindings = bindings.concat(bindingSQL.bindings);
return bindingSQL.sql;
}
if (match === '??') {
2015-05-09 13:58:18 -04:00
return client.wrapIdentifier(value);
}
2015-05-09 13:58:18 -04:00
bindings.push(value);
return '?';
});
2015-04-27 16:50:52 -04:00
if (expectedBindings !== index) {
2015-05-09 13:58:18 -04:00
throw new Error('Expected ' + expectedBindings + ' bindings, saw ' + index);
}
return {
method: 'raw',
sql: sql,
bindings: bindings
2015-05-09 13:58:18 -04:00
};
}
function replaceKeyBindings(raw) {
2015-05-09 13:58:18 -04:00
var values = raw.bindings;
var client = raw.client;
var sql = raw.sql,
bindings = [];
var regex = new RegExp('\\s(\\:\\w+\\:?)', 'g');
sql = raw.sql.replace(regex, function (full, key) {
var isIdentifier = key[key.length - 1] === ':';
var value = isIdentifier ? values[key.slice(1, -1)] : values[key.slice(1)];
if (value === undefined) return '';
2015-05-06 10:48:05 -04:00
if (value && typeof value.toSQL === 'function') {
2015-05-09 13:58:18 -04:00
var bindingSQL = value.toSQL();
bindings = bindings.concat(bindingSQL.bindings);
return full.replace(key, bindingSQL.sql);
2015-05-06 10:48:05 -04:00
}
if (isIdentifier) {
2015-05-09 13:58:18 -04:00
return full.replace(key, client.wrapIdentifier(value));
2015-05-06 10:48:05 -04:00
}
2015-05-09 13:58:18 -04:00
bindings.push(value);
return full.replace(key, '?');
});
return {
method: 'raw',
sql: sql,
bindings: bindings
2015-05-09 13:58:18 -04:00
};
}
// Allow the `Raw` object to be utilized with full access to the relevant
// promise API.
2015-05-09 13:58:18 -04:00
require('./interface')(Raw);
2015-05-09 13:58:18 -04:00
module.exports = Raw;