Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Added stack trace for DB queries #83

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions yii-debug-toolbar/YiiDebugToolbarRoute.php
Expand Up @@ -61,7 +61,8 @@ class YiiDebugToolbarRoute extends CLogRoute


private $_proxyMap = array(
'viewRenderer' => 'YiiDebugViewRenderer'
'viewRenderer' => 'YiiDebugViewRenderer',
'db' => 'YiiDebugDbConnection'
);

public function setPanels(array $pannels)
Expand Down Expand Up @@ -104,6 +105,7 @@ protected function getToolbarWidget()

public function init()
{
$this->initComponents();
$this->_startTime=microtime(true);

parent::init();
Expand All @@ -127,8 +129,6 @@ public function init()

protected function onBeginRequest(CEvent $event)
{
$this->initComponents();

$this->getToolbarWidget()
->init();
}
Expand Down
2 changes: 1 addition & 1 deletion yii-debug-toolbar/assets/yii.debugtoolbar.js
Expand Up @@ -140,7 +140,7 @@
$('.yii-debug-toolbar-button').bind('click',$.proxy( this.buttonClicked, this ));
$('.yii-debug-toolbar-panel-close').bind('click',$.proxy( this.closeButtonClicked, this ));
$('#yii-debug-toolbar .collapsible').bind('click', function(){ yiiDebugToolbar.toggleSection($(this).attr('rel'), this); });
$('#yii-debug-toolbar p.collapsible.collapsed').next().hide();
$('#yii-debug-toolbar p.collapsible.collapsed, #yii-debug-toolbar div.collapsible.collapsed').next().hide();
$('#yii-debug-toolbar .yii-debug-toolbar-panel-content tbody tr').bind('click', function(){ $(this).toggleClass('selected'); });
},

Expand Down
61 changes: 61 additions & 0 deletions yii-debug-toolbar/components/YiiDebugDbCommand.php
@@ -0,0 +1,61 @@
<?php
/**
* YiiDebugDbCommand class file.
*
* @author Roman Pronskiy <roman@pronskiy.com>
*/

/**
* YiiDebugDbCommand represents an SQL statement to execute against a database.
*
* It is a decorator for original CDbCommand however implemented as a descendant
* in order to be fully compatible with Yii core.
*
* @author Roman Pronskiy <roman@pronskiy.com>
* @version $Id$
* @package YiiDebugToolbar
* @since 1.1.7
*/
class YiiDebugDbCommand extends CDbCommand
{
protected function saveDebugStackTrace()
{
Yii::app()->db->collectDebugInfo(array_slice(debug_backtrace(), 1));
}

public function execute($params=array())
{
$this->saveDebugStackTrace();
return parent::execute($params);
}

public function query($params=array())
{
$this->saveDebugStackTrace();
return parent::query($params);
}

public function queryAll($fetchAssociative=true,$params=array())
{
$this->saveDebugStackTrace();
return parent::queryAll($fetchAssociative, $params);
}

public function queryRow($fetchAssociative=true,$params=array())
{
$this->saveDebugStackTrace();
return parent::queryRow($fetchAssociative, $params);
}

public function queryScalar($params=array())
{
$this->saveDebugStackTrace();
return parent::queryScalar($params);
}

public function queryColumn($params=array())
{
$this->saveDebugStackTrace();
return parent::queryColumn($params);
}
}
82 changes: 82 additions & 0 deletions yii-debug-toolbar/components/YiiDebugDbConnection.php
@@ -0,0 +1,82 @@
<?php
/**
* YiiDebugDbConnection class file.
*
* @author Roman Pronskiy <roman@pronskiy.com>
*/

