'use strict'; var assign = require('lodash/object/assign'); // JoinClause // ------- // The "JoinClause" is an object holding any necessary info about a join, // including the type, and any associated tables & columns being joined. function JoinClause(table, type, schema) { this.schema = schema; this.table = table; this.joinType = type; this.and = this; this.clauses = []; } assign(JoinClause.prototype, { grouping: 'join', // Adds an "on" clause to the current join object. on: function on(first, operator, second) { var data, bool = this._bool(); switch (arguments.length) { case 1: { if (typeof first === 'object' && typeof first.toSQL !== 'function') { var i = -1, keys = Object.keys(first); var method = bool === 'or' ? 'orOn' : 'on'; while (++i < keys.length) { this[method](keys[i], first[keys[i]]); } return this; } else { data = [bool, 'on', first]; } break; } case 2: data = [bool, 'on', first, '=', operator];break; default: data = [bool, 'on', first, operator, second]; } this.clauses.push(data); return this; }, // Adds a "using" clause to the current join. using: function using(column) { return this.clauses.push([this._bool(), 'using', column]); }, // Adds an "and on" clause to the current join object. andOn: function andOn() { return this.on.apply(this, arguments); }, // Adds an "or on" clause to the current join object. orOn: function orOn(first, operator, second) { /*jshint unused: false*/ return this._bool('or').on.apply(this, arguments); }, // Explicitly set the type of join, useful within a function when creating a grouped join. type: function type(_type) { this.joinType = _type; return this; }, _bool: function _bool(bool) { if (arguments.length === 1) { this._boolFlag = bool; return this; } var ret = this._boolFlag || 'and'; this._boolFlag = 'and'; return ret; } }); Object.defineProperty(JoinClause.prototype, 'or', { get: function get() { return this._bool('or'); } }); module.exports = JoinClause;