mirror of
https://github.com/phpbb/phpbb.git
synced 2025-08-06 16:56:44 +02:00
[feature/migrations] Reverse data functionality
If data step fails, attempt to roll back any previous calls from the migration that failed. Fix some failing tests PHPBB3-9737
This commit is contained in:
@@ -103,4 +103,46 @@ class phpbb_db_migration_tool_config implements phpbb_db_migration_tool_interfac
|
||||
|
||||
$this->config->delete($config_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse an original install action
|
||||
*
|
||||
* First argument is the original call to the class (e.g. add, remove)
|
||||
* After the first argument, send the original arguments to the function in the original call
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
$original_call = array_shift($arguments);
|
||||
|
||||
$call = false;
|
||||
switch ($original_call)
|
||||
{
|
||||
case 'add':
|
||||
$call = 'remove';
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
$call = 'add';
|
||||
break;
|
||||
|
||||
case 'update_if_equals':
|
||||
$call = 'update_if_equals';
|
||||
|
||||
// Set to the original value if the current value is what we compared to originally
|
||||
$arguments = array(
|
||||
$arguments[2],
|
||||
$arguments[1],
|
||||
$arguments[0],
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($call)
|
||||
{
|
||||
return call_user_func_array(array(&$this, $call), $arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,4 +20,14 @@ interface phpbb_db_migration_tool_interface
|
||||
* @return string short name
|
||||
*/
|
||||
public function get_name();
|
||||
|
||||
/**
|
||||
* Reverse an original install action
|
||||
*
|
||||
* First argument is the original call to the class (e.g. add, remove)
|
||||
* After the first argument, send the original arguments to the function in the original call
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function reverse();
|
||||
}
|
||||
|
@@ -471,4 +471,35 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac
|
||||
$this->cache->destroy("_modules_$class");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse an original install action
|
||||
*
|
||||
* First argument is the original call to the class (e.g. add, remove)
|
||||
* After the first argument, send the original arguments to the function in the original call
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
$original_call = array_shift($arguments);
|
||||
|
||||
$call = false;
|
||||
switch ($original_call)
|
||||
{
|
||||
case 'add':
|
||||
$call = 'remove';
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
$call = 'add';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($call)
|
||||
{
|
||||
return call_user_func_array(array(&$this, $call), $arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -563,4 +563,59 @@ class phpbb_db_migration_tool_permission implements phpbb_db_migration_tool_inte
|
||||
|
||||
$this->auth->acl_clear_prefetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse an original install action
|
||||
*
|
||||
* First argument is the original call to the class (e.g. add, remove)
|
||||
* After the first argument, send the original arguments to the function in the original call
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
$original_call = array_shift($arguments);
|
||||
|
||||
$call = false;
|
||||
switch ($original_call)
|
||||
{
|
||||
case 'add':
|
||||
$call = 'remove';
|
||||
break;
|
||||
|
||||
case 'remove':
|
||||
$call = 'add';
|
||||
break;
|
||||
|
||||
case 'permission_set':
|
||||
$call = 'permission_unset';
|
||||
break;
|
||||
|
||||
case 'permission_unset':
|
||||
$call = 'permission_set';
|
||||
break;
|
||||
|
||||
case 'role_add':
|
||||
$call = 'role_remove';
|
||||
break;
|
||||
|
||||
case 'role_remove':
|
||||
$call = 'role_add';
|
||||
break;
|
||||
|
||||
case 'role_update':
|
||||
// Set to the original value if the current value is what we compared to originally
|
||||
$arguments = array(
|
||||
$arguments[1],
|
||||
$arguments[0],
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($call)
|
||||
{
|
||||
return call_user_func_array(array(&$this, $call), $arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -347,6 +347,17 @@ class phpbb_db_migrator
|
||||
catch (phpbb_db_migration_exception $e)
|
||||
{
|
||||
// We should try rolling back here
|
||||
foreach ($steps as $reverse_step)
|
||||
{
|
||||
// Reverse the step that was run
|
||||
$result = $this->run_step($step, false, true);
|
||||
|
||||
// If we've reached the current step we can break because we reversed everything that was run
|
||||
if ($reverse_step === $step)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($step);
|
||||
echo $e;
|
||||
@@ -364,11 +375,12 @@ class phpbb_db_migrator
|
||||
*
|
||||
* @param mixed $step Data step from migration
|
||||
* @param mixed $last_result Result to pass to the callable (only for 'custom' method)
|
||||
* @param bool $reverse False to install, True to attempt uninstallation by reversing the call
|
||||
* @return null
|
||||
*/
|
||||
protected function run_step($step, $last_result = false)
|
||||
protected function run_step($step, $last_result = false, $reverse = false)
|
||||
{
|
||||
$callable_and_parameters = $this->get_callable_from_step($step, $last_result);
|
||||
$callable_and_parameters = $this->get_callable_from_step($step, $last_result, $reverse);
|
||||
|
||||
if ($callable_and_parameters === false)
|
||||
{
|
||||
@@ -386,9 +398,10 @@ class phpbb_db_migrator
|
||||
*
|
||||
* @param mixed $step Data step from migration
|
||||
* @param mixed $last_result Result to pass to the callable (only for 'custom' method)
|
||||
* @param bool $reverse False to install, True to attempt uninstallation by reversing the call
|
||||
* @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters
|
||||
*/
|
||||
protected function get_callable_from_step($step, $last_result = false)
|
||||
protected function get_callable_from_step($step, $last_result = false, $reverse = false)
|
||||
{
|
||||
$type = $step[0];
|
||||
$parameters = $step[1];
|
||||
@@ -425,14 +438,7 @@ class phpbb_db_migrator
|
||||
|
||||
$step = $parameters[1];
|
||||
|
||||
$callable_and_parameters = $this->get_callable_from_step($step);
|
||||
$callable = $callable_and_parameters[0];
|
||||
$sub_parameters = $callable_and_parameters[1];
|
||||
|
||||
return array(
|
||||
$callable,
|
||||
$sub_parameters,
|
||||
);
|
||||
return $this->get_callable_from_step($step);
|
||||
break;
|
||||
case 'custom':
|
||||
if (!is_callable($parameters[0]))
|
||||
@@ -462,6 +468,15 @@ class phpbb_db_migrator
|
||||
throw new phpbb_db_migration_exception('MIGRATION_INVALID_DATA_UNDEFINED_METHOD', $step);
|
||||
}
|
||||
|
||||
// Attempt to reverse operations
|
||||
if ($reverse)
|
||||
{
|
||||
return array(
|
||||
array($this->tools[$class], 'reverse'),
|
||||
array_unshift($parameters, $method),
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
array($this->tools[$class], $method),
|
||||
$parameters,
|
||||
|
Reference in New Issue
Block a user