(function(define) { "use strict"; // Common // ------- define(function(require, exports) { var _ = require('underscore'); var when = require('when'); var Raw = require('./raw').Raw; var Helpers = require('./helpers').Helpers; // Methods common to both the `Grammar` and `SchemaGrammar` interfaces, // used to generate the sql in one form or another. exports.Common = { _debug: false, _promise: null, debug: function() { this._debug = true; return this; }, // For those who dislike promise interfaces. // Multiple calls to `exec` will resolve with the same value // if called more than once. Any unhandled errors will be thrown // after the last block. exec: function(callback) { this._promise || (this._promise = this.runQuery()); return this._promise.then(function(resp) { if (callback) callback(null, resp); }, function(err) { if (callback) callback(err, null); }).then(null, function(err) { setTimeout(function() { throw err; }, 0); }); }, // The promise interface for the query builder. then: function(onFulfilled, onRejected) { this._promise || (this._promise = this.runQuery()); return this._promise.then(onFulfilled, onRejected); }, // Returns an array of query strings filled out with the // correct values based on bindings, etc. Useful for debugging. toString: function() { this.type || (this.type = 'select'); var data = this.toSql(); var builder = this; if (!_.isArray(data)) data = [data]; return _.map(data, function(str) { var questionCount = 0; return str.replace(/\?/g, function() { return builder.bindings[questionCount++]; }); }).join('; '); }, // Explicitly sets the connection. connection: function(connection) { this._connection = connection; return this; }, // The connection the current query is being run on, optionally // specified by the `connection` method. _connection: false, // Sets the "type" of the current query, so we can potentially place // `select`, `update`, `del`, etc. anywhere in the query statement // and have it come out fine. _setType: function(type) { if (this.type) { throw new Error('The query type has already been set to ' + this.type); } this.type = type; return this; }, // Returns all bindings excluding the `Knex.Raw` types. _cleanBindings: function() { var bindings = this.bindings; var cleaned = []; for (var i = 0, l = bindings.length; i < l; i++) { if (!(bindings[i] instanceof Raw)) { cleaned.push(bindings[i]); } else { push.apply(cleaned, bindings[i].bindings); } } return cleaned; }, // Runs the query on the current builder instance and returns a promise. runQuery: function() { if (this.transaction) { if (!this.transaction.connection) { throw new Error('The transaction has already completed.'); } this._connection = this.transaction.connection; } // Prep the SQL associated with the this. this.sql = this.toSql(); this.bindings = this._cleanBindings(); if (!_.isArray(this.sql)) this.sql = [this.sql]; var chain; for (var i = 0, l = this.sql.length; i < l; i++) { if (chain) { chain.then(Helpers.multiQuery(this, i, chain)); } else { chain = Helpers.multiQuery(this, i); } } return chain; } }; }); })( typeof define === 'function' && define.amd ? define : function (factory) { factory(require, exports); } );