Passed
Push — 1.0.0-dev ( 97be91...7decce )
by nguereza
09:55
created

Database::having()   B

Complexity

Conditions 10
Paths 5

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 10
eloc 18
c 1
b 1
f 0
nc 5
nop 4
dl 0
loc 27
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 Database{
27
	
28
	/**
29
	 * The PDO instance
30
	 * @var object
31
	*/
32
    private $pdo                 = null;
33
    
34
	/**
35
	 * The database name used for the application
36
	 * @var string
37
	*/
38
	private $databaseName        = null;
39
    
40
	/**
41
	 * The SQL SELECT statment
42
	 * @var string
43
	*/
44
	private $select              = '*';
45
	
46
	/**
47
	 * The SQL FROM statment
48
	 * @var string
49
	*/
50
    private $from                = null;
51
	
52
	/**
53
	 * The SQL WHERE statment
54
	 * @var string
55
	*/
56
    private $where               = null;
57
	
58
	/**
59
	 * The SQL LIMIT statment
60
	 * @var string
61
	*/
62
    private $limit               = null;
63
	
64
	/**
65
	 * The SQL JOIN statment
66
	 * @var string
67
	*/
68
    private $join                = null;
69
	
70
	/**
71
	 * The SQL ORDER BY statment
72
	 * @var string
73
	*/
74
    private $orderBy             = null;
75
	
76
	/**
77
	 * The SQL GROUP BY statment
78
	 * @var string
79
	*/
80
    private $groupBy             = null;
81
	
82
	/**
83
	 * The SQL HAVING statment
84
	 * @var string
85
	*/
86
    private $having              = null;
87
	
88
	/**
89
	 * The number of rows returned by the last query
90
	 * @var int
91
	*/
92
    private $numRows             = 0;
93
	
94
	/**
95
	 * The last insert id for the primary key column that have auto increment or sequence
96
	 * @var mixed
97
	*/
98
    private $insertId            = null;
99
	
100
	/**
101
	 * The full SQL query statment after build for each command
102
	 * @var string
103
	*/
104
    private $query               = null;
105
	
106
	/**
107
	 * The error returned for the last query
108
	 * @var string
109
	*/
110
    private $error               = null;
111
	
112
	/**
113
	 * The result returned for the last query
114
	 * @var mixed
115
	*/
116
    private $result              = array();
117
	
118
	/**
119
	 * The prefix used in each database table
120
	 * @var string
121
	*/
122
    private $prefix              = null;
123
	
124
	/**
125
	 * The list of SQL valid operators
126
	 * @var array
127
	*/
128
    private $operatorList        = array('=','!=','<','>','<=','>=','<>');
129
    
130
	/**
131
	 * The cache default time to live in second. 0 means no need to use the cache feature
132
	 * @var int
133
	*/
134
	private $cacheTtl              = 0;
135
	
136
	/**
137
	 * The cache current time to live. 0 means no need to use the cache feature
138
	 * @var int
139
	*/
140
    private $temporaryCacheTtl   = 0;
141
	
142
	/**
143
	 * The number of executed query for the current request
144
	 * @var int
145
	*/
146
    private $queryCount          = 0;
147
	
148
	/**
149
	 * The default data to be used in the statments query INSERT, UPDATE
150
	 * @var array
151
	*/
152
    private $data                = array();
153
	
154
	/**
155
	 * The database configuration
156
	 * @var array
157
	*/
158
    private $config              = array();
159
	
160
	/**
161
	 * The logger instance
162
	 * @var Log
163
	 */
164
    private $logger              = null;
165
166
167
    /**
168
    * The cache instance
169
    * @var CacheInterface
170
    */
171
    private $cacheInstance       = null;
172
173
     /**
174
    * The benchmark instance
175
    * @var Benchmark
176
    */
177
    private $benchmarkInstance   = null;
178
179
180
    /**
181
     * Construct new database
182
     * @param array $overwriteConfig the config to overwrite with the config set in database.php
183
     */
184
    public function __construct($overwriteConfig = array()){
185
        //Set Log instance to use
186
        $this->setLoggerFromParamOrCreateNewInstance(null);
187
188
        //Set global configuration using the config file
189
        $this->setDatabaseConfigurationFromConfigFile($overwriteConfig);
190
        
191
    		$this->temporaryCacheTtl = $this->cacheTtl;
192
    }
193
194
    /**
195
     * This is used to connect to database
196
     * @return bool 
197
     */
198
    public function connect(){
199
      $config = $this->getDatabaseConfiguration();
200
      if(! empty($config)){
201
        try{
202
            $this->pdo = new PDO($this->getDsnFromDriver(), $config['username'], $config['password']);
203
            $this->pdo->exec("SET NAMES '" . $config['charset'] . "' COLLATE '" . $config['collation'] . "'");
204
            $this->pdo->exec("SET CHARACTER SET '" . $config['charset'] . "'");
205
            $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
206
            return true;
207
          }
208
          catch (PDOException $e){
209
            $this->logger->fatal($e->getMessage());
210
            show_error('Cannot connect to Database.');
211
            return false;
212
          }
213
      }
214
      else{
215
        show_error('Database configuration is not set.');
216
        return false;
217
      }
218
    }
219
220
    /**
221
     * Set the SQL FROM statment
222
     * @param  string|array $table the table name or array of table list
223
     * @return object        the current Database instance
224
     */
225
    public function from($table){
226
      if(is_array($table)){
227
        $froms = '';
228
        foreach($table as $key){
229
          $froms .= $this->prefix . $key . ', ';
230
        }
231
        $this->from = rtrim($froms, ', ');
232
      }
233
      else{
234
        $this->from = $this->prefix . $table;
235
      }
236
      return $this;
237
    }
238
239
    /**
240
     * Set the SQL SELECT statment
241
     * @param  string|array $fields the field name or array of field list
242
     * @return object        the current Database instance
243
     */
244
    public function select($fields){
245
      $select = (is_array($fields) ? implode(', ', $fields) : $fields);
246
      $this->select = ($this->select == '*' ? $select : $this->select . ', ' . $select);
247
      return $this;
248
    }
249
250
    /**
251
     * Set the SQL SELECT DISTINCT statment
252
     * @param  string $field the field name to distinct
253
     * @return object        the current Database instance
254
     */
255
    public function distinct($field){
256
      $distinct = ' DISTINCT ' . $field;
257
      $this->select = ($this->select == '*' ? $distinct : $this->select . ', ' . $distinct);
258
259
      return $this;
260
    }
261
262
    /**
263
     * Set the SQL function MAX in SELECT statment
264
     * @param  string $field the field name
265
     * @param  string $name  if is not null represent the alias used for this field in the result
266
     * @return object        the current Database instance
267
     */
268
    public function max($field, $name = null){
269
      $func = 'MAX(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
270
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
271
      return $this;
272
    }
273
274
    /**
275
     * Set the SQL function MIN in SELECT statment
276
     * @param  string $field the field name
277
     * @param  string $name  if is not null represent the alias used for this field in the result
278
     * @return object        the current Database instance
279
     */
280
    public function min($field, $name = null){
281
      $func = 'MIN(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
282
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
283
      return $this;
284
    }
285
286
    /**
287
     * Set the SQL function SUM in SELECT statment
288
     * @param  string $field the field name
289
     * @param  string $name  if is not null represent the alias used for this field in the result
290
     * @return object        the current Database instance
291
     */
292
    public function sum($field, $name = null){
293
      $func = 'SUM(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
294
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
295
      return $this;
296
    }
297
298
    /**
299
     * Set the SQL function COUNT in SELECT statment
300
     * @param  string $field the field name
301
     * @param  string $name  if is not null represent the alias used for this field in the result
302
     * @return object        the current Database instance
303
     */
304
    public function count($field = '*', $name = null){
305
      $func = 'COUNT(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
306
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
307
      return $this;
308
    }
309
310
    /**
311
     * Set the SQL function AVG in SELECT statment
312
     * @param  string $field the field name
313
     * @param  string $name  if is not null represent the alias used for this field in the result
314
     * @return object        the current Database instance
315
     */
316
    public function avg($field, $name = null){
317
      $func = 'AVG(' . $field . ')' . (!is_null($name) ? ' AS ' . $name : '');
318
      $this->select = ($this->select == '*' ? $func : $this->select . ', ' . $func);
319
      return $this;
320
    }
321
322
    /**
323
     * Set the SQL JOIN statment
324
     * @param  string $table  the join table name
325
     * @param  string $field1 the first field for join conditions	
326
     * @param  string $op     the join condition operator. If is null the default will be "="
327
     * @param  string $field2 the second field for join conditions
328
     * @param  string $type   the type of join (INNER, LEFT, RIGHT)
329
     * @return object        the current Database instance
330
     */
331
    public function join($table, $field1 = null, $op = null, $field2 = null, $type = ''){
332
      $on = $field1;
333
      $table = $this->prefix . $table;
334
      if(! is_null($op)){
335
        $on = (! in_array($op, $this->operatorList) ? $this->prefix . $field1 . ' = ' . $this->prefix . $op : $this->prefix . $field1 . ' ' . $op . ' ' . $this->prefix . $field2);
336
      }
337
      if (empty($this->join)){
338
        $this->join = ' ' . $type . 'JOIN' . ' ' . $table . ' ON ' . $on;
339
      }
340
      else{
341
        $this->join = $this->join . ' ' . $type . 'JOIN' . ' ' . $table . ' ON ' . $on;
342
      }
343
      return $this;
344
    }
345
346
    /**
347
     * Set the SQL INNER JOIN statment
348
     * @see  Database::join()
349
     * @return object        the current Database instance
350
     */
351
    public function innerJoin($table, $field1, $op = null, $field2 = ''){
352
      return $this->join($table, $field1, $op, $field2, 'INNER ');
353
    }
354
355
    /**
356
     * Set the SQL LEFT JOIN statment
357
     * @see  Database::join()
358
     * @return object        the current Database instance
359
     */
360
    public function leftJoin($table, $field1, $op = null, $field2 = ''){
361
      return $this->join($table, $field1, $op, $field2, 'LEFT ');
362
	}
363
364
	/**
365
     * Set the SQL RIGHT JOIN statment
366
     * @see  Database::join()
367
     * @return object        the current Database instance
368
     */
369
    public function rightJoin($table, $field1, $op = null, $field2 = ''){
370
      return $this->join($table, $field1, $op, $field2, 'RIGHT ');
371
    }
372
373
    /**
374
     * Set the SQL FULL OUTER JOIN statment
375
     * @see  Database::join()
376
     * @return object        the current Database instance
377
     */
378
    public function fullOuterJoin($table, $field1, $op = null, $field2 = ''){
379
    	return $this->join($table, $field1, $op, $field2, 'FULL OUTER ');
380
    }
381
382
    /**
383
     * Set the SQL LEFT OUTER JOIN statment
384
     * @see  Database::join()
385
     * @return object        the current Database instance
386
     */
387
    public function leftOuterJoin($table, $field1, $op = null, $field2 = ''){
388
      return $this->join($table, $field1, $op, $field2, 'LEFT OUTER ');
389
    }
390
391
    /**
392
     * Set the SQL RIGHT OUTER JOIN statment
393
     * @see  Database::join()
394
     * @return object        the current Database instance
395
     */
396
    public function rightOuterJoin($table, $field1, $op = null, $field2 = ''){
397
      return $this->join($table, $field1, $op, $field2, 'RIGHT OUTER ');
398
    }
399
400
    /**
401
     * Set the SQL WHERE CLAUSE for IS NULL
402
     * @param  string|array $field  the field name or array of field list
403
     * @param  string $andOr the separator type used 'AND', 'OR', etc.
404
     * @return object        the current Database instance
405
     */
406
    public function whereIsNull($field, $andOr = 'AND'){
407
      if(is_array($field)){
408
        foreach($field as $f){
409
        	$this->whereIsNull($f, $andOr);
410
        }
411
      }
412
      else{
413
           $this->setWhereStr($field.' IS NULL ', $andOr);
414
      }
415
      return $this;
416
    }
417
418
    /**
419
     * Set the SQL WHERE CLAUSE for IS NOT NULL
420
     * @param  string|array $field  the field name or array of field list
421
     * @param  string $andOr the separator type used 'AND', 'OR', etc.
422
     * @return object        the current Database instance
423
     */
424
    public function whereIsNotNull($field, $andOr = 'AND'){
425
      if(is_array($field)){
426
        foreach($field as $f){
427
          $this->whereIsNotNull($f, $andOr);
428
        }
429
      }
430
      else{
431
          $this->setWhereStr($field.' IS NOT NULL ', $andOr);
432
      }
433
      return $this;
434
    }
435
    
436
    /**
437
     * Set the SQL WHERE CLAUSE statment
438
     * @param  string|array  $where the where field or array of field list
439
     * @param  array|string  $op     the condition operator. If is null the default will be "="
440
     * @param  mixed  $val    the where value
441
     * @param  string  $type   the type used for this where clause (NOT, etc.)
442
     * @param  string  $andOr the separator type used 'AND', 'OR', etc.
443
     * @param  boolean $escape whether to escape or not the $val
444
     * @return object        the current Database instance
445
     */
446
    public function where($where, $op = null, $val = null, $type = '', $andOr = 'AND', $escape = true){
447
      $whereStr = '';
448
      if (is_array($where)){
449
        $whereStr = $this->getWhereStrIfIsArray($where, $type, $andOr, $escape);
450
      }
451
      else{
452
        if(is_array($op)){
453
          $whereStr = $this->getWhereStrIfOperatorIsArray($where, $op, $type, $escape);
454
        } else {
455
          $whereStr = $this->getWhereStrForOperator($where, $op, $val, $type, $escape = true);
456
        }
457
      }
458
      $this->setWhereStr($whereStr, $andOr);
459
      return $this;
460
    }
461
462
    /**
463
     * Set the SQL WHERE CLAUSE statment using OR
464
     * @see  Database::where()
465
     * @return object        the current Database instance
466
     */
467
    public function orWhere($where, $op = null, $val = null, $escape = true){
468
      return $this->where($where, $op, $val, '', 'OR', $escape);
469
    }
470
471
472
    /**
473
     * Set the SQL WHERE CLAUSE statment using AND and NOT
474
     * @see  Database::where()
475
     * @return object        the current Database instance
476
     */
477
    public function notWhere($where, $op = null, $val = null, $escape = true){
478
      return $this->where($where, $op, $val, 'NOT ', 'AND', $escape);
479
    }
480
481
    /**
482
     * Set the SQL WHERE CLAUSE statment using OR and NOT
483
     * @see  Database::where()
484
     * @return object        the current Database instance
485
     */
486
    public function orNotWhere($where, $op = null, $val = null, $escape = true){
487
    	return $this->where($where, $op, $val, 'NOT ', 'OR', $escape);
488
    }
489
490
    /**
491
     * Set the opened parenthesis for the complex SQL query
492
     * @param  string $type   the type of this grouped (NOT, etc.)
493
     * @param  string $andOr the multiple conditions separator (AND, OR, etc.)
494
     * @return object        the current Database instance
495
     */
496
    public function groupStart($type = '', $andOr = ' AND'){
497
      if (empty($this->where)){
498
        $this->where = $type . ' (';
499
      }
500
      else{
501
          if(substr($this->where, -1) == '('){
502
            $this->where .= $type . ' (';
503
          }
504
          else{
505
          	$this->where .= $andOr . ' ' . $type . ' (';
506
          }
507
      }
508
      return $this;
509
    }
510
511
    /**
512
     * Set the opened parenthesis for the complex SQL query using NOT type
513
     * @see  Database::groupStart()
514
     * @return object        the current Database instance
515
     */
516
    public function notGroupStart(){
517
      return $this->groupStart('NOT');
518
    }
519
520
    /**
521
     * Set the opened parenthesis for the complex SQL query using OR for separator
522
     * @see  Database::groupStart()
523
     * @return object        the current Database instance
524
     */
525
    public function orGroupStart(){
526
      return $this->groupStart('', ' OR');
527
    }
528
529
     /**
530
     * Set the opened parenthesis for the complex SQL query using OR for separator and NOT for type
531
     * @see  Database::groupStart()
532
     * @return object        the current Database instance
533
     */
534
    public function orNotGroupStart(){
535
      return $this->groupStart('NOT', ' OR');
536
    }
537
538
    /**
539
     * Close the parenthesis for the grouped SQL
540
     * @return object        the current Database instance
541
     */
542
    public function groupEnd(){
543
      $this->where .= ')';
544
      return $this;
545
    }
546
547
    /**
548
     * Set the SQL WHERE CLAUSE statment for IN
549
     * @param  string  $field  the field name for IN statment
550
     * @param  array   $keys   the list of values used
551
     * @param  string  $type   the condition separator type (NOT)
552
     * @param  string  $andOr the multiple conditions separator (OR, AND)
553
     * @param  boolean $escape whether to escape or not the values
554
     * @return object        the current Database instance
555
     */
556
    public function in($field, array $keys, $type = '', $andOr = 'AND', $escape = true){
557
      $_keys = array();
558
      foreach ($keys as $k => $v){
559
        if(is_null($v)){
560
          $v = '';
561
        }
562
        $_keys[] = (is_numeric($v) ? $v : $this->escape($v, $escape));
563
      }
564
      $keys = implode(', ', $_keys);
565
      $whereStr = $field . ' ' . $type . ' IN (' . $keys . ')';
566
      $this->setWhereStr($whereStr, $andOr);
567
      return $this;
568
    }
569
570
    /**
571
     * Set the SQL WHERE CLAUSE statment for NOT IN with AND separator
572
     * @see  Database::in()
573
     * @return object        the current Database instance
574
     */
575
    public function notIn($field, array $keys, $escape = true){
576
      return $this->in($field, $keys, 'NOT ', 'AND', $escape);
577
    }
578
579
    /**
580
     * Set the SQL WHERE CLAUSE statment for IN with OR separator
581
     * @see  Database::in()
582
     * @return object        the current Database instance
583
     */
584
    public function orIn($field, array $keys, $escape = true){
585
      return $this->in($field, $keys, '', 'OR', $escape);
586
    }
587
588
    /**
589
     * Set the SQL WHERE CLAUSE statment for NOT IN with OR separator
590
     * @see  Database::in()
591
     * @return object        the current Database instance
592
     */
593
    public function orNotIn($field, array $keys, $escape = true){
594
      return $this->in($field, $keys, 'NOT ', 'OR', $escape);
595
    }
596
597
    /**
598
     * Set the SQL WHERE CLAUSE statment for BETWEEN
599
     * @param  string  $field  the field used for the BETWEEN statment
600
     * @param  mixed  $value1 the BETWEEN begin value
601
     * @param  mixed  $value2 the BETWEEN end value
602
     * @param  string  $type   the condition separator type (NOT)
603
     * @param  string  $andOr the multiple conditions separator (OR, AND)
604
     * @param  boolean $escape whether to escape or not the values
605
     * @return object        the current Database instance
606
     */
607
    public function between($field, $value1, $value2, $type = '', $andOr = 'AND', $escape = true){
608
      if(is_null($value1)){
609
        $value1 = '';
610
      }
611
      if(is_null($value2)){
612
        $value2 = '';
613
      }
614
      $whereStr = $field . ' ' . $type . ' BETWEEN ' . $this->escape($value1, $escape) . ' AND ' . $this->escape($value2, $escape);
615
      $this->setWhereStr($whereStr, $andOr);
616
      return $this;
617
    }
618
619
    /**
620
     * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and AND separator
621
     * @see  Database::between()
622
     * @return object        the current Database instance
623
     */
624
    public function notBetween($field, $value1, $value2, $escape = true){
625
      return $this->between($field, $value1, $value2, 'NOT ', 'AND', $escape);
626
    }
627
628
    /**
629
     * Set the SQL WHERE CLAUSE statment for BETWEEN with OR separator
630
     * @see  Database::between()
631
     * @return object        the current Database instance
632
     */
633
    public function orBetween($field, $value1, $value2, $escape = true){
634
      return $this->between($field, $value1, $value2, '', 'OR', $escape);
635
    }
636
637
    /**
638
     * Set the SQL WHERE CLAUSE statment for BETWEEN with NOT type and OR separator
639
     * @see  Database::between()
640
     * @return object        the current Database instance
641
     */
642
    public function orNotBetween($field, $value1, $value2, $escape = true){
643
      return $this->between($field, $value1, $value2, 'NOT ', 'OR', $escape);
644
    }
645
646
    /**
647
     * Set the SQL WHERE CLAUSE statment for LIKE
648
     * @param  string  $field  the field name used in LIKE statment
649
     * @param  string  $data   the LIKE value for this field including the '%', and '_' part
650
     * @param  string  $type   the condition separator type (NOT)
651
     * @param  string  $andOr the multiple conditions separator (OR, AND)
652
     * @param  boolean $escape whether to escape or not the values
653
     * @return object        the current Database instance
654
     */
655
    public function like($field, $data, $type = '', $andOr = 'AND', $escape = true){
656
      if(empty($data)){
657
        $data = '';
658
      }
659
      $this->setWhereStr($field . ' ' . $type . ' LIKE ' . ($this->escape($data, $escape)), $andOr);
660
      return $this;
661
    }
662
663
    /**
664
     * Set the SQL WHERE CLAUSE statment for LIKE with OR separator
665
     * @see  Database::like()
666
     * @return object        the current Database instance
667
     */
668
    public function orLike($field, $data, $escape = true){
669
      return $this->like($field, $data, '', 'OR', $escape);
670
    }
671
672
    /**
673
     * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and AND separator
674
     * @see  Database::like()
675
     * @return object        the current Database instance
676
     */
677
    public function notLike($field, $data, $escape = true){
678
      return $this->like($field, $data, 'NOT ', 'AND', $escape);
679
    }
680
681
    /**
682
     * Set the SQL WHERE CLAUSE statment for LIKE with NOT type and OR separator
683
     * @see  Database::like()
684
     * @return object        the current Database instance
685
     */
686
    public function orNotLike($field, $data, $escape = true){
687
      return $this->like($field, $data, 'NOT ', 'OR', $escape);
688
    }
689
690
    /**
691
     * Set the SQL LIMIT statment
692
     * @param  int $limit    the limit offset. If $limitEnd is null this will be the limit count
693
     * like LIMIT n;
694
     * @param  int $limitEnd the limit count
695
     * @return object        the current Database instance
696
     */
697
    public function limit($limit, $limitEnd = null){
698
      if(empty($limit)){
699
        return;
700
      }
701
      if (! is_null($limitEnd)){
702
        $this->limit = $limit . ', ' . $limitEnd;
703
      }
704
      else{
705
        $this->limit = $limit;
706
      }
707
      return $this;
708
    }
709
710
    /**
711
     * Set the SQL ORDER BY CLAUSE statment
712
     * @param  string $orderBy   the field name used for order
713
     * @param  string $orderDir the order direction (ASC or DESC)
714
     * @return object        the current Database instance
715
     */
716
    public function orderBy($orderBy, $orderDir = ' ASC'){
717
        if(stristr($orderBy, ' ') || $orderBy == 'rand()'){
718
          $this->orderBy = empty($this->orderBy) ? $orderBy : $this->orderBy . ', ' . $orderBy;
719
        }
720
        else{
721
          $this->orderBy = empty($this->orderBy) ? ($orderBy . ' ' 
722
                            . strtoupper($orderDir)) : $this->orderBy 
723
                            . ', ' . $orderBy . ' ' . strtoupper($orderDir);
724
        }
725
      return $this;
726
    }
727
728
    /**
729
     * Set the SQL GROUP BY CLAUSE statment
730
     * @param  string|array $field the field name used or array of field list
731
     * @return object        the current Database instance
732
     */
733
    public function groupBy($field){
734
      if(is_array($field)){
735
        $this->groupBy = implode(', ', $field);
736
      }
737
      else{
738
        $this->groupBy = $field;
739
      }
740
      return $this;
741
    }
742
743
    /**
744
     * Set the SQL HAVING CLAUSE statment
745
     * @param  string  $field  the field name used for HAVING statment
746
     * @param  string|array  $op     the operator used or array
747
     * @param  mixed  $val    the value for HAVING comparaison
748
     * @param  boolean $escape whether to escape or not the values
749
     * @return object        the current Database instance
750
     */
751
    public function having($field, $op = null, $val = null, $escape = true){
752
      if(is_array($op)){
753
        $x = explode('?', $field);
754
        $w = '';
755
        foreach($x as $k => $v){
756
  	      if(!empty($v)){
757
            if(isset($op[$k]) && is_null($op[$k])){
758
              $op[$k] = '';
759
            }
760
  	      	$w .= $v . (isset($op[$k]) ? $this->escape($op[$k], $escape) : '');
761
  	      }
762
      	}
763
        $this->having = $w;
764
      }
765
      else if (! in_array($op, $this->operatorList)){
766
        if(is_null($op)){
767
          $op = '';
768
        }
769
        $this->having = $field . ' > ' . ($this->escape($op, $escape));
770
      }
771
      else{
772
        if(is_null($val)){
773
          $val = '';
774
        }
775
        $this->having = $field . ' ' . $op . ' ' . ($this->escape($val, $escape));
776
      }
777
      return $this;
778
    }
779
780
    /**
781
     * Return the number of rows returned by the current query
782
     * @return int
783
     */
784
    public function numRows(){
785
      return $this->numRows;
786
    }
787
788
    /**
789
     * Return the last insert id value
790
     * @return mixed
791
     */
792
    public function insertId(){
793
      return $this->insertId;
794
    }
795
796
    /**
797
     * Show an error got from the current query (SQL command synthax error, database driver returned error, etc.)
798
     */
799
    public function error(){
800
  		if($this->error){
801
  			show_error('Query: "' . $this->query . '" Error: ' . $this->error, 'Database Error');
802
  		}
803
    }
804
805
    /**
806
     * Get the result of one record rows returned by the current query
807
     * @param  boolean $returnSQLQueryOrResultType if is boolean and true will return the SQL query string.
808
     * If is string will determine the result type "array" or "object"
809
     * @return mixed       the query SQL string or the record result
810
     */
811
    public function get($returnSQLQueryOrResultType = false){
812
      $this->limit = 1;
813
      $query = $this->getAll(true);
814
      if($returnSQLQueryOrResultType === true){
815
        return $query;
816
      }
817
      else{
818
        return $this->query( $query, false, (($returnSQLQueryOrResultType == 'array') ? true : false) );
819
      }
820
    }
821
822
    /**
823
     * Get the result of record rows list returned by the current query
824
     * @param  boolean $returnSQLQueryOrResultType if is boolean and true will return the SQL query string.
825
     * If is string will determine the result type "array" or "object"
826
     * @return mixed       the query SQL string or the record result
827
     */
828
    public function getAll($returnSQLQueryOrResultType = false){
829
      $query = 'SELECT ' . $this->select . ' FROM ' . $this->from;
830
      if (! empty($this->join)){
831
        $query .= $this->join;
832
      }
833
	  
834
      if (! empty($this->where)){
835
        $query .= ' WHERE ' . $this->where;
836
      }
837
838
      if (! empty($this->groupBy)){
839
        $query .= ' GROUP BY ' . $this->groupBy;
840
      }
841
842
      if (! empty($this->having)){
843
        $query .= ' HAVING ' . $this->having;
844
      }
845
846
      if (! empty($this->orderBy)){
847
          $query .= ' ORDER BY ' . $this->orderBy;
848
      }
849
850
      if(! empty($this->limit)){
851
      	$query .= ' LIMIT ' . $this->limit;
852
      }
853
	  
854
	   if($returnSQLQueryOrResultType === true){
855
      	return $query;
856
      }
857
      else{
858
    	   return $this->query($query, true, (($returnSQLQueryOrResultType == 'array') ? true : false) );
859
      }
860
    }
861
862
    /**
863
     * Insert new record in the database
864
     * @param  array   $data   the record data if is empty will use the $this->data array.
865
     * @param  boolean $escape  whether to escape or not the values
866
     * @return mixed          the insert id of the new record or null
867
     */
868
    public function insert($data = array(), $escape = true){
869
      $column = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $column is dead and can be removed.
Loading history...
870
      $val = array();
0 ignored issues
show
Unused Code introduced by
The assignment to $val is dead and can be removed.
Loading history...
871
      if(empty($data) && $this->getData()){
872
        //as when using $this->setData() the data already escaped
873
        $escape = false;
874
        $data = $this->getData();
875
      }
876
877
      $columns = array_keys($data);
878
      $column = implode(',', $columns);
879
      $val = implode(', ', ($escape ? array_map(array($this, 'escape'), $data) : $data));
880
881
      $query = 'INSERT INTO ' . $this->from . ' (' . $column . ') VALUES (' . $val . ')';
882
      $query = $this->query($query);
883
884
      if ($query){
885
        if(! $this->pdo){
886
          $this->connect();
887
        }
888
        $this->insertId = $this->pdo->lastInsertId();
889
        return $this->insertId();
890
      }
891
      else{
892
		  return false;
893
      }
894
    }
895
896
    /**
897
     * Update record in the database
898
     * @param  array   $data   the record data if is empty will use the $this->data array.
899
     * @param  boolean $escape  whether to escape or not the values
900
     * @return mixed          the update status
901
     */
902
    public function update($data = array(), $escape = true){
903
      $query = 'UPDATE ' . $this->from . ' SET ';
904
      $values = array();
905
      if(empty($data) && $this->getData()){
906
        //as when using $this->setData() the data already escaped
907
        $escape = false;
908
        $data = $this->getData();
909
      }
910
      foreach ($data as $column => $val){
911
        $values[] = $column . ' = ' . ($this->escape($val, $escape));
912
      }
913
      $query .= implode(', ', $values);
914
      if (! empty($this->where)){
915
        $query .= ' WHERE ' . $this->where;
916
      }
917
918
      if (! empty($this->orderBy)){
919
        $query .= ' ORDER BY ' . $this->orderBy;
920
      }
921
922
      if (! empty($this->limit)){
923
        $query .= ' LIMIT ' . $this->limit;
924
      }
925
      return $this->query($query);
926
    }
927
928
    /**
929
     * Delete the record in database
930
     * @return mixed the delete status
931
     */
932
    public function delete(){
933
    	$query = 'DELETE FROM ' . $this->from;
934
935
    	if (! empty($this->where)){
936
    		$query .= ' WHERE ' . $this->where;
937
      	}
938
939
    	if (! empty($this->orderBy)){
940
    	  $query .= ' ORDER BY ' . $this->orderBy;
941
      	}
942
943
    	if (! empty($this->limit)){
944
    		$query .= ' LIMIT ' . $this->limit;
945
      	}
946
947
    	if($query == 'DELETE FROM ' . $this->from && $this->config['driver'] != 'sqlite'){  
948
    		$query = 'TRUNCATE TABLE ' . $this->from;
949
      }
950
    	return $this->query($query);
951
    }
952
953
954
    /**
955
     * Execute an SQL query
956
     * @param  string  $query the query SQL string
957
     * @param  boolean|array $all  if boolean this indicate whether to return all record or not, if array 
958
     * will 
959
     * @param  boolean $array return the result as array
960
     * @return mixed         the query result
961
     */
962
    public function query($query, $all = true, $array = false){
963
      $this->reset();
964
      $query = $this->transformPreparedQuery($query, $all);
965
      $this->query = preg_replace('/\s\s+|\t\t+/', ' ', trim($query));
966
      
967
      $isSqlSELECTQuery = stristr($this->query, 'SELECT');
968
969
      $this->logger->info('Execute SQL query ['.$this->query.'], return type: ' . ($array?'ARRAY':'OBJECT') .', return as list: ' . ($all ? 'YES':'NO'));
970
      //cache expire time
971
  	  $cacheExpire = $this->temporaryCacheTtl;
972
  	  
973
  	  //return to the initial cache time
974
  	  $this->temporaryCacheTtl = $this->cacheTtl;
975
  	  
976
  	  //config for cache
977
      $cacheEnable = get_config('cache_enable');
978
  	  
979
  	  //the database cache content
980
      $cacheContent = null;
981
982
  	  //if can use cache feature for this query
983
  	  $dbCacheStatus = $cacheEnable && $cacheExpire > 0;
984
	  
985
      if ($dbCacheStatus && $isSqlSELECTQuery){
986
          $cacheContent = $this->getCacheContentForQuery($query, $all, $array);  
987
      }
988
      else{
989
		      $this->logger->info('The cache is not enabled for this query or is not the SELECT query, get the result directly from real database');
990
      }
991
     
992
      if (! $cacheContent && $isSqlSELECTQuery){
993
        $sqlQuery = $this->runSqlQuery($query, $all, $array);
994
        if ($sqlQuery){
0 ignored issues
show
introduced by
$sqlQuery is of type object, thus it always evaluated to true.
Loading history...
995
            $this->setQueryResultForSelect($sqlQuery, $all, $array);
996
            $this->setCacheContentForQuery(
997
                                            $this->query, 
998
                                            $this->getCacheBenchmarkKeyForQuery($this->query, $all, $array), 
999
                                            $this->result, 
1000
                                            $dbCacheStatus && $isSqlSELECTQuery, 
1001
                                            $this->temporaryCacheTtl
1002
                                          );
1003
        }
1004
      }
1005
      else if ((! $cacheContent && !$isSqlSELECTQuery) || ($cacheContent && !$isSqlSELECTQuery)){
1006
    		$sqlQuery = $this->runSqlQuery($query, $all, $array);
1007
    		if($sqlQuery){
0 ignored issues
show
introduced by
$sqlQuery is of type object, thus it always evaluated to true.
Loading history...
1008
          $this->setQueryResultForNonSelect($sqlQuery, $all, $array);
1009
    		}
1010
        if (! $this->result){
1011
          $this->setQueryError();
1012
        }
1013
      }
1014
      else{
1015
        $this->logger->info('The result for query [' .$this->query. '] already cached use it');
1016
        $this->result = $cacheContent;
1017
	     	$this->numRows = count($this->result);
1018
      }
1019
      $this->queryCount++;
1020
      if(! $this->result){
1021
        $this->logger->info('No result where found for the query [' . $query . ']');
1022
      }
1023
      return $this->result;
1024
    }
1025
1026
    /**
1027
     * Set database cache time to live
1028
     * @param integer $ttl the cache time to live in second
1029
     * @return object        the current Database instance
1030
     */
1031
    public function setCache($ttl = 0){
1032
      if($ttl > 0){
1033
        $this->cacheTtl = $ttl;
1034
		    $this->temporaryCacheTtl = $ttl;
1035
      }
1036
      return $this;
1037
    }
1038
	
1039
	/**
1040
	 * Enabled cache temporary for the current query not globally	
1041
	 * @param  integer $ttl the cache time to live in second
1042
	 * @return object        the current Database instance
1043
	 */
1044
	public function cached($ttl = 0){
1045
      if($ttl > 0){
1046
        $this->temporaryCacheTtl = $ttl;
1047
      }
1048
	  return $this;
1049
    }
1050
1051
    /**
1052
     * Escape the data before execute query useful for security.
1053
     * @param  mixed $data the data to be escaped
1054
     * @param boolean $escaped whether we can do escape of not 
1055
     * @return mixed       the data after escaped or the same data if not
1056
     */
1057
    public function escape($data, $escaped = true){
1058
      if($escaped){
1059
        if(! $this->pdo){
1060
          $this->connect();
1061
        }
1062
        return $this->pdo->quote(trim($data)); 
1063
      }
1064
      return $data;
1065
    }
1066
1067
    /**
1068
     * Return the number query executed count for the current request
1069
     * @return int
1070
     */
1071
    public function queryCount(){
1072
      return $this->queryCount;
1073
    }
1074
1075
    /**
1076
     * Return the current query SQL string
1077
     * @return string
1078
     */
1079
    public function getQuery(){
1080
      return $this->query;
1081
    }
1082
1083
    /**
1084
     * Return the application database name
1085
     * @return string
1086
     */
1087
    public function getDatabaseName(){
1088
      return $this->databaseName;
1089
    }
1090
1091
     /**
1092
     * Return the database configuration
1093
     * @return array
1094
     */
1095
    public  function getDatabaseConfiguration(){
1096
      return $this->config;
1097
    }
1098
1099
    /**
1100
     * set the database configuration
1101
     * @param array $config the configuration
1102
     */
1103
    public function setDatabaseConfiguration(array $config){
1104
      $this->config = array_merge($this->config, $config);
1105
      $this->prefix = $this->config['prefix'];
1106
      $this->databaseName = $this->config['database'];
1107
      $this->logger->info('The database configuration are listed below: ' . stringfy_vars(array_merge($this->config, array('password' => string_hidden($this->config['password'])))));
1108
      return $this;
1109
    }
1110
1111
    /**
1112
     * Return the PDO instance
1113
     * @return PDO
1114
     */
1115
    public function getPdo(){
1116
      return $this->pdo;
1117
    }
1118
1119
    /**
1120
     * Set the PDO instance
1121
     * @param PDO $pdo the pdo object
1122
     */
1123
    public function setPdo(PDO $pdo){
1124
      $this->pdo = $pdo;
1125
      return $this;
1126
    }
1127
1128
1129
    /**
1130
     * Return the Log instance
1131
     * @return Log
1132
     */
1133
    public function getLogger(){
1134
      return $this->logger;
1135
    }
1136
1137
    /**
1138
     * Set the log instance
1139
     * @param Log $logger the log object
1140
     */
1141
    public function setLogger($logger){
1142
      $this->logger = $logger;
1143
      return $this;
1144
    }
1145
1146
     /**
1147
     * Return the cache instance
1148
     * @return CacheInterface
1149
     */
1150
    public function getCacheInstance(){
1151
      return $this->cacheInstance;
1152
    }
1153
1154
    /**
1155
     * Set the cache instance
1156
     * @param CacheInterface $cache the cache object
1157
     */
1158
    public function setCacheInstance($cache){
1159
      $this->cacheInstance = $cache;
1160
      return $this;
1161
    }
1162
1163
    /**
1164
     * Return the benchmark instance
1165
     * @return Benchmark
1166
     */
1167
    public function getBenchmark(){
1168
      return $this->benchmarkInstance;
1169
    }
1170
1171
    /**
1172
     * Set the benchmark instance
1173
     * @param Benchmark $cache the cache object
1174
     */
1175
    public function setBenchmark($benchmark){
1176
      $this->benchmarkInstance = $benchmark;
1177
      return $this;
1178
    }
1179
1180
    /**
1181
     * Return the data to be used for insert, update, etc.
1182
     * @return array
1183
     */
1184
    public function getData(){
1185
      return $this->data;
1186
    }
1187
1188
    /**
1189
     * Set the data to be used for insert, update, etc.
1190
     * @param string $key the data key identified
1191
     * @param mixed $value the data value
1192
     * @param boolean $escape whether to escape or not the $value
1193
     * @return object        the current Database instance
1194
     */
1195
    public function setData($key, $value, $escape = true){
1196
      $this->data[$key] = $this->escape($value, $escape);
1197
      return $this;
1198
    }
1199
1200
    /**
1201
     * Set the Log instance using argument or create new instance
1202
     * @param object $logger the Log instance if not null
1203
     */
1204
    protected function setLoggerFromParamOrCreateNewInstance(Log $logger = null){
1205
      if($logger !== null){
1206
        $this->logger = $logger;
1207
      }
1208
      else{
1209
          $this->logger =& class_loader('Log', 'classes');
1210
          $this->logger->setLogger('Library::Database');
1211
      }
1212
    }
1213
1214
   /**
1215
    * Setting the database configuration using the configuration file
1216
    * @param array $overwriteConfig the additional configuration to overwrite with the existing one
1217
    */
1218
    protected function setDatabaseConfigurationFromConfigFile(array $overwriteConfig = array()){
1219
        $db = array();
1220
        if(file_exists(CONFIG_PATH . 'database.php')){
1221
            //here don't use require_once because somewhere user can create database instance directly
1222
            require CONFIG_PATH . 'database.php';
1223
        }
1224
          
1225
        if(! empty($overwriteConfig)){
1226
          $db = array_merge($db, $overwriteConfig);
1227
        }
1228
        $config = array(
1229
          'driver' => 'mysql',
1230
          'username' => 'root',
1231
          'password' => '',
1232
          'database' => '',
1233
          'hostname' => 'localhost',
1234
          'charset' => 'utf8',
1235
          'collation' => 'utf8_general_ci',
1236
          'prefix' => '',
1237
          'port' => ''
1238
        );
1239
        $this->setDatabaseConfiguration(array_merge($config, $db));
1240
        $this->determinePortConfigurationFromHostname();  
1241
    }
1242
1243
    /**
1244
     * This method is used to get the PDO DSN string using th configured driver
1245
     * @return string the DSN string
1246
     */
1247
    protected function getDsnFromDriver(){
1248
      $config = $this->getDatabaseConfiguration();
1249
      if(! empty($config)){
1250
            $driverDsnMap = array(
1251
                                    'mysql' => 'mysql:host=' . $config['hostname'] . ';' 
1252
                                                . (($config['port']) != '' ? 'port=' . $config['port'] . ';' : '') 
1253
                                                . 'dbname=' . $config['database'],
1254
                                    'pgsql' => 'pgsql:host=' . $config['hostname'] . ';' 
1255
                                                . (($config['port']) != '' ? 'port=' . $config['port'] . ';' : '')
1256
                                                . 'dbname=' . $config['database'],
1257
                                    'sqlite' => 'sqlite:' . $config['database'],
1258
                                    'oracle' => 'oci:dbname=' . $config['hostname'] 
1259
                                                . (($config['port']) != '' ? ':' . $config['port'] : '')
1260
                                                . '/' . $config['database']
1261
                                  );
1262
            return isset($driverDsnMap[$config['driver']]) ? $driverDsnMap[$config['driver']] : '';
1263
      }                   
1264
      return null;
1265
    }
1266
1267
    /**
1268
     * Set the database server port configuration using the current hostname like localhost:3309 
1269
     * @return void
1270
     */
1271
    protected function determinePortConfigurationFromHostname(){
1272
      if(strstr($this->config['hostname'], ':')){
1273
        $p = explode(':', $this->config['hostname']);
1274
        if(count($p) > 2){
1275
          $this->setDatabaseConfiguration(array(
1276
            'hostname' => $p[0],
1277
            'port' => $p[1]
1278
          ));
1279
        }
1280
      }
1281
    }
1282
1283
   /**
1284
     * Get the SQL WHERE clause using array column => value
1285
     * @see Database::where
1286
     *
1287
     * @return string
1288
     */
1289
    protected function getWhereStrIfIsArray(array $where, $type = '', $andOr = 'AND', $escape = true){
1290
        $_where = array();
1291
        foreach ($where as $column => $data){
1292
          if(is_null($data)){
1293
            $data = '';
1294
          }
1295
          $_where[] = $type . $column . ' = ' . ($this->escape($data, $escape));
1296
        }
1297
        $where = implode(' '.$andOr.' ', $_where);
1298
        return $where;
1299
    }
1300
1301
     /**
1302
     * Get the SQL WHERE clause when operator argument is an array
1303
     * @see Database::where
1304
     *
1305
     * @return string
1306
     */
1307
    protected function getWhereStrIfOperatorIsArray($where, array $op, $type = '', $escape = true){
1308
       $x = explode('?', $where);
1309
       $w = '';
1310
        foreach($x as $k => $v){
1311
          if(! empty($v)){
1312
              if(isset($op[$k]) && is_null($op[$k])){
1313
                $op[$k] = '';
1314
              }
1315
              $w .= $type . $v . (isset($op[$k]) ? ($this->escape($op[$k], $escape)) : '');
1316
          }
1317
        }
1318
        return $w;
1319
    }
1320
1321
    /**
1322
     * Get the default SQL WHERE clause using operator = or the operator argument
1323
     * @see Database::where
1324
     *
1325
     * @return string
1326
     */
1327
    protected function getWhereStrForOperator($where, $op = null, $val = null, $type = '', $escape = true){
1328
       $w = '';
1329
       if (! in_array((string)$op, $this->operatorList)){
1330
          if(is_null($op)){
1331
            $op = '';
1332
          }
1333
          $w = $type . $where . ' = ' . ($this->escape($op, $escape));
1334
        }
1335
        else{
1336
          if(is_null($val)){
1337
            $val = '';
1338
          }
1339
          $w = $type . $where . $op . ($this->escape($val, $escape));
1340
        }
1341
        return $w;
1342
      }
1343
1344
      /**
1345
       * Set the $this->where property 
1346
       * @param string $whereStr the WHERE clause string
1347
       * @param  string  $andOr the separator type used 'AND', 'OR', etc.
1348
       */
1349
      protected function setWhereStr($whereStr, $andOr = 'AND'){
1350
        if (empty($this->where)){
1351
          $this->where = $whereStr;
1352
        }
1353
        else{
1354
          if(substr($this->where, -1) == '('){
1355
            $this->where = $this->where . ' ' . $whereStr;
1356
          }
1357
          else{
1358
            $this->where = $this->where . ' '.$andOr.' ' . $whereStr;
1359
          }
1360
        }
1361
      }
1362
1363
        /**
1364
     * Transform the prepared query like (?, ?, ?) into string format
1365
     * @see Database::query
1366
     *
1367
     * @return string
1368
     */
1369
    protected function transformPreparedQuery($query, $data){
1370
      if(is_array($data)){
1371
        $x = explode('?', $query);
1372
        $q = '';
1373
        foreach($x as $k => $v){
1374
          if(! empty($v)){
1375
            $q .= $v . (isset($data[$k]) ? $this->escape($data[$k]) : '');
1376
          }
1377
        }
1378
        return $q;
1379
      }
1380
      return $query;
1381
    }
1382
1383
    /**
1384
     * Return the cache key for the query
1385
     * @see Database::query
1386
     * 
1387
     *  @return string
1388
     */
1389
    protected function getCacheBenchmarkKeyForQuery($query, $all, $array){
1390
      return md5($query . $all . $array);
1391
    }
1392
1393
    /**
1394
     * Get the cache content for this query
1395
     * @see Database::query
1396
     *      
1397
     * @return mixed
1398
     */
1399
    protected function getCacheContentForQuery($query, $all, $array){
1400
       $this->logger->info('The cache is enabled for this query, try to get result from cache'); 
1401
        $cacheKey = $this->getCacheBenchmarkKeyForQuery($query, $all, $array);
1402
        if(is_object($this->cacheInstance)){
1403
          return $this->cacheInstance->get($cacheKey);
1404
        }
1405
        $instance = & get_instance()->cache;
1406
        $this->setCacheInstance($instance);
1407
        return $instance->get($cacheKey);
1408
    }
1409
1410
    /**
1411
     * Save the result of query into cache
1412
     * @param string $query  the SQL query
1413
     * @param string $key    the cache key
1414
     * @param mixed $result the query result to save
1415
     * @param boolean $status whether can save the query result into cache
1416
     * @param int $expire the cache TTL
1417
     */
1418
     protected function setCacheContentForQuery($query, $key, $result, $status, $expire){
1419
        if ($status){
1420
            $this->logger->info('Save the result for query [' .$query. '] into cache for future use');
1421
            $this->getCacheInstance()->set($key, $result, $expire);
1422
        }
1423
     }
1424
1425
    /**
1426
     * Set the result for SELECT query using PDOStatment
1427
     * @see Database::query
1428
     */
1429
    protected function setQueryResultForSelect($pdoStatment, $all = true, $array = false){
1430
      //if need return all result like list of record
1431
      if ($all){
1432
          $this->result = ($array === false) ? $pdoStatment->fetchAll(PDO::FETCH_OBJ) : $pdoStatment->fetchAll(PDO::FETCH_ASSOC);
1433
      }
1434
      else{
1435
          $this->result = ($array === false) ? $pdoStatment->fetch(PDO::FETCH_OBJ) : $pdoStatment->fetch(PDO::FETCH_ASSOC);
1436
      }
1437
      //Sqlite and pgsql always return 0 when using rowCount()
1438
      if(in_array($this->config['driver'], array('sqlite', 'pgsql'))){
1439
        $this->numRows = count($this->result);  
1440
      }
1441
      else{
1442
        $this->numRows = $pdoStatment->rowCount(); 
1443
      }
1444
    }
1445
1446
    /**
1447
     * Set the result for other command than SELECT query using PDOStatment
1448
     * @see Database::query
1449
     */
1450
    protected function setQueryResultForNonSelect($pdoStatment, $all = true, $array = false){
0 ignored issues
show
Unused Code introduced by
The parameter $all is not used and could be removed. ( Ignorable by Annotation )

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

1450
    protected function setQueryResultForNonSelect($pdoStatment, /** @scrutinizer ignore-unused */ $all = true, $array = false){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $array is not used and could be removed. ( Ignorable by Annotation )

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

1450
    protected function setQueryResultForNonSelect($pdoStatment, $all = true, /** @scrutinizer ignore-unused */ $array = false){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1451
      //Sqlite and pgsql always return 0 when using rowCount()
1452
      if(in_array($this->config['driver'], array('sqlite', 'pgsql'))){
1453
        $this->result = 1; //to test the result for the query like UPDATE, INSERT, DELETE
1454
        $this->numRows = 1;  
1455
      }
1456
      else{
1457
          $this->result = $pdoStatment->rowCount() >= 0; //to test the result for the query like UPDATE, INSERT, DELETE
1458
          $this->numRows = $pdoStatment->rowCount(); 
1459
      }
1460
    }
1461
1462
    /**
1463
     * Set error for database query execution
1464
     */
1465
    protected function setQueryError(){
1466
      $error = $this->pdo->errorInfo();
1467
      $this->error = isset($error[2]) ? $error[2] : '';
1468
      $this->logger->error('The database query execution got error: ' . stringfy_vars($error));
1469
      $this->error();
1470
    }
1471
1472
    /**
1473
     * Run the database SQL query and return the PDOStatment object
1474
     * @see Database::query
1475
     * 
1476
     * @return object|void
1477
     */
1478
    protected function runSqlQuery($query, $all, $array){
1479
       //for database query execution time
1480
        $benchmarkMarkerKey = $this->getCacheBenchmarkKeyForQuery($query, $all, $array);
1481
        $benchmarkInstance = $this->getBenchmark();
1482
        if(! is_object($benchmarkInstance)){
1483
          $obj = & get_instance();
1484
          $benchmarkInstance = $obj->benchmark; 
1485
          $this->setBenchmark($benchmarkInstance);
1486
        }
1487
        if(! $this->pdo){
1488
            $this->connect();
1489
        }
1490
        
1491
        $benchmarkInstance->mark('DATABASE_QUERY_START(' . $benchmarkMarkerKey . ')');
1492
        //Now execute the query
1493
        $sqlQuery = $this->pdo->query($query);
1494
        
1495
        //get response time for this query
1496
        $responseTime = $benchmarkInstance->elapsedTime('DATABASE_QUERY_START(' . $benchmarkMarkerKey . ')', 'DATABASE_QUERY_END(' . $benchmarkMarkerKey . ')');
1497
        //TODO use the configuration value for the high response time currently is 1 second
1498
        if($responseTime >= 1 ){
1499
            $this->logger->warning('High response time while processing database query [' .$query. ']. The response time is [' .$responseTime. '] sec.');
1500
        }
1501
        if($sqlQuery){
1502
          return $sqlQuery;
1503
        }
1504
        $this->setQueryError();
1505
    }
1506
1507
  /**
1508
   * Reset the database class attributs to the initail values before each query.
1509
   */
1510
  private function reset(){
1511
    $this->select   = '*';
1512
    $this->from     = null;
1513
    $this->where    = null;
1514
    $this->limit    = null;
1515
    $this->orderBy  = null;
1516
    $this->groupBy  = null;
1517
    $this->having   = null;
1518
    $this->join     = null;
1519
    $this->numRows  = 0;
1520
    $this->insertId = null;
1521
    $this->query    = null;
1522
    $this->error    = null;
1523
    $this->result   = array();
1524
    $this->data     = array();
1525
  }
1526
1527
  /**
1528
   * The class destructor
1529
   */
1530
  public function __destruct(){
1531
    $this->pdo = null;
1532
  }
1533
1534
}
1535