Completed
Push — develop ( a8f2f9...e187dc )
by Michael
04:21
created

QueryBuilder::join()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 4
crap 1
1
<?php
2
3
/**
4
 * This file is part of the miBadger package.
5
 *
6
 * @author Michael Webbers <[email protected]>
7
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
8
 * @version 1.0.0
9
 */
10
11
namespace miBadger\Query;
12
13
/**
14
 * The query builder class.
15
 *
16
 * @since 1.0.0
17
 */
18
class QueryBuilder implements QueryInterface
19
{
20
	/* @var string The modifier. SELECT, INSERT INTO, UPDATE or DELETE */
21
	private $modifier;
22
23
	/* @var string The table name. */
24
	private $table;
25
26
	/* @var array The columns. */
27
	private $columns;
28
29
	/* @var array The values. */
30
	private $values;
31
32
	/* @var array The join conditions. */
33
	private $join;
34
35
	/* @var array The where conditions. */
36
	private $where;
37
38
	/* @var array The group by conditions. */
39
	private $groupBy;
40
41
	/* @var array The order by conditions. */
42
	private $orderBy;
43
44
	/* @var string The limit. */
45
	private $limit;
46
47
	/* @var string The offset. */
48
	private $offset;
49
50
	/**
51
	 * Construct a query builder object with the given table.
52
	 *
53
	 * @param string $table
54
	 */
55 45
	public function __construct($table)
56
	{
57 45
		$this->table = $table;
58 45
		$this->join = [];
59 45
		$this->where = [];
60 45
		$this->groupBy = [];
61 45
		$this->orderBy = [];
62 45
	}
63
64
	/**
65
	 * Returns a string representation of the query object.
66
	 *
67
	 * @return string a string representation of the query object.
68
	 */
69 45
	public function __toString()
70
	{
71 45
		switch ($this->modifier) {
72 45
			case self::SELECT:
73 33
				return $this->getSelectQuery();
74
75 12
			case self::INSERT:
76 3
				return $this->getInsertQuery();
77
78 9
			case self::UPDATE:
79 4
				return $this->getUpdateQuery();
80
81 5
			case self::DELETE:
82 3
				return $this->getDeleteQuery();
83
84 2
			default:
85 2
				return '';
86 2
		}
87
	}
88
89
	/**
90
	 * {@inheritdoc}
91
	 */
92 33
	public function select($columns = ['*'])
93
	{
94 33
		$this->columns = is_array($columns) ? $columns : func_get_args();
95 33
		$this->modifier = self::SELECT;
96
97 33
		return $this;
98
	}
99
100
	/**
101
	 * Returns the select clause.
102
	 *
103
	 * @return string the select clause.
104
	 */
105 33
	private function getSelectClause()
106
	{
107 33
		return sprintf('SELECT %s FROM %s', implode(', ', $this->columns), $this->table);
108
	}
109
110
	/**
111
	 * Returns the select query.
112
	 *
113
	 * @return string the select query.
114
	 */
115 33
	private function getSelectQuery()
116
	{
117 33
		$result = $this->getSelectClause();
118
119 33
		if ($join = $this->getJoinClause()) {
120 8
			$result .= ' ' . $join;
121 8
		}
122
123 33
		if ($where = $this->getWhereClause()) {
124 9
			$result .= ' ' . $where;
125 9
		}
126
127 33
		if ($groupBy = $this->getGroupByClause()) {
128 2
			$result .= ' ' . $groupBy;
129 2
		}
130
131 33
		if ($orderBy = $this->getOrderByClause()) {
132 4
			$result .= ' ' . $orderBy;
133 4
		}
134
135 33
		if ($limit = $this->getLimitClause()) {
136 4
			$result .= ' ' . $limit;
137 4
		}
138
139 33
		if ($offset = $this->getOffsetClause()) {
140 2
			$result .= ' ' . $offset;
141 2
		}
142
143 33
		return $result;
144
	}
145
146
	/**
147
	 * {@inheritdoc}
148
	 */
149 3
	public function insert(array $values)
150
	{
151 3
		$this->values = $values;
152 3
		$this->modifier = self::INSERT;
153
154 3
		return $this;
155
	}
156
157
	/**
158
	 * Returns the insert clause.
159
	 *
160
	 * @return string the insert clause.
161
	 */
162 3
	private function getInsertClause()
163
	{
164 3
		$columns = [];
165 3
		$values = [];
166
167 3
		foreach ($this->values as $key => $value) {
168 3
			$columns[] = $key;
169 3
			$values[] = sprintf('%s', $value);
170 3
		}
171
172 3
		return sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->table, implode(', ', $columns), implode(', ', $values));
173
	}
