Passed
Push — v2 ( 9e3e75...bd3a11 )
by Berend
01:38
created

Query::AndArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 9
ccs 1
cts 1
cp 1
crap 3
rs 10
c 0
b 0
f 0
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 class.
14
 *
15
 * @since 1.0.0
16
 */
17
class Query implements QueryInterface
18
{
19
	/* @var \PDO The PDO. */
20
	private $pdo;
21
22
	/* @var array The bindings. */
23
	private $bindings;
24
25
	/* @var QueryBuilder The query builder. */
26
	private $queryBuilder;
27
28
	/**
29
	 * Construct a query object with the given pdo and table.
30
	 *
31
	 * @param \PDO $pdo
32
	 * @param string $table
33
	 */
34 21
	public function __construct(\PDO $pdo, $table)
35
	{
36 21
		$this->pdo = $pdo;
37 21
		$this->bindings = [];
38 21
		$this->queryBuilder = new QueryBuilder($table);
39 21
	}
40
41
	/**
42
	 * Returns a string representation of the query object.
43
	 *
44
	 * @return string a string representation of the query object.
45
	 */
46 21
	public function __toString()
47
	{
48 21
		return $this->queryBuilder->__toString();
49
	}
50
51
	/**
52
	 * {@inheritdoc}
53
	 */
54 17
	public function select($columns = ['*'])
55
	{
56 17
		$this->queryBuilder->select(is_array($columns) ? $columns : func_get_args());
57
58 17
		return $this;
59
	}
60
61
	/**
62
	 * {@inheritdoc}
63
	 */
64 1
	public function insert(array $values)
65
	{
66 1
		$this->bindings['insert'] = [];
67 1
		$this->queryBuilder->insert($this->setBindings('insert', $values));
68
69 1
		return $this;
70
	}
71
72
	/**
73
	 * {@inheritdoc}
74
	 */
75 1
	public function update(array $values)
76
	{
77 1
		$this->queryBuilder->update($this->setBindings('update', $values));
78
79 1
		return $this;
80
	}
81
82
	/**
83
	 * {@inheritdoc}
84
	 */
85 1
	public function delete()
86
	{
87 1
		$this->queryBuilder->delete();
88
89 1
		return $this;
90
	}
91
92
	/**
93
	 * {@inheritdoc}
94
	 */
95 1
	public function join($table, $primary, $operator, $secondary)
96
	{
97 1
		$this->queryBuilder->join($table, $primary, $operator, $secondary);
98
99 1
		return $this;
100
	}
101
102
	/**
103
	 * {@inheritdoc}
104
	 */
105 1
	public function leftJoin($table, $primary, $operator, $secondary)
106
	{
107 1
		$this->queryBuilder->leftJoin($table, $primary, $operator, $secondary);
108
109 1
		return $this;
110
	}
111
112
	/**
113
	 * {@inheritdoc}
114
	 */
115 1
	public function rightJoin($table, $primary, $operator, $secondary)
116
	{
117 1
		$this->queryBuilder->rightJoin($table, $primary, $operator, $secondary);
118
119 1
		return $this;
120
	}
121
122
	/**
123
	 * {@inheritdoc}
124
	 */
125 1
	public function crossJoin($table, $primary, $operator, $secondary)
126
	{
127 1
		$this->queryBuilder->crossJoin($table, $primary, $operator, $secondary);
128
129 1
		return $this;
130
	}
131
132
	/**
133
	 * {@inheritdoc}
134
	 */
135 7
	public function where(QueryExpression $exp)
136
	{
137 7
		$conds = $exp->getFlattenedConditions();
138
139 7
		foreach ($conds as $cond) {
140 7
			$cond->bind($this);
141
		}
142
143 7
		$this->queryBuilder->where($exp);
144 7
		return $this;
145
	}
146
147
	/**
148
	 * {@inheritdoc}
149
	 */
150 1
	public function groupBy($column)
151
	{
152 1
		$this->queryBuilder->groupBy($column);
153
154 1
		return $this;
155
	}
156
157
	/**
158
	 * {@inheritdoc}
159
	 */
160 1
	public function orderBy($column, $order = null)
161
	{
162 1
		$this->queryBuilder->orderBy($column, $order);
163
164 1
		return $this;
165
	}
166
167
	/**
168
	 * {@inheritdoc}
169
	 */
170 2
	public function limit($limit)
171
	{
172 2
		$this->queryBuilder->limit($this->setBinding('limit', (int) $limit));
173
174 2
		return $this;
175
	}
176
177
	/**
178
	 * {@inheritdoc}
179
	 */
180 1
	public function offset($offset)
181
	{
182 1
		$this->queryBuilder->offset($this->setBinding('offset', (int) $offset));
183
184 1
		return $this;
185
	}
186
187
	/**
188
	 * Returns the result of the executed prepared query.
189
	 *
190
	 * @return QueryResult the result of the executed prepared query.
191
	 */
192 4
	public function execute()
193
	{
194 4
		$pdoStatement = $this->pdo->prepare((string) $this);
195
196 4
		foreach ($this->bindings as $clause => $predicate) {
197 1
			foreach ($predicate as $key => $value) {
198 1
				$pdoStatement->bindValue(sprintf(':%s%d', $clause, $key + 1), $value, $this->getPdoDataType($value));
199
			}
200
		}
201
202 4
		$pdoStatement->execute();
203
204 4
		return new QueryResult($pdoStatement);
0 ignored issues
show
Bug introduced by
It seems like $pdoStatement can also be of type boolean; however, parameter $pdoStatement of miBadger\Query\QueryResult::__construct() does only seem to accept PDOStatement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

204
		return new QueryResult(/** @scrutinizer ignore-type */ $pdoStatement);
Loading history...
205
	}
206
207
	/**
208
	 * Returns the data type of the given value.
209
	 *
210
	 * @param mixed $value
211
	 * @return int the data type of the given value.
212
	 */
213 1
	private function getPdoDataType($value)
214
	{
215 1
		$result = \PDO::PARAM_STR;
216
217 1
		if (is_bool($value)) {
218 1
			$result = \PDO::PARAM_BOOL;
219 1
		} elseif (is_null($value)) {
220 1
			$result = \PDO::PARAM_NULL;
221 1
		} elseif (is_int($value)) {
222 1
			$result = \PDO::PARAM_INT;
223
		}
224
225 1
		return $result;
226
	}
227
228
	/**
229
	 * Returns a binding for the given clause and value.
230
	 *
231
	 * @param string $clause
232
	 * @param string $value
233
	 * @return string a binding for the given clause and value.
234
	 */
235 10
	public function addBinding($clause, $value)
236
	{
237 10
		$this->bindings[$clause][] = $value;
238
239 10
		return sprintf(':%s%d', $clause, count($this->bindings[$clause]));
240
	}
241
242
	/**
243
	 * Returns bindings for the given clause and values.
244
	 *
245
	 * @param string $clause
246
	 * @param array $values
247
	 * @return array bindings for the given clause and values.
248
	 */
249 3
	public function addBindings($clause, array $values)
250
	{
251 3
		$result = [];
252
253 3
		foreach ($values as $key => $value) {
254 3
			$result[$key] = $this->addBinding($clause, $value);
255
		}
256
257 3
		return $result;
258
	}
259
260
	/**
261
	 * Returns a binding for the given clause and value.
262
	 *
263
	 * @param string $clause
264
	 * @param string $value
265
	 * @return string a binding for the given clause and value.
266
	 */
267 2
	private function setBinding($clause, $value)
268
	{
269 2
		return $this->removeBindings($clause)->addBinding($clause, $value);
270
	}
271
272
	/**
273
	 * Returns bindings for the given clause and values.
274
	 *
275
	 * @param string $clause
276
	 * @param array $values
277
	 * @return array bindings for the given clause and values.
278
	 */
279 2
	private function setBindings($clause, array $values)
280
	{
281 2
		return $this->removeBindings($clause)->addBindings($clause, $values);
282
	}
283
284
	/**
285
	 * Remove the bindings that are associated with the given clause.
286
	 *
287
	 * @param string $clause
288
	 * @return $this
289
	 */
290 4
	private function removeBindings($clause)
291
	{
292 4
		$this->bindings[$clause] = [];
293
294 4
		return $this;
295
	}
296
297
	/**
298
	 * Creates a Greater than Query condition, equivalent to mysql > operator
299
	 * @param string $left the lhs of the condition
300
	 * @param mixed $right the rhs of the condition
301
	 * @return QueryCondition the query condition
302
	 */
303
	public static function Greater($left, $right)
304
	{
305
		return new QueryCondition($left, '>', $right);
306
	}
307
308
	/**
309
	 * Creates a "Greater than or equal to" Query condition, equivalent to mysql >= operator
310
	 * @param string $left the lhs of the condition
311
	 * @param mixed $right the rhs of the condition
312
	 * @return QueryCondition the query condition
313
	 */
314
	public static function GreaterOrEqual($left, $right)
315
	{
316
		return new QueryCondition($left, '>=', $right);
317
	}
318
319
	/**
320
	 * Creates a "Less than" Query condition, equivalent to mysql < operator
321
	 * @param string $left the lhs of the condition
322
	 * @param mixed $right the rhs of the condition
323
	 * @return QueryCondition the query condition
324
	 */
325
	public static function Less($left, $right)
326
	{
327
		return new QueryCondition($left, '<', $right);
328
	}
329
330
	/**
331
	 * Creates a "Less than or equal to" Query condition, equivalent to mysql <= operator
332
	 * @param string $left the lhs of the condition
333
	 * @param mixed $right the rhs of the condition
334
	 * @return QueryCondition the query condition
335
	 */
336
	public static function LessOrEqual($left, $right)
337
	{
338
		return new QueryCondition($left, '<=', $right);
339
	}
340
341
	/**
342
	 * Creates an "equal to" Query condition, equivalent to mysql = operator
343
	 * @param string $left the lhs of the condition
344
	 * @param mixed $right the rhs of the condition
345
	 * @return QueryCondition the query condition
346
	 */
347 7
	public static function Equal($left, $right)
348
	{
349 7
		return new QueryCondition($left, '=', $right);
350
	}
351
352
	/**
353
	 * Creates a "Not equal to" Query condition, equivalent to mysql <> or != operators
354
	 * @param string $left the lhs of the condition
355
	 * @param mixed $right the rhs of the condition
356
	 * @return QueryCondition the query condition
357
	 */
358
	public static function NotEqual($left, $right)
359
	{
360
		return new QueryCondition($left, '<>', $right);
361
	}
362
363
	/**
364
	 * Creates a "Not Like" Query condition, equivalent to mysql NOT LIKE operator
365
	 * @param string $left the lhs of the condition
366
	 * @param mixed $right the rhs of the condition
367
	 * @return QueryCondition the query condition
368
	 */
369 1
	public static function NotLike($left, $right)
370
	{
371 1
		return new QueryCondition($left, 'NOT LIKE', $right);
372
	}
373
374
	/**
375
	 * Creates a "Like" Query condition, equivalent to mysql LIKE operator
376
	 * @param string $left the lhs of the condition
377
	 * @param mixed $right the rhs of the condition
378
	 * @return QueryCondition the query condition
379
	 */
380 8
	public static function Like($left, $right)
381
	{
382 8
		return new QueryCondition($left, 'LIKE', $right);
383
	}
384
385
	/**
386
	 * Creates an "Is" Query condition, equivalent to mysql IS operator
387
	 * @param string $left the lhs of the condition
388
	 * @param mixed $right the rhs of the condition
389
	 * @return QueryCondition the query condition
390
	 */
391
	public static function Is($left, $right)
392
	{
393
		return new QueryCondition($left, 'IS', $right);
394
	}
395
396
	/**
397
	 * Creates an "Is not" Query condition, equivalent to mysql IS NOT operator
398
	 * @param string $left the lhs of the condition
399
	 * @param mixed $right the rhs of the condition
400
	 * @return QueryCondition the query condition
401
	 */
402 1
	public static function IsNot($left, $right)
403
	{
404 1
		return new QueryCondition($left, 'IS NOT', $right);
405
	}
406
407
	/**
408
	 * Creates a "Not in" Query condition, equivalent to mysql NOT IN operator
409
	 * @param string $needle the parameter that cannot be present in the haystack
410
	 * @param string|Array $haystack the values that can be searched through
411
	 * @return QueryCondition the query condition
412
	 */
413
	public static function NotIn($needle, $haystack)
414
	{
415
		return new QueryCondition($needle, 'NOT IN', $haystack);
416
	}
417
418
	/**
419
	 * Creates a "In" Query condition, equivalent to mysql IN operator
420
	 * @param string $needle the parameter that has to be found
421
	 * @param string|Array $haystack the values that can be searched through
422
	 * @return QueryCondition the query condition
423
	 */
424 3
	public static function In($needle, $haystack)
425
	{
426 3
		return new QueryCondition($needle, 'IN', $haystack);
427
	}
428
429
	/**
430
	 * Creates an "AND" predicate from a variable number of expressions
431
	 * @return QueryPredicate the predicate expression
432
	 */
433 3
	public static function And(QueryExpression $left, QueryExpression ...$others)
434
	{
435 3
		return new QueryPredicate('AND', $left, ...$others);
436
	}
437
438
	/**
439
	 * Combines an array of QueryExpression clauses into an AND predicate
440
	 * @return miBadger\Query\QueryExpression|null Either null (if array contains no clauses), 
0 ignored issues
show
Bug introduced by
The type miBadger\Query\miBadger\Query\QueryExpression was not found. Did you mean miBadger\Query\QueryExpression? If so, make sure to prefix the type with \.
Loading history...
441
	 * 				the single clause in the input array, or a QueryPredicate combining the clauses
442 1
	 */
443
	public static function AndArray(Array $clauses)
444 1
	{
445
		if (count($clauses) == 0) {
446
			return null;
447
		} else if (count($clauses) == 1) 
448
		{
449
			return $clauses[0];
450
		} else {
451
			return new QueryPredicate('AND', $clauses[0], ...array_slice($clauses, 1));
452 1
		}
453
	}
454 1
455
	/**
456
	 * Creates an "OR" predicate from a variable number of expressions
457
	 * @return QueryPredicate the predicate expression
458
	 */
459
	public static function Or(QueryExpression $left, QueryExpression ...$others)
460
	{
461
		return new QueryPredicate('OR', $left, ...$others);
462
	}
463
464
	/**
465
	 * Combines an array of QueryExpression clauses into an OR predicate
466
	 * @return miBadger\Query\QueryExpression|null Either null (if array contains no clauses), 
467
	 * 				the single clause in the input array, or a QueryPredicate combining the clauses
468
	 */
469
	public static function OrArray(Array $clauses)
470
	{
471
		if (count($clauses) == 0) {
472
			return null;
473
		} else if (count($clauses) == 1)
474
		{
475
			return $clauses[0];
476
		} else {
477
			return new QueryPredicate('OR', $clauses[0], ...array_slice($clauses, 1));
478
		}
479
	}
480
481
	/**
482
	 * Creates a "NOT" predicate negating an expression
483
	 * @param QueryExpression The condition to be negated
0 ignored issues
show
Bug introduced by
The type miBadger\Query\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
484
	 * @return QueryPredicate the predicate expression
485
	 */
486
	public static function Not(QueryExpression $exp)
487
	{
488
		return new QueryPredicate('NOT', $exp);
489
	}
490
}
491