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:
parent
2c6d6d5954
commit
8130c5a1e1
pandora_console
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -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>';
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>';
|
||||
?>
|
||||
|
|
Loading…
Reference in New Issue