2009-02-25 Esteban Sanchez <estebans@artica.es>

* include/functions_db.php: Added database debug support. If the debug
	flag in config is set, a table with all the queries done in a page is
	shown. To do so, add_database_debug_trace() and print_database_debug()
	were added.

	* include/functions_ui.php: Added debug() function which shows a
	given variable content and a traceback which can be toggled to make
	developers life easier.

	* index.php: Print database debug table.

	* include/styles/pandora.css: Styles for debug functionallity.



git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1483 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
Esteban Sanchez 2009-02-25 12:24:06 +00:00
parent d579ec4ea3
commit b6a6b3fe90
5 changed files with 233 additions and 24 deletions

View File

@ -1,3 +1,18 @@
2009-02-25 Esteban Sanchez <estebans@artica.es>
* include/functions_db.php: Added database debug support. If the debug
flag in config is set, a table with all the queries done in a page is
shown. To do so, add_database_debug_trace() and print_database_debug()
were added.
* include/functions_ui.php: Added debug() function which shows a
given variable content and a traceback which can be toggled to make
developers life easier.
* index.php: Print database debug table.
* include/styles/pandora.css: Styles for debug functionallity.
2009-02-24 Evi Vanoost <vanooste@rcbi.rochester.edu>
* include/functions_db.php: Fixed where clause

View File

@ -1683,6 +1683,41 @@ function sql_error_handler ($errno, $errstr) {
return true;
}
/**
* Add a database query to the debug trace.
*
* This functions does nothing if the config['debug'] flag is not set. If a
* sentence was repeated, then the 'saved' counter is incremented.
*
* @param string SQL sentence.
* @param mixed Query result. On error, error string should be given.
* @param int Affected rows after running the query.
* @param mixed Extra parameter for future values.
*/
function add_database_debug_trace ($sql, $result = false, $affected = false, $extra = false) {
global $config;
if (! isset ($config['debug']))
return false;
if (! isset ($config['db_debug']))
$config['db_debug'] = array ();
if (isset ($config['db_debug'][$sql])) {
$config['db_debug'][$sql]['saved']++;
return;
}
$var = array ();
$var['sql'] = $sql;
$var['result'] = $result;
$var['affected'] = $affected;
$var['saved'] = 0;
$var['extra'] = $extra;
$config['db_debug'][$sql] = $var;
}
/**
* This function comes back with an array in case of SELECT
* in case of UPDATE, DELETE etc. with affected rows
@ -1710,24 +1745,31 @@ function process_sql ($sql, $rettype = "affected_rows") {
if (! empty ($sql_cache[$sql])) {
$retval = $sql_cache[$sql];
$sql_cache['saved']++;
add_database_debug_trace ($sql);
} else {
$result = mysql_query ($sql);
if ($result === false) {
$backtrace = debug_backtrace ();
$error = sprintf ('%s (\'%s\') in <strong>%s</strong> on line %d',
mysql_error (), $sql, $backtrace[0]['file'], $backtrace[0]['line']);
add_database_debug_trace ($sql, mysql_error ());
set_error_handler ('sql_error_handler');
trigger_error ($error);
restore_error_handler ();
return false;
} elseif ($result === true) {
if ($rettype == "insert_id") {
return mysql_insert_id ();
$result = mysql_insert_id ();
} elseif ($rettype == "info") {
return mysql_info ();
$result = mysql_info ();
} else {
$result = mysql_affected_rows ();
}
return mysql_affected_rows (); //This happens in case the statement was executed but didn't need a resource
add_database_debug_trace ($sql, $result, mysql_affected_rows ());
return $result;
} else {
add_database_debug_trace ($sql, 0, mysql_affected_rows ());
while ($row = mysql_fetch_array ($result)) {
array_push ($retval, $row);
}
@ -2844,4 +2886,61 @@ function get_group_users ($id_group, $filter = false) {
return $retval;
}
/**
* Prints a database debug table with all the queries done in the page loading.
*
* This functions does nothing if the config['debug'] flag is not set.
*
* @param bool Wheter to return the table or print it.
*
* @return string If $return was set, the table is returned.
*/
function print_database_debug ($return = false) {
global $config;
if (! isset ($config['debug']))
return '';
$output = '';
$output = '<div class="database_debug_title">'.__('Database debug').'</div>';
$table->id = 'database_debug';
$table->cellpadding = '0';
$table->width = '95%';
$table->align = array ();
$table->align[1] = 'left';
$table->size = array ();
$table->size[0] = '40px';
$table->size[2] = '30%';
$table->size[3] = '40px';
$table->size[4] = '40px';
$table->data = array ();
$table->head = array ();
$table->head[0] = '#';
$table->head[1] = __('SQL sentence');
$table->head[2] = __('Result');
$table->head[3] = __('Rows');
$table->head[4] = __('Saved');
if (! isset ($config['db_debug']))
$config['db_debug'] = array ();
$i = 1;
foreach ($config['db_debug'] as $debug) {
$data = array ();
$data[0] = $i++;
$data[1] = $debug['sql'];
$data[2] = (($debug['result'] == 0) ? __('OK') : $debug['result']);
$data[3] = $debug['affected'];
$data[4] = $debug['saved'];
array_push ($table->data, $data);
}
$output .= print_table ($table, true);
if ($return)
return $output;
echo $output;
}
?>