174
175
	/**
176
	 * Returns the insert query.
177
	 *
178
	 * @return string the insert query.
179
	 */
180 3
	private function getInsertQuery()
181
	{
182 3
		return $this->getInsertClause();
183
	}
184
185
	/**
186
	 * {@inheritdoc}
187
	 */
188 4
	public function update(array $values)
189
	{
190 4
		$this->values = $values;
191 4
		$this->modifier = self::UPDATE;
192
193 4
		return $this;
194
	}
195
196
	/**
197
	 * Returns the update clause.
198
	 *
199
	 * @return string the update clause.
200
	 */
201 4
	private function getUpdateClause()
202
	{
203 4
		$placeholders = [];
204
205 4
		foreach ($this->values as $key => $value) {
206 4
			$placeholders[] = sprintf('%s = %s', $key, $value);
207 4
		}
208
209 4
		return sprintf('UPDATE %s SET %s', $this->table, implode(', ', $placeholders));
210
	}
211
212
	/**
213
	 * Returns the update query.
214
	 *
215
	 * @return string the update query.
216
	 */
217 4 View Code Duplication
	private function getUpdateQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
	{
219 4
		$result = $this->getUpdateClause();
220
221 4
		if ($where = $this->getWhereClause()) {
222 4
			$result .= ' ' . $where;
223 4
		}
224
225 4
		if ($limit = $this->getLimitClause()) {
226 1
			$result .= ' ' . $limit;
227 1
		}
228
229 4
		return $result;
230
	}
231
232
	/**
233
	 * {@inheritdoc}
234
	 */
235 3
	public function delete()
236
	{
237 3
		$this->modifier = self::DELETE;
238
239 3
		return $this;
240
	}
241
242
	/**
243
	 * Returns the delete clause.
244
	 *
245
	 * @return string the delete clause.
246
	 */
247 3
	private function getDeleteClause()
248
	{
249 3
		return sprintf('DELETE FROM %s', $this->table);
250
	}
251
252
	/**
253
	 * Returns the delete query.
254
	 *
255
	 * @return string the delete query.
256
	 */
257 3 View Code Duplication
	private function getDeleteQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
	{
259
260 3
		$result = $this->getDeleteClause();
261
262 3
		if ($where = $this->getWhereClause()) {
263 2
			$result .= ' ' . $where;
264 2
		}
265
266 3
		if ($limit = $this->getLimitClause()) {
267 1
			$result .= ' ' . $limit;
268 1
		}
269
270 3
		return $result;
271
	}
272
273
	/**
274
	 * {@inheritdoc}
275
	 */
276 2
	public function join($table, $primary, $operator, $secondary)
277
	{
278 2
		$this->join[] = ['INNER JOIN', $table, $primary, $operator, $secondary];
279
280 2
		return $this;
281
	}
282
283
	/**
284
	 * {@inheritdoc}
285
	 */
286 2
	public function leftJoin($table, $primary, $operator, $secondary)
287
	{
288 2
		$this->join[] = ['LEFT JOIN', $table, $primary, $operator, $secondary];
289
290 2
		return $this;
291
	}
292
293
	/**
294
	 * {@inheritdoc}
295
	 */
296 2
	public function rightJoin($table, $primary, $operator, $secondary)
297
	{
298 2
		$this->join[] = ['RIGHT JOIN', $table, $primary, $operator, $secondary];
299
300 2
		return $this;
301
	}
302
303
	/**
304
	 * {@inheritdoc}
305
	 */
306 2
	public function crossJoin($table, $primary, $operator, $secondary)
307
	{
308 2
		$this->join[] = ['CROSS JOIN', $table, $primary, $operator, $secondary];
309
310 2
		return $this;
311
	}
312
313 33
	private function getJoinClause()
