Passed
Push — v2 ( 3f2240 )
by Berend
04:06
created

QueryBuilder::getSelectClause()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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
 */
9
10
namespace miBadger\Query;
11
12
/**
13
 * The query builder class.
14
 *
15
 * @since 1.0.0
16
 */
17
class QueryBuilder implements QueryInterface
18
{
19
	/* @var string The modifier. SELECT, INSERT INTO, UPDATE or DELETE */
20
	private $modifier;
21
22
	/* @var string The table name. */
23
	private $table;
24
25
	/* @var array The columns. */
26
	private $columns;
27
28
	/* @var array The values. */
29
	private $values;
30
31
	/* @var array The join conditions. */
32
	private $join;
33
34
	/* @var string The where clause. */
35
	private $where;
36
37
	/* @var array The group by conditions. */
38
	private $groupBy;
39
40
	/* @var array The order by conditions. */
41
	private $orderBy;
42
43
	/* @var string The limit. */
44
	private $limit;
45
46
	/* @var string The offset. */
47
	private $offset;
48
49
	/**
50
	 * Construct a query builder object with the given table.
51
	 *
52
	 * @param string $table
53
	 */
54 45
	public function __construct($table)
55
	{
56 45
		$this->table = $table;
57 45
		$this->join = [];
58 45
		$this->where = '';
59 45
		$this->groupBy = [];
60 45
		$this->orderBy = [];
61 45
	}
62
63
	/**
64
	 * Returns a string representation of the query object.
65
	 *
66
	 * @return string a string representation of the query object.
67
	 */
68 45
	public function __toString()
69
	{
70 45
		switch ($this->modifier) {
71 45
			case self::SELECT:
72 33
				return $this->getSelectQuery();
73
74 12
			case self::INSERT:
75 3
				return $this->getInsertQuery();
76
77 9
			case self::UPDATE:
78 4
				return $this->getUpdateQuery();
79
80 5
			case self::DELETE:
81 3
				return $this->getDeleteQuery();
82
83
			default:
84 2
				return '';
85
		}
86
	}
87
88
	/**
89
	 * {@inheritdoc}
90
	 */
91 33
	public function select($columns = ['*'])
92
	{
93 33
		$this->columns = is_array($columns) ? $columns : func_get_args();
94 33
		$this->modifier = self::SELECT;
95
96 33
		return $this;
97
	}
98
99
	/**
100
	 * Returns the select clause.
101
	 *
102
	 * @return string the select clause.
103
	 */
104 33
	private function getSelectClause()
105
	{
106 33
		return sprintf('SELECT %s FROM %s', implode(', ', $this->columns), $this->table);
107
	}
108
109
	/**
110
	 * Returns the select query.
111
	 *
112
	 * @return string the select query.
113
	 */
114 33
	private function getSelectQuery()
115
	{
116 33
		$result = $this->getSelectClause();
117
118 33
		if ($join = $this->getJoinClause()) {
119 8
			$result .= ' ' . $join;
120
		}
121
122 33
		if ($where = $this->getWhereClause()) {
123 9
			$result .= ' ' . $where;
124
		}
125
126 33
		if ($groupBy = $this->getGroupByClause()) {
127 2
			$result .= ' ' . $groupBy;
128
		}
129
130 33
		if ($orderBy = $this->getOrderByClause()) {
131 4
			$result .= ' ' . $orderBy;
132
		}
133
134 33
		if ($limit = $this->getLimitClause()) {
135 4
			$result .= ' ' . $limit;
136
		}
137
138 33
		if ($offset = $this->getOffsetClause()) {
139 2
			$result .= ' ' . $offset;
140
		}
141
142 33
		return $result;
143
	}
144
145
	/**
146
	 * {@inheritdoc}
147
	 */
148 3
	public function insert(array $values)
149
	{
150 3
		$this->values = $values;
151 3
		$this->modifier = self::INSERT;
152
153 3
		return $this;
154
	}
155
156
	/**
157
	 * Returns the insert clause.
158
	 *
159
	 * @return string the insert clause.
160
	 */
161 3
	private function getInsertClause()
162
	{
163 3
		$columns = [];
164 3
		$values = [];
165
166 3
		foreach ($this->values as $key => $value) {
167 3
			$columns[] = $key;
168 3
			$values[] = sprintf('%s', $value);
169
		}
170
171 3
		return sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->table, implode(', ', $columns), implode(', ', $values));
172
	}
