--- db_maintenance.module.orig 2008-10-01 07:43:02.000000000 +0200 +++ db_maintenance.module 2009-01-20 13:19:18.000000000 +0200 @@ -88,10 +88,10 @@ function _db_maintenance_list_tables($db $table_names = array(); // Set the database to query. $previous = db_set_active($db); - if (_db_maintenance_determine_software() == 'mysql') { + if (_db_maintenance_determine_software($db) == 'mysql') { $result = db_query('SHOW TABLES'); } - elseif (_db_maintenance_determine_software() == 'pgsql') { + elseif (_db_maintenance_determine_software($db) == 'pgsql') { $result = db_query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name"); } // Return to the previously set database. @@ -108,6 +108,7 @@ function _db_maintenance_list_tables($db * */ function db_maintenance_cron() { + global $base_url; $last_run = variable_get('db_maintenance_cron_last', 0); $now = time(); $optimize_frequency = variable_get('db_maintenance_cron_frequency', 86400); @@ -116,7 +117,7 @@ function db_maintenance_cron() { $interval = $now - $optimize_frequency; // Only run cron if enough time has elapsed - if ($optimize_frequencty != -1 && $interval > $last_run) { + if ($optimize_frequency != -1 && $interval > $last_run) { db_maintenance_optimize_tables(); } @@ -126,12 +127,21 @@ function db_maintenance_cron() { $last_files_backup = variable_get('db_maintenance_last_files_backup', 0); if ($db_backup_freq != -1 && $last_db_backup <= $now - $db_backup_freq) { - $email['db_backup'] = db_maintenance_do_db_backup(); + $databases = db_maintenance_get_databases(); + foreach ($databases as $db => $url) { + $backuppath = db_maintenance_do_db_backup($db, $url); + if (is_file($backuppath)) { + $email['custom_message'] .= t('Database \'@DB@\' backed up. The sql dump is available at \'@STATUS@\' when connected to \'@URL@\'', array('@DB@' => $db, '@STATUS@' => $status, '@URL' => $base_url)); + } + else { + $email['custom_message'] .= t('Database \'@DB@\' backup failed.', array('@DB@' => $db, )); + } + } variable_set('db_maintenance_last_db_backup', $now); } if ($files_backup_freq != -1 && $last_files_backup <= $now - $files_backup_freq) { - $email['files_backup'] = db_maintanence_do_files_backup(); + $email['files_backup'] = db_maintenance_do_files_backup(); variable_set('db_maintenance_last_files_backup', $now); } @@ -144,15 +154,8 @@ function db_maintenance_cron() { * */ function db_maintenance_optimize_tables() { - global $db_url; - - // Set the databases array if not already set in $db_url. - if (is_array(($db_url))) { - $databases = $db_url; - } - else { - $databases['default'] = $db_url; - } + $databases = db_maintenance_get_databases(); + // Loop through each database optimizing any selected tables. foreach ($databases as $db => $connection) { $config_tables = variable_get('db_maintenance_table_list_'. $db, NULL); @@ -163,7 +166,7 @@ function db_maintenance_optimize_tables( // Set the database to query. $previous = db_set_active($db); if (db_table_exists($table_name)) { - if (_db_maintenance_determine_software() == 'mysql') { + if (_db_maintenance_determine_software($db) == 'mysql') { $result = db_query('OPTIMIZE TABLE %s', $table_name); $status = db_fetch_array($result); while($status[] = db_fetch_array($result)) { @@ -171,7 +174,7 @@ function db_maintenance_optimize_tables( } db_maintenance_check_status($status, 'OPTIMIZE'); } - elseif (_db_maintenance_determine_software() == 'pgsql') { + elseif (_db_maintenance_determine_software($db) == 'pgsql') { db_query('VACUUM ANALYZE %s', $table_name); } } @@ -200,7 +203,6 @@ function db_maintenance_optimize_tables( * @return array */ function db_maintenance_admin_settings() { - global $db_url; $form = array(); $form['db_maintenance_log'] = array( @@ -236,14 +238,12 @@ function db_maintenance_admin_settings() '#default_value' => variable_get('db_maintenance_cron_frequency', 86400), '#description' => t('Select how often database tables should be optimized.') .' '. l(t('Optimize now.'), 'db_maintenance/optimize'), ); + // Set the databases array if not already set in $db_url. - if (is_array($db_url)) { - $databases = $db_url; - } - else { - $databases['default'] = $db_url; - } + $databases = db_maintenance_get_databases(); + $options = array(); + // Loop through each database and list the possible tables to optimize. foreach ($databases as $db => $connection) { $options = _db_maintenance_list_tables($db); @@ -294,6 +294,12 @@ function db_maintenance_admin_settings() '#default_value' => variable_get('db_maintenance_path_to_mysqldump', '/usr/bin/mysqldump'), ); + $form['db_maintenance_path_to_pg_dump'] = array( + '#type' => 'textfield', + '#title' => t('Path to pg_dump'), + '#default_value' => variable_get('db_maintenance_path_to_pg_dump', '/usr/bin/pg_dump'), + ); + $form['db_maintenance_email_notify'] = array( '#type' => 'textfield', '#title' => t('Email address to notify'), @@ -358,20 +364,15 @@ function db_maintenance_admin_settings_v /** * Determine which database software is in use */ -function _db_maintenance_determine_software() { - global $db_url; - static $db_type; +function _db_maintenance_determine_software($db = 'default') { + $databases = db_maintenance_get_databases(); + $url = $databases[$db]; - if (!empty($db_type)) { - return $db_type; + if (strpos($url, 'mysql://') === 0 || strpos($url, 'mysqli://') === 0) { + return('mysql'); } - elseif (strpos($db_url, 'mysql://') === 0 || strpos($db_url, 'mysqli://') === 0) { - $db_type = 'mysql'; - return $db_type; - } - elseif (strpos($db_url, 'pgsql://') === 0) { - $db_type = 'pgsql'; - return $db_type; + elseif (strpos($url, 'pgsql://') === 0) { + return('pgsql'); } else { return false; @@ -422,8 +423,12 @@ function db_maintenance_email($email) { $backupdir = variable_get('db_maintenance_backup_directory', '/tmp'); foreach($email as $task => $status) { switch($task) { + case 'custom_message': + $message[] = $status; + break; case 'db_backup': if (is_file($status)) { + _backup_migrate_save_to_disk($temp_file, $filename, $mode); $message[] = t('Database backed up. mysqldump is available at \'@STATUS@\' when connected to \'@URL@\'', array('@STATUS@' => $status, '@URL' => $base_url)); } else { @@ -456,20 +461,28 @@ function db_maintenance_email($email) { } } -function db_maintenance_do_db_backup() { - global $db_url; - $mysqldump = variable_get('db_maintenance_path_to_mysqldump', '/usr/bin/mysqldump'); +function db_maintenance_do_db_backup($db_id, $db_url) { + $db_software = _db_maintenance_determine_software($db_id); + if ($db_software == 'mysql') { + $dump_exec = variable_get('db_maintenance_path_to_mysqldump', '/usr/bin/mysqldump'); + $dump_options = db_maintenance_get_mysql_options($db_url); + } + else { + $dump_exec = variable_get('db_maintenance_path_to_pg_dump', '/usr/bin/pg_dump'); + $dump_options = db_maintenance_get_pgsql_options($db_url); + } + $backupdir = variable_get('db_maintenance_backup_directory', '/tmp'); $dateformat = 'Ymd_H-i-s'; - $dbname = db_maintenance_get_db_info('dbname'); + $dbname = db_maintenance_get_db_info($db_url, 'dbname'); $now = time(); $date = date($dateformat, $now); $filename = $backupdir.'/'.$date.'_'.$dbname.'_db.sql'; - $mysqloptions = db_maintenance_get_mysql_options(); - $mysqldumpexec = $mysqldump.' '.$mysqloptions.' > '.$filename; + $dump_exec .= ' '.$dump_options.' > '.$filename; + if (is_dir($backupdir)) { - exec($mysqldumpexec, $output, $return); + exec($dump_exec, $output, $return); //variable_set('db_maintenance_debug', variable_get('db_maintenance_debug', '') . 'MYSQLDUMP: '.$mysqldumpexec.' ('. var_export($return, TRUE) .') '. var_export($output, TRUE)."\n"); if (!$return && !is_file($filename)) { return FALSE; @@ -485,7 +498,7 @@ function db_maintenance_do_db_backup() { } } -function db_maintanence_do_files_backup() { +function db_maintenance_do_files_backup() { $filespath = file_directory_path(); $tarpath = variable_get('db_maintenance_path_to_tar', '/bin/tar'); $backupdir = variable_get('db_maintenance_backup_directory', '/tmp'); @@ -516,8 +529,7 @@ function db_maintanence_do_files_backup( } } -function db_maintenance_get_db_info($param) { - global $db_url; +function db_maintenance_get_db_info($db_url, $param) { $url = parse_url($db_url); switch(strtolower($param)) { @@ -560,8 +572,7 @@ function db_maintenance_get_db_info($par return $return; } -function db_maintenance_get_mysql_options() { - global $db_url; +function db_maintenance_get_mysql_options($db_url) { $url = parse_url($db_url); $url['host'] = urldecode($url['host']); @@ -595,4 +606,58 @@ function db_maintenance_get_mysql_option return $return; } +function db_maintenance_get_pgsql_options($db_url) { + $url = parse_url($db_url); + + $url['host'] = urldecode($url['host']); + $url['path'] = urldecode($url['path']); + $url['user'] = urldecode($url['user']); + $db_name = substr($url['path'], 1); // lop off leading '/' + + if ($url['host']) { + $options[] = '--host='.$url['host']; + } + if (!empty($url['port'])) { + $options[] = '--port='.$url['port']; + } + if($url['user']) { + $options[] = '--username='.$url['user']; + } + + // This tries to create a .dbpass file in the www-data home directory, but + // has the following problems: + // 1. There is no way to identify www-data's home directory from PHP, + // 2. Even when the file is generated properly, it is not picked up + // in this process. It needs to be created by hand beforehand it seems. + $logonStr = $url['host'].":*:$db_name:".$url['user'].':'.$url['pass']; + $url['pass'] = ''; // reset because this parm does not take a parameter + + $output = array(); + $runStr = "echo $logonStr > ../.pgpass;chmod 600 ../.pgpass;"; + exec($runStr, $output, $return); + + $return = implode(' ', $options); + $return .= " $db_name"; + return $return; +} + +/** + * @brief Returns an array of the db urls defined for this site + * + * @return The array of db urls if there are more than one defined, + * else an array with one entry: + * 'default' => $db_url + */ +function db_maintenance_get_databases() { + global $db_url; + + // Set the databases array if not already set in $db_url. + if (is_array(($db_url))) { + $databases = $db_url; + } + else { + $databases['default'] = $db_url; + } + return $databases; +}