314
	{
315 33
		$result = [];
316
317 33
		foreach ($this->join as $key => $value) {
318 8
			$result[] = sprintf('%s %s ON %s %s %s', $value[0], $value[1], $value[2], $value[3], $value[4]);
319 33
		}
320
321 33
		return implode(' ', $result);
322
	}
323
324
	/**
325
	 * {@inheritdoc}
326
	 */
327 15
	public function where($column, $operator, $value)
328
	{
329 15
		$this->where[] = [$column, $operator, $value];
330
331 15
		return $this;
332
	}
333
334
	/**
335
	 * Returns the where clause.
336
	 *
337
	 * @return string the where clause.
338
	 */
339 40
	private function getWhereClause()
340
	{
341 40
		if (empty($this->where)) {
342 25
			return '';
343
		}
344
345 15
		$result = [];
346
347 15
		foreach ($this->where as $key => $value) {
348 15
			$result[] = $this->getWhereCondition($value[0], $value[1], $value[2]);
349 15
		}
350
351 15
		return sprintf('WHERE %s', implode(' AND ', $result));
352
	}
353
354
	/**
355
	 * Returns the where condition.
356
	 *
357
	 * @param string $column
358
	 * @param string $operator
359
	 * @param mixed $value
360
	 * @return string the where condition.
361
	 */
362 15
	private function getWhereCondition($column, $operator, $value)
363
	{
364 15
		if ($operator == 'IN') {
365 3
			return sprintf('%s IN (%s)', $column, is_array($value) ? implode(', ', $value) : $value);
366
		} else {
367 12
			return sprintf('%s %s %s', $column, $operator, $value);
368
		}
369
	}
370
371
	/**
372
	 * {@inheritdoc}
373
	 */
374 2
	public function groupBy($column)
375
	{
376 2
		$this->groupBy[] = $column;
377
378 2
		return $this;
379
	}
380
381
	/**
382
	 * Returns the group by clause.
383
	 *
384
	 * @return string the group by clause.
385
	 */
386 33
	private function getGroupByClause()
387
	{
388 33
		if (empty($this->groupBy)) {
389 31
			return '';
390
		}
391
392 2
		return sprintf('GROUP BY %s', implode(', ', $this->groupBy));
393
	}
394
395
	/**
396
	 * {@inheritdoc}
397
	 */
398 4
	public function orderBy($column, $order = null)
399
	{
400 4
		if (strcasecmp($order, 'asc') == 0) {
401 1
			$column .= ' ASC';
402 4
		} elseif(strcasecmp($order, 'desc') == 0) {
403 2
			$column .= ' DESC';
404 2
		}
405
406 4
		$this->orderBy[] = $column;
407
408 4
		return $this;
409
	}
410
411
	/**
412
	 * Returns the order by clause.
413
	 *
414
	 * @return string the order by clause.
415
	 */
416 33
	private function getOrderByClause()
417
	{
418 33
		if (empty($this->orderBy)) {
419 29
			return '';
420
		}
421
422 4
		return sprintf('ORDER BY %s', implode(', ', $this->orderBy));
423
	}
424
425
	/**
426
	 * {@inheritdoc}
427
	 */
428 6
	public function limit($limit)
429
	{
430 6
		$this->limit = $limit;
431
432 6
		return $this;
433
	}
434
435
	/**
436
	 * Returns the limit clause.
437
	 *
438
	 * @return string the limit clause.
439
	 */
440 40
	private function getLimitClause()
441
	{
442 40
		if (!$this->limit) {
443 34
			return '';
444
		}
445
446 6
		return sprintf('LIMIT %s', $this->limit);
447
	}
448
449
	/**
450
	 * {@inheritdoc}
451
	 */
452 2
	public function offset($offset)
453
	{
454 2
		$this->offset = $offset;
455
456 2
		return $this;
457
	}
458
459
	/**
460
	 * Returns the offset clause.
461
	 *
462
	 * @return string the offset clause.
463
	 */
464 33
	private function getOffsetClause()
465
	{
466 33
		if (!$this->limit || !$this->offset) {
467 31
			return '';
468
		}
469
470 2
		return sprintf('OFFSET %s', $this->offset);
471
	}
472
}
473