Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
97.78% covered (success)
97.78%
44 / 45
CRAP
99.31% covered (success)
99.31%
143 / 144
QueryBuilder
0.00% covered (danger)
0.00%
0 / 1
97.78% covered (success)
97.78%
44 / 45
68
99.31% covered (success)
99.31%
143 / 144
 select
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
13 / 13
 selectMax
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 selectMin
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 selectAvg
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 selectSum
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 returning
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 distinct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 explain
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 table
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 from
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
6 / 6
 like
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orLike
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 notLike
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orNotLike
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 having
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orHaving
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 where
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orWhere
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 whereIn
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orWhereIn
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 whereNotIn
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 orWhereNotIn
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 set
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
13 / 13
 join
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
8 / 8
 groupBy
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
8 / 8
 orderBy
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
13 / 13
 limit
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 groupStart
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 notGroupStart
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 orGroupStart
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 orNotGroupStart
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 groupEnd
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 get
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 getWhere
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 countAll
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 countAllResults
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 insert
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 insertBatch
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 update
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 updateBatch
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
5 / 5
 delete
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 getCompiledSelect
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 getCompiledInsert
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getCompiledUpdate
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getCompiledDelete
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
1<?php declare(strict_types=1);
2/**
3 * Query
4 *
5 * SQL Query Builder / Database Abstraction Layer
6 *
7 * PHP version 7.4
8 *
9 * @package     Query
10 * @author      Timothy J. Warren <tim@timshomepage.net>
11 * @copyright   2012 - 2020 Timothy J. Warren
12 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13 * @link        https://git.timshomepage.net/aviat/Query
14 * @version     3.0.0
15 */
16namespace Query;
17
18use function is_array;
19use function is_int;
20use function mb_trim;
21
22use PDOStatement;
23
24/**
25 * Convenience class for creating sql queries
26 */
27class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
28    // --------------------------------------------------------------------------
29    // ! Select Queries
30    // --------------------------------------------------------------------------
31
32    /**
33     * Specifies rows to select in a query
34     *
35     * @param string $fields
36     * @return self
37     */
38    public function select(string $fields): self
39    {
40        // Split fields by comma
41        $fieldsArray = explode(',', $fields);
42        $fieldsArray = array_map('mb_trim', $fieldsArray);
43
44        // Split on 'As'
45        foreach ($fieldsArray as $key => $field)
46        {
47            if (stripos($field, 'as') !== FALSE)
48            {
49                $fieldsArray[$key] = preg_split('` as `i', $field);
50                $fieldsArray[$key] = array_map('mb_trim', $fieldsArray[$key]);
51            }
52        }
53
54        // Quote the identifiers
55        $safeArray = $this->driver->quoteIdent($fieldsArray);
56
57        unset($fieldsArray);
58
59        // Join the strings back together
60        foreach ($safeArray as $i => $iValue)
61        {
62            if (is_array($iValue))
63            {
64                $safeArray[$i] = implode(' AS ', $iValue);
65            }
66        }
67
68        $this->state->appendSelectString(implode(', ', $safeArray));
69
70        return $this;
71    }
72
73    /**
74     * Selects the maximum value of a field from a query
75     *
76     * @param string $field
77     * @param string|bool $as
78     * @return self
79     */
80    public function selectMax(string $field, $as=FALSE): self
81    {
82        // Create the select string
83        $this->state->appendSelectString(' MAX'.$this->_select($field, $as));
84        return $this;
85    }
86
87    /**
88     * Selects the minimum value of a field from a query
89     *
90     * @param string $field
91     * @param string|bool $as
92     * @return self
93     */
94    public function selectMin(string $field, $as=FALSE): self
95    {
96        // Create the select string
97        $this->state->appendSelectString(' MIN'.$this->_select($field, $as));
98        return $this;
99    }
100
101    /**
102     * Selects the average value of a field from a query
103     *
104     * @param string $field
105     * @param string|bool $as
106     * @return self
107     */
108    public function selectAvg(string $field, $as=FALSE): self
109    {
110        // Create the select string
111        $this->state->appendSelectString(' AVG'.$this->_select($field, $as));
112        return $this;
113    }
114
115    /**
116     * Selects the sum of a field from a query
117     *
118     * @param string $field
119     * @param string|bool $as
120     * @return self
121     */
122    public function selectSum(string $field, $as=FALSE): self
123    {
124        // Create the select string
125        $this->state->appendSelectString(' SUM'.$this->_select($field, $as));
126        return $this;
127    }
128
129    /**
130     * Add a 'returning' clause to an insert,update, or delete query
131     *
132     * @param string $fields
133     * @return $this
134     */
135    public function returning(string $fields = ''): self
136    {
137        $this->returning = TRUE;
138
139        // Re-use the string select field for generating the returning type clause
140        if ($fields !== '')
141        {
142            return $this->select($fields);
143        }
144
145        return $this;
146    }
147
148    /**
149     * Adds the 'distinct' keyword to a query
150     *
151     * @return self
152     */
153    public function distinct(): self
154    {
155        // Prepend the keyword to the select string
156        $this->state->setSelectString(' DISTINCT' . $this->state->getSelectString());
157        return $this;
158    }
159
160    /**
161     * Tell the database to give you the query plan instead of result set
162     *
163     * @return self
164     */
165    public function explain(): self
166    {
167        $this->explain = TRUE;
168        return $this;
169    }
170
171    /**
172     * Specify the database table to select from
173     *
174     * Alias of `from` method to better match CodeIgniter 4
175     *
176     * @param string $tableName
177     * @return self
178     */
179    public function table(string $tableName): self
180    {
181        return $this->from($tableName);
182    }
183
184    /**
185     * Specify the database table to select from
186     *
187     * @param string $tableName
188     * @return self
189     */
190    public function from(string $tableName): self
191    {
192        // Split identifiers on spaces
193        $identArray = explode(' ', mb_trim($tableName));
194        $identArray = array_map('mb_trim', $identArray);
195
196        // Quote the identifiers
197        $identArray[0] = $this->driver->quoteTable($identArray[0]);
198        $identArray = $this->driver->quoteIdent($identArray);
199
200        // Paste it back together
201        $this->state->setFromString(implode(' ', $identArray));
202
203        return $this;
204    }
205
206    // --------------------------------------------------------------------------
207    // ! 'Like' methods
208    // --------------------------------------------------------------------------
209
210    /**
211     * Creates a Like clause in the sql statement
212     *
213     * @param string $field
214     * @param mixed $val
215     * @param string $pos
216     * @return self
217     */
218    public function like(string $field, $val, string $pos=LikeType::BOTH): self
219    {
220        return $this->_like($field, $val, $pos);
221    }
222
223    /**
224     * Generates an OR Like clause
225     *
226     * @param string $field
227     * @param mixed $val
228     * @param string $pos
229     * @return self
230     */
231    public function orLike(string $field, $val, string $pos=LikeType::BOTH): self
232    {
233        return $this->_like($field, $val, $pos, 'LIKE', 'OR');
234    }
235
236    /**
237     * Generates a NOT LIKE clause
238     *
239     * @param string $field
240     * @param mixed $val
241     * @param string $pos
242     * @return self
243     */
244    public function notLike(string $field, $val, string $pos=LikeType::BOTH): self
245    {
246        return $this->_like($field, $val, $pos, 'NOT LIKE');
247    }
248
249    /**
250     * Generates a OR NOT LIKE clause
251     *
252     * @param string $field
253     * @param mixed $val
254     * @param string $pos
255     * @return self
256     */
257    public function orNotLike(string $field, $val, string $pos=LikeType::BOTH): self
258    {
259        return $this->_like($field, $val, $pos, 'NOT LIKE', 'OR');
260    }
261
262    // --------------------------------------------------------------------------
263    // ! Having methods
264    // --------------------------------------------------------------------------
265
266    /**
267     * Generates a 'Having' clause
268     *
269     * @param mixed $key
270     * @param mixed $val
271     * @return self
272     */
273    public function having($key, $val=[]): self
274    {
275        return $this->_having($key, $val);
276    }
277
278    /**
279     * Generates a 'Having' clause prefixed with 'OR'
280     *
281     * @param mixed $key
282     * @param mixed $val
283     * @return self
284     */
285    public function orHaving($key, $val=[]): self
286    {
287        return $this->_having($key, $val, 'OR');
288    }
289
290    // --------------------------------------------------------------------------
291    // ! 'Where' methods
292    // --------------------------------------------------------------------------
293
294    /**
295     * Specify condition(s) in the where clause of a query
296     * Note: this function works with key / value, or a
297     * passed array with key / value pairs
298     *
299     * @param mixed $key
300     * @param mixed $val
301     * @param mixed $escape
302     * @return self
303     */
304    public function where($key, $val=[], $escape=NULL): self
305    {
306        return $this->_whereString($key, $val);
307    }
308
309    /**
310     * Where clause prefixed with "OR"
311     *
312     * @param string $key
313     * @param mixed $val
314     * @return self
315     */
316    public function orWhere($key, $val=[]): self
317    {
318        return $this->_whereString($key, $val, 'OR');
319    }
320
321    /**
322     * Where clause with 'IN' statement
323     *
324     * @param mixed $field
325     * @param mixed $val
326     * @return self
327     */
328    public function whereIn($field, $val=[]): self
329    {
330        return $this->_whereIn($field, $val);
331    }
332
333    /**
334     * Where in statement prefixed with "or"
335     *
336     * @param string $field
337     * @param mixed $val
338     * @return self
339     */
340    public function orWhereIn($field, $val=[]): self
341    {
342        return $this->_whereIn($field, $val, 'IN', 'OR');
343    }
344
345    /**
346     * WHERE NOT IN (FOO) clause
347     *
348     * @param string $field
349     * @param mixed $val
350     * @return self
351     */
352    public function whereNotIn($field, $val=[]): self
353    {
354        return $this->_whereIn($field, $val, 'NOT IN');
355    }
356
357    /**
358     * OR WHERE NOT IN (FOO) clause
359     *
360     * @param string $field
361     * @param mixed $val
362     * @return self
363     */
364    public function orWhereNotIn($field, $val=[]): self
365    {
366        return $this->_whereIn($field, $val, 'NOT IN', 'OR');
367    }
368
369    // --------------------------------------------------------------------------
370    // ! Other Query Modifier methods
371    // --------------------------------------------------------------------------
372
373    /**
374     * Sets values for inserts / updates / deletes
375     *
376     * @param mixed $key
377     * @param mixed $val
378     * @return self
379     */
380    public function set($key, $val = NULL): self
381    {
382        if (is_scalar($key))
383        {
384            $pairs = [$key => $val];
385        }
386        else
387        {
388            $pairs = $key;
389        }
390
391        $keys = array_keys($pairs);
392        $values = array_values($pairs);
393
394        $this->state->appendSetArrayKeys($keys);
395        $this->state->appendValues($values);
396
397        // Use the keys of the array to make the insert/update string
398        // Escape the field names
399        $this->state->setSetArrayKeys(
400            array_map([$this->driver, '_quote'], $this->state->getSetArrayKeys())
401        );
402
403        // Generate the "set" string
404        $setString = implode('=?,', $this->state->getSetArrayKeys());
405        $setString .= '=?';
406
407        $this->state->setSetString($setString);
408
409        return $this;
410    }
411
412    /**
413     * Creates a join phrase in a compiled query
414     *
415     * @param string $table
416     * @param string $condition
417     * @param string $type
418     * @return self
419     */
420    public function join(string $table, string $condition, string $type=''): self
421    {
422        // Prefix and quote table name
423        $tableArr = explode(' ', mb_trim($table));
424        $tableArr[0] = $this->driver->quoteTable($tableArr[0]);
425        $tableArr = $this->driver->quoteIdent($tableArr);
426        $table = implode(' ', $tableArr);
427
428        // Parse out the join condition
429        $parsedCondition = $this->parser->compileJoin($condition);
430        $condition = $table . ' ON ' . $parsedCondition;
431
432        $this->state->appendMap("\n" . strtoupper($type) . ' JOIN ', $condition, MapType::JOIN);
433
434        return $this;
435    }
436
437    /**
438     * Group the results by the selected field(s)
439     *
440     * @param mixed $field
441     * @return self
442     */
443    public function groupBy($field): self
444    {
445        if ( ! is_scalar($field))
446        {
447            $newGroupArray = array_merge(
448                $this->state->getGroupArray(),
449                array_map([$this->driver, 'quoteIdent'], $field)
450            );
451            $this->state->setGroupArray($newGroupArray);
452        }
453        else
454        {
455            $this->state->appendGroupArray($this->driver->quoteIdent($field));
456        }
457
458        $this->state->setGroupString(' GROUP BY ' . implode(',', $this->state->getGroupArray()));
459
460        return $this;
461    }
462
463    /**
464     * Order the results by the selected field(s)
465     *
466     * @param string $field
467     * @param string $type
468     * @return self
469     */
470    public function orderBy(string $field, string $type=''): self
471    {
472        // When ordering by random, do an ascending order if the driver
473        // doesn't support random ordering
474        if (stripos($type, 'rand') !== FALSE)
475        {
476            $rand = $this->driver->getSql()->random();
477            $type = $rand ?? 'ASC';
478        }
479
480        // Set fields for later manipulation
481        $field = $this->driver->quoteIdent($field);
482        $this->state->setOrderArray($field, $type);
483
484        $orderClauses = [];
485
486        // Flatten key/val pairs into an array of space-separated pairs
487        foreach($this->state->getOrderArray() as $k => $v)
488        {
489            $orderClauses[] = $k . ' ' . strtoupper($v);
490        }
491
492        // Set the final string
493        $orderString =  ! isset($rand)
494            ? "\nORDER BY ".implode(', ', $orderClauses)
495            : "\nORDER BY".$rand;
496
497        $this->state->setOrderString($orderString);
498
499        return $this;
500    }
501
502    /**
503     * Set a limit on the current sql statement
504     *
505     * @param int $limit
506     * @param int|null $offset
507     * @return self
508     */
509    public function limit(int $limit, ?int $offset=NULL): self
510    {
511        $this->state->setLimit($limit);
512        $this->state->setOffset($offset);
513
514        return $this;
515    }
516
517    // --------------------------------------------------------------------------
518    // ! Query Grouping Methods
519    // --------------------------------------------------------------------------
520
521    /**
522     * Adds a paren to the current query for query grouping
523     *
524     * @return self
525     */
526    public function groupStart(): self
527    {
528        $conj = empty($this->state->getQueryMap()) ? ' WHERE ' : ' ';
529
530        $this->state->appendMap($conj, '(', MapType::GROUP_START);
531
532        return $this;
533    }
534
535    /**
536     * Adds a paren to the current query for query grouping,
537     * prefixed with 'NOT'
538     *
539     * @return self
540     */
541    public function notGroupStart(): self
542    {
543        $conj = empty($this->state->getQueryMap()) ? ' WHERE ' : ' AND ';
544
545        $this->state->appendMap($conj, ' NOT (', MapType::GROUP_START);
546
547        return $this;
548    }
549
550    /**
551     * Adds a paren to the current query for query grouping,
552     * prefixed with 'OR'
553     *
554     * @return self
555     */
556    public function orGroupStart(): self
557    {
558        $this->state->appendMap('', ' OR (', MapType::GROUP_START);
559
560        return $this;
561    }
562
563    /**
564     * Adds a paren to the current query for query grouping,
565     * prefixed with 'OR NOT'
566     *
567     * @return self
568     */
569    public function orNotGroupStart(): self
570    {
571        $this->state->appendMap('', ' OR NOT (', MapType::GROUP_START);
572
573        return $this;
574    }
575
576    /**
577     * Ends a query group
578     *
579     * @return self
580     */
581    public function groupEnd(): self
582    {
583        $this->state->appendMap('', ')', MapType::GROUP_END);
584
585        return $this;
586    }
587
588    // --------------------------------------------------------------------------
589    // ! Query execution methods
590    // --------------------------------------------------------------------------
591
592    /**
593     * Select and retrieve all records from the current table, and/or
594     * execute current compiled query
595     *
596     * @param string $table
597     * @param int|null $limit
598     * @param int|null $offset
599     * @return PDOStatement
600     */
601    public function get(string $table='', ?int $limit=NULL, ?int $offset=NULL): PDOStatement
602    {
603        // Set the table
604        if ( ! empty($table))
605        {
606            $this->from($table);
607        }
608
609        // Set the limit, if it exists
610        if (is_int($limit))
611        {
612            $this->limit($limit, $offset);
613        }
614
615        return $this->_run('get', $table);
616    }
617
618    /**
619     * Convenience method for get() with a where clause
620     *
621     * @param string $table
622     * @param mixed $where
623     * @param int|null $limit
624     * @param int|null $offset
625     * @return PDOStatement
626     */
627    public function getWhere(string $table, $where=[], ?int $limit=NULL, ?int $offset=NULL): PDOStatement
628    {
629        // Create the where clause
630        $this->where($where);
631
632        // Return the result
633        return $this->get($table, $limit, $offset);
634    }
635
636    /**
637     * Retrieve the number of rows in the selected table
638     *
639     * @param string $table
640     * @return int
641     */
642    public function countAll(string $table): int
643    {
644        $sql = 'SELECT * FROM '.$this->driver->quoteTable($table);
645        $res = $this->driver->query($sql);
646        return (int) count($res->fetchAll());
647    }
648
649    /**
650     * Retrieve the number of results for the generated query - used
651     * in place of the get() method
652     *
653     * @param string $table
654     * @param boolean $reset
655     * @return int
656     */
657    public function countAllResults(string $table='', bool $reset = TRUE): int
658    {
659        // Set the table
660        if ( ! empty($table))
661        {
662            $this->from($table);
663        }
664
665        $result = $this->_run(QueryType::SELECT, $table, NULL, NULL, $reset);
666        $rows = $result->fetchAll();
667
668        return (int) count($rows);
669    }
670
671    /**
672     * Creates an insert clause, and executes it
673     *
674     * @param string $table
675     * @param mixed $data
676     * @return PDOStatement
677     */
678    public function insert(string $table, $data=[]): PDOStatement
679    {
680        if ( ! empty($data))
681        {
682            $this->set($data);
683        }
684
685        return $this->_run(QueryType::INSERT, $table);
686    }
687
688    /**
689     * Creates and executes a batch insertion query
690     *
691     * @param string $table
692     * @param array $data
693     * @return PDOStatement
694     */
695    public function insertBatch(string $table, $data=[]): ?PDOStatement
696    {
697        // Get the generated values and sql string
698        [$sql, $data] = $this->driver->insertBatch($table, $data);
699
700        return $sql !== NULL
701            ? $this->_run('', $table, $sql, $data)
702            : NULL;
703    }
704
705    /**
706     * Creates an update clause, and executes it
707     *
708     * @param string $table
709     * @param mixed $data
710     * @return PDOStatement
711     */
712    public function update(string $table, $data=[]): PDOStatement
713    {
714        if ( ! empty($data))
715        {
716            $this->set($data);
717        }
718
719        return $this->_run(QueryType::UPDATE, $table);
720    }
721
722    /**
723     * Creates a batch update, and executes it.
724     * Returns the number of affected rows
725     *
726     * @param string $table
727     * @param array $data
728     * @param string $where
729     * @return int|null
730     */
731    public function updateBatch(string $table, array $data, string $where): ?int
732    {
733        if (empty($table) || empty($data) || empty($where))
734        {
735            return NULL;
736        }
737
738        // Get the generated values and sql string
739        [$sql, $data, $affectedRows] = $this->driver->updateBatch($table, $data, $where);
740
741        $this->_run('', $table, $sql, $data);
742        return $affectedRows;
743    }
744
745    /**
746     * Deletes data from a table
747     *
748     * @param string $table
749     * @param mixed $where
750     * @return PDOStatement
751     */
752    public function delete(string $table, $where=''): PDOStatement
753    {
754        // Set the where clause
755        if ( ! empty($where))
756        {
757            $this->where($where);
758        }
759
760        return $this->_run(QueryType::DELETE, $table);
761    }
762
763    // --------------------------------------------------------------------------
764    // ! SQL Returning Methods
765    // --------------------------------------------------------------------------
766
767    /**
768     * Returns the generated 'select' sql query
769     *
770     * @param string $table
771     * @param bool $reset
772     * @return string
773     */
774    public function getCompiledSelect(string $table='', bool $reset=TRUE): string
775    {
776        // Set the table
777        if ( ! empty($table))
778        {
779            $this->from($table);
780        }
781
782        return $this->_getCompile(QueryType::SELECT, $table, $reset);
783    }
784
785    /**
786     * Returns the generated 'insert' sql query
787     *
788     * @param string $table
789     * @param bool $reset
790     * @return string
791     */
792    public function getCompiledInsert(string $table, bool $reset=TRUE): string
793    {
794        return $this->_getCompile(QueryType::INSERT, $table, $reset);
795    }
796
797    /**
798     * Returns the generated 'update' sql query
799     *
800     * @param string $table
801     * @param bool $reset
802     * @return string
803     */
804    public function getCompiledUpdate(string $table='', bool $reset=TRUE): string
805    {
806        return $this->_getCompile(QueryType::UPDATE, $table, $reset);
807    }
808
809    /**
810     * Returns the generated 'delete' sql query
811     *
812     * @param string $table
813     * @param bool $reset
814     * @return string
815     */
816    public function getCompiledDelete(string $table='', bool $reset=TRUE): string
817    {
818        return $this->_getCompile(QueryType::DELETE, $table, $reset);
819    }
820}