From 6c70be1553c436f9420b2eb120ef190736ffe699 Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 26 Dec 2013 10:12:58 -0500 Subject: [PATCH] Split union into 2 methods. Having separate methods for union and unionAll makes reading code simpler as there are fewer boolean arguments floating around. --- Cake/Database/Dialect/SqliteDialectTrait.php | 2 +- Cake/Database/Query.php | 38 ++++++++++++++++---- Cake/Test/TestCase/Database/QueryTest.php | 4 +-- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Cake/Database/Dialect/SqliteDialectTrait.php b/Cake/Database/Dialect/SqliteDialectTrait.php index e3a7157297d..d267719fcb7 100644 --- a/Cake/Database/Dialect/SqliteDialectTrait.php +++ b/Cake/Database/Dialect/SqliteDialectTrait.php @@ -125,7 +125,7 @@ protected function _insertQueryTranslator($query) { } $q = $newQuery->connection()->newQuery(); - $newQuery->union($q->select($select), true); + $newQuery->unionAll($q->select($select)); } if ($newQuery->type()) { diff --git a/Cake/Database/Query.php b/Cake/Database/Query.php index 7783d95055b..dd34cd2aec3 100644 --- a/Cake/Database/Query.php +++ b/Cake/Database/Query.php @@ -1163,7 +1163,7 @@ public function offset($num) { * required by calling multiple times this method with different queries. * * By default, the UNION operator will remove duplicate rows, if you wish to include - * every row for all queries, set the second argument to true. + * every row for all queries, use unionAll() * * ## Examples * @@ -1176,9 +1176,33 @@ public function offset($num) { * * ``SELECT id, name FROM things d UNION SELECT id, title FROM articles a`` * + * @param string|Query $query full SQL query to be used in UNION operator + * @param boolean $overwrite whether to reset the list of queries to be operated or not + * @return Query + */ + public function union($query, $overwrite = false) { + if ($overwrite) { + $this->_parts['union'] = []; + } + $this->_parts['union'][] = [ + 'all' => false, + 'query' => $query + ]; + $this->_dirty(); + return $this; + } + +/** + * Adds a complete query to be used in conjunction with the UNION ALL operator with + * this query. This is used to combine the result set of this query with the one + * that will be returned by the passed query. You can add as many queries as you + * required by calling multiple times this method with different queries. + * + * Unlike UNION, UNION ALL will not remove duplicate rows. + * * {{{ - * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']); - * $query->select(['id', 'name'])->from(['d' => 'things'])->union($union, true); + * $union = (new Query($conn))->select(['id', 'title'])->from(['a' => 'articles']); + * $query->select(['id', 'name'])->from(['d' => 'things'])->unionAll($union); * }}} * * Will produce: @@ -1186,15 +1210,17 @@ public function offset($num) { * ``SELECT id, name FROM things d UNION ALL SELECT id, title FROM articles a`` * * @param string|Query $query full SQL query to be used in UNION operator - * @param boolean $all whether to use UNION ALL or not * @param boolean $overwrite whether to reset the list of queries to be operated or not * @return Query */ - public function union($query, $all = false, $overwrite = false) { + public function unionAll($query, $overwrite = false) { if ($overwrite) { $this->_parts['union'] = []; } - $this->_parts['union'][] = compact('all', 'query'); + $this->_parts['union'][] = [ + 'all' => true, + 'query' => $query + ]; $this->_dirty(); return $this; } diff --git a/Cake/Test/TestCase/Database/QueryTest.php b/Cake/Test/TestCase/Database/QueryTest.php index 1444fbb531e..a44a71a583e 100644 --- a/Cake/Test/TestCase/Database/QueryTest.php +++ b/Cake/Test/TestCase/Database/QueryTest.php @@ -1449,7 +1449,7 @@ public function testUnion() { $union = (new Query($this->connection)) ->select(['id', 'title']) ->from(['c' => 'articles']); - $query->select(['id', 'comment'], true)->union($union, false, true); + $query->select(['id', 'comment'], true)->union($union, true); $result = $query->execute(); $this->assertCount(self::COMMENT_COUNT + self::ARTICLE_COUNT, $result); $this->assertEquals($rows, $result->fetchAll()); @@ -1477,7 +1477,7 @@ public function testUnionAll() { ->where(['id ' => 1]) ->order(['id' => 'desc']); - $query->select(['foo' => 'id', 'bar' => 'comment'])->union($union, true); + $query->select(['foo' => 'id', 'bar' => 'comment'])->unionAll($union); $result = $query->execute(); $this->assertCount(1 + self::COMMENT_COUNT + self::ARTICLE_COUNT, $result); $this->assertNotEquals($rows, $result->fetchAll());