MDL-21432 backup - move all the files handling on restore to use new backup_files_temp table
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user