MDL-32149 significantly faster database reset, "util.php --drop" can now be interrupted at any time

This commit is contained in:
Petr Skoda
2012-04-03 22:30:54 +02:00
parent dbf5a44798
commit 728eadac78
2 changed files with 85 additions and 34 deletions
+3 -1
View File
@@ -225,7 +225,9 @@ function phpunit_bootstrap_error($text, $errorcode = 1) {
function phpunit_bootstrap_initdataroot($dataroot) {
global $CFG;
file_put_contents("$dataroot/phpunittestdir.txt", 'Contents of this directory are used during tests only, do not delete this file!');
if (!file_exists("$dataroot/phpunittestdir.txt")) {
file_put_contents("$dataroot/phpunittestdir.txt", 'Contents of this directory are used during tests only, do not delete this file!');
}
chmod("$dataroot/phpunittestdir.txt", $CFG->filepermissions);
if (!file_exists("$CFG->phpunit_dataroot/phpunit")) {
mkdir("$CFG->phpunit_dataroot/phpunit", $CFG->directorypermissions);
+82 -33
View File
@@ -127,27 +127,60 @@ class phpunit_util {
if (is_null(self::$lastdbwrites) or self::$lastdbwrites != $DB->perf_get_writes()) {
if ($data = self::get_tabledata()) {
$trans = $DB->start_delegated_transaction(); // faster and safer
$resetseq = array();
foreach ($data as $table=>$records) {
$DB->delete_records($table, array());
$resetseq = null;
foreach ($records as $record) {
if (is_null($resetseq)) {
$resetseq = property_exists($record, 'id');
if (empty($records)) {
if ($DB->count_records($table)) {
$DB->delete_records($table, array());
$resetseq[$table] = $table;
}
continue;
}
$firstrecord = reset($records);
if (property_exists($firstrecord, 'id')) {
if ($DB->count_records($table) == count($records)) {
$currentrecords = $DB->get_records($table, array(), 'id ASC');
$changed = false;
foreach ($records as $id=>$record) {
if (!isset($currentrecords[$id])) {
$changed = true;
break;
}
if ((array)$record != (array)$currentrecords[$id]) {
$changed = true;
break;
}
}
if (!$changed) {
continue;
}
}
}
$DB->delete_records($table, array());
if (property_exists($firstrecord, 'id')) {
$resetseq[$table] = $table;
}
foreach ($records as $record) {
$DB->import_record($table, $record, false, true);
}
if ($resetseq === true) {
$DB->get_manager()->reset_sequence($table, true);
}
}
// reset all sequences
foreach ($resetseq as $table) {
$DB->get_manager()->reset_sequence($table, true);
}
$trans->allow_commit();
$dbreset = true;
// remove extra tables
foreach ($tables as $tablename) {
if (!isset($data[$tablename])) {
$DB->get_manager()->drop_table(new xmldb_table($tablename));
}
}
$dbreset = true;
}
}
@@ -156,6 +189,32 @@ class phpunit_util {
return $dbreset;
}
/**
* Purge dataroot
* @static
* @return void
*/
public static function reset_dataroot() {
global $CFG;
$handle = opendir($CFG->dataroot);
$skip = array('.', '..', 'phpunittestdir.txt', 'phpunit', '.htaccess');
while (false !== ($item = readdir($handle))) {
if (in_array($item, $skip)) {
continue;
}
if (is_dir("$CFG->dataroot/$item")) {
remove_dir("$CFG->dataroot/$item", false);
} else {
unlink("$CFG->dataroot/$item");
}
}
closedir($handle);
make_temp_directory('');
make_cache_directory('');
make_cache_directory('htmlpurifier');
}
/**
* Reset contents of all database tables to initial values, reset caches, etc.
*
@@ -230,22 +289,7 @@ class phpunit_util {
//TODO: add more resets here and probably refactor them to new core function
// purge dataroot
$handle = opendir($CFG->dataroot);
$skip = array('.', '..', 'phpunittestdir.txt', 'phpunit', '.htaccess');
while (false !== ($item = readdir($handle))) {
if (in_array($item, $skip)) {
continue;
}
if (is_dir("$CFG->dataroot/$item")) {
remove_dir("$CFG->dataroot/$item", false);
} else {
unlink("$CFG->dataroot/$item");
}
}
closedir($handle);
make_temp_directory('');
make_cache_directory('');
make_cache_directory('htmlpurifier');
self::reset_dataroot();
// restore original config once more in case resetting of caches changes CFG
$CFG = self::get_global_backup('CFG');
@@ -379,18 +423,17 @@ class phpunit_util {
}
// drop dataroot
remove_dir($CFG->dataroot, true);
self::reset_dataroot();
phpunit_bootstrap_initdataroot($CFG->dataroot);
remove_dir("$CFG->dataroot/phpunit", true);
// drop all tables
$trans = $DB->start_delegated_transaction();
$tables = $DB->get_tables(false);
foreach ($tables as $tablename) {
$DB->delete_records($tablename, array());
if (isset($tables['config'])) {
// config always last to prevent problems with interrupted drops!
unset($tables['config']);
$tables['config'] = 'config';
}
$trans->allow_commit();
// now drop them
foreach ($tables as $tablename) {
$table = new xmldb_table($tablename);
$DB->get_manager()->drop_table($table);
@@ -434,7 +477,13 @@ class phpunit_util {
$data = array();
$tables = $DB->get_tables();
foreach ($tables as $table) {
$data[$table] = $DB->get_records($table, array());
$columns = $DB->get_columns($table);
if (isset($columns['id'])) {
$data[$table] = $DB->get_records($table, array(), 'id ASC');
} else {
// there should not be many of these
$data[$table] = $DB->get_records($table, array());
}
}
$data = serialize($data);
@unlink("$CFG->dataroot/phpunit/tabledata.ser");