Skip to content

Commit fef36b1

Browse files
committed
Merge pull request #224 from avbdr/master
Added setQueryOption and setTrace methods
2 parents deba295 + 97c09d9 commit fef36b1

File tree

3 files changed

+142
-14
lines changed

3 files changed

+142
-14
lines changed

MysqliDb.php

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class MysqliDb
4343
* @var string
4444
*/
4545
protected $_lastQuery;
46+
/**
47+
* The SQL query options required after SELECT, INSERT, UPDATE or DELETE
48+
*
49+
* @var string
50+
*/
51+
protected $_queryOptions = array();
4652
/**
4753
* An array that holds where joins
4854
*
@@ -81,7 +87,6 @@ class MysqliDb
8187
* @var string
8288
*/
8389
public $totalCount = 0;
84-
protected $fetchTotalCount = false;
8590
/**
8691
* Variable which holds last statement error
8792
*
@@ -107,6 +112,15 @@ class MysqliDb
107112
*/
108113
protected $isSubQuery = false;
109114

115+
/**
116+
* Variables for query execution tracing
117+
*
118+
*/
119+
protected $traceStartQ;
120+
protected $traceEnabled;
121+
protected $traceStripPrefix;
122+
public $trace = array();
123+
110124
/**
111125
* @param string $host
112126
* @param string $username
@@ -187,13 +201,16 @@ public static function getInstance()
187201
*/
188202
protected function reset()
189203
{
204+
if ($this->traceEnabled)
205+
$this->trace[] = array ($this->_lastQuery, (microtime(true) - $this->traceStartQ) , $this->_traceGetCaller());
206+
190207
$this->_where = array();
191208
$this->_join = array();
192209
$this->_orderBy = array();
193210
$this->_groupBy = array();
194211
$this->_bindParams = array(''); // Create the empty 0 index
195212
$this->_query = null;
196-
$this->count = 0;
213+
$this->_queryOptions = array();
197214
}
198215

199216
/**
@@ -238,9 +255,10 @@ public function rawQuery ($query, $bindParams = null, $sanitize = true)
238255
$stmt->execute();
239256
$this->_stmtError = $stmt->error;
240257
$this->_lastQuery = $this->replacePlaceHolders ($this->_query, $params);
258+
$res = $this->_dynamicBindResults($stmt);
241259
$this->reset();
242260

243-
return $this->_dynamicBindResults($stmt);
261+
return $res;
244262
}
245263

246264
/**
@@ -256,9 +274,37 @@ public function query($query, $numRows = null)
256274
$stmt = $this->_buildQuery($numRows);
257275
$stmt->execute();
258276
$this->_stmtError = $stmt->error;
277+
$res = $this->_dynamicBindResults($stmt);
259278
$this->reset();
260279

261-
return $this->_dynamicBindResults($stmt);
280+
return $res;
281+
}
282+
283+
/**
284+
* This method allows you to specify multiple (method chaining optional) options for SQL queries.
285+
*
286+
* @uses $MySqliDb->setQueryOption('name');
287+
*
288+
* @param string/array $options The optons name of the query.
289+
*
290+
* @return MysqliDb
291+
*/
292+
public function setQueryOption ($options) {
293+
$allowedOptions = Array ('ALL','DISTINCT','DISTINCTROW','HIGH_PRIORITY','STRAIGHT_JOIN','SQL_SMALL_RESULT',
294+
'SQL_BIG_RESULT','SQL_BUFFER_RESULT','SQL_CACHE','SQL_NO_CACHE', 'SQL_CALC_FOUND_ROWS',
295+
'LOW_PRIORITY','IGNORE','QUICK');
296+
if (!is_array ($options))
297+
$options = Array ($options);
298+
299+
foreach ($options as $option) {
300+
$option = strtoupper ($option);
301+
if (!in_array ($option, $allowedOptions))
302+
die ('Wrong query option: '.$option);
303+
304+
$this->_queryOptions[] = $option;
305+
}
306+
307+
return $this;
262308
}
263309