173
174
	/**
175
	 * Returns the insert query.
176
	 *
177
	 * @return string the insert query.
178
	 */
179 3
	private function getInsertQuery()
180
	{
181 3
		return $this->getInsertClause();
182
	}
183
184
	/**
185
	 * {@inheritdoc}
186
	 */
187 4
	public function update(array $values)
188
	{
189 4
		$this->values = $values;
190 4
		$this->modifier = self::UPDATE;
191
192 4
		return $this;
193
	}
194
195
	/**
196
	 * Returns the update clause.
197
	 *
198
	 * @return string the update clause.
199
	 */
200 4
	private function getUpdateClause()
201
	{
202 4
		$placeholders = [];
203
204 4
		foreach ($this->values as $key => $value) {
205 4
			$placeholders[] = sprintf('%s = %s', $key, $value);
206
		}
207
208 4
		return sprintf('UPDATE %s SET %s', $this->table, implode(', ', $placeholders));
209
	}
210
211
	/**
212
	 * Returns the update query.
213
	 *
214
	 * @return string the update query.
215
	 */
216 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...
217
	{
218 4
		$result = $this->getUpdateClause();
219
220 4
		if ($where = $this->getWhereClause()) {
221 4
			$result .= ' ' . $where;
222
		}
223
224 4
		if ($limit = $this->getLimitClause()) {
225 1
			$result .= ' ' . $limit;
226
		}
227
228 4
		return $result;
229
	}
230
231
	/**
232
	 * {@inheritdoc}
233
	 */
234 3
	public function delete()
235
	{
236 3
		$this->modifier = self::DELETE;
237
238 3
		return $this;
239
	}
240
241
	/**
242
	 * Returns the delete clause.
243
	 *
244
	 * @return string the delete clause.
245
	 */
246 3
	private function getDeleteClause()
247
	{
248 3
		return sprintf('DELETE FROM %s', $this->table);
249
	}
250
251
	/**
252
	 * Returns the delete query.
253
	 *
254
	 * @return string the delete query.
255
	 */
256 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...
257
	{
258
259 3
		$result = $this->getDeleteClause();
260
261 3
		if ($where = $this->getWhereClause()) {
262 2
			$result .= ' ' . $where;
263
		}
264
265 3
		if ($limit = $this->getLimitClause()) {
266 1
			$result .= ' ' . $limit;
267
		}
268
269 3
		return $result;
270
	}
271
272
	/**
273
	 * {@inheritdoc}
274
	 */
275 2
	public function join($table, $primary, $operator, $secondary)
276
	{
277 2
		$this->join[] = ['INNER JOIN', $table, $primary, $operator, $secondary];
278
279 2
		return $this;
280
	}
281
282
	/**
283
	 * {@inheritdoc}
284
	 */
285 2
	public function leftJoin($table, $primary, $operator, $secondary)
286
	{
287 2
		$this->join[] = ['LEFT JOIN', $table, $primary, $operator, $secondary];
288
289 2
		return $this;
290
	}
291
292
	/**
293
	 * {@inheritdoc}
294
	 */
295 2
	public function rightJoin($table, $primary, $operator, $secondary)
296
	{
297 2
		$this->join[] = ['RIGHT JOIN', $table, $primary, $operator, $secondary];
298
299 2
		return $this;
300
	}
301
302
	/**
303
	 * {@inheritdoc}
304
	 */
305 2
	public function crossJoin($table, $primary, $operator, $secondary)
306
	{
307 2
		$this->join[] = ['CROSS JOIN', $table, $primary, $operator, $secondary];
308
309 2
		return $this;
310
	}
311
312 33
	private function getJoinClause()
