Commit fef36b1d authored by Alexander Butenko's avatar Alexander Butenko

Merge pull request #224 from avbdr/master

Added setQueryOption and setTrace methods
parents deba2950 97c09d9f
......@@ -43,6 +43,12 @@ class MysqliDb
* @var string
*/
protected $_lastQuery;
/**
* The SQL query options required after SELECT, INSERT, UPDATE or DELETE
*
* @var string
*/
protected $_queryOptions = array();
/**
* An array that holds where joins
*
......@@ -81,7 +87,6 @@ class MysqliDb
* @var string
*/
public $totalCount = 0;
protected $fetchTotalCount = false;
/**
* Variable which holds last statement error
*
......@@ -107,6 +112,15 @@ class MysqliDb
*/
protected $isSubQuery = false;
/**
* Variables for query execution tracing
*
*/
protected $traceStartQ;
protected $traceEnabled;
protected $traceStripPrefix;
public $trace = array();
/**
* @param string $host
* @param string $username
......@@ -187,13 +201,16 @@ class MysqliDb
*/
protected function reset()
{
if ($this->traceEnabled)
$this->trace[] = array ($this->_lastQuery, (microtime(true) - $this->traceStartQ) , $this->_traceGetCaller());
$this->_where = array();
$this->_join = array();
$this->_orderBy = array();
$this->_groupBy = array();
$this->_bindParams = array(''); // Create the empty 0 index
$this->_query = null;
$this->count = 0;
$this->_queryOptions = array();
}
/**
......@@ -238,9 +255,10 @@ class MysqliDb
$stmt->execute();
$this->_stmtError = $stmt->error;
$this->_lastQuery = $this->replacePlaceHolders ($this->_query, $params);
$res = $this->_dynamicBindResults($stmt);
$this->reset();
return $this->_dynamicBindResults($stmt);
return $res;
}
/**
......@@ -256,9 +274,37 @@ class MysqliDb
$stmt = $this->_buildQuery($numRows);
$stmt->execute();
$this->_stmtError = $stmt->error;
$res = $this->_dynamicBindResults($stmt);
$this->reset();
return $this->_dynamicBindResults($stmt);
return $res;
}
/**
* This method allows you to specify multiple (method chaining optional) options for SQL queries.
*
* @uses $MySqliDb->setQueryOption('name');
*
* @param string/array $options The optons name of the query.
*
* @return MysqliDb
*/
public function setQueryOption ($options) {
$allowedOptions = Array ('ALL','DISTINCT','DISTINCTROW','HIGH_PRIORITY','STRAIGHT_JOIN','SQL_SMALL_RESULT',
'SQL_BIG_RESULT','SQL_BUFFER_RESULT','SQL_CACHE','SQL_NO_CACHE', 'SQL_CALC_FOUND_ROWS',
'LOW_PRIORITY','IGNORE','QUICK');
if (!is_array ($options))
$options = Array ($options);
foreach ($options as $option) {
$option = strtoupper ($option);
if (!in_array ($option, $allowedOptions))
die ('Wrong query option: '.$option);
$this->_queryOptions[] = $option;
}
return $this;
}
/**
......@@ -267,7 +313,7 @@ class MysqliDb
* @return MysqliDb
*/
public function withTotalCount () {
$this->fetchTotalCount = true;
$this->setQueryOption ('SQL_CALC_FOUND_ROWS');
return $this;
}
......@@ -284,9 +330,9 @@ class MysqliDb
if (empty ($columns))
$columns = '*';
$this->_query = $this->fetchTotalCount == true ? 'SELECT SQL_CALC_FOUND_ROWS ' : 'SELECT ';
$column = is_array($columns) ? implode(', ', $columns) : $columns;
$this->_query .= "$column FROM " .self::$_prefix . $tableName;
$this->_query = 'SELECT ' . implode(' ', $this->_queryOptions) . ' ' .
$column . " FROM " .self::$_prefix . $tableName;
$stmt = $this->_buildQuery($numRows);
if ($this->isSubQuery)
......@@ -294,9 +340,10 @@ class MysqliDb
$stmt->execute();
$this->_stmtError = $stmt->error;
$res = $this->_dynamicBindResults($stmt);
$this->reset();
return $this->_dynamicBindResults($stmt);
return $res;
}
/**
......@@ -724,9 +771,8 @@ class MysqliDb
if ($this->_mysqli->more_results())
$this->_mysqli->next_result();
if ($this->fetchTotalCount === true) {
$this->fetchTotalCount = false;
$stmt = $this->_mysqli->query ('SELECT FOUND_ROWS();');
if (in_array ('SQL_CALC_FOUND_ROWS', $this->_queryOptions)) {
$stmt = $this->_mysqli->query ('SELECT FOUND_ROWS()');
$totalCount = $stmt->fetch_row();
$this->totalCount = $totalCount[0];
}
......@@ -934,6 +980,9 @@ class MysqliDb
if (!$stmt = $this->_mysqli->prepare($this->_query)) {
trigger_error("Problem preparing query ($this->_query) " . $this->_mysqli->error, E_USER_ERROR);
}
if ($this->traceEnabled)
$this->traceStartQ = microtime (true);
return $stmt;
}
......@@ -1170,5 +1219,31 @@ class MysqliDb
return;
$this->rollback ();
}
/**
* Query exection time tracking switch
*
* @param bool $enabled Enable execution time tracking
* @param string $stripPrefix Prefix to strip from the path in exec log
**/
public function setTrace ($enabled, $stripPrefix = null) {
$this->traceEnabled = $enabled;
$this->traceStripPrefix = $stripPrefix;
return $this;
}
/**
* Get where and what function was called for query stored in MysqliDB->trace
*
* @return string with information
*/
private function _traceGetCaller () {
$dd = debug_backtrace ();
$caller = next ($dd);
while (isset ($caller) && $caller["file"] == __FILE__ )
$caller = next($dd);
return __CLASS__ . "->" . $caller["function"] . "() >> file \"" .
str_replace ($this->traceStripPrefix, '', $caller["file"] ) . "\" line #" . $caller["line"] . " " ;
}
} // END class
?>
......@@ -7,6 +7,7 @@ MysqliDb -- Simple MySQLi wrapper with prepared statements
**[Select Query](#select-query)**
**[Delete Query](#delete-query)**
**[Generic Query](#generic-query-method)**
**[Query Keywords](#query-keywords)**
**[Raw Query](#raw-query-method)**
**[Where Conditions](#where-method)**
**[Order Conditions](#ordering-method)**
......@@ -287,6 +288,28 @@ $users = $db->withTotalCount()->get('users', Array ($offset, $count));
echo "Showing {$count} from {$db->totalCount}";
```
### Query Keywords
To add LOW PRIORITY | DELAYED | HIGH PRIORITY | IGNORE and the rest of mysql keywords to INSERT , SELECT , UPDATE, DELETE query:
```php
$db->setQueryOption('LOW_PRIORITY');
$db->insert($table,$param);
// GIVES: INSERT LOW_PRIORITY INTO table ...
```
Also you can use an array of keywords:
```php
$db->setQueryOption(Array('LOW_PRIORITY', 'IGNORE'));
$db->insert($table,$param);
// GIVES: INSERT LOW_PRIORITY IGNORE INTO table ...
```
Same way keywords could be used in SELECT queries as well:
```php
$db->setQueryOption('SQL_NO_CACHE');
$db->get("users");
// GIVES: SELECT SQL_NO_CACHE * FROM USERS;
```
Optionally you can use method chaining to call where multiple times without referencing your object over an over:
```php
......@@ -418,7 +441,6 @@ if($db->has("users")) {
return "Wrong user/password";
}
```
### Helper commands
Reconnect in case mysql connection died
```php
......@@ -452,3 +474,31 @@ if (!$db->insert ('myTable', $insertData)) {
$db->commit();
}
```
### Query exectution time benchmarking
To track query execution time setTrace() function should be called.
```php
$db->setTrace (true);
// As a second parameter it is possible to define prefix of the path which should be striped from filename
// $db->setTrace (true, $_SERVER['SERVER_ROOT']);
$db->get("users");
$db->get("test");
print_r ($db->trace);
```
```
[0] => Array
(
[0] => SELECT * FROM t_users ORDER BY `id` ASC
[1] => 0.0010669231414795
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #151
)
[1] => Array
(
[0] => SELECT * FROM t_test
[1] => 0.00069189071655273
[2] => MysqliDb->get() >> file "/avb/work/PHP-MySQLi-Database-Class/tests.php" line #152
)
```
......@@ -5,6 +5,9 @@ error_reporting(E_ALL);
$db = new Mysqlidb('localhost', 'root', '', 'testdb');
if(!$db) die("Database error");
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
$db = new Mysqlidb($mysqli);
$db = new Mysqlidb(Array (
'host' => 'localhost',
'username' => 'root',
......@@ -13,11 +16,10 @@ $db = new Mysqlidb(Array (
'charset' => null));
if(!$db) die("Database error");
$mysqli = new mysqli ('localhost', 'root', '', 'testdb');
$db = new Mysqlidb($mysqli);
$prefix = 't_';
$db->setPrefix($prefix);
$db->setTrace(true);
$tables = Array (
'users' => Array (
......@@ -360,4 +362,5 @@ echo "All done";
//print_r($db->rawQuery("CALL simpleproc(?)",Array("test")));
print_r ($db->trace);
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment