Passed
Branch 1.0.0-dev (c78053)
by nguereza
04:10 queued 15s
created

Database::setPortConfigurationFromHostname()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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