View File

@ -825,5 +825,69 @@ function print_help_tip ($text, $return = false) {
return $output;
echo $output;
}
/**
* Powerful debug function that also shows a backtrace.
*
* This functions need to have active $config['debug'] variable to work.
*
* @param mixed Variable name to debug
*/
function debug ($var) {
global $config;
if (! isset ($config['debug']))
return;
static $id = 0;
static $trace_id = 0;
$id++;
echo '<div class="debug">';
echo '<a href="#" onclick="$(\'#trace-'.$id.'\').toggle ();return false;">Backtrace</a>';
echo '<div id="trace-'.$id.'" class="backtrace invisible">';
echo '<ol>';
$traces = debug_backtrace ();
/* Ignore debug function */
unset ($traces[0]);
foreach ($traces as $trace) {
$trace_id++;
/* Many classes are used to allow better customization. Please, do not
remove them */
echo '<li>';
if (isset ($trace['class']))
echo '<span class="class">'.$trace['class'].'</span>';
if (isset ($trace['type']))
echo '<span class="type">'.$trace['type'].'</span>';
echo '<span class="function">';
echo '<a href="#" onclick="$(\'#args-'.$trace_id.'\').toggle ();return false;">'.$trace['function'].'()</a>';
echo '</span>';
if (isset ($trace['file'])) {
echo ' - <span class="filename">';
echo str_replace ($config['homedir'].'/', '', $trace['file']);
echo ':'.$trace['line'].'</span>';
} else {
echo ' - <span class="filename"><em>Unknown file</em></span>';
}
echo '<pre id="args-'.$trace_id.'" class="invisible">';
echo '<div class="parameters">Parameter values:</div>';
echo '<ol>';
foreach ($trace['args'] as $arg) {
echo '<li>';
print_r ($arg);
echo '<li>';
}
echo '</ol>';
echo '</pre>';
echo '</li>';
}
echo '</ol>';
echo '</div></div>';
/* Actually print the variable given */
echo '<pre class="debug">';
print_r ($var);
echo '</pre>';
}
?>

View File

@ -908,41 +908,69 @@ div.actions_container label {
font-weight: normal;
font-style: italic;
}
pre.debug, div.backtrace {
font-family: monospace !important;
text-align: left;
padding: 10px;
margin: 5px;
border: 1px solid black;
}
div.backtrace ol {
margin: 0;
padding-left: 20px;
}
pre.debug {
background-color: #fff55f;
}
div.debug, div.database_debug_title, div.debug a, div.debug a:hover {
background-color: white;
color: black;
text-align: left;
}
div.debug a, div.debug a:hover, div.parameters {
text-decoration: underline;
}
div.database_debug_title {
font-size: 15pt;
margin-top: 15px;
padding: 5px;
width: 95%;
}
/* timeEntry styles */
.timeEntry_control {
vertical-align: middle;
margin-left: 2px;
}
/* the overlay element */
#overlay {
background-image:url(../../images/transparent.png);
background-image:url(../../images/transparent.png);
/* dimensions after the growing animation finishes */
width:600px;
height:470px;
/* initially overlay is hidden */
display:none;
/* some padding to layout nested elements nicely */
padding:55px;
/* dimensions after the growing animation finishes */
width:600px;
height:470px;
/* initially overlay is hidden */
display:none;
/* some padding to layout nested elements nicely */
padding:55px;
overflow:auto;
}
/* default close button positioned on upper right corner */
#overlay div.close {
background-image:url(../../images/close.png);
position:absolute;
right:5px;
top:5px;
cursor:pointer;
height:35px;
width:35px;
background-image:url(../../images/close.png);
position:absolute;
right:5px;
top:5px;
cursor:pointer;
height:35px;
width:35px;
}
/* external content */
#overlay div.wrap {
height:441px;
overflow:auto;
height:441px;
overflow:auto;
}

View File

@ -211,7 +211,7 @@ if ($config["pure"] == 0) {
//This is a generic overlay (hidden) which can be filled with jQuery
// To use you have to use <a href="ajax.php?page=operation/page" rel="#overlay">Load overlay</a>
echo '<div class="overlay" id="overlay"><div class="wrap"></div></div>';
require_jquery_file ('overlay');
require_jquery_file ('overlay');
}
// Page loader / selector
@ -250,6 +250,9 @@ if ($config["pure"] == 0) {
echo '</div>';
echo '</div>'; //container div
}
print_database_debug ();
while (@ob_end_flush ());
echo '</html>';
?>