264310
/**
@@ -267,7 +313,7 @@ public function query($query, $numRows = null)
267313
* @return MysqliDb
268314
*/
269315
public function withTotalCount () {
270-
$this->fetchTotalCount = true;
316+
$this->setQueryOption ('SQL_CALC_FOUND_ROWS');
271317
return $this;
272318
}
273319

@@ -284,19 +330,20 @@ public function get($tableName, $numRows = null, $columns = '*')
284330
if (empty ($columns))
285331
$columns = '*';
286332

287-
$this->_query = $this->fetchTotalCount == true ? 'SELECT SQL_CALC_FOUND_ROWS ' : 'SELECT ';
288333
$column = is_array($columns) ? implode(', ', $columns) : $columns;
289-
$this->_query .= "$column FROM " .self::$_prefix . $tableName;
334+
$this->_query = 'SELECT ' . implode(' ', $this->_queryOptions) . ' ' .
335+
$column . " FROM " .self::$_prefix . $tableName;
290336
$stmt = $this->_buildQuery($numRows);
291337

292338
if ($this->isSubQuery)
293339
return $this;
294340

295341
$stmt->execute();
296342
$this->_stmtError = $stmt->error;
343+
$res = $this->_dynamicBindResults($stmt);
297344
$this->reset();
298345

299-
return $this->_dynamicBindResults($stmt);
346+
return $res;
300347
}
301348

302349
/**
@@ -724,9 +771,8 @@ protected function _dynamicBindResults(mysqli_stmt $stmt)
724771
if ($this->_mysqli->more_results())
725772
$this->_mysqli->next_result();
726773

727-
if ($this->fetchTotalCount === true) {
728-
$this->fetchTotalCount = false;
729-
$stmt = $this->_mysqli->query ('SELECT FOUND_ROWS();');
774+
if (in_array ('SQL_CALC_FOUND_ROWS', $this->_queryOptions)) {
775+
$stmt = $this->_mysqli->query ('SELECT FOUND_ROWS()');
730776
$totalCount = $stmt->fetch_row();
731777
$this->totalCount = $totalCount[0];
732778
}
@@ -934,6 +980,9 @@ protected function _prepareQuery()
934980
if (!$stmt = $this->_mysqli->prepare($this->_query)) {
935981
trigger_error("Problem preparing query ($this->_query) " . $this->_mysqli->error, E_USER_ERROR);
936982
}
983+
if ($this->traceEnabled)
984+
$this->traceStartQ = microtime (true);
985+
937986
return $stmt;
938987
}
939988

@@ -1170,5 +1219,31 @@ public function _transaction_status_check () {
11701219
return;
11711220
$this->rollback ();
11721221
}
1222+
1223+
/**
1224+
* Query exection time tracking switch
1225+
*
1226+
* @param bool $enabled Enable execution time tracking
1227+
* @param string $stripPrefix Prefix to strip from the path in exec log
1228+
**/
1229+
public function setTrace ($enabled, $stripPrefix = null) {
1230+
$this->traceEnabled = $enabled;
1231+
$this->traceStripPrefix = $stripPrefix;
1232+
return $this;
1233+
}
1234+
/**
1235+
* Get where and what function was called for query stored in MysqliDB->trace
1236+
*
1237+
* @return string with information
1238+
*/
1239+
private function _traceGetCaller () {
1240+
$dd = debug_backtrace ();
1241+
$caller = next ($dd);
1242+
while (isset ($caller) && $caller["file"] == __FILE__ )
1243+
$caller = next($dd);
1244+
1245+
return __CLASS__ . "->" . $caller["function"] . "() >> file \"" .
1246+
str_replace ($this->traceStripPrefix, '', $caller["file"] ) . "\" line #" . $caller["line"] . " " ;
1247+
}
11731248
} // END class
11741249
?>

