By chud on
I have developed a new module, inspired by the devel module but with some convenient features for logging all "action" queries -- that is, all insert/update/delete queries.
This becomes very useful when you are performing a configuration task on your "staging" or "development" site and then want to propagate those changes to the live site...
Please give it a try. I am currently trying to get a cvs account so I can upload this to drupal.org properly.
Code follows...
qrecorder.module
// $Id: qrecorder.module,v 0.1 2006/11/25 00:00:00 chud Exp $
/**
* Implementation of hook_help().
*/
function qrecorder_help($section) {
switch ($section) {
case 'admin/modules#description':
return t('Records all insert/update/delete queries... makes it easy to tranfer changes from one version of a site to another.');
case 'admin/settings/qrecorder':
return '<p>'. t('Settings for the Query Recorder.'). '</p>';
}
}
/**
* Implementation of hook_menu().
*/
function qrecorder_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array('path' => 'qrecorder/start',
'title' => t('start recording'),
'callback' => 'qrecorder_start',
'access' => user_access('use query recorder'),
'type' => MENU_CALLBACK,
);
$items[] = array('path' => 'qrecorder/stop',
'title' => t('stop recording'),
'callback' => 'qrecorder_stop',
'access' => user_access('use query recorder'),
'type' => MENU_CALLBACK,
);
$items[] = array('path' => 'qrecorder/empty',
'title' => t('empty query log'),
'callback' => 'qrecorder_empty',
'access' => user_access('use query recorder'),
'type' => MENU_CALLBACK,
);
$items[] = array('path' => 'qrecorder/qview',
'title' => t('view query log'),
'callback' => 'qrecorder_qview',
'access' => user_access('use query recorder'),
'type' => MENU_CALLBACK,
);
}
return $items;
}
function qrecorder_start() {
global $base_url;
variable_set("dev_query", 1);
variable_set("qrecorder_state", 1);
drupal_set_message('query recorder started').
$referer = referer_uri();
header('Location: '. ($referer ? $referer : $base_url));
exit();
}
function qrecorder_stop() {
global $base_url;
variable_set("qrecorder_state", 0);
drupal_set_message('query recorder stopped').
$referer = referer_uri();
header('Location: '. ($referer ? $referer : $base_url));
exit();
}
function qrecorder_empty() {
global $base_url;
db_query('DELETE FROM {qrecorder_queries}');
drupal_set_message('query log emptied').
$referer = referer_uri();
header('Location: '. ($referer ? $referer : $base_url));
exit();
}
function qrecorder_qview() {
$result = db_query("SELECT query FROM {qrecorder_queries} ORDER BY qid;");
while ($row = db_fetch_object($result)) {
$output .= $row->query . "\n";
}
$form['qlog'] = array(
'#type' => 'textarea',
'#title' => t('queries'),
'#attributes' => array('wrap' => 'off'),
'#default_value' => $output,
'#rows' => 15,
);
$output = drupal_get_form('qlog', $form);
return $output;
}
/**
* Implementation of hook_perm().
*/
function qrecorder_perm() {
return array('use query recorder');
}
/**
* Implementation of hook_block().
*/
function qrecorder_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$blocks[0]['info'] = t('Query Recorder');
// Auto-enable the qrecorder blocks for fresh installations.
$blocks[0]['status'] = 1;
return $blocks;
}
else if ($op == 'view') {
switch ($delta) {
case 0:
if (user_access('use query recorder')) {
$block['subject'] = t('query recorder');
$block['content'] = theme_qrecorder_block();
}
}
return $block;
}
}
function theme_qrecorder_block() {
$output = '<p>';
$output .= l('start recording', 'qrecorder/start');
$output .= " | ";
$output .= l('stop recording', 'qrecorder/stop');
$output .= '</p>';
$output .= '<p>';
$output .= l('empty query log', 'qrecorder/empty');
$output .= " | ";
$output .= l('view query log', 'qrecorder/qview');
$output .= '</p>';
$output .= '<p>';
$output .= '<b>' . t('current status: ') . '</b>';
$output .= variable_get('qrecorder_state',0) ? t('active') : t('inactive');
$output .= '</p>';
return $output;
}
function qrecorder_log_queries($queries) {
$pos = array();
// print_a($queries, "new");
// die();
foreach ($queries as $query) {
$ar = explode("\n", $query[0]);
$function=array_shift($ar);
$pos[0] = strpos(strtolower($ar[0]), "insert into");
$pos[1] = strpos(strtolower($ar[0]), "update");
$pos[2] = strpos(strtolower($ar[0]), "delete");
if (in_array(0, $pos, TRUE)) { // we found an action query
db_query("INSERT INTO {qrecorder_queries} (query, function, created) VALUES ('%s', '%s', %d)", $ar[0], $function, time());
}
}
}
function qrecorder_exit($destination = NULL) {
global $queries;
if ($queries) {
// print_a($queries,"new2");
if (variable_get('qrecorder_state', 0)) {
qrecorder_log_queries($queries);
}
}
}
qrecorder.install
<?php
// $Id: qrecorder.install,v 0.1 2006/11/25 00:00:00 chud Exp $
/**
* Implementation of hook_install()
*/
function qrecorder_install() {
// New module weights in core: put qrecorder as the very last in the chain.
db_query("UPDATE {system} SET weight = 10 WHERE name = 'qrecorder'");
switch ($GLOBALS['db_type']) {
case 'mysqli':
case 'mysql':
$sql = "CREATE TABLE {qrecorder_queries} (
qid int(10) NOT NULL auto_increment,
function varchar(255) NOT NULL default '',
query text NOT NULL,
created int(11) NOT NULL,
PRIMARY KEY (`qid`)
) /*!40100 DEFAULT CHARACTER SET utf8 */;";
db_query($sql);
break;
}
// Enable the blocks automatically at install.
_block_rehash();
}
Comments
ooooo, you should update
ooooo, you should update this for 5.x (or maybe 6.0 instead). this sounds quite useful, but doesn't work... and i can't find anything else like this elsewhere