knex/src/query/joinclause.js

96 lines
2.3 KiB
JavaScript
Raw Normal View History

2016-03-02 17:07:05 +01:00
import {assign} from 'lodash'
// 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;
2016-03-02 17:07:05 +01:00
this.joinType = type;
this.and = this;
this.clauses = [];
2016-03-02 17:07:05 +01:00
}
assign(JoinClause.prototype, {
grouping: 'join',
// Adds an "on" clause to the current join object.
on(first, operator, second) {
2016-05-11 15:26:53 +02:00
if (typeof first === 'function') {
this.clauses.push({
type: 'onWrapped',
value: first,
bool: this._bool()
});
return this;
}
let data;
const bool = this._bool()
2016-03-02 17:07:05 +01:00
switch (arguments.length) {
case 1: {
if (typeof first === 'object' && typeof first.toSQL !== 'function') {
const keys = Object.keys(first);
let i = -1;
const method = bool === 'or' ? 'orOn' : 'on'
2016-03-02 17:07:05 +01:00
while (++i < keys.length) {
this[method](keys[i], first[keys[i]])
}
return this;
} else {
data = {type: 'onRaw', value: first, bool};
2016-03-02 17:07:05 +01:00
}
break;
}
case 2: data = {type: 'onBasic', column: first, operator: '=', value: operator, bool}; break;
default: data = {type: 'onBasic', column: first, operator, value: second, bool};
2016-03-02 17:07:05 +01:00
}
this.clauses.push(data);
return this;
},
// Adds a "using" clause to the current join.
using(column) {
return this.clauses.push({type: 'onUsing', column, bool: this._bool()});
2016-03-02 17:07:05 +01:00
},
// Adds an "and on" clause to the current join object.
andOn() {
2016-03-02 17:07:05 +01:00
return this.on.apply(this, arguments);
},
// Adds an "or on" clause to the current join object.
orOn(first, operator, second) {
2016-03-02 17:07:05 +01:00
return this._bool('or').on.apply(this, arguments);
},
// Explicitly set the type of join, useful within a function when creating a grouped join.
type(type) {
2016-03-02 17:07:05 +01:00
this.joinType = type;
return this;
},
_bool(bool) {
2016-03-02 17:07:05 +01:00
if (arguments.length === 1) {
this._boolFlag = bool;
return this;
}
const ret = this._boolFlag || 'and';
2016-03-02 17:07:05 +01:00
this._boolFlag = 'and';
return ret;
}
})
Object.defineProperty(JoinClause.prototype, 'or', {
get () {
2016-03-02 17:07:05 +01:00
return this._bool('or');
}
});
export default JoinClause;