Differences Between: [Versions 39 and 311]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Export db content to file. 19 * 20 * @package tool_dbtransfer 21 * @copyright 2008 Petr Skoda {@link http://skodak.org/} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die; 26 /* 27 28 TODO: 29 - exporting to server file >2GB fails in 32bit operating systems - needs warning 30 - we may run out of disk space exporting to server file - we must verify the file is not truncated; read from the end of file? 31 - when sending file >4GB - FAT32 limit, Apache limit, browser limit - needs warning 32 - there must be some form of progress bar during export, transfer - new tracking class could be passed around 33 - command line operation - could work around some 2G/4G limits in PHP; useful for cron full backups 34 - by default allow exporting into empty database only (no tables with the same prefix yet) 35 - all dangerous operation (like deleting of all data) should be confirmed by key found in special file in dataroot 36 (user would need file access to dataroot which might prevent various "accidents") 37 - implement "Export/import running" notification in lib/setup.php (similar to new upgrade flag in config table) 38 - gzip compression when storing xml file - the xml is very verbose and full of repeated tags (zip is not suitable here at all) 39 this could help us keep the files below 2G (expected ratio is > 10:1) 40 41 */ 42 43 require_once($CFG->libdir.'/adminlib.php'); 44 require_once($CFG->libdir.'/dtllib.php'); 45 46 /** 47 * Initiate database export. 48 * @param string $description 49 * @param moodle_database $mdb 50 * @return does not return, calls die() 51 */ 52 function tool_dbtransfer_export_xml_database($description, $mdb) { 53 core_php_time_limit::raise(); 54 55 \core\session\manager::write_close(); // Release session. 56 57 header('Content-Type: application/xhtml+xml; charset=utf-8'); 58 header('Content-Disposition: attachment; filename=database.xml'); 59 header('Expires: 0'); 60 header('Cache-Control: must-revalidate,post-check=0,pre-check=0'); 61 header('Pragma: public'); 62 63 while(@ob_flush()); 64 65 $var = new file_xml_database_exporter('php://output', $mdb); 66 $var->export_database($description); 67 68 // No more output. 69 die; 70 } 71 72 /** 73 * Initiate database transfer. 74 * @param moodle_database $sourcedb 75 * @param moodle_database $targetdb 76 * @param progress_trace $feedback 77 * @return void 78 */ 79 function tool_dbtransfer_transfer_database(moodle_database $sourcedb, moodle_database $targetdb, progress_trace $feedback = null) { 80 core_php_time_limit::raise(); 81 82 \core\session\manager::write_close(); // Release session. 83 84 $var = new database_mover($sourcedb, $targetdb, true, $feedback); 85 $var->export_database(null); 86 87 tool_dbtransfer_rebuild_target_log_actions($targetdb, $feedback); 88 } 89 90 /** 91 * Very hacky function for rebuilding of log actions in target database. 92 * @param moodle_database $target 93 * @param progress_trace $feedback 94 * @return void 95 * @throws Exception on conversion error 96 */ 97 function tool_dbtransfer_rebuild_target_log_actions(moodle_database $target, progress_trace $feedback = null) { 98 global $DB, $CFG; 99 require_once("$CFG->libdir/upgradelib.php"); 100 101 $feedback->output(get_string('convertinglogdisplay', 'tool_dbtransfer')); 102 103 $olddb = $DB; 104 $DB = $target; 105 try { 106 $DB->delete_records('log_display', array('component'=>'moodle')); 107 log_update_descriptions('moodle'); 108 $plugintypes = core_component::get_plugin_types(); 109 foreach ($plugintypes as $type => $location) { 110 $plugs = core_component::get_plugin_list($type); 111 foreach ($plugs as $plug => $fullplug) { 112 $component = $type.'_'.$plug; 113 $DB->delete_records('log_display', array('component'=>$component)); 114 log_update_descriptions($component); 115 } 116 } 117 } catch (Exception $e) { 118 $DB = $olddb; 119 throw $e; 120 } 121 $DB = $olddb; 122 $feedback->output(get_string('done', 'core_dbtransfer', null), 1); 123 } 124 125 /** 126 * Returns list of fully working database drivers present in system. 127 * @return array 128 */ 129 function tool_dbtransfer_get_drivers() { 130 global $CFG; 131 132 $files = new RegexIterator(new DirectoryIterator("$CFG->libdir/dml"), '|^.*_moodle_database\.php$|'); 133 $drivers = array(); 134 135 foreach ($files as $file) { 136 $matches = null; 137 preg_match('|^([a-z0-9]+)_([a-z]+)_moodle_database\.php$|', $file->getFilename(), $matches); 138 if (!$matches) { 139 continue; 140 } 141 $dbtype = $matches[1]; 142 $dblibrary = $matches[2]; 143 144 if ($dbtype === 'sqlite3') { 145 // The sqlite3 driver is not fully working yet and should not be returned. 146 continue; 147 } 148 149 $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary, false); 150 if ($targetdb->driver_installed() !== true) { 151 continue; 152 } 153 154 $driver = $dbtype.'/'.$dblibrary; 155 156 $drivers[$driver] = $targetdb->get_name(); 157 }; 158 159 return $drivers; 160 } 161 162 /** 163 * Create CLI maintenance file to prevent all access. 164 */ 165 function tool_dbtransfer_create_maintenance_file() { 166 global $CFG; 167 168 core_shutdown_manager::register_function('tool_dbtransfer_maintenance_callback'); 169 170 $options = new stdClass(); 171 $options->trusted = false; 172 $options->noclean = false; 173 $options->smiley = false; 174 $options->filter = false; 175 $options->para = true; 176 $options->newlines = false; 177 178 $message = format_text(get_string('climigrationnotice', 'tool_dbtransfer'), FORMAT_MARKDOWN, $options); 179 $message = bootstrap_renderer::early_error_content($message, '', '', array()); 180 $html = <<<OET 181 <!DOCTYPE html> 182 <html> 183 <header><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><header/> 184 <body>$message</body> 185 </html> 186 OET; 187 188 file_put_contents("$CFG->dataroot/climaintenance.html", $html); 189 @chmod("$CFG->dataroot/climaintenance.html", $CFG->filepermissions); 190 } 191 192 /** 193 * This callback is responsible for unsetting maintenance mode 194 * if the migration is interrupted. 195 */ 196 function tool_dbtransfer_maintenance_callback() { 197 global $CFG; 198 199 if (empty($CFG->tool_dbransfer_migration_running)) { 200 // Migration was finished properly - keep the maintenance file in place. 201 return; 202 } 203 204 if (file_exists("$CFG->dataroot/climaintenance.html")) { 205 // Failed migration, revert to normal site operation. 206 unlink("$CFG->dataroot/climaintenance.html"); 207 error_log('tool_dbtransfer: Interrupted database migration detected, switching off CLI maintenance mode.'); 208 } 209 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body