313
	{
314 33
		$result = [];
315
316 33
		foreach ($this->join as $key => $value) {
317 8
			$result[] = sprintf('%s %s ON %s %s %s', $value[0], $value[1], $value[2], $value[3], $value[4]);
318
		}
319
320 33
		return implode(' ', $result);
321
	}
322
323
	/**
324
	 * {@inheritdoc}
325
	 */
326 15
	public function where(QueryExpression $whereClause)
327
	{
328 15
		$this->where = $whereClause;
0 ignored issues
show
Documentation Bug introduced by
It seems like $whereClause of type object<miBadger\Query\QueryExpression> is incompatible with the declared type string of property $where.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
329
330 15
		return $this;
331
	}
332
333
	/**
334
	 * Returns the where clause.
335
	 *
336
	 * @return string the where clause.
337
	 */
338 40
	private function getWhereClause()
339
	{
340 40
		if (empty($this->where)) {
341 25
			return '';
342
		}
343
344 15
		return sprintf('WHERE %s', (string) $this->where);
345
	}
346
347
	/**
348
	 * Returns the where condition.
349
	 *
350
	 * @param string $column
351
	 * @param string $operator
352
	 * @param mixed $value
353
	 * @return string the where condition.
354
	 */
355
	private function getWhereCondition($column, $operator, $value)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
356
	{
357
		if ($operator == 'IN') {
358
			return sprintf('%s IN (%s)', $column, is_array($value) ? implode(', ', $value) : $value);
359
		} else {
360
			return sprintf('%s %s %s', $column, $operator, $value);
361
		}
362
	}
363
364
	/**
365
	 * {@inheritdoc}
366
	 */
367 2
	public function groupBy($column)
368
	{
369 2
		$this->groupBy[] = $column;
370
371 2
		return $this;
372
	}
373
374
	/**
375
	 * Returns the group by clause.
376
	 *
377
	 * @return string the group by clause.
378
	 */
379 33
	private function getGroupByClause()
380
	{
381 33
		if (empty($this->groupBy)) {
382 31
			return '';
383
		}
384
385 2
		return sprintf('GROUP BY %s', implode(', ', $this->groupBy));
386
	}
387
388
	/**
389
	 * {@inheritdoc}
390
	 */
391 4
	public function orderBy($column, $order = null)
392
	{
393 4
		if (strcasecmp($order, 'asc') == 0) {
394 1
			$column .= ' ASC';
395 3
		} elseif(strcasecmp($order, 'desc') == 0) {
396 2
			$column .= ' DESC';
397
		}
398
399 4
		$this->orderBy[] = $column;
400
401 4
		return $this;
402
	}
403
404
	/**
405
	 * Returns the order by clause.
406
	 *
407
	 * @return string the order by clause.
408
	 */
409 33
	private function getOrderByClause()
410
	{
411 33
		if (empty($this->orderBy)) {
412 29
			return '';
413
		}
414
415 4
		return sprintf('ORDER BY %s', implode(', ', $this->orderBy));
416
	}
417
418
	/**
419
	 * {@inheritdoc}
420
	 */
421 6
	public function limit($limit)
422
	{
423 6
		$this->limit = $limit;
424
425 6
		return $this;
426
	}
427
428
	/**
429
	 * Returns the limit clause.
430
	 *
431
	 * @return string the limit clause.
432
	 */
433 40
	private function getLimitClause()
434
	{
435 40
		if (!$this->limit) {
436 34
			return '';
437
		}
438
439 6
		return sprintf('LIMIT %s', $this->limit);
440
	}
441
442
	/**
443
	 * {@inheritdoc}
444
	 */
445 2
	public function offset($offset)
446
	{
447 2
		$this->offset = $offset;
448
449 2
		return $this;
450
	}
451
452
	/**
453
	 * Returns the offset clause.
454
	 *
455
	 * @return string the offset clause.
456
	 */
457 33
	private function getOffsetClause()
458
	{
459 33
		if (!$this->limit || !$this->offset) {
460 31
			return '';
461
		}
462
463 2
		return sprintf('OFFSET %s', $this->offset);
464
	}
465
}
466