Passed
Push — 1.0.0-dev ( 73c7ea...ea6d41 )
by nguereza
02:46
created

DatabaseQueryRunner::setLoggerFromParamOrCreateNewInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 2
eloc 5
c 1
b 1
f 1
nc 2
nop 1
dl 0
loc 6
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 DatabaseQueryRunner extends BaseClass {
27
        /**
28
         * The last query result
29
         * @var object
30
         */
31
        private $queryResult = null;
32
  	
33
        /**
34
         * The benchmark instance
35
         * @var object
36
         */
37
        private $benchmarkInstance = null;
38
        
39
        /**
40
         * The SQL query statment to execute
41
         * @var string
42
         */
43
        private $query = null;
44
    
45
        /**
46
         * Indicate if we need return result as list
47
         * @var boolean
48
         */
49
        private $returnAsList = true;
50
     
51
     
52
        /**
53
         * Indicate if we need return result as array or not
54
         * @var boolean
55
         */
56
        private $returnAsArray = true;
57
     
58
        /**
59
         * The last PDOStatment instance
60
         * @var object
61
         */
62
        private $pdoStatment = null;
63
     
64
        /**
65
         * The error returned for the last query
66
         * @var string
67
         */
68
        private $error = null;
69
	
70
        /**
71
         * The PDO instance
72
         * @var object
73
         */
74
        private $pdo = null;
75
      
76
        /**
77
         * The database driver name used
78
         * @var string
79
         */
80
        private $driver = null;
81
82
83
	
84
        /**
85
         * Construct new DatabaseQueryRunner
86
         * @param object $pdo the PDO object
87
         * @param string $query the SQL query to be executed
88
         * @param boolean $returnAsList if need return as list or just one row
89
         * @param boolean $returnAsArray whether to return the result as array or not
90
         */
91
        public function __construct(PDO $pdo = null, $query = null, $returnAsList = true, $returnAsArray = false) {
92
            parent::__construct();
93
            if (is_object($pdo)) {
94
                $this->pdo = $pdo;
95
            }
96
            $this->query         = $query;
97
            $this->returnAsList  = $returnAsList;
98
            $this->returnAsArray = $returnAsArray;
99
        }
100
        
101
        /**
102
         * Run the database SQL query and return the DatabaseQueryResult object
103
         * @see Database::query
104
         * 
105
         * @return object|void
106
         */
107
        public function execute() {
108
            //reset instance
109
            $this->reset();
110
           
111
            //for database query execution time
112
            $benchmarkMarkerKey = $this->getBenchmarkKey();
113
            if (!is_object($this->benchmarkInstance)) {
114
                $this->benchmarkInstance = & class_loader('Benchmark');
115
            }
116
            
117
            $this->benchmarkInstance->mark('DATABASE_QUERY_START(' . $benchmarkMarkerKey . ')');                
118
            //Now execute the query
119
            $this->pdoStatment = $this->pdo->query($this->query);
120
            
121
            //get response time for this query
122
            $responseTime = $this->benchmarkInstance->elapsedTime(
123
                                                                    'DATABASE_QUERY_START(' . $benchmarkMarkerKey . ')', 
124
                                                                    'DATABASE_QUERY_END(' . $benchmarkMarkerKey . ')'
125
                                                                    );
126
                //TODO use the configuration value for the high response time currently is 1 second
127
            if ($responseTime >= 1) {
128
                $this->logger->warning(
129
                                        'High response time while processing database query [' . $this->query . ']. 
130
                                         The response time is [' .$responseTime . '] sec.'
131
                                        );
132
            }
133
    		
134
            if ($this->pdoStatment !== false) {
135
                $isSqlSELECTQuery = stristr($this->query, 'SELECT') !== false;
136
                if ($isSqlSELECTQuery) {
137
                    $this->setResultForSelect();              
138
                } else {
139
                    $this->setResultForNonSelect();
140
                }
141
                return $this->queryResult;
142
            }
143
            $this->setQueryRunnerError();
144
        }
145
    	
146
        /**
147
         * Return the result for SELECT query
148
         * @see DatabaseQueryRunner::execute
149
         */
150
        protected function setResultForSelect() {
151
            //if need return all result like list of record
152
            $result = null;
153
            $numRows = 0;
154
            $fetchMode = PDO::FETCH_OBJ;
155
            if ($this->returnAsArray) {
156
            $fetchMode = PDO::FETCH_ASSOC;
157
            }
158
            if ($this->returnAsList) {
159
                $result = $this->pdoStatment->fetchAll($fetchMode);
160
            } else {
161
                $result = $this->pdoStatment->fetch($fetchMode);
162
            }
163
            //Sqlite and pgsql always return 0 when using rowCount()
164
            if (in_array($this->driver, array('sqlite', 'pgsql'))) {
165
            $numRows = count($result);  
166
            } else {
167
            $numRows = $this->pdoStatment->rowCount(); 
168
            }
169
            if (!is_object($this->queryResult)) {
170
                $this->queryResult = & class_loader('DatabaseQueryResult', 'classes/database');
171
            }
172
            $this->queryResult->setResult($result);
173
            $this->queryResult->setNumRows($numRows);
174
        }
175
176
        /**
177
         * Return the result for non SELECT query
178
         * @see DatabaseQueryRunner::execute
179
         */
180
        protected function setResultForNonSelect() {
181
            //Sqlite and pgsql always return 0 when using rowCount()
182
            $result = false;
183
            $numRows = 0;
184
            if (in_array($this->driver, array('sqlite', 'pgsql'))) {
185
            $result = true; //to test the result for the query like UPDATE, INSERT, DELETE
186
            $numRows = 1; //TODO use the correct method to get the exact affected row
187
            } else {
188
                //to test the result for the query like UPDATE, INSERT, DELETE
189
                $result  = $this->pdoStatment->rowCount() >= 0; 
190
                $numRows = $this->pdoStatment->rowCount(); 
191
            }
192
            if (!is_object($this->queryResult)) {
193
                $this->queryResult = & class_loader('DatabaseQueryResult', 'classes/database');
194
            }
195
            $this->queryResult->setResult($result);
196
            $this->queryResult->setNumRows($numRows);
197
        }
198
199
200
        /**
201
         * Return the benchmark instance
202
         * @return Benchmark
203
         */
204
        public function getBenchmark() {
205
            return $this->benchmarkInstance;
206
        }
207
208
        /**
209
         * Set the benchmark instance
210
         * @param Benchmark $benchmark the benchmark object
211
         * @return object DatabaseQueryRunner
212
         */
213
        public function setBenchmark($benchmark) {
214
            $this->benchmarkInstance = $benchmark;
215
            return $this;
216
        }
217
        
218
        /**
219
         * Return the database query result
220
         *
221
         * @return object DatabaseQueryResult
222
         */
223
        public function getQueryResult() {
224
            return $this->queryResult;
225
        }
226
227
        /**
228
         * Set the database query result instance
229
         * @param object $queryResult the query result
230
         *
231
         * @return object DatabaseQueryRunner
232
         */
233
        public function setQueryResult(DatabaseQueryResult $queryResult) {
234
            $this->queryResult = $queryResult;
235
            return $this;
236
        }
237
        
238
        /**
239
         * Return the current query SQL string
240
         * @return string
241
         */
242
        public function getQuery() {
243
            return $this->query;
244
        }
245
        
246
        /**
247
         * Set the query SQL string
248
         * @param string $query the SQL query to set
249
         * @return object DatabaseQueryRunner
250
         */
251
        public function setQuery($query) {
252
            $this->query = $query;
253
            return $this;
254
        }
255
        
256
        /**
257
         * Set the query return type as list or not
258
         * @param boolean $returnType
259
         * @return object DatabaseQueryRunner
260
         */
261
        public function setReturnType($returnType) {
262
            $this->returnAsList = $returnType;
263
            return $this;
264
        }
265
        
266
        /**
267
         * Set the return as array or not
268
         * @param boolean $status the status if true will return as array
269
         * @return object DatabaseQueryRunner
270
         */
271
        public function setReturnAsArray($status = true) {
272
            $this->returnAsArray = $status;
273
            return $this;
274
        }
275
        
276
        /**
277
         * Return the error for last query execution
278
         * @return string
279
         */
280
        public function getQueryError() {
281
            return $this->error;
282
        }
283
284
        /**
285
         * Return the PDO instance
286
         * @return object
287
         */
288
        public function getPdo() {
289
            return $this->pdo;
290
        }
291
292
        /**
293
         * Set the PDO instance
294
         * @param PDO $pdo the pdo object
295
         * @return object DatabaseQueryRunner
296
         */
297
        public function setPdo(PDO $pdo = null) {
298
            $this->pdo = $pdo;
299
            return $this;
300
        }
301
      
302
            /**
303
             * Return the database driver
304
             * @return string
305
             */
306
        public function getDriver() {
307
            return $this->driver;
308
        }
309
310
        /**
311
         * Set the database driver
312
         * @param string $driver the new driver
313
         * @return object DatabaseQueryRunner
314
         */
315
        public function setDriver($driver) {
316
            $this->driver = $driver;
317
            return $this;
318
        }
319
        
320
        /**
321
         * Return the benchmark key for the current query
322
         * 
323
         *  @return string
324
         */
325
        protected function getBenchmarkKey() {
326
            return md5($this->query . $this->returnAsList . $this->returnAsArray);
327
        }
328
        
329
        /**
330
         * Set error for database query execution
331
         */
332
        protected function setQueryRunnerError() {
333
            $error = $this->pdo->errorInfo();
334
            $this->error = isset($error[2]) ? $error[2] : '';
335
            $this->logger->error('The database query execution got an error: ' . stringfy_vars($error));
336
            //show error message
337
            show_error('Query: "' . $this->query . '" Error: ' . $this->error, 'Database Error');
338
        }
339
        
340
        
341
        /**
342
         * Reset the instance before run each query
343
         */
344
        private function reset() {
345
            $this->error = null;
346
            $this->pdoStatment = null;
347
        }
348
349
    }
350