readme.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ MysqliDb -- Simple MySQLi wrapper with prepared statements
77
**[Select Query](#select-query)**
88
**[Delete Query](#delete-query)**
99
**[Generic Query](#generic-query-method)**
10+
**[Query Keywords](#query-keywords)**
1011
**[Raw Query](#raw-query-method)**
1112
**[Where Conditions](#where-method)**
1213
**[Order Conditions](#ordering-method)**
@@ -287,6 +288,28 @@ $users = $db->withTotalCount()->get('users', Array ($offset, $count));
287288
echo "Showing {$count} from {$db->totalCount}";
288289
```
289290

291+
### Query Keywords
292+
To add LOW PRIORITY | DELAYED | HIGH PRIORITY | IGNORE and the rest of mysql keywords to INSERT , SELECT , UPDATE, DELETE query:
293+
```php
294+
$db->setQueryOption('LOW_PRIORITY');
295+
$db->insert($table,$param);
296+
// GIVES: INSERT LOW_PRIORITY INTO table ...
297+
```
298+
299+
Also you can use an array of keywords:
300+
```php
301+
$db->setQueryOption(Array('LOW_PRIORITY', 'IGNORE'));
302+
$db->insert($table,$param);
303+
// GIVES: INSERT LOW_PRIORITY IGNORE INTO table ...
304+
```
305+
306+
Same way keywords could be used in SELECT queries as well:
307+
```php
308+
$db->setQueryOption('SQL_NO_CACHE');
309+
$db->get("users");
310+
// GIVES: SELECT SQL_NO_CACHE * FROM USERS;
311+
```
312+
290313
Optionally you can use method chaining to call where multiple times without referencing your object over an over:
291314

292315
```php
@@ -418,7 +441,6 @@ if($db->has("users")) {
418441
return "Wrong user/password";
419442
}
420443
```
421-
422444
### Helper commands
423445
Reconnect in case mysql connection died
424446
```php
@@ -452,3 +474,31 @@ if (!$db->insert ('myTable', $insertData)) {
452474
$db->commit();
453475
}
454476
```
477+
478+
### Query exectution time benchmarking
479+
To track query execution time setTrace() function should be called.
480+
```php
481+
$db->setTrace (true);
482+
// As a second parameter it is possible to define prefix of the path which should be striped from filename
483+
// $db->setTrace (true, $_SERVER['SERVER_ROOT']);
484+
$db->get("users");
485+
$db->get("test");
486+
print_r ($db->trace);
487+
```
488+
489+
```
490+
[0] => Array
491+
(
492+
[0] => SELECT * FROM t_users ORDER BY `id` ASC
493+
[1] => 0.0010669231414795
494+
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #151
495+
)
496+
497+
[1] => Array
498+
(
499+
[0] => SELECT * FROM t_test
500+
[1] => 0.00069189071655273
501+
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #152
502+
)
503+
504+
```

tests.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
$db = new Mysqlidb('localhost', 'root', '', 'testdb');
66
if(!$db) die("Database error");
77

8+
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
9+
$db = new Mysqlidb($mysqli);
10+
811
$db = new Mysqlidb(Array (
912
'host' => 'localhost',
1013
'username' => 'root',
@@ -13,11 +16,10 @@
1316
'charset' => null));
1417
if(!$db) die("Database error");
1518

16-
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
17-
$db = new Mysqlidb($mysqli);
1819

1920
$prefix = 't_';
2021
$db->setPrefix($prefix);
22+
$db->setTrace(true);
2123

2224
$tables = Array (
2325
'users' => Array (
@@ -360,4 +362,5 @@ function createTable ($name, $data) {
360362

361363
//print_r($db->rawQuery("CALL simpleproc(?)",Array("test")));
362364

365+
print_r ($db->trace);
363366
?>

0 commit comments

Comments
 (0)