Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MDL-21432 backup - added operation to separate backup & restore
  • Loading branch information
stronk7 committed Jul 5, 2010
1 parent 37fb7c0 commit f60f466
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 23 deletions.
23 changes: 15 additions & 8 deletions backup/backup.class.php
Expand Up @@ -40,7 +40,9 @@ abstract class backup implements checksumable {

// Backup format
const FORMAT_MOODLE = 'moodle2';
const FORMAT_MOODLE1 = 'moodle1';
const FORMAT_IMSCC = 'imscc';
const FORMAT_UNKNOWN = 'unknown';

// Interactive
const INTERACTIVE_YES = true;
Expand All @@ -58,13 +60,14 @@ abstract class backup implements checksumable {

// Status of the backup_controller
const STATUS_CREATED = 100;
const STATUS_PLANNED = 200;
const STATUS_CONFIGURED = 300;
const STATUS_SETTING_UI = 400;
const STATUS_AWAITING = 500;
const STATUS_EXECUTING = 600;
const STATUS_FINISHED_OK = 700;
const STATUS_REQUIRE_CONV= 200;
const STATUS_PLANNED = 300;
const STATUS_CONFIGURED = 400;
const STATUS_SETTING_UI = 500;
const STATUS_AWAITING = 600;
const STATUS_EXECUTING = 700;
const STATUS_FINISHED_ERR= 800;
const STATUS_FINISHED_OK = 900;

// Logging levels
const LOG_DEBUG = 50;
Expand All @@ -90,9 +93,13 @@ abstract class backup implements checksumable {
const VAR_BACKUPID = -1001; // To reference the backupid being processed
const VAR_BASEPATH = -1011; // To reference the dir where the file is generated

// Type of operation
const OPERATION_BACKUP ='backup'; // We are performing one backup
const OPERATION_RESTORE ='restore';// We are performing one restore

// Version (to keep CFG->backup_version (and release) updated automatically)
const VERSION = 2010050500;
const RELEASE = '2.0 Preview 1';
const VERSION = 2010070500;
const RELEASE = '2.0 Preview 5';
}

/*
Expand Down
28 changes: 17 additions & 11 deletions backup/controller/backup_controller.class.php
Expand Up @@ -51,6 +51,7 @@ class backup_controller extends backup implements loggable {
protected $interactive; // yes/no
protected $mode; // Purpose of the backup (default settings)
protected $userid; // user id executing the backup
protected $operation; // Type of operation (backup/restore)

protected $status; // Current status of the controller (created, planned, configured...)

Expand All @@ -75,6 +76,7 @@ public function __construct($type, $id, $format, $interactive, $mode, $userid){

// Apply some defaults
$this->execution = backup::EXECUTION_INMEDIATE;
$this->operation = backup::OPERATION_BACKUP;
$this->executiontime = 0;
$this->checksum = '';

Expand Down Expand Up @@ -179,6 +181,7 @@ public function calculate_checksum() {
'interactive-'. $this->interactive .
'mode-' . $this->mode .
'userid-' . $this->userid .
'operation-' . $this->operation .
'status-' . $this->status .
'execution-' . $this->execution .
'plan-' . backup_general_helper::array_checksum_recursive(array($this->plan)) .
Expand All @@ -200,6 +203,10 @@ public function get_type() {
return $this->type;
}

public function get_operation() {
return $this->operation;
}

public function get_id() {
return $this->id;
}
Expand Down Expand Up @@ -259,17 +266,6 @@ public function log($message, $level, $a = null, $depth = null, $display = false
backup_helper::log($message, $level, $a, $depth, $display, $this->logger);
}


// Protected API starts here

protected function calculate_backupid() {
// Current epoch time + type + id + format + interactive + mode + userid
// should be unique enough. Add one random part at the end
$this->backupid = md5(time() . '-' . $this->type . '-' . $this->id . '-' . $this->format . '-' .
$this->interactive . '-' . $this->mode . '-' . $this->userid . '-' .
random_string(20));
}

public function save_controller() {
// Going to save controller to persistent storage, calculate checksum for later checks and save it
// TODO: flag the controller as NA. Any operation on it should be forbidden util loaded back
Expand All @@ -286,6 +282,16 @@ public static function load_controller($backupid) {
return $controller;
}

// Protected API starts here

protected function calculate_backupid() {
// Current epoch time + type + id + format + interactive + mode + userid + operation
// should be unique enough. Add one random part at the end
$this->backupid = md5(time() . '-' . $this->type . '-' . $this->id . '-' . $this->format . '-' .
$this->interactive . '-' . $this->mode . '-' . $this->userid . '-' .
$this->operation . '-' . random_string(20));
}

protected function load_plan() {
$this->log('loading controller plan', backup::LOG_DEBUG);
$this->plan = new backup_plan($this);
Expand Down
1 change: 1 addition & 0 deletions backup/util/dbops/backup_controller_dbops.class.php
Expand Up @@ -45,6 +45,7 @@ public static function save_controller($controller, $checksum) {
// Get all the columns
$rec = new stdclass();
$rec->backupid = $controller->get_backupid();
$rec->operation = $controller->get_operation();
$rec->type = $controller->get_type();
$rec->itemid = $controller->get_id();
$rec->format = $controller->get_format();
Expand Down
43 changes: 43 additions & 0 deletions backup/util/helper/backup_general_helper.class.php
Expand Up @@ -55,4 +55,47 @@ public static function array_checksum_recursive($arr) {
}
return $checksum;
}

/**
* Given one temp/backup/xxx dir, detect its format
*
* TODO: Move harcoded detection here to delegated classes under backup/format (moodle1, imscc..)
* conversion code will be there too.
*/
public static function detect_backup_format($tempdir) {
global $CFG;

// First look for MOODLE (moodle2) format
$filepath = $CFG->dataroot . '/temp/backup/' . $tempdir . '/moodle_backup.xml';
if (file_exists($filepath)) { // Looks promising, lets load some information
$handle = fopen ($filepath, "r");
$first_chars = fread($handle,200);
$status = fclose ($handle);
// Check if it has the required strings
if (strpos($first_chars,'<?xml version="1.0" encoding="UTF-8"?>') !== false &&
strpos($first_chars,'<moodle_backup>') !== false &&
strpos($first_chars,'<information>') !== false) {
return backup::FORMAT_MOODLE;
}
}

// Then look for MOODLE1 (moodle1) format
$filepath = $CFG->dataroot . '/temp/backup/' . $tempdir . '/moodle.xml';
if (file_exists($filepath)) { // Looks promising, lets load some information
$handle = fopen ($filepath, "r");
$first_chars = fread($handle,200);
$status = fclose ($handle);
// Check if it has the required strings
if (strpos($first_chars,'<?xml version="1.0" encoding="UTF-8"?>') !== false &&
strpos($first_chars,'<MOODLE_BACKUP>') !== false &&
strpos($first_chars,'<INFO>') !== false) {
return backup::FORMAT_MOODLE1;
}
}

// Other formats

// Arrived here, unknown format
return backup::FORMAT_UNKNOWN;
}
}
7 changes: 4 additions & 3 deletions lib/db/install.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20100625" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20100705" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
Expand Down Expand Up @@ -2617,8 +2617,9 @@
<TABLE NAME="backup_controllers" COMMENT="To store the backup_controllers as they are used" PREVIOUS="registration_hubs" NEXT="backup_ids_template">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="backupid"/>
<FIELD NAME="backupid" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="unique id of the backup" PREVIOUS="id" NEXT="type"/>
<FIELD NAME="type" TYPE="char" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Type of the backup (activity/section/course)" PREVIOUS="backupid" NEXT="itemid"/>
<FIELD NAME="backupid" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" COMMENT="unique id of the backup" PREVIOUS="id" NEXT="operation"/>
<FIELD NAME="operation" TYPE="char" LENGTH="20" NOTNULL="true" DEFAULT="backup" SEQUENCE="false" COMMENT="Type of operation (backup/restore)" PREVIOUS="backupid" NEXT="type"/>
<FIELD NAME="type" TYPE="char" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Type of the backup (activity/section/course)" PREVIOUS="operation" NEXT="itemid"/>
<FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="id of the module/section/activity being backup" PREVIOUS="type" NEXT="format"/>
<FIELD NAME="format" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="format of the backup (moodle/imscc...)" PREVIOUS="itemid" NEXT="interactive"/>
<FIELD NAME="interactive" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="is the backup interactive (1-yes/0-no)" PREVIOUS="format" NEXT="purpose"/>
Expand Down
15 changes: 15 additions & 0 deletions lib/db/upgrade.php
Expand Up @@ -4829,6 +4829,21 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2010070300);
}

if ($oldversion < 2010070500) {

/// Define field operation to be added to backup_controllers
$table = new xmldb_table('backup_controllers');
$field = new xmldb_field('operation', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'backup', 'backupid');

/// Conditionally launch add field operation
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

/// Main savepoint reached
upgrade_main_savepoint(true, 2010070500);
}


return true;
}
Expand Down
2 changes: 1 addition & 1 deletion version.php
Expand Up @@ -6,7 +6,7 @@
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)

$version = 2010070300; // YYYYMMDD = date of the last version bump
$version = 2010070500; // YYYYMMDD = date of the last version bump
// XX = daily increments

$release = '2.0 Preview 4 (Build: 20100705)'; // Human-friendly version name
Expand Down

0 comments on commit f60f466

Please sign in to comment.