Skip to content

Commit

Permalink
Merge pull request #660 from werkt/union_wrap_ignored
Browse files Browse the repository at this point in the history
Respect union wrap parameter as last argument
  • Loading branch information
tgriesser committed Feb 9, 2015
2 parents 1c37f76 + 16b234c commit d1d11f1
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 15 deletions.
5 changes: 3 additions & 2 deletions index.html
Expand Up @@ -1014,9 +1014,10 @@ <h3>Join Methods</h3>
</pre>

<p id="Builder-union">
<b class="header">union</b><code>.union(query)</code>
<b class="header">union</b><code>.union([*queries], [wrap])</code>
<br />
Creates a <tt>union</tt> query, taking a callback to build the union statement.
Creates a <tt>union</tt> query, taking an array or a list of callbacks to build the union statement, with optional
boolean wrap. The queries will be individually wrapped in parentheses with a <tt>true</tt> wrap parameter.
</p>

<pre class="display">
Expand Down
34 changes: 21 additions & 13 deletions lib/query/builder.js
Expand Up @@ -435,21 +435,29 @@ QueryBuilder.prototype.orderByRaw = function(sql, bindings) {
};

// Add a union statement to the query.
QueryBuilder.prototype.union = function(callback, wrap) {
if (arguments.length > 1) {
var args = new Array(arguments.length);
for (var i = 0, l = args.length; i < l; i++) {
args[i] = arguments[i];
this.union(args[i]);
QueryBuilder.prototype.union = function(callbacks, wrap) {
if (arguments.length === 1 ||
(arguments.length === 2 && _.isBoolean(wrap))) {
if (!_.isArray(callbacks)) {
callbacks = [callbacks];
}
return this;
for (var i = 0, l = callbacks.length; i < l; i++) {
this._statements.push({
grouping: 'union',
clause: 'union',
value: callbacks[i],
wrap: wrap || false
});
}
} else {
callbacks = _.toArray(arguments).slice(0, arguments.length - 1);
wrap = arguments[arguments.length - 1];
if (!_.isBoolean(wrap)) {
callbacks.push(wrap);
wrap = false;
}
this.union(callbacks, wrap);
}
this._statements.push({
grouping: 'union',
clause: 'union',
value: callback,
wrap: wrap || false
});
return this;
};

Expand Down
87 changes: 87 additions & 0 deletions test/unit/query/builder.js
Expand Up @@ -474,6 +474,93 @@ module.exports = function(qb, clientName, aliasName) {
bindings: [1, 2]
}
});

var multipleArgumentsChain = qb().select('*').from('users').where({id: 1}).union(function() {
this.select('*').from('users').where({id: 2});
}, function() {
this.select('*').from('users').where({id: 3});
});
testsql(multipleArgumentsChain, {
mysql: {
sql: 'select * from `users` where `id` = ? union select * from `users` where `id` = ? union select * from `users` where `id` = ?',
bindings: [1, 2, 3]
},
default: {
sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?',
bindings: [1, 2, 3]
}
});

var arrayChain = qb().select('*').from('users').where({id: 1}).union([
function() {
this.select('*').from('users').where({id: 2});
}, function() {
this.select('*').from('users').where({id: 3});
}
]);
testsql(arrayChain, {
mysql: {
sql: 'select * from `users` where `id` = ? union select * from `users` where `id` = ? union select * from `users` where `id` = ?',
bindings: [1, 2, 3]
},
default: {
sql: 'select * from "users" where "id" = ? union select * from "users" where "id" = ? union select * from "users" where "id" = ?',
bindings: [1, 2, 3]
}
});
});

it("wraps unions", function() {
var wrappedChain = qb().select('*').from('users').where('id', 'in', function() {
this.table('users').max("id").union(function() {
this.table('users').min("id");
}, true);
});
testsql(wrappedChain, {
mysql: {
sql: 'select * from `users` where `id` in (select max(`id`) from `users` union (select min(`id`) from `users`))',
bindings: []
},
default: {
sql: 'select * from "users" where "id" in (select max("id") from "users" union (select min("id") from "users"))',
bindings: []
}
});

// worthwhile since we're playing games with the 'wrap' specification with arguments
var multipleArgumentsWrappedChain = qb().select('*').from('users').where({id: 1}).union(function() {
this.select('*').from('users').where({id: 2});
}, function() {
this.select('*').from('users').where({id: 3});
}, true);
testsql(multipleArgumentsWrappedChain, {
mysql: {
sql: 'select * from `users` where `id` = ? union (select * from `users` where `id` = ?) union (select * from `users` where `id` = ?)',
bindings: [1, 2, 3]
},
default: {
sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)',
bindings: [1, 2, 3]
}
});

var arrayWrappedChain = qb().select('*').from('users').where({id: 1}).union([
function() {
this.select('*').from('users').where({id: 2});
}, function() {
this.select('*').from('users').where({id: 3});
}
], true);
testsql(arrayWrappedChain, {
mysql: {
sql: 'select * from `users` where `id` = ? union (select * from `users` where `id` = ?) union (select * from `users` where `id` = ?)',
bindings: [1, 2, 3]
},
default: {
sql: 'select * from "users" where "id" = ? union (select * from "users" where "id" = ?) union (select * from "users" where "id" = ?)',
bindings: [1, 2, 3]
}
});
});

// it("handles grouped mysql unions", function() {
Expand Down

0 comments on commit d1d11f1

Please sign in to comment.