MDL-21432 backup - move all the files handling on restore to use new backup_files_temp table

This commit is contained in:
Eloy Lafuente
2010-07-18 11:13:03 +00:00
parent 8bc29d46b4
commit b8bb45b001
5 changed files with 59 additions and 44 deletions
+6 -17
View File
@@ -32,7 +32,7 @@
class restore_create_and_clean_temp_stuff extends restore_execution_step {
protected function define_execution() {
$exists = restore_controller_dbops::create_backup_ids_temp_table($this->get_restoreid()); // Create temp table conditionally
$exists = restore_controller_dbops::create_restore_temp_tables($this->get_restoreid()); // temp tables conditionally
// If the table already exists, it's because restore_prechecks have been executed in the same
// request (without problems) and it already contains a bunch of preloaded information (users...)
// that we aren't going to execute again
@@ -54,7 +54,7 @@ class restore_drop_and_clean_temp_stuff extends restore_execution_step {
protected function define_execution() {
global $CFG;
backup_controller_dbops::drop_backup_ids_temp_table($this->get_restoreid()); // Drop ids temp table
restore_controller_dbops::drop_restore_temp_tables($this->get_restoreid()); // Drop ids temp table
backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
if (empty($CFG->keeptempdirectoriesonbackup)) { // Conditionally
backup_helper::delete_backup_dir($this->get_restoreid()); // Empty backup dir
@@ -84,11 +84,7 @@ class restore_load_included_inforef_records extends restore_execution_step {
}
/*
* Execution step that will load all the needed files into backup_temp_ids.
* - itemname: contains "file*component*fileara"
* - itemid: contains the original id of the file
* - newitemid: contains the itemid of the file
* - parentitemid: contains the context of the file
* Execution step that will load all the needed files into backup_files_temp
* - info: contains the whole original object (times, names...)
* (all them being original ids as loaded from xml)
*/
@@ -106,19 +102,13 @@ class restore_load_included_files extends restore_structure_step {
$data = (object)$data; // handy
$itemname = 'file*' . $data->component . '*' . $data->filearea;
$itemid = $data->id;
$newitemid = $data->itemid;
$parentitemid = $data->contextid;
$info = $data;
// load it if needed:
// - it it is one of the annotated inforef files (course/section/activity/block)
// - it is one "user", "group" or "grade" component file
$isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $itemid);
$isfileref = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'fileref', $data->id);
$iscomponent = ($data->component == 'user' || $data->component == 'group' || $data->component == 'grade');
if ($isfileref || $iscomponent) {
restore_dbops::set_backup_ids_record($this->get_restoreid(), $itemname, $itemid, $newitemid, $parentitemid, $info);
restore_dbops::set_backup_files_record($this->get_restoreid(), $data);
}
}
}
@@ -257,10 +247,9 @@ class restore_groups_structure_step extends restore_structure_step {
}
protected function after_execute() {
return;
// Add group related files, matching with "group" mappings
$this->add_related_files('group', 'icon', 'group');
$this->add_related_files('group', 'description', 'group');
restore_dbops::send_files_to_pool($basepath, $restoreid, 'user', 'private', $recuser->parentitemid);
}
}
@@ -85,16 +85,24 @@ abstract class backup_controller_dbops extends backup_dbops {
}
public static function create_backup_ids_temp_table($backupid) {
self::create_temptable_from_real_table($backupid, 'backup_ids_template', 'backup_ids_temp');
}
/**
* Given one "real" tablename, create one temp table suitable for be used in backup/restore operations
*/
public static function create_temptable_from_real_table($backupid, $realtablename, $temptablename) {
global $CFG, $DB;
$dbman = $DB->get_manager(); // We are going to use database_manager services
// Note: For now we are going to load the backup_ids_template from core lib/db/install.xml
// Note: For now we are going to load the realtablename from core lib/db/install.xml
// that way, any change in the "template" will be applied here automatically. If this causes
// too much slow, we can always forget about the template and keep maintained the xmldb_table
// structure inline - manually - here.
$templatetablename = 'backup_ids_template';
$targettablename = 'backup_ids_temp';
$xmldb_file = new xmldb_file($CFG->dirroot . '/lib/db/install.xml');
$templatetablename = $realtablename;
$targettablename = $temptablename;
$xmlfile = $CFG->dirroot . '/lib/db/install.xml';
$xmldb_file = new xmldb_file($xmlfile);
if (!$xmldb_file->fileExists()) {
throw new ddl_exception('ddlxmlfileerror', null, 'File does not exist');
}
@@ -105,7 +113,7 @@ abstract class backup_controller_dbops extends backup_dbops {
$xmldb_structure = $xmldb_file->getStructure();
$xmldb_table = $xmldb_structure->getTable($templatetablename);
if (is_null($xmldb_table)) {
throw new ddl_exception('ddlunknowntable', null, 'The table ' . $templatetablename . ' is not defined in file ' . $file);
throw new ddl_exception('ddlunknowntable', null, 'The table ' . $templatetablename . ' is not defined in file ' . $xmlfile);
}
// Set default backupid (not needed but this enforce any missing backupid). That's hackery in action!
$xmldb_table->getField('backupid')->setDefault($backupid);
@@ -84,7 +84,7 @@ abstract class restore_controller_dbops extends restore_dbops {
return $controller;
}
public static function create_backup_ids_temp_table($restoreid) {
public static function create_restore_temp_tables($restoreid) {
global $CFG, $DB;
$dbman = $DB->get_manager(); // We are going to use database_manager services
@@ -93,7 +93,19 @@ abstract class restore_controller_dbops extends restore_dbops {
// TODO: If not match, exception, table corresponds to another backup/restore operation
return true;
}
backup_controller_dbops::create_backup_ids_temp_table($restoreid); // Create ids temp table
backup_controller_dbops::create_temptable_from_real_table($restoreid, 'backup_ids_template', 'backup_ids_temp');
backup_controller_dbops::create_temptable_from_real_table($restoreid, 'backup_files_template', 'backup_files_temp');
return false;
}
public static function drop_restore_temp_tables($backupid) {
global $DB;
$dbman = $DB->get_manager(); // We are going to use database_manager services
$targettablenames = array('backup_ids_temp', 'backup_files_temp');
foreach ($targettablenames as $targettablename) {
$table = new xmldb_table($targettablename);
$dbman->drop_temp_table($table); // And drop it
}
}
}
+24 -18
View File
@@ -124,41 +124,39 @@ abstract class restore_dbops {
}
// Important: remember how files have been loaded to backup_ids_temp
// - itemname: contains "file*component*fileara"
// - itemid: contains the original id of the file
// - newitemid: contains the itemid of the file
// - parentitemid: contains the context of the file
// - info: contains the whole original object (times, names...)
// (all them being original ids as loaded from xml)
// itemname = null, we are going to match only by context, no need to use itemid (all them are 0)
if ($itemname == null) {
$sql = 'SELECT id, itemname, itemid, 0 AS newitemid
FROM {backup_ids_temp}
$sql = 'SELECT contextid, component, filearea, itemid, 0 AS newitemid, info
FROM {backup_files_temp}
WHERE backupid = ?
AND itemname = ?
AND parentitemid = ?';
$params = array($restoreid, 'file*' . $component . '*' . $filearea, $oldcontextid);
AND contextid = ?
AND component = ?
AND filearea = ?';
$params = array($restoreid, $oldcontextid, $component, $filearea);
// itemname not null, going to join by context and itemid, we'll need itemid (non zero)
// itemname not null, going to join with backup_ids to perform the old-new mapping of itemids
} else {
$sql = 'SELECT f.id, f.itemname, f.itemid, i.newitemid
FROM {backup_ids_temp} f
$sql = 'SELECT f.contextid, f.component, f.filearea, f.itemid, i.newitemid, f.info
FROM {backup_files_temp} f
JOIN {backup_ids_temp} i ON i.backupid = f.backupid
AND i.parentitemid = f.parentitemid
AND i.itemid = f.newitemid
AND i.parentitemid = f.contextid
AND i.itemid = f.itemid
WHERE f.backupid = ?
AND f.itemname = ?
AND f.parentitemid = ?
AND f.contextid = ?
AND f.component = ?
AND f.filearea = ?
AND i.itemname = ?';
$params = array($restoreid, 'file*' . $component . '*' . $filearea, $oldcontextid, $itemname);
$params = array($restoreid, $oldcontextid, $component, $filearea, $itemname);
}
$rs = $DB->get_recordset_sql($sql, $params);
$fs = get_file_storage(); // Get moodle file storage
$basepath = $basepath . '/files/';// Get backup file pool base
foreach ($rs as $rec) {
$file = (object)self::get_backup_ids_record($restoreid, $rec->itemname, $rec->itemid)->info;
$file = (object)unserialize(base64_decode($rec->info));
// ignore root dirs (they are created automatically)
if ($file->filepath == '/' && $file->filename == '.') {
continue;
@@ -649,6 +647,14 @@ abstract class restore_dbops {
}
}
public static function set_backup_files_record($restoreid, $filerec) {
global $DB;
$filerec->info = base64_encode(serialize($filerec)); // Serialize the whole rec in info
$filerec->backupid = $restoreid;
$DB->insert_record('backup_files_temp', $filerec);
}
public static function set_backup_ids_record($restoreid, $itemname, $itemid, $newitemid = 0, $parentitemid = null, $info = null) {
global $DB;
@@ -244,8 +244,8 @@ abstract class restore_structure_step extends restore_step {
/**
* Add all the existing file, given their component and filearea and one backup_ids itemname to match with
*/
protected function add_related_files($componentname, $filearea, $mappingitemname) {
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $componentname,
protected function add_related_files($component, $filearea, $mappingitemname) {
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
$filearea, $this->task->get_old_contextid(), $mappingitemname);
}