Skip to content

Commit

Permalink
Allow Database plugin to trace queries
Browse files Browse the repository at this point in the history
Extending Zend_Db_Profiler to generate a backtrace.

This makes it easy to see, what method is responsible for each query
  • Loading branch information
jokkedk committed Sep 8, 2017
1 parent 0450584 commit efbaa26
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
2 changes: 1 addition & 1 deletion library/ZFDebug/Controller/Plugin/Debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class ZFDebug_Controller_Plugin_Debug extends Zend_Controller_Plugin_Abstract
*
* @var string
*/
protected $_version = '1.6.2';
protected $_version = '1.6.4';

/**
* Creates a new instance of the Debug Bar
Expand Down
18 changes: 17 additions & 1 deletion library/ZFDebug/Controller/Plugin/Debug/Plugin/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ZFDebug_Controller_Plugin_Debug_Plugin_Database
protected $_db = array();

protected $_explain = false;
protected $_backtrace = false;

/**
* Create ZFDebug_Controller_Plugin_Debug_Plugin_Variables
Expand All @@ -52,7 +53,12 @@ public function __construct(array $options = array())
if (!isset($options['adapter']) || !count($options['adapter'])) {
if (Zend_Db_Table_Abstract::getDefaultAdapter()) {
$this->_db[0] = Zend_Db_Table_Abstract::getDefaultAdapter();
$this->_db[0]->getProfiler()->setEnabled(true);
if (isset($options['backtrace']) && $options['backtrace']) {
$this->_backtrace = true;
$this->_db[0]->setProfiler(new ZFDebug_Db_Profiler(true));
} else {
$this->_db[0]->getProfiler()->setEnabled(true);
}
}
} else if ($options['adapter'] instanceof Zend_Db_Adapter_Abstract ) {
$this->_db[0] = $options['adapter'];
Expand Down Expand Up @@ -186,6 +192,16 @@ public function getProfile()
}

$queries .= "</td>\n</tr>\n";
if ($this->_backtrace) {
$trace = $profile->getTrace();
array_walk(
$trace,
function (&$v, $k) {
$v = ($k+1).'. '.$v;
}
);
$queries .= "<tr>\n<td></td>\n<td>".implode('<br>', $trace)."</td>\n</tr>\n";
}
}
$queries .= "</table>\n";
}
Expand Down
62 changes: 62 additions & 0 deletions library/ZFDebug/Db/Profiler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

class ZFDebug_Db_Profiler extends Zend_Db_Profiler
{
/**
* Undocumented function
*
* @param string $queryText SQL statement
* @param integer $queryType OPTIONAL Type of query, one of the Zend_Db_Profiler::* constants
* @return integer|null
*/
public function queryStart($queryText, $queryType = null)
{
if (!$this->_enabled) {
return null;
}

$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$trace = array_filter(
$trace,
function ($t) {
return strstr($t['file'], 'application/') !== false;
}
);
$trace = array_values($trace);
$trace = array_map(
function ($t) {
$t = $t['class'].$t['type'].$t['function'].'() '
. $t['file'] . ':'.$t['line'];
return $t;
},
$trace
);

// make sure we have a query type
if (null === $queryType) {
switch (strtolower(substr(ltrim($queryText), 0, 6))) {
case 'insert':
$queryType = self::INSERT;
break;
case 'update':
$queryType = self::UPDATE;
break;
case 'delete':
$queryType = self::DELETE;
break;
case 'select':
$queryType = self::SELECT;
break;
default:
$queryType = self::QUERY;
break;
}
}

$this->_queryProfiles[] = new ZFDebug_Db_Profiler_Query($queryText, $queryType, $trace);

end($this->_queryProfiles);

return key($this->_queryProfiles);
}
}
18 changes: 18 additions & 0 deletions library/ZFDebug/Db/Profiler/Query.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

class ZFDebug_Db_Profiler_Query extends Zend_Db_Profiler_Query
{
protected $_trace = [];

public function __construct($query, $queryType, $trace)
{
$this->_trace = $trace;

parent::__construct($query, $queryType);
}

public function getTrace()
{
return $this->_trace;
}
}

0 comments on commit efbaa26

Please sign in to comment.