Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit eb12562

Browse files
committed
#196: Add DatabaseQueryUnion to perform UNION operations
1 parent e858424 commit eb12562

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed

code/database/query/union.php

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<?php
2+
/**
3+
* Kodekit - http://timble.net/kodekit
4+
*
5+
* @copyright Copyright (C) 2007 - 2016 Johan Janssens and Timble CVBA. (http://www.timble.net)
6+
* @license MPL v2.0 <https://www.mozilla.org/en-US/MPL/2.0>
7+
* @link https://github.com/timble/kodekit for the canonical source repository
8+
*/
9+
10+
namespace Kodekit\Library;
11+
12+
/**
13+
* Union Database Query
14+
*
15+
* @author Ercan Ozkaya <https://github.com/ercanozkaya>
16+
* @package Kodekit\Library\Database\Query
17+
*/
18+
class DatabaseQueryUnion extends DatabaseQuerySelect
19+
{
20+
/**
21+
* Queries
22+
*/
23+
public $queries = [];
24+
25+
/**
26+
* UNION DISTINCT operation
27+
*
28+
* @var boolean
29+
*/
30+
public $distinct = false;
31+
32+
/**
33+
* UNION ALL operation
34+
*
35+
* @var boolean
36+
*/
37+
public $all = false;
38+
39+
/**
40+
* Add queries for the UNION operation
41+
*
42+
* @param DatabaseQuerySelect $query
43+
* @return $this
44+
*/
45+
public function union(DatabaseQuerySelect $query)
46+
{
47+
$this->queries[] = $query;
48+
49+
return $this;
50+
}
51+
52+
/**
53+
* Checks if the current query should use UNION ALL
54+
*
55+
* @return boolean
56+
*/
57+
public function isUnionAllQuery()
58+
{
59+
return (bool) $this->all;
60+
}
61+
62+
/**
63+
* Make the query use UNION ALL
64+
*
65+
* @return $this
66+
*/
67+
public function all()
68+
{
69+
$this->all = true;
70+
71+
return $this;
72+
}
73+
74+
/**
75+
* Set columns in all queries
76+
*
77+
* @param array $columns
78+
* @return DatabaseQuerySelect|void
79+
*/
80+
public function columns($columns = array())
81+
{
82+
foreach ($this->queries as $query) {
83+
$query->where($columns);
84+
}
85+
}
86+
87+
/**
88+
* Set tables in all queries
89+
*
90+
* @param $table
91+
* @return DatabaseQuerySelect|void
92+
*/
93+
public function table($table)
94+
{
95+
foreach ($this->queries as $query) {
96+
$query->table($table);
97+
}
98+
}
99+
100+
/**
101+
* Set joins in all queries
102+
*
103+
* @param string $table
104+
* @param null $condition
105+
* @param string $type
106+
* @return $this|DatabaseQuerySelect
107+
*/
108+
public function join($table, $condition = null, $type = 'LEFT')
109+
{
110+
foreach ($this->queries as $query) {
111+
$query->where($table, $condition, $type);
112+
}
113+
114+
return $this;
115+
}
116+
117+
/**
118+
* Set where clauses in all queries
119+
*
120+
* @param string $condition
121+
* @param string $combination
122+
* @return $this|DatabaseQuerySelect
123+
*/
124+
public function where($condition, $combination = 'AND')
125+
{
126+
foreach ($this->queries as $query) {
127+
$query->where($condition, $combination);
128+
}
129+
130+
return $this;
131+
}
132+
133+
/**
134+
* Set groups in all queries
135+
*
136+
* @param array|string $columns
137+
* @return $this|DatabaseQuerySelect
138+
*/
139+
public function group($columns)
140+
{
141+
foreach ($this->queries as $query) {
142+
$query->group($columns);
143+
}
144+
145+
return $this;
146+
}
147+
148+
/**
149+
* Set having constraints in all queries
150+
* @param array|string $columns
151+
* @return $this|DatabaseQuerySelect
152+
*/
153+
public function having($columns)
154+
{
155+
foreach ($this->queries as $query) {
156+
$query->having($columns);
157+
}
158+
159+
return $this;
160+
}
161+
162+
/**
163+
* Render the query to a string
164+
*
165+
* @return string The completed query
166+
* @throws \RuntimeException When there are less than 2 queries to combine
167+
*/
168+
public function toString()
169+
{
170+
if (count($this->queries) < 2) {
171+
throw new \RuntimeException("Union needs at least 2 SELECT queries");
172+
}
173+
174+
$queries = [];
175+
176+
foreach ($this->queries as $query) {
177+
$queries[] = '('.$query->toString().')';
178+
}
179+
180+
$driver = $this->getDriver();
181+
$glue = $this->all ? 'UNION ALL' : ($this->distinct ? 'UNION DISTINCT' : 'UNION');
182+
$query = implode("\n".$glue."\n", $queries);
183+
184+
if($this->order)
185+
{
186+
$query .= ' ORDER BY ';
187+
188+
$list = array();
189+
foreach($this->order as $order) {
190+
$list[] = $driver->quoteIdentifier($order['column']).' '.$order['direction'];
191+
}
192+
193+
$query .= implode(' , ', $list);
194+
}
195+
196+
if($this->limit) {
197+
$query .= ' LIMIT '.$this->offset.' , '.$this->limit;
198+
}
199+
200+
if($this->_parameters) {
201+
$query = $this->_replaceParams($query);
202+
}
203+
204+
return $query;
205+
}
206+
}

0 commit comments

Comments
 (0)