Passed
Push — 1.0.0-dev ( ead601...e21083 )
by nguereza
04:39
created

DatabaseQueryBuilder::leftOuterJoin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 4
dl 0
loc 2
rs 10
c 1
b 1
f 0
1
<?php
2
    defined('ROOT_PATH') || exit('Access denied');
3
  /**
4
   * TNH Framework
5
   *
6
   * A simple PHP framework using HMVC architecture
7
   *
8
   * This content is released under the GNU GPL License (GPL)
9
   *
10
   * Copyright (C) 2017 Tony NGUEREZA
11
   *
12
   * This program is free software; you can redistribute it and/or
13
   * modify it under the terms of the GNU General Public License
14
   * as published by the Free Software Foundation; either version 3
15
   * of the License, or (at your option) any later version.
16
   *
17
   * This program is distributed in the hope that it will be useful,
18
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
   * GNU General Public License for more details.
21
   *
22
   * You should have received a copy of the GNU General Public License
23
   * along with this program; if not, write to the Free Software
24
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
  */
26
  class DatabaseQueryBuilder{
27
  	/**
28
  	 * The SQL SELECT statment
29
  	 * @var string
30
  	*/
31
  	private $select              = '*';
32
  	
33
  	/**
34
  	 * The SQL FROM statment
35
  	 * @var string
36
  	*/
37
      private $from                = null;
38
  	
39
  	/**
40
  	 * The SQL WHERE statment
41
  	 * @var string
42
  	*/
43
      private $where               = null;
44
  	
45
  	/**
46
  	 * The SQL LIMIT statment
47
  	 * @var string
48
  	*/
49
      private $limit               = null;
50
  	
51
  	/**
52
  	 * The SQL JOIN statment
53
  	 * @var string
54
  	*/
55
      private $join                = null;
56
  	
57
  	/**
58
  	 * The SQL ORDER BY statment
59
  	 * @var string
60
  	*/
61
      private $orderBy             = null;
62
  	
63
  	/**
64
  	 * The SQL GROUP BY statment
65
  	 * @var string
66
  	*/
67
      private $groupBy             = null;
68
  	
69
  	/**
70
  	 * The SQL HAVING statment
71
  	 * @var string
72
  	*/
73
      private $having              = null;
74
  	
75
  	/**
76
  	 * The full SQL query statment after build for each command
77
  	 * @var string
78
  	*/
79
      private $query               = null;
80
  	
81
  	/**
82
  	 * The list of SQL valid operators
83
  	 * @var array
84
  	*/
85
    private $operatorList        = array('=','!=','<','>','<=','>=','<>');
86
  	
87
	
88
	/**
89
	 * The prefix used in each database table
90
	 * @var string
91
	*/
92
    private $prefix              = null;
93
    
94
95
  /**
96
	 * The PDO instance
97
	 * @var object
98
	*/
99
  private $pdo                 = null;
100
	
101
  	/**
102
  	 * The database driver name used
103
  	 * @var string
104
  	*/
105
  	private $driver              = null;
106
  	
107
	
108
    /**
109
     * Construct new DatabaseQueryBuilder
110
     * @param object $pdo the PDO object
111
     */
112
    public function __construct(PDO $pdo = null){
113
        if (is_object($pdo)){
114
          $this->setPdo($pdo);
115
        }
116
    }
117
118
    /**
119
     * Set the SQL FROM statment
120
     * @param  string|array $table the table name or array of table list
121
     * @return object        the current DatabaseQueryBuilder instance
122
     */
123
    public function from($table){
124
	  if (is_array($table)){
125
        $froms = '';
126
        foreach($table as $key){
127
          $froms .= $this->getPrefix() . $key . ', ';
128
        }
129
        $this->from = rtrim($froms, ', ');
130
      } else {
131
        $this->from = $this->getPrefix() . $table;
132
      }
133
      return $this;
134
    }
135
136
    /**
137
     * Set the SQL SELECT statment
138
     * @param  string|array $fields the field name or array of field list
139
     * @return object        the current DatabaseQueryBuilder instance
140
     */
141
    public function select($fields){
142
      $select = (is_array($fields) ? implode(', ', $fields) : $fields);
143
      $this->select = (($this->select == '*' || empty($this->select)) ? $select : $this->select . ', ' . $select);
144
      return $this;
145
    }
146
147
    /**
148
     * Set the SQL SELECT DISTINCT statment
149
     * @param  string $field the field name to distinct
150
     * @return object        the current DatabaseQueryBuilder instance
151
     */
152
    public function distinct($field){
153
      $distinct = ' DISTINCT ' . $field;
154
      $this->select = (($this->select == '*' || empty($this->select)) ? $distinct : $this->select . ', ' . $distinct);
155
      return $this;
156
    }
157
158
     /**
159
     * Set the SQL function COUNT in SELECT statment
160
     * @param  string $field the field name
161
     * @param  string $name  if is not null represent the alias used for this field in the result
162
     * @return object        the current DatabaseQueryBuilder instance
163
     */
164
    public function count($field = '*', $name = null){
165
      return $this->select_min_max_sum_count_avg('COUNT', $field, $name);
166
    }
167
    
168
    /**
169
     * Set the SQL function MIN in SELECT statment
170
     * @param  string $field the field name
171
     * @param  string $name  if is not null represent the alias used for this field in the result
172
     * @return object        the current DatabaseQueryBuilder instance
173
     */
174
    public function min($field, $name = null){
175
      return $this->select_min_max_sum_count_avg('MIN', $field, $name);
176
    }
177
178
    /**
179
     * Set the SQL function MAX in SELECT statment
180
     * @param  string $field the field name
181
     * @param  string $name  if is not null represent the alias used for this field in the result
182
     * @return object        the current DatabaseQueryBuilder instance
183
     */
184
    public function max($field, $name = null){
185
      return $this->select_min_max_sum_count_avg('MAX', $field, $name);
186
    }
187
188
    /**
189
     * Set the SQL function SUM in SELECT statment
190
     * @param  string $field the field name
191
     * @param  string $name  if is not null represent the alias used for this field in the result
192
     * @return object        the current DatabaseQueryBuilder instance
193
     */
194
    public function sum($field, $name = null){
195
      return $this->select_min_max_sum_count_avg('SUM', $field, $name);
196
    }
197
198
    /**
199
     * Set the SQL function AVG in SELECT statment
200
     * @param  string $field the field name
201
     * @param  string $name  if is not null represent the alias used for this field in the result
202
     * @return object        the current DatabaseQueryBuilder instance
203
     */
204
    public function avg($field, $name = null){
205
      return $this->select_min_max_sum_count_avg('AVG', $field, $name);
206
    }
207
208
209
    /**
210
     * Set the SQL JOIN statment
211
     * @param  string $table  the join table name
212
     * @param  string $field1 the first field for join conditions	
213
     * @param  string $op     the join condition operator. If is null the default will be "="
214
     * @param  string $field2 the second field for join conditions
215
     * @param  string $type   the type of join (INNER, LEFT, RIGHT)
216
     * @return object        the current DatabaseQueryBuilder instance
217
     */
218
    public function join($table, $field1 = null, $op = null, $field2 = null, $type = ''){
219
      $on = $field1;
220
      $table = $this->getPrefix() . $table;
221
      if (! is_null($op)){
222
        $on = (! in_array($op, $this->operatorList) 
223
													? ($this->getPrefix() . $field1 . ' = ' . $this->getPrefix() . $op) 
224
													: ($this->getPrefix() . $field1 . ' ' . $op . ' ' . $this->getPrefix() . $field2));
225
      }
226
      if (empty($this->join)){
227
        $this->join = ' ' . $type . 'JOIN' . ' ' . $table . ' ON ' . $on;
228
      }
229
      else{
230
        $this->join = $this->join . ' ' . $type . 'JOIN' . ' ' . $table . ' ON ' . $on;
231
      }
232
      return $this;
233
    }
234
235
    /**
236
     * Set the SQL INNER JOIN statment
237
     * @see  DatabaseQueryBuilder::join()
238
     * @return object        the current DatabaseQueryBuilder instance
239
     */
240
    public function innerJoin($table, $field1, $op = null, $field2 = ''){
241
      return $this->join($table, $field1, $op, $field2, 'INNER ');
242
    }
243
244
    /**
245
     * Set the SQL LEFT JOIN statment
246
     * @see  DatabaseQueryBuilder::join()
247
     * @return object        the current DatabaseQueryBuilder instance
248
     */
249
    public function leftJoin($table, $field1, $op = null, $field2 = ''){
250
      return $this->join($table, $field1, $op, $field2, 'LEFT ');
251
	}
252
253
	/**
254
     * Set the SQL RIGHT JOIN statment
255
     * @see  DatabaseQueryBuilder::join()
256
     * @return object        the current DatabaseQueryBuilder instance
257
     */
258
    public function rightJoin($table, $field1, $op = null, $field2 = ''){
259
      return $this->join($table, $field1, $op, $field2, 'RIGHT ');
260
    }
261
262
    /**
263
     * Set the SQL FULL OUTER JOIN statment
264
     * @see  DatabaseQueryBuilder::join()
265
     * @return object        the current DatabaseQueryBuilder instance
266
     */
267
    public function fullOuterJoin($table, $field1, $op = null, $field2 = ''){
268
    	return $this->join($table, $field1, $op, $field2, 'FULL OUTER ');
269
    }
270
271
    /**
272
     * Set the SQL LEFT OUTER JOIN statment
273
     * @see  DatabaseQueryBuilder::join()
274
     * @return object        the current DatabaseQueryBuilder instance
275
     */
276
    public function leftOuterJoin($table, $field1, $op = null, $field2 = ''){
277
      return $this->join($table, $field1, $op, $field2, 'LEFT OUTER ');
278
    }
279
280
    /**
281
     * Set the SQL RIGHT OUTER JOIN statment
282
     * @see  DatabaseQueryBuilder::join()
283
     * @return object        the current DatabaseQueryBuilder instance
284
     */
285
    public function rightOuterJoin($table, $field1, $op = null, $field2 = ''){
286
      return $this->join($table, $field1, $op, $field2, 'RIGHT OUTER ');
287
    }
288
289
    /**
290
     * Set the SQL WHERE CLAUSE for IS NULL
291
     * @param  string|array $field  the field name or array of field list
292
     * @param  string $andOr the separator type used 'AND', 'OR', etc.
293
     * @return object        the current DatabaseQueryBuilder instance
294
     */
295
    public function whereIsNull($field, $andOr = 'AND'){
296
      if (is_array($field)){
297
        foreach($field as $f){
298
        	$this->whereIsNull($f, $andOr);
299
        }
300
      } else {
301
          $this->setWhereStr($field.' IS NULL ', $andOr);
302
      }
303
      return $this;
304
    }
305
306
    /**
307
     * Set the SQL WHERE CLAUSE for IS NOT NULL
308
     * @param  string|array $field  the field name or array of field list
309
     * @param  string $andOr the separator type used 'AND', 'OR', etc.
310
     * @return object        the current DatabaseQueryBuilder instance
311
     */
312
    public function whereIsNotNull($field, $andOr = 'AND'){
313
      if (is_array($field)){
314
        foreach($field as $f){
315
          $this->whereIsNotNull($f, $andOr);
316
        }
317
      } else {
318
          $this->setWhereStr($field.' IS NOT NULL ', $andOr);
319
      }
320
      return $this;
321
    }
322
    
323
    /**
324
     * Set the SQL WHERE CLAUSE statment
325
     * @param  string|array  $where the where field or array of field list
326
     * @param  array|string  $op     the condition operator. If is null the default will be "="
327
     * @param  mixed  $val    the where value
328
     * @param  string  $type   the type used for this where clause (NOT, etc.)
329
     * @param  string  $andOr the separator type used 'AND', 'OR', etc.
330
     * @param  boolean $escape whether to escape or not the $val
331
     * @return object        the current DatabaseQueryBuilder instance
332
     */
333
    public function where($where, $op = null, $val = null, $type = '', $andOr = 'AND', $escape = true){
334
      $whereStr = '';
335
      if (is_array($where)){
336
        $whereStr = $this->getWhereStrIfIsArray($where, $type, $andOr, $escape);
337
      }
338
      else{
339
        if (is_array($op)){
340
          $whereStr = $this->getWhereStrIfOperatorIsArray($where, $op, $type, $escape);
341
        } else {
342
          $whereStr = $this->getWhereStrForOperator($where, $op, $val, $type, $escape = true);
343
        }
344
      }
345
      $this->setWhereStr($whereStr, $andOr);
346
      return $this;
347
    }
348
349
    /**
350
     * Set the SQL WHERE CLAUSE statment using OR
351
     * @see  DatabaseQueryBuilder::where()
352
     * @return object        the current DatabaseQueryBuilder instance
353
     */
354
    public function orWhere($where, $op = null, $val = null, $escape = true){
355
      return $this->where($where, $op, $val, '', 'OR', $escape);
356
    }
357
358
359
    /**
360
     * Set the SQL WHERE CLAUSE statment using AND and NOT
361
     * @see  DatabaseQueryBuilder::where()
362
     * @return object        the current DatabaseQueryBuilder instance
363
     */
364
    public function notWhere($where, $op = null, $val = null, $escape = true){
365
      return $this->where($where, $op, $val, 'NOT ', 'AND', $escape);
366
    }
367
368
    /**
369
     * Set the SQL WHERE CLAUSE statment using OR and NOT
370
     * @see  DatabaseQueryBuilder::where()
371
     * @return object        the current DatabaseQueryBuilder instance
372
     */
373
    public function orNotWhere($where, $op = null, $val = null, $escape = true){
374
    	return $this->where($where, $op, $val, 'NOT ', 'OR', $escape);
375
    }
376
377
    /**
378
     * Set the opened parenthesis for the complex SQL query
379
     * @param  string $type   the type of this grouped (NOT, etc.)
380
     * @param  string $andOr the multiple conditions separator (AND, OR, etc.)
381
     * @return object        the current DatabaseQueryBuilder instance
382
     */
383
    public function groupStart($type = '', $andOr = ' AND'){
384
      if (empty($this->where)){
385
        $this->where = $type . ' (';
386
      } else {
387
          if (substr(trim($this->where), -1) == '('){
388
            $this->where .= $type . ' (';
389
          } else {
390
          	$this->where .= $andOr . ' ' . $type . ' (';
391
          }
392
      }
393
      return $this;
394
    }
395
396
    /**
397
     * Set the opened parenthesis for the complex SQL query using NOT type
398
     * @see  DatabaseQueryBuilder::groupStart()
399
     * @return object        the current DatabaseQueryBuilder instance
400
     */
401
    public function notGroupStart(){
402
      return $this->groupStart('NOT');
403
    }
404
405
    /**
406
     * Set the opened parenthesis for the complex SQL query using OR for separator
407
     * @see  DatabaseQueryBuilder::groupStart()
408
     * @return object        the current DatabaseQueryBuilder instance
409
     */
410
    public function orGroupStart(){
411
      return $this->groupStart('', ' OR');
412
    }
413
414
     /**
415
     * Set the opened parenthesis for the complex SQL query using OR for separator and NOT for type
416
     * @see  DatabaseQueryBuilder::groupStart()
417
     * @return object        the current DatabaseQueryBuilder instance
418
     */
419
    public function orNotGroupStart(){
420
      return $this->groupStart('NOT', ' OR');
421
    }
422
423
    /**
424
     * Close the parenthesis for the grouped SQL
425
     * @return object        the current DatabaseQueryBuilder instance
426
     */
427
    public function groupEnd(){
428
      $this->where .= ')';
429
      return $this;
430
    }
431
432
    /**
433
     * Set the SQL WHERE CLAUSE statment for IN
434
     * @param  string  $field  the field name for IN statment
435
     * @param  array   $keys   the list of values used
436
     * @param  string  $type   the condition separator type (NOT)
437
     * @param  string  $andOr the multiple conditions separator (OR, AND)
438
     * @param  boolean $escape whether to escape or not the values
439
     * @return object        the current DatabaseQueryBuilder instance
440
     */
441
    public function in($field, array $keys, $type = '', $andOr = 'AND', $escape = true){
442
      $_keys = array();
443
      foreach ($keys as $k => $v){
444
        if (is_null($v)){
445
          $v = '';
446
        }
447
        $_keys[] = (is_numeric($v) ? $v : $this->escape($v, $escape));
448
      }
449
      $keys = implode(', ', $_keys);
450
      $whereStr = $field . ' ' . $type . ' IN (' . $keys . ')';
451
      $this->setWhereStr($whereStr, $andOr);
452
      return $this;
453
    }
454
455
    /**
456
     * Set the SQL WHERE CLAUSE statment for NOT IN with AND separator
457
     * @see  DatabaseQueryBuilder::in()
458
     * @return object        the current DatabaseQueryBuilder instance
459
     */
460
    public function notIn($field, array $keys, $escape = true){
461
      return $this->in($field, $keys, 'NOT ', 'AND', $escape);
462
    }
463
464
    /**
465
     * Set the SQL WHERE CLAUSE statment for IN with OR separator
466
     * @see  DatabaseQueryBuilder::in()
467
     * @return object        the current DatabaseQueryBuilder instance
468
     */
469
    public function orIn($field, array $keys, $escape = true){
470
      return $this->in($field, $keys, '', 'OR', $escape);
471
    }
472
473
    /**
474
     * Set the SQL WHERE CLAUSE statment for NOT IN with OR separator
475
     * @see  DatabaseQueryBuilder::in()
476
     * @return object        the current DatabaseQueryBuilder instance
477
     */
478
    public function orNotIn($field, array $keys, $escape = true){
479
      return $this->in($field, $keys, 'NOT ', 'OR', $escape);
480
    }
481
482
    /**
483
     * Set the SQL WHERE CLAUSE statment for BETWEEN
484
     * @param  string  $field  the field used for the BETWEEN statment
485
     * @param  mixed  $value1 the BETWEEN begin value
486
     * @param  mixed  $value2 the BETWEEN end value
487
     * @param  string  $type   the condition separator type (NOT)
488
     * @param  string  $andOr the multiple conditions separator (OR, AND)
489
     * @param  boolean $escape whether to escape or not the values
490
     * @return object        the current DatabaseQueryBuilder instance
491
     */
492
    public function between($field, $value1, $value2, $type = '', $andOr = 'AND', $escape = true){
493
      if (is_null($value1)){
494
        $value1 = '';
495
      }
496
      if (is_null($value2)){
497
        $value2 = '';
498
      }
499
      $whereStr = $field . ' ' . $type . ' BETWEEN ' . $this->escape($value1, $escape) . ' AND ' . $this->escape($value2, $escape);
500
      $this->setWhereStr($whereStr, $andOr);
501
      return $this;
502
    }
503
504
    /**
505
     * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and AND separator
506
     * @see  DatabaseQueryBuilder::between()
507
     * @return object        the current DatabaseQueryBuilder instance
508
     */
509
    public function notBetween($field, $value1, $value2, $escape = true){
510
      return $this->between($field, $value1, $value2, 'NOT ', 'AND', $escape);
511
    }
512
513
    /**
514
     * Set the SQL WHERE CLAUSE statment for BETWEEN with OR separator
515
     * @see  DatabaseQueryBuilder::between()
516
     * @return object        the current DatabaseQueryBuilder instance
517
     */
518
    public function orBetween($field, $value1, $value2, $escape = true){
519
      return $this->between($field, $value1, $value2, '', 'OR', $escape);
520
    }
521
522
    /**
523
     * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and OR separator
524
     * @see  DatabaseQueryBuilder::between()
525
     * @return object        the current DatabaseQueryBuilder instance
526
     */
527
    public function orNotBetween($field, $value1, $value2, $escape = true){
528
      return $this->between($field, $value1, $value2, 'NOT ', 'OR', $escape);
529
    }
530
531
    /**
532
     * Set the SQL WHERE CLAUSE statment for LIKE
533
     * @param  string  $field  the field name used in LIKE statment
534
     * @param  string  $data   the LIKE value for this field including the '%', and '_' part
535
     * @param  string  $type   the condition separator type (NOT)
536
     * @param  string  $andOr the multiple conditions separator (OR, AND)
537
     * @param  boolean $escape whether to escape or not the values
538
     * @return object        the current DatabaseQueryBuilder instance
539
     */
540
    public function like($field, $data, $type = '', $andOr = 'AND', $escape = true){
541
      if (empty($data)){
542
        $data = '';
543
      }
544
      $this->setWhereStr($field . ' ' . $type . ' LIKE ' . ($this->escape($data, $escape)), $andOr);
545
      return $this;
546
    }
547
548
    /**
549
     * Set the SQL WHERE CLAUSE statment for LIKE with OR separator
550
     * @see  DatabaseQueryBuilder::like()
551
     * @return object        the current DatabaseQueryBuilder instance
552
     */
553
    public function orLike($field, $data, $escape = true){
554
      return $this->like($field, $data, '', 'OR', $escape);
555
    }
556
557
    /**
558
     * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and AND separator
559
     * @see  DatabaseQueryBuilder::like()
560
     * @return object        the current DatabaseQueryBuilder instance
561
     */
562
    public function notLike($field, $data, $escape = true){
563
      return $this->like($field, $data, 'NOT ', 'AND', $escape);
564
    }
565
566
    /**
567
     * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and OR separator
568
     * @see  DatabaseQueryBuilder::like()
569
     * @return object        the current DatabaseQueryBuilder instance
570
     */
571
    public function orNotLike($field, $data, $escape = true){
572
      return $this->like($field, $data, 'NOT ', 'OR', $escape);
573
    }
574
575
    /**
576
     * Set the SQL LIMIT statment
577
     * @param  int $limit    the limit offset. If $limitEnd is null this will be the limit count
578
     * like LIMIT n;
579
     * @param  int $limitEnd the limit count
580
     * @return object        the current DatabaseQueryBuilder instance
581
     */
582
    public function limit($limit, $limitEnd = null){
583
      if (empty($limit)){
584
        $limit = 0;
585
      }
586
      if (! is_null($limitEnd)){
587
        $this->limit = $limit . ', ' . $limitEnd;
588
      }
589
      else{
590
        $this->limit = $limit;
591
      }
592
      return $this;
593
    }
594
595
    /**
596
     * Set the SQL ORDER BY CLAUSE statment
597
     * @param  string $orderBy   the field name used for order
598
     * @param  string $orderDir the order direction (ASC or DESC)
599
     * @return object        the current DatabaseQueryBuilder instance
600
     */
601
    public function orderBy($orderBy, $orderDir = ' ASC'){
602
      if (stristr($orderBy, ' ') || $orderBy == 'rand()'){
603
        $this->orderBy = empty($this->orderBy) ? $orderBy : $this->orderBy . ', ' . $orderBy;
604
      }
605
      else{
606
        $this->orderBy = empty($this->orderBy) 
607
						? ($orderBy . ' ' . strtoupper($orderDir)) 
608
						: $this->orderBy . ', ' . $orderBy . ' ' . strtoupper($orderDir);
609
      }
610
      return $this;
611
    }
612
613
    /**
614
     * Set the SQL GROUP BY CLAUSE statment
615
     * @param  string|array $field the field name used or array of field list
616
     * @return object        the current DatabaseQueryBuilder instance
617
     */
618
    public function groupBy($field){
619
      if (is_array($field)){
620
        $this->groupBy = implode(', ', $field);
621
      }
622
      else{
623
        $this->groupBy = $field;
624
      }
625
      return $this;
626
    }
627
628
    /**
629
     * Set the SQL HAVING CLAUSE statment
630
     * @param  string  $field  the field name used for HAVING statment
631
     * @param  string|array  $op     the operator used or array
632
     * @param  mixed  $val    the value for HAVING comparaison
633
     * @param  boolean $escape whether to escape or not the values
634
     * @return object        the current DatabaseQueryBuilder instance
635
     */
636
    public function having($field, $op = null, $val = null, $escape = true){
637
      if (is_array($op)){
638
        $this->having = $this->getHavingStrIfOperatorIsArray($field, $op, $escape);
639
      }
640
      else if (! in_array($op, $this->operatorList)){
641
        if (is_null($op)){
642
          $op = '';
643
        }
644
        $this->having = $field . ' > ' . ($this->escape($op, $escape));
645
      }
646
      else{
647
        if (is_null($val)){
648
          $val = '';
649
        }
650
        $this->having = $field . ' ' . $op . ' ' . ($this->escape($val, $escape));
651
      }
652
      return $this;
653
    }
654
655
    /**
656
     * Insert new record in the database
657
     * @param  array   $data   the record data
658
     * @param  boolean $escape  whether to escape or not the values
659
     * @return object  the current DatabaseQueryBuilder instance        
660
     */
661
    public function insert($data = array(), $escape = true){
662
      $columns = array_keys($data);
663
      $column = implode(',', $columns);
664
      $val = implode(', ', ($escape ? array_map(array($this, 'escape'), $data) : $data));
665
666
      $this->query = 'INSERT INTO ' . $this->from . ' (' . $column . ') VALUES (' . $val . ')';
667
      return $this;
668
    }
669
670
    /**
671
     * Update record in the database
672
     * @param  array   $data   the record data if is empty will use the $this->data array.
673
     * @param  boolean $escape  whether to escape or not the values
674
     * @return object  the current DatabaseQueryBuilder instance 
675
     */
676
    public function update($data = array(), $escape = true){
677
      $query = 'UPDATE ' . $this->from . ' SET ';
678
      $values = array();
679
      foreach ($data as $column => $val){
680
        $values[] = $column . ' = ' . ($this->escape($val, $escape));
681
      }
682
      $query .= implode(', ', $values);
683
      if (! empty($this->where)){
684
        $query .= ' WHERE ' . $this->where;
685
      }
686
687
      if (! empty($this->orderBy)){
688
        $query .= ' ORDER BY ' . $this->orderBy;
689
      }
690
691
      if (! empty($this->limit)){
692
        $query .= ' LIMIT ' . $this->limit;
693
      }
694
      $this->query = $query;
695
      return $this;
696
    }
697
698
    /**
699
     * Delete the record in database
700
     * @return object  the current DatabaseQueryBuilder instance 
701
     */
702
    public function delete(){
703
    	$query = 'DELETE FROM ' . $this->from;
704
      $isTruncate = $query;
705
    	if (! empty($this->where)){
706
  		  $query .= ' WHERE ' . $this->where;
707
    	}
708
709
    	if (! empty($this->orderBy)){
710
    	  $query .= ' ORDER BY ' . $this->orderBy;
711
      }
712
713
    	if (! empty($this->limit)){
714
    		$query .= ' LIMIT ' . $this->limit;
715
      }
716
717
  		if ($isTruncate == $query && $this->driver != 'sqlite'){  
718
      	$query = 'TRUNCATE TABLE ' . $this->from;
719
  		}
720
	   $this->query = $query;
721
	   return $this;
722
    }
723
724
    /**
725
     * Escape the data before execute query useful for security.
726
     * @param  mixed $data the data to be escaped
727
     * @param boolean $escaped whether we can do escape of not 
728
     * @return mixed       the data after escaped or the same data if not
729
     */
730
    public function escape($data, $escaped = true){
731
      return $escaped 
732
                    ? $this->getPdo()->quote(trim($data)) 
733
                    : $data; 
734
    }
735
736
737
    /**
738
     * Return the current SQL query string
739
     * @return string
740
     */
741
    public function getQuery(){
742
  	  //INSERT, UPDATE, DELETE already set it, if is the SELECT we need set it now
743
  	  if(empty($this->query)){
744
  		  $query = 'SELECT ' . $this->select . ' FROM ' . $this->from;
745
  		  if (! empty($this->join)){
746
          $query .= $this->join;
747
  		  }
748
  		  
749
  		  if (! empty($this->where)){
750
          $query .= ' WHERE ' . $this->where;
751
  		  }
752
753
  		  if (! empty($this->groupBy)){
754
          $query .= ' GROUP BY ' . $this->groupBy;
755
  		  }
756
757
  		  if (! empty($this->having)){
758
          $query .= ' HAVING ' . $this->having;
759
  		  }
760
761
  		  if (! empty($this->orderBy)){
762
  			  $query .= ' ORDER BY ' . $this->orderBy;
763
  		  }
764
765
  		  if (! empty($this->limit)){
766
          $query .= ' LIMIT ' . $this->limit;
767
  		  }
768
  		  $this->query = $query;
769
  	  }
770
      return $this->query;
771
    }
772
773
	
774
	 /**
775
     * Return the PDO instance
776
     * @return PDO
777
     */
778
    public function getPdo(){
779
      return $this->pdo;
780
    }
781
782
    /**
783
     * Set the PDO instance
784
     * @param PDO $pdo the pdo object
785
	 * @return object DatabaseQueryBuilder
786
     */
787
    public function setPdo(PDO $pdo = null){
788
      $this->pdo = $pdo;
789
      return $this;
790
    }
791
	
792
   /**
793
   * Return the database table prefix
794
   * @return string
795
   */
796
    public function getPrefix(){
797
      return $this->prefix;
798
    }
799
800
    /**
801
     * Set the database table prefix
802
     * @param string $prefix the new prefix
803
	   * @return object DatabaseQueryBuilder
804
     */
805
    public function setPrefix($prefix){
806
      $this->prefix = $prefix;
807
      return $this;
808
    }
809
	
810
	   /**
811
     * Return the database driver
812
     * @return string
813
     */
814
    public function getDriver(){
815
      return $this->driver;
816
    }
817
818
    /**
819
     * Set the database driver
820
     * @param string $driver the new driver
821
	   * @return object DatabaseQueryBuilder
822
     */
823
    public function setDriver($driver){
824
      $this->driver = $driver;
825
      return $this;
826
    }
827
	
828
	   /**
829
     * Reset the DatabaseQueryBuilder class attributs to the initial values before each query.
830
	   * @return object  the current DatabaseQueryBuilder instance 
831
     */
832
    public function reset(){
833
      $this->select   = '*';
834
      $this->from     = null;
835
      $this->where    = null;
836
      $this->limit    = null;
837
      $this->orderBy  = null;
838
      $this->groupBy  = null;
839
      $this->having   = null;
840
      $this->join     = null;
841
      $this->query    = null;
842
      return $this;
843
    }
844
845
	   /**
846
     * Get the SQL HAVING clause when operator argument is an array
847
     * @see DatabaseQueryBuilder::having
848
     *
849
     * @return string
850
     */
851
    protected function getHavingStrIfOperatorIsArray($field, $op = null, $escape = true){
852
        $x = explode('?', $field);
853
        $w = '';
854
        foreach($x as $k => $v){
855
  	      if (!empty($v)){
856
            if (! isset($op[$k])){
857
              $op[$k] = '';
858
            }
859
  	      	$w .= $v . (isset($op[$k]) ? $this->escape($op[$k], $escape) : '');
860
  	      }
861
      	}
862
        return $w;
863
    }
864
865
866
    /**
867
     * Get the SQL WHERE clause using array column => value
868
     * @see DatabaseQueryBuilder::where
869
     *
870
     * @return string
871
     */
872
    protected function getWhereStrIfIsArray(array $where, $type = '', $andOr = 'AND', $escape = true){
873
      $_where = array();
874
      foreach ($where as $column => $data){
875
        if (is_null($data)){
876
          $data = '';
877
        }
878
        $_where[] = $type . $column . ' = ' . ($this->escape($data, $escape));
879
      }
880
      $where = implode(' '.$andOr.' ', $_where);
881
      return $where;
882
    }
883
884
     /**
885
     * Get the SQL WHERE clause when operator argument is an array
886
     * @see DatabaseQueryBuilder::where
887
     *
888
     * @return string
889
     */
890
    protected function getWhereStrIfOperatorIsArray($where, array $op, $type = '', $escape = true){
891
     $x = explode('?', $where);
892
     $w = '';
893
      foreach($x as $k => $v){
894
        if (! empty($v)){
895
            if (isset($op[$k]) && is_null($op[$k])){
896
              $op[$k] = '';
897
            }
898
            $w .= $type . $v . (isset($op[$k]) ? ($this->escape($op[$k], $escape)) : '');
899
        }
900
      }
901
      return $w;
902
    }
903
904
    /**
905
     * Get the default SQL WHERE clause using operator = or the operator argument
906
     * @see DatabaseQueryBuilder::where
907
     *
908
     * @return string
909
     */
910
    protected function getWhereStrForOperator($where, $op = null, $val = null, $type = '', $escape = true){
911
       $w = '';
912
       if (! in_array((string)$op, $this->operatorList)){
913
          if (is_null($op)){
914
            $op = '';
915
          }
916
          $w = $type . $where . ' = ' . ($this->escape($op, $escape));
917
        } else {
918
          if (is_null($val)){
919
            $val = '';
920
          }
921
          $w = $type . $where . $op . ($this->escape($val, $escape));
922
        }
923
        return $w;
924
      }
925
926
      /**
927
       * Set the $this->where property 
928
       * @param string $whereStr the WHERE clause string
929
       * @param  string  $andOr the separator type used 'AND', 'OR', etc.
930
       */
931
      protected function setWhereStr($whereStr, $andOr = 'AND'){
932
        if (empty($this->where)){
933
          $this->where = $whereStr;
934
        } else {
935
          if (substr(trim($this->where), -1) == '('){
936
            $this->where = $this->where . ' ' . $whereStr;
937
          } else {
938
            $this->where = $this->where . ' '.$andOr.' ' . $whereStr;
939
          }
940
        }
941
      }
942
943
944
	 /**
945
     * Set the SQL SELECT for function MIN, MAX, SUM, AVG, COUNT, AVG
946
     * @param  string $clause the clause type like MIN, MAX, etc.
947
     * @see  DatabaseQueryBuilder::min
948
     * @see  DatabaseQueryBuilder::max
949
     * @see  DatabaseQueryBuilder::sum
950
     * @see  DatabaseQueryBuilder::count
951
     * @see  DatabaseQueryBuilder::avg
952
     * @return object
953
     */
954
    protected function select_min_max_sum_count_avg($clause, $field, $name = null){
955
      $clause = strtoupper($clause);
956
      $func = $clause . '(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
957
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
958
      return $this;
959
    }
960
}
961