Index: devel.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/devel/devel.module,v
retrieving revision 1.61
diff -u -p -r1.61 devel.module
--- devel.module	26 Jan 2006 13:32:39 -0000	1.61
+++ devel.module	3 Feb 2006 16:15:50 -0000
@@ -37,6 +37,13 @@ function devel_menu($may_cache) {
       'callback' => 'devel_switch_user',
       'access' => user_access('switch users'),
       'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'devel/queries', 'title' => t('database queries'),
+      'callback' => 'devel_queries',
+      'access' => user_access('access devel information'));
+    $items[] = array('path' => 'devel/queries/empty', 'title' => t('empty database queries'),
+      'callback' => 'devel_queries_empty',
+      'access' => user_access('access devel information'),
+      'type' => MENU_CALLBACK);
     $items[] = array('path' => 'devel/execute', 'title' => t('execute PHP code'),
       'callback' => 'devel_execute',
       'access' => user_access('execute php code'));
@@ -146,6 +153,37 @@ function devel_exit($destination = NULL)
     // TODO: gzip this text if we are sending a gzip page. see drupal_page_header()
     print $output;
   }
+  if (variable_get('devel_store_queries', 0)) {
+    global $active_db;
+    $qids = array();
+    foreach ($queries as $query) {
+      $query[0] = preg_replace(array("/'[^'].*'/", "/\d.*\.\d.*/", "/\d.*/"), array("S", "F", "D"), $query[0]);
+      $hash = md5($query[0]);
+      if (!isset($qids[$hash])) {
+        $qids[$hash] = db_result(devel_db_query("SELECT qid FROM {devel_queries} WHERE hash = '%s'", $hash));
+        if (!$qids[$hash]) {
+          devel_db_query("INSERT INTO {devel_queries} (query, hash) VALUES ('%s', '%s')", $query[0], $hash);
+          $qids[$hash] = mysql_insert_id();
+        }
+      }
+      print "foo\n";
+      devel_db_query("INSERT INTO {devel_times} (qid, time) VALUES (%d, %f)", $qids[$hash], $query[1]);
+    }
+    
+  }
+}
+
+function devel_db_query($query) {
+  global $active_db;
+  $args = func_get_args();
+  array_shift($args);
+  $query = db_prefix_tables($query);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  _db_query_callback($args, TRUE);
+  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+  return mysql_query($query, $active_db);
 }
 
 /**
@@ -248,6 +286,7 @@ function devel_settings() {
   $form['devel_execution'] = array('#type' => 'textfield', '#title' => t('Query execution threshold'), '#default_value' => variable_get('devel_execution', 5), '#size' => 4, '#maxlength' => 4, '#description' => t('Enter an integer in milliseconds. Any query which takes longer than this many milliseconds will be highlighted in the query log. This indicates a possibliy inefficient query, or a candidate for caching.'));
   $form['devel_redirect_page'] = array('#type' => 'select', '#title' => t('Display redirection page'), '#default_value' => variable_get('devel_redirect_page', 0), '#options' => array(t('Disabled'), t('Enabled')), '#description' => t('When a module executes drupal_goto(), the query log and other developer information is lost. Enabling this setting presents an intermediate page to developers so that the log can be examined before continuing to the destination page.'));
   $form['devel_form_weights'] = array('#type' => 'select', '#title' => t('Display form element weights'), '#default_value' => variable_get('devel_form_weights', 0), '#options' => array(t('Disabled'), t('Enabled')), '#description' => t('Form elements may have weights that determine their position in a form. Enabling this setting will show these weights.'));
+  $form['devel_store_queries'] = array('#type' => 'select', '#title' => t('Store executed queries'), '#default_value' => variable_get('devel_store_queries', 0), '#options' => array(t('Disabled'), t('Enabled')), '#description' => t('Collect statistics about executed queries.'));
   return $form;
 }
 
@@ -289,6 +328,38 @@ function devel_switch_user($uid = NULL) 
   drupal_goto();
 }
 
+function devel_queries() {
+  $header = array(
+                  array('data' => t('Total time'), 'field' => 'total_time', 'sort' => 'desc'),
+                  array('data' => t('Standard deviation')),
+                  array('data' => t('Count'), 'field' => 'count'),
+                  array('data' => t('Query'), 'field' => 'd.query'),
+                  );
+
+  $result = pager_query('SELECT q.qid, q.query, t.*, COUNT(t.qid) AS count, SUM(t.time) AS total_time, STD(t.time) AS stddev FROM {devel_queries} q INNER JOIN {devel_times} t ON q.qid = t.qid GROUP BY t.qid '. tablesort_sql($header), 30, 0, 'SELECT COUNT(qid) FROM {devel_queries}');
+  while ($log = db_fetch_object($result)) {
+    $rows[] = array(
+                    round($log->total_time, 3),
+                    round($log->stddev, 3),
+                    $log->count,
+                    check_plain($log->query)
+                    );
+  }
+
+  drupal_set_title(check_plain($node->title));
+  $output = theme('table', $header, $rows);
+  $output .= theme('pager', NULL, 30, 0, tablesort_pager());
+  $output .= l(t('clear collected query info'), 'devel/queries/empty');
+
+  return $output;
+}
+
+function devel_queries_empty() {
+  db_query('DELETE FROM {devel_queries}');
+  db_query('DELETE FROM {devel_times}');
+}
+
+
 function devel_execute() {
   if ($edit = $_POST['edit']) {
     ob_start();