/**
* YiiDebugDbConnection represents a proxy object to database connection.
*
* Though this class is meant to be a proxy, actually it isn't. In fact it's a
* CDbConnection descendant. This is made because of "instanceof CDbConnection" calls
* in Yii core files.
*
* The only significant difference from the original CDbConnection class is that it instantiates
* YiiDebugDbCommand instead of CDbCommand in the createCommand().
*
* @author Roman Pronskiy <roman@pronskiy.com>
* @version $Id$
* @package
* @since 1.1.7
*/
class YiiDebugDbConnection extends CDbConnection
{
private $_instance;

protected $_debugStackTrace = array();

/**
* @var String Path which is subtracted from the stack trace file paths
*/
protected $_basePath;

public function setInstance($value)
{
if (null === $this->_instance && false !== is_object($value))
{
$this->_instance = $value;
}
}

public function getInstance()
{
return $this->_instance;
}

public function init()
{
$reflect = new ReflectionClass($this->_instance);

foreach ($reflect->getProperties(ReflectionProperty::IS_PUBLIC) as $prop)
{
$name = $prop->getName();
$this->$name = $prop->getValue($this->_instance);
}

$this->_basePath = dirname(Yii::app()->request->scriptFile);

parent::init();
}

public function getDebugStackTrace()
{
return $this->_debugStackTrace;
}

public function createCommand($query=null)
{
$this->setActive(true);
return new YiiDebugDbCommand($this,$query);
}

public function collectDebugInfo($trace)
{
foreach ($trace as &$traceItem)
{
if (isset($traceItem['file']))
$traceItem['file'] = str_replace($this->_basePath, '', $traceItem['file']);
}
array_push($this->_debugStackTrace, $trace);
}
}
21 changes: 18 additions & 3 deletions yii-debug-toolbar/panels/YiiDebugToolbarPanelSql.php
Expand Up @@ -165,7 +165,7 @@ public function run()
'connections' => $this->getDbConnections(),
'connectionsCount' => $this->getDbConnectionsCount(),
'summary' => $this->processSummary($logs),
'callstack' => $this->processCallstack($logs)
'callstack' => $this->processCallstack($logs, $this->getDebugStackTrace())
));
}

Expand Down Expand Up @@ -229,7 +229,7 @@ public function getServerInfo($connectionId)
* @param array $logs Logs.
* @return array
*/
protected function processCallstack(array $logs)
protected function processCallstack(array $logs, array $debugStackTrace)
{
if (empty($logs))
{
Expand Down Expand Up @@ -260,7 +260,8 @@ protected function processCallstack(array $logs)
if(null !== ($last = array_pop($stack)) && $last[0] === $token)
{
$delta = $log[3] - $last[3];
$results[$last[4]] = array($token, $delta, count($stack));
$results[$last[4]] = array(
$token, $delta, count($stack), $debugStackTrace[$last[4]]);
}
else
throw new CException(Yii::t('yii-debug-toolbar',
Expand Down Expand Up @@ -384,6 +385,15 @@ public function formatLogEntry(array $entry)
}

$entry[0] = strip_tags($entry[0], '<div>,<span>');

if (is_array($entry[3]))
foreach ($entry[3] as &$traceItem)
{
$traceItem = (isset($traceItem['file']))
? ($traceItem['file'] . ':' . $traceItem['line'])
: ($traceItem['class'] . ':' . $traceItem['function'] . '()');
}

return $entry;
}

Expand Down Expand Up @@ -453,4 +463,9 @@ protected function filterLogs()
return $logs;
}

protected function getDebugStackTrace()
{
return Yii::app()->db->getDebugStackTrace();
}

}
5 changes: 4 additions & 1 deletion yii-debug-toolbar/views/panels/sql/callstack.php
Expand Up @@ -11,7 +11,10 @@
<?php foreach($callstack as $id=>$entry):?>
<tr class="<?php echo ($id%2?'odd':'even') ?><?php echo ($entry[1]>$this->timeLimit?' warning':'') ?>">
<td class="text-right"><?php echo $id; ?></td>
<td width="100%"><?php echo $entry[0]; ?></td>
<td width="100%">
<div class="collapsible collapsed"><?php echo $entry[0]; ?></div>
<div><?php echo implode('<br />', $entry[3]); ?></div>
</td>
<td nowrap="nowrap">
<?php echo sprintf('%0.6F',$entry[1]); ?>
</td>
Expand Down