These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Query |
||
4 | * |
||
5 | * SQL Query Builder / Database Abstraction Layer |
||
6 | * |
||
7 | * PHP version 5.4 |
||
8 | * |
||
9 | * @package Query |
||
10 | * @author Timothy J. Warren <[email protected]> |
||
11 | * @copyright 2012 - 2015 Timothy J. Warren |
||
12 | * @license http://www.opensource.org/licenses/mit-license.html MIT License |
||
13 | * @link https://git.timshomepage.net/aviat4ion/Query |
||
14 | */ |
||
15 | |||
16 | namespace Query; |
||
17 | |||
18 | use Query\Drivers\DriverInterface; |
||
19 | use BadMethodCallException; |
||
20 | |||
21 | /** |
||
22 | * Convenience class for creating sql queries - also the class that |
||
23 | * instantiates the specific db driver |
||
24 | * |
||
25 | * @package Query |
||
26 | * @subpackage Query_Builder |
||
27 | */ |
||
28 | class QueryBuilder extends AbstractQueryBuilder implements QueryBuilderInterface { |
||
29 | |||
30 | /** |
||
31 | * String class values to be reset |
||
32 | * |
||
33 | * @var array |
||
34 | */ |
||
35 | private $string_vars = [ |
||
36 | 'select_string', |
||
37 | 'from_string', |
||
38 | 'set_string', |
||
39 | 'order_string', |
||
40 | 'group_string', |
||
41 | 'limit', |
||
42 | 'offset', |
||
43 | 'explain', |
||
44 | ]; |
||
45 | |||
46 | /** |
||
47 | * Array class variables to be reset |
||
48 | * |
||
49 | * @var array |
||
50 | */ |
||
51 | private $array_vars = [ |
||
52 | 'set_array_keys', |
||
53 | 'order_array', |
||
54 | 'group_array', |
||
55 | 'values', |
||
56 | 'where_values', |
||
57 | 'query_map', |
||
58 | 'having_map' |
||
59 | ]; |
||
60 | |||
61 | // -------------------------------------------------------------------------- |
||
62 | // ! Methods |
||
63 | // -------------------------------------------------------------------------- |
||
64 | |||
65 | /** |
||
66 | * Constructor |
||
67 | * |
||
68 | * @param DriverInterface $db |
||
69 | * @param QueryParser $parser |
||
70 | */ |
||
71 | public function __construct(DriverInterface $db, QueryParser $parser) |
||
72 | { |
||
73 | // Inject driver and parser |
||
74 | $this->db = $db; |
||
75 | $this->parser = $parser; |
||
76 | |||
77 | $this->queries['total_time'] = 0; |
||
78 | |||
79 | // Alias driver sql and util classes |
||
80 | $this->sql = $this->db->get_sql(); |
||
81 | $this->util = $this->db->get_util(); |
||
82 | } |
||
83 | |||
84 | // -------------------------------------------------------------------------- |
||
85 | |||
86 | /** |
||
87 | * Destructor |
||
88 | * @codeCoverageIgnore |
||
89 | */ |
||
90 | public function __destruct() |
||
91 | { |
||
92 | $this->db = NULL; |
||
93 | } |
||
94 | |||
95 | // -------------------------------------------------------------------------- |
||
96 | |||
97 | /** |
||
98 | * Calls a function further down the inheritence chain |
||
99 | * |
||
100 | * @param string $name |
||
101 | * @param array $params |
||
102 | * @return mixed |
||
103 | * @throws BadMethodCallException |
||
104 | */ |
||
105 | public function __call($name, $params) |
||
106 | { |
||
107 | // Allow camel-case method calls |
||
108 | $snake_name = \from_camel_case($name); |
||
109 | |||
110 | foreach([$this, $this->db] as $object) |
||
111 | { |
||
112 | foreach([$name, $snake_name] as $method_name) |
||
113 | { |
||
114 | if (method_exists($object, $method_name)) |
||
115 | { |
||
116 | return call_user_func_array([$object, $method_name], $params); |
||
117 | } |
||
118 | } |
||
119 | |||
120 | } |
||
121 | |||
122 | throw new BadMethodCallException("Method does not exist"); |
||
123 | } |
||
124 | |||
125 | // -------------------------------------------------------------------------- |
||
126 | // ! Select Queries |
||
127 | // -------------------------------------------------------------------------- |
||
128 | |||
129 | /** |
||
130 | * Specifies rows to select in a query |
||
131 | * |
||
132 | * @param string $fields |
||
133 | * @return QueryBuilderInterface |
||
134 | */ |
||
135 | public function select($fields) |
||
136 | { |
||
137 | // Split fields by comma |
||
138 | $fields_array = explode(",", $fields); |
||
139 | $fields_array = array_map('mb_trim', $fields_array); |
||
140 | |||
141 | // Split on 'As' |
||
142 | foreach ($fields_array as $key => $field) |
||
143 | { |
||
144 | if (stripos($field, 'as') !== FALSE) |
||
145 | { |
||
146 | $fields_array[$key] = preg_split('` as `i', $field); |
||
147 | $fields_array[$key] = array_map('mb_trim', $fields_array[$key]); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | // Quote the identifiers |
||
152 | $safe_array = $this->db->quote_ident($fields_array); |
||
153 | |||
154 | unset($fields_array); |
||
155 | |||
156 | // Join the strings back together |
||
157 | for($i = 0, $c = count($safe_array); $i < $c; $i++) |
||
158 | { |
||
159 | if (is_array($safe_array[$i])) |
||
160 | { |
||
161 | $safe_array[$i] = implode(' AS ', $safe_array[$i]); |
||
162 | } |
||
163 | } |
||
164 | |||
165 | $this->select_string .= implode(', ', $safe_array); |
||
166 | |||
167 | unset($safe_array); |
||
168 | |||
169 | return $this; |
||
170 | } |
||
171 | |||
172 | // -------------------------------------------------------------------------- |
||
173 | |||
174 | /** |
||
175 | * Selects the maximum value of a field from a query |
||
176 | * |
||
177 | * @param string $field |
||
178 | * @param string|bool $as |
||
179 | * @return QueryBuilderInterface |
||
180 | */ |
||
181 | public function select_max($field, $as=FALSE) |
||
182 | { |
||
183 | // Create the select string |
||
184 | $this->select_string .= ' MAX'.$this->_select($field, $as); |
||
185 | return $this; |
||
186 | } |
||
187 | |||
188 | // -------------------------------------------------------------------------- |
||
189 | |||
190 | /** |
||
191 | * Selects the minimum value of a field from a query |
||
192 | * |
||
193 | * @param string $field |
||
194 | * @param string|bool $as |
||
195 | * @return QueryBuilderInterface |
||
196 | */ |
||
197 | public function select_min($field, $as=FALSE) |
||
198 | { |
||
199 | // Create the select string |
||
200 | $this->select_string .= ' MIN'.$this->_select($field, $as); |
||
201 | return $this; |
||
202 | } |
||
203 | |||
204 | // -------------------------------------------------------------------------- |
||
205 | |||
206 | /** |
||
207 | * Selects the average value of a field from a query |
||
208 | * |
||
209 | * @param string $field |
||
210 | * @param string|bool $as |
||
211 | * @return QueryBuilderInterface |
||
212 | */ |
||
213 | public function select_avg($field, $as=FALSE) |
||
214 | { |
||
215 | // Create the select string |
||
216 | $this->select_string .= ' AVG'.$this->_select($field, $as); |
||
217 | return $this; |
||
218 | } |
||
219 | |||
220 | // -------------------------------------------------------------------------- |
||
221 | |||
222 | /** |
||
223 | * Selects the sum of a field from a query |
||
224 | * |
||
225 | * @param string $field |
||
226 | * @param string|bool $as |
||
227 | * @return QueryBuilderInterface |
||
228 | */ |
||
229 | public function select_sum($field, $as=FALSE) |
||
230 | { |
||
231 | // Create the select string |
||
232 | $this->select_string .= ' SUM'.$this->_select($field, $as); |
||
233 | return $this; |
||
234 | } |
||
235 | |||
236 | // -------------------------------------------------------------------------- |
||
237 | |||
238 | /** |
||
239 | * Adds the 'distinct' keyword to a query |
||
240 | * |
||
241 | * @return QueryBuilderInterface |
||
242 | */ |
||
243 | public function distinct() |
||
244 | { |
||
245 | // Prepend the keyword to the select string |
||
246 | $this->select_string = ' DISTINCT '.$this->select_string; |
||
247 | return $this; |
||
248 | } |
||
249 | |||
250 | // -------------------------------------------------------------------------- |
||
251 | |||
252 | /** |
||
253 | * Tell the database to give you the query plan instead of result set |
||
254 | * |
||
255 | * @return QueryBuilderInterface |
||
256 | */ |
||
257 | public function explain() |
||
258 | { |
||
259 | $this->explain = TRUE; |
||
260 | return $this; |
||
261 | } |
||
262 | |||
263 | // -------------------------------------------------------------------------- |
||
264 | |||
265 | /** |
||
266 | * Specify the database table to select from |
||
267 | * |
||
268 | * @param string $tblname |
||
269 | * @return QueryBuilderInterface |
||
270 | */ |
||
271 | public function from($tblname) |
||
272 | { |
||
273 | // Split identifiers on spaces |
||
274 | $ident_array = explode(' ', \mb_trim($tblname)); |
||
275 | $ident_array = array_map('\\mb_trim', $ident_array); |
||
276 | |||
277 | // Quote the identifiers |
||
278 | $ident_array[0] = $this->db->quote_table($ident_array[0]); |
||
279 | $ident_array = $this->db->quote_ident($ident_array); |
||
280 | |||
281 | // Paste it back together |
||
282 | $this->from_string = implode(' ', $ident_array); |
||
283 | |||
284 | return $this; |
||
285 | } |
||
286 | |||
287 | // -------------------------------------------------------------------------- |
||
288 | // ! 'Like' methods |
||
289 | // -------------------------------------------------------------------------- |
||
290 | |||
291 | /** |
||
292 | * Creates a Like clause in the sql statement |
||
293 | * |
||
294 | * @param string $field |
||
295 | * @param mixed $val |
||
296 | * @param string $pos |
||
297 | * @return QueryBuilderInterface |
||
298 | */ |
||
299 | public function like($field, $val, $pos='both') |
||
300 | { |
||
301 | return $this->_like($field, $val, $pos, 'LIKE', 'AND'); |
||
302 | } |
||
303 | |||
304 | // -------------------------------------------------------------------------- |
||
305 | |||
306 | /** |
||
307 | * Generates an OR Like clause |
||
308 | * |
||
309 | * @param string $field |
||
310 | * @param mixed $val |
||
311 | * @param string $pos |
||
312 | * @return QueryBuilderInterface |
||
313 | */ |
||
314 | public function or_like($field, $val, $pos='both') |
||
315 | { |
||
316 | return $this->_like($field, $val, $pos, 'LIKE', 'OR'); |
||
317 | } |
||
318 | |||
319 | // -------------------------------------------------------------------------- |
||
320 | |||
321 | /** |
||
322 | * Generates a NOT LIKE clause |
||
323 | * |
||
324 | * @param string $field |
||
325 | * @param mixed $val |
||
326 | * @param string $pos |
||
327 | * @return QueryBuilderInterface |
||
328 | */ |
||
329 | public function not_like($field, $val, $pos='both') |
||
330 | { |
||
331 | return $this->_like($field, $val, $pos, 'NOT LIKE', 'AND'); |
||
332 | } |
||
333 | |||
334 | // -------------------------------------------------------------------------- |
||
335 | |||
336 | /** |
||
337 | * Generates a OR NOT LIKE clause |
||
338 | * |
||
339 | * @param string $field |
||
340 | * @param mixed $val |
||
341 | * @param string $pos |
||
342 | * @return QueryBuilderInterface |
||
343 | */ |
||
344 | public function or_not_like($field, $val, $pos='both') |
||
345 | { |
||
346 | return $this->_like($field, $val, $pos, 'NOT LIKE', 'OR'); |
||
347 | } |
||
348 | |||
349 | // -------------------------------------------------------------------------- |
||
350 | // ! Having methods |
||
351 | // -------------------------------------------------------------------------- |
||
352 | |||
353 | /** |
||
354 | * Generates a 'Having' clause |
||
355 | * |
||
356 | * @param mixed $key |
||
357 | * @param mixed $val |
||
358 | * @return QueryBuilderInterface |
||
359 | */ |
||
360 | public function having($key, $val=[]) |
||
361 | { |
||
362 | return $this->_having($key, $val, 'AND'); |
||
363 | } |
||
364 | |||
365 | // -------------------------------------------------------------------------- |
||
366 | |||
367 | /** |
||
368 | * Generates a 'Having' clause prefixed with 'OR' |
||
369 | * |
||
370 | * @param mixed $key |
||
371 | * @param mixed $val |
||
372 | * @return QueryBuilderInterface |
||
373 | */ |
||
374 | public function or_having($key, $val=[]) |
||
375 | { |
||
376 | return $this->_having($key, $val, 'OR'); |
||
377 | } |
||
378 | |||
379 | // -------------------------------------------------------------------------- |
||
380 | // ! 'Where' methods |
||
381 | // -------------------------------------------------------------------------- |
||
382 | |||
383 | /** |
||
384 | * Specify condition(s) in the where clause of a query |
||
385 | * Note: this function works with key / value, or a |
||
386 | * passed array with key / value pairs |
||
387 | * |
||
388 | * @param mixed $key |
||
389 | * @param mixed $val |
||
390 | * @param mixed $escape |
||
391 | * @return QueryBuilderInterface |
||
392 | */ |
||
393 | public function where($key, $val=[], $escape=NULL) |
||
394 | { |
||
395 | return $this->_where_string($key, $val, 'AND'); |
||
396 | } |
||
397 | |||
398 | // -------------------------------------------------------------------------- |
||
399 | |||
400 | /** |
||
401 | * Where clause prefixed with "OR" |
||
402 | * |
||
403 | * @param string $key |
||
404 | * @param mixed $val |
||
405 | * @return QueryBuilderInterface |
||
406 | */ |
||
407 | public function or_where($key, $val=[]) |
||
408 | { |
||
409 | return $this->_where_string($key, $val, 'OR'); |
||
410 | } |
||
411 | |||
412 | // -------------------------------------------------------------------------- |
||
413 | |||
414 | /** |
||
415 | * Where clause with 'IN' statement |
||
416 | * |
||
417 | * @param mixed $field |
||
418 | * @param mixed $val |
||
419 | * @return QueryBuilderInterface |
||
420 | */ |
||
421 | public function where_in($field, $val=[]) |
||
422 | { |
||
423 | return $this->_where_in($field, $val); |
||
424 | } |
||
425 | |||
426 | // -------------------------------------------------------------------------- |
||
427 | |||
428 | /** |
||
429 | * Where in statement prefixed with "or" |
||
430 | * |
||
431 | * @param string $field |
||
432 | * @param mixed $val |
||
433 | * @return QueryBuilderInterface |
||
434 | */ |
||
435 | public function or_where_in($field, $val=[]) |
||
436 | { |
||
437 | return $this->_where_in($field, $val, 'IN', 'OR'); |
||
438 | } |
||
439 | |||
440 | // -------------------------------------------------------------------------- |
||
441 | |||
442 | /** |
||
443 | * WHERE NOT IN (FOO) clause |
||
444 | * |
||
445 | * @param string $field |
||
446 | * @param mixed $val |
||
447 | * @return QueryBuilderInterface |
||
448 | */ |
||
449 | public function where_not_in($field, $val=[]) |
||
450 | { |
||
451 | return $this->_where_in($field, $val, 'NOT IN', 'AND'); |
||
452 | } |
||
453 | |||
454 | // -------------------------------------------------------------------------- |
||
455 | |||
456 | /** |
||
457 | * OR WHERE NOT IN (FOO) clause |
||
458 | * |
||
459 | * @param string $field |
||
460 | * @param mixed $val |
||
461 | * @return QueryBuilderInterface |
||
462 | */ |
||
463 | public function or_where_not_in($field, $val=[]) |
||
464 | { |
||
465 | return $this->_where_in($field, $val, 'NOT IN', 'OR'); |
||
466 | } |
||
467 | |||
468 | // -------------------------------------------------------------------------- |
||
469 | // ! Other Query Modifier methods |
||
470 | // -------------------------------------------------------------------------- |
||
471 | |||
472 | /** |
||
473 | * Sets values for inserts / updates / deletes |
||
474 | * |
||
475 | * @param mixed $key |
||
476 | * @param mixed $val |
||
477 | * @return QueryBuilderInterface |
||
478 | */ |
||
479 | public function set($key, $val = NULL) |
||
480 | { |
||
481 | $this->_mixed_set($this->set_array_keys, $key, $val, self::KEY); |
||
482 | $this->_mixed_set($this->values, $key, $val, self::VALUE); |
||
483 | |||
484 | // Use the keys of the array to make the insert/update string |
||
485 | // Escape the field names |
||
486 | $this->set_array_keys = array_map([$this->db, '_quote'], $this->set_array_keys); |
||
487 | |||
488 | // Generate the "set" string |
||
489 | $this->set_string = implode('=?,', $this->set_array_keys); |
||
490 | $this->set_string .= '=?'; |
||
491 | |||
492 | return $this; |
||
493 | } |
||
494 | |||
495 | // -------------------------------------------------------------------------- |
||
496 | |||
497 | /** |
||
498 | * Creates a join phrase in a compiled query |
||
499 | * |
||
500 | * @param string $table |
||
501 | * @param string $condition |
||
502 | * @param string $type |
||
503 | * @return QueryBuilderInterface |
||
504 | */ |
||
505 | public function join($table, $condition, $type='') |
||
506 | { |
||
507 | // Prefix and quote table name |
||
508 | $table = explode(' ', mb_trim($table)); |
||
509 | $table[0] = $this->db->quote_table($table[0]); |
||
510 | $table = $this->db->quote_ident($table); |
||
511 | $table = implode(' ', $table); |
||
512 | |||
513 | // Parse out the join condition |
||
514 | $parsed_condition = $this->parser->compile_join($condition); |
||
515 | $condition = $table . ' ON ' . $parsed_condition; |
||
516 | |||
517 | $this->_append_map("\n" . strtoupper($type) . ' JOIN ', $condition, 'join'); |
||
518 | |||
519 | return $this; |
||
520 | } |
||
521 | |||
522 | // -------------------------------------------------------------------------- |
||
523 | |||
524 | /** |
||
525 | * Group the results by the selected field(s) |
||
526 | * |
||
527 | * @param mixed $field |
||
528 | * @return QueryBuilderInterface |
||
529 | */ |
||
530 | public function group_by($field) |
||
531 | { |
||
532 | if ( ! is_scalar($field)) |
||
533 | { |
||
534 | $new_group_array = array_map([$this->db, 'quote_ident'], $field); |
||
535 | $this->group_array = array_merge($this->group_array, $new_group_array); |
||
536 | } |
||
537 | else |
||
538 | { |
||
539 | $this->group_array[] = $this->db->quote_ident($field); |
||
540 | } |
||
541 | |||
542 | $this->group_string = ' GROUP BY ' . implode(',', $this->group_array); |
||
543 | |||
544 | return $this; |
||
545 | } |
||
546 | |||
547 | // -------------------------------------------------------------------------- |
||
548 | |||
549 | /** |
||
550 | * Order the results by the selected field(s) |
||
551 | * |
||
552 | * @param string $field |
||
553 | * @param string $type |
||
554 | * @return QueryBuilderInterface |
||
555 | */ |
||
556 | public function order_by($field, $type="") |
||
557 | { |
||
558 | // When ordering by random, do an ascending order if the driver |
||
559 | // doesn't support random ordering |
||
560 | if (stripos($type, 'rand') !== FALSE) |
||
561 | { |
||
562 | $rand = $this->sql->random(); |
||
563 | $type = ($rand !== FALSE) ? $rand : 'ASC'; |
||
564 | } |
||
565 | |||
566 | // Set fields for later manipulation |
||
567 | $field = $this->db->quote_ident($field); |
||
568 | $this->order_array[$field] = $type; |
||
569 | |||
570 | $order_clauses = []; |
||
571 | |||
572 | // Flatten key/val pairs into an array of space-separated pairs |
||
573 | foreach($this->order_array as $k => $v) |
||
574 | { |
||
575 | $order_clauses[] = $k . ' ' . strtoupper($v); |
||
576 | } |
||
577 | |||
578 | // Set the final string |
||
579 | $this->order_string = ( ! isset($rand)) |
||
580 | ? "\nORDER BY ".implode(', ', $order_clauses) |
||
581 | : "\nORDER BY".$rand; |
||
582 | |||
583 | return $this; |
||
584 | } |
||
585 | |||
586 | // -------------------------------------------------------------------------- |
||
587 | |||
588 | /** |
||
589 | * Set a limit on the current sql statement |
||
590 | * |
||
591 | * @param int $limit |
||
592 | * @param int|bool $offset |
||
593 | * @return QueryBuilderInterface |
||
594 | */ |
||
595 | public function limit($limit, $offset=FALSE) |
||
596 | { |
||
597 | $this->limit = (int) $limit; |
||
598 | $this->offset = $offset; |
||
599 | |||
600 | return $this; |
||
601 | } |
||
602 | |||
603 | // -------------------------------------------------------------------------- |
||
604 | // ! Query Grouping Methods |
||
605 | // -------------------------------------------------------------------------- |
||
606 | |||
607 | /** |
||
608 | * Adds a paren to the current query for query grouping |
||
609 | * |
||
610 | * @return QueryBuilderInterface |
||
611 | */ |
||
612 | public function group_start() |
||
613 | { |
||
614 | $conj = (empty($this->query_map)) ? ' WHERE ' : ' '; |
||
615 | |||
616 | $this->_append_map($conj, '(', 'group_start'); |
||
617 | |||
618 | return $this; |
||
619 | } |
||
620 | |||
621 | // -------------------------------------------------------------------------- |
||
622 | |||
623 | /** |
||
624 | * Adds a paren to the current query for query grouping, |
||
625 | * prefixed with 'NOT' |
||
626 | * |
||
627 | * @return QueryBuilderInterface |
||
628 | */ |
||
629 | public function not_group_start() |
||
630 | { |
||
631 | $conj = (empty($this->query_map)) ? ' WHERE ' : ' AND '; |
||
632 | |||
633 | $this->_append_map($conj, ' NOT (', 'group_start'); |
||
634 | |||
635 | return $this; |
||
636 | } |
||
637 | |||
638 | // -------------------------------------------------------------------------- |
||
639 | |||
640 | /** |
||
641 | * Adds a paren to the current query for query grouping, |
||
642 | * prefixed with 'OR' |
||
643 | * |
||
644 | * @return QueryBuilderInterface |
||
645 | */ |
||
646 | public function or_group_start() |
||
647 | { |
||
648 | $this->_append_map('', ' OR (', 'group_start'); |
||
649 | |||
650 | return $this; |
||
651 | } |
||
652 | |||
653 | // -------------------------------------------------------------------------- |
||
654 | |||
655 | /** |
||
656 | * Adds a paren to the current query for query grouping, |
||
657 | * prefixed with 'OR NOT' |
||
658 | * |
||
659 | * @return QueryBuilderInterface |
||
660 | */ |
||
661 | public function or_not_group_start() |
||
662 | { |
||
663 | $this->_append_map('', ' OR NOT (', 'group_start'); |
||
664 | |||
665 | return $this; |
||
666 | } |
||
667 | |||
668 | // -------------------------------------------------------------------------- |
||
669 | |||
670 | /** |
||
671 | * Ends a query group |
||
672 | * |
||
673 | * @return QueryBuilderInterface |
||
674 | */ |
||
675 | public function group_end() |
||
676 | { |
||
677 | $this->_append_map('', ')', 'group_end'); |
||
678 | |||
679 | return $this; |
||
680 | } |
||
681 | |||
682 | // -------------------------------------------------------------------------- |
||
683 | // ! Query execution methods |
||
684 | // -------------------------------------------------------------------------- |
||
685 | |||
686 | /** |
||
687 | * Select and retrieve all records from the current table, and/or |
||
688 | * execute current compiled query |
||
689 | * |
||
690 | * @param string $table |
||
691 | * @param int|bool $limit |
||
692 | * @param int|bool $offset |
||
693 | * @return \PDOStatement |
||
694 | */ |
||
695 | public function get($table='', $limit=FALSE, $offset=FALSE) |
||
696 | { |
||
697 | // Set the table |
||
698 | if ( ! empty($table)) |
||
699 | { |
||
700 | $this->from($table); |
||
701 | } |
||
702 | |||
703 | // Set the limit, if it exists |
||
704 | if (is_int($limit)) |
||
705 | { |
||
706 | $this->limit($limit, $offset); |
||
707 | } |
||
708 | |||
709 | return $this->_run("get", $table); |
||
710 | } |
||
711 | |||
712 | // -------------------------------------------------------------------------- |
||
713 | |||
714 | /** |
||
715 | * Convenience method for get() with a where clause |
||
716 | * |
||
717 | * @param string $table |
||
718 | * @param array $where |
||
719 | * @param int|bool $limit |
||
720 | * @param int|bool $offset |
||
721 | * @return \PDOStatement |
||
722 | */ |
||
723 | public function get_where($table, $where=[], $limit=FALSE, $offset=FALSE) |
||
724 | { |
||
725 | // Create the where clause |
||
726 | $this->where($where); |
||
727 | |||
728 | // Return the result |
||
729 | return $this->get($table, $limit, $offset); |
||
730 | } |
||
731 | |||
732 | // -------------------------------------------------------------------------- |
||
733 | |||
734 | /** |
||
735 | * Retrieve the number of rows in the selected table |
||
736 | * |
||
737 | * @param string $table |
||
738 | * @return int |
||
739 | */ |
||
740 | public function count_all($table) |
||
741 | { |
||
742 | $sql = 'SELECT * FROM '.$this->db->quote_table($table); |
||
743 | $res = $this->db->query($sql); |
||
0 ignored issues
–
show
|
|||
744 | return (int) count($res->fetchAll()); |
||
745 | } |
||
746 | |||
747 | // -------------------------------------------------------------------------- |
||
748 | |||
749 | /** |
||
750 | * Retrieve the number of results for the generated query - used |
||
751 | * in place of the get() method |
||
752 | * |
||
753 | * @param string $table |
||
754 | * @param boolean $reset |
||
755 | * @return int |
||
756 | */ |
||
757 | public function count_all_results($table='', $reset = TRUE) |
||
758 | { |
||
759 | // Set the table |
||
760 | if ( ! empty($table)) |
||
761 | { |
||
762 | $this->from($table); |
||
763 | } |
||
764 | |||
765 | $result = $this->_run('get', $table, NULL, NULL, $reset); |
||
766 | $rows = $result->fetchAll(); |
||
767 | |||
768 | return (int) count($rows); |
||
769 | } |
||
770 | |||
771 | // -------------------------------------------------------------------------- |
||
772 | |||
773 | /** |
||
774 | * Creates an insert clause, and executes it |
||
775 | * |
||
776 | * @param string $table |
||
777 | * @param mixed $data |
||
778 | * @return \PDOStatement |
||
779 | */ |
||
780 | public function insert($table, $data=[]) |
||
781 | { |
||
782 | if ( ! empty($data)) |
||
783 | { |
||
784 | $this->set($data); |
||
785 | } |
||
786 | |||
787 | return $this->_run("insert", $table); |
||
788 | } |
||
789 | |||
790 | // -------------------------------------------------------------------------- |
||
791 | |||
792 | /** |
||
793 | * Creates and executes a batch insertion query |
||
794 | * |
||
795 | * @param string $table |
||
796 | * @param array $data |
||
797 | * @return \PDOStatement |
||
798 | */ |
||
799 | View Code Duplication | public function insert_batch($table, $data=[]) |
|
800 | { |
||
801 | // Get the generated values and sql string |
||
802 | list($sql, $data) = $this->db->insert_batch($table, $data); |
||
803 | |||
804 | return ( ! is_null($sql)) |
||
805 | ? $this->_run('', $table, $sql, $data) |
||
806 | : NULL; |
||
807 | } |
||
808 | |||
809 | // -------------------------------------------------------------------------- |
||
810 | |||
811 | /** |
||
812 | * Creates an update clause, and executes it |
||
813 | * |
||
814 | * @param string $table |
||
815 | * @param mixed $data |
||
816 | * @return \PDOStatement |
||
817 | */ |
||
818 | public function update($table, $data=[]) |
||
819 | { |
||
820 | if ( ! empty($data)) |
||
821 | { |
||
822 | $this->set($data); |
||
823 | } |
||
824 | |||
825 | return $this->_run("update", $table); |
||
826 | } |
||
827 | |||
828 | // -------------------------------------------------------------------------- |
||
829 | |||
830 | /** |
||
831 | * Creates a batch update, and executes it. |
||
832 | * Returns the number of affected rows |
||
833 | * |
||
834 | * @param string $table |
||
835 | * @param array|object $data |
||
836 | * @param string $where |
||
837 | * @return int|null |
||
838 | */ |
||
839 | View Code Duplication | public function update_batch($table, $data, $where) |
|
840 | { |
||
841 | // Get the generated values and sql string |
||
842 | list($sql, $data) = $this->db->update_batch($table, $data, $where); |
||
843 | |||
844 | return ( ! is_null($sql)) |
||
0 ignored issues
–
show
|
|||
845 | ? $this->_run('', $table, $sql, $data) |
||
846 | : NULL; |
||
847 | } |
||
848 | |||
849 | // -------------------------------------------------------------------------- |
||
850 | |||
851 | /** |
||
852 | * Insertion with automatic overwrite, rather than attempted duplication |
||
853 | * |
||
854 | * @param string $table |
||
855 | * @param array $data |
||
856 | * @return \PDOStatement|null |
||
857 | */ |
||
858 | public function replace($table, $data=[]) |
||
859 | { |
||
860 | if ( ! empty($data)) |
||
861 | { |
||
862 | $this->set($data); |
||
863 | } |
||
864 | |||
865 | return $this->_run("replace", $table); |
||
866 | } |
||
867 | |||
868 | // -------------------------------------------------------------------------- |
||
869 | |||
870 | /** |
||
871 | * Deletes data from a table |
||
872 | * |
||
873 | * @param string $table |
||
874 | * @param mixed $where |
||
875 | * @return \PDOStatement |
||
876 | */ |
||
877 | public function delete($table, $where='') |
||
878 | { |
||
879 | // Set the where clause |
||
880 | if ( ! empty($where)) |
||
881 | { |
||
882 | $this->where($where); |
||
883 | } |
||
884 | |||
885 | return $this->_run("delete", $table); |
||
886 | } |
||
887 | |||
888 | // -------------------------------------------------------------------------- |
||
889 | // ! SQL Returning Methods |
||
890 | // -------------------------------------------------------------------------- |
||
891 | |||
892 | |||
893 | |||
894 | /** |
||
895 | * Returns the generated 'select' sql query |
||
896 | * |
||
897 | * @param string $table |
||
898 | * @param bool $reset |
||
899 | * @return string |
||
900 | */ |
||
901 | public function get_compiled_select($table='', $reset=TRUE) |
||
902 | { |
||
903 | // Set the table |
||
904 | if ( ! empty($table)) |
||
905 | { |
||
906 | $this->from($table); |
||
907 | } |
||
908 | |||
909 | return $this->_get_compile('select', $table, $reset); |
||
910 | } |
||
911 | |||
912 | // -------------------------------------------------------------------------- |
||
913 | |||
914 | /** |
||
915 | * Returns the generated 'insert' sql query |
||
916 | * |
||
917 | * @param string $table |
||
918 | * @param bool $reset |
||
919 | * @return string |
||
920 | */ |
||
921 | public function get_compiled_insert($table, $reset=TRUE) |
||
922 | { |
||
923 | return $this->_get_compile('insert', $table, $reset); |
||
924 | } |
||
925 | |||
926 | // -------------------------------------------------------------------------- |
||
927 | |||
928 | /** |
||
929 | * Returns the generated 'update' sql query |
||
930 | * |
||
931 | * @param string $table |
||
932 | * @param bool $reset |
||
933 | * @return string |
||
934 | */ |
||
935 | public function get_compiled_update($table='', $reset=TRUE) |
||
936 | { |
||
937 | return $this->_get_compile('update', $table, $reset); |
||
938 | } |
||
939 | |||
940 | // -------------------------------------------------------------------------- |
||
941 | |||
942 | /** |
||
943 | * Returns the generated 'delete' sql query |
||
944 | * |
||
945 | * @param string $table |
||
946 | * @param bool $reset |
||
947 | * @return string |
||
948 | */ |
||
949 | public function get_compiled_delete($table="", $reset=TRUE) |
||
950 | { |
||
951 | return $this->_get_compile('delete', $table, $reset); |
||
952 | } |
||
953 | |||
954 | |||
955 | // -------------------------------------------------------------------------- |
||
956 | // ! Miscellaneous Methods |
||
957 | // -------------------------------------------------------------------------- |
||
958 | |||
959 | /** |
||
960 | * Clear out the class variables, so the next query can be run |
||
961 | * |
||
962 | * @return void |
||
963 | */ |
||
964 | public function reset_query() |
||
965 | { |
||
966 | // Reset strings and booleans |
||
967 | foreach($this->string_vars as $var) |
||
968 | { |
||
969 | $this->$var = NULL; |
||
970 | } |
||
971 | |||
972 | // Reset arrays |
||
973 | foreach($this->array_vars as $var) |
||
974 | { |
||
975 | $this->$var = []; |
||
976 | } |
||
977 | } |
||
978 | } |
||
979 | // End of query_builder.php |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.