mirror of
https://github.com/phpbb/phpbb.git
synced 2025-07-30 21:40:43 +02:00
[feature/migrations] Fixing returns of callables and handling data state
Lots of comments and some other miscellaneous fixes. PHPBB3-9737
This commit is contained in:
@@ -22,26 +22,40 @@ if (!defined('IN_PHPBB'))
|
||||
*/
|
||||
class phpbb_db_migrator
|
||||
{
|
||||
/** @var phpbb_config */
|
||||
protected $config;
|
||||
|
||||
/** @var phpbb_db_driver */
|
||||
protected $db;
|
||||
|
||||
/** @var phpbb_db_tools */
|
||||
protected $db_tools;
|
||||
|
||||
/** @var string */
|
||||
protected $table_prefix;
|
||||
|
||||
/** @var string */
|
||||
protected $phpbb_root_path;
|
||||
|
||||
/** @var string */
|
||||
protected $php_ext;
|
||||
|
||||
/** @var string */
|
||||
protected $migrations_table;
|
||||
|
||||
/** @var array State of all migrations (SELECT * FROM migrations table) */
|
||||
protected $migration_state;
|
||||
|
||||
/** @var array Array of all migrations available to be run */
|
||||
protected $migrations = array();
|
||||
|
||||
/** @var string Name of the last migration run */
|
||||
/** @var array 'name' and 'class' of the last migration run */
|
||||
public $last_run_migration = false;
|
||||
|
||||
/**
|
||||
* Constructor of the database migrator
|
||||
*/
|
||||
public function __construct($config, phpbb_db_driver $db, $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools)
|
||||
public function __construct(phpbb_config $config, phpbb_db_driver $db, phpbb_db_tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
@@ -96,17 +110,42 @@ class phpbb_db_migrator
|
||||
/**
|
||||
* Load migration data files from a directory
|
||||
*
|
||||
* @param string $path
|
||||
* This does not loop through sub-directories.
|
||||
* Migration data files loaded with this function MUST contain
|
||||
* ONLY ONE class in them (or an exception will be thrown).
|
||||
*
|
||||
* @param string $path Path to migration data files
|
||||
* @param bool $check_fulfillable If TRUE (default), we will check
|
||||
* if all of the migrations are fulfillable after loading them.
|
||||
* If FALSE, we will not check. You SHOULD check at least once
|
||||
* to prevent errors (if including multiple directories, check
|
||||
* with the last call to prevent throwing errors unnecessarily).
|
||||
* @return array Array of migrations with names
|
||||
*/
|
||||
public function load_migrations($path)
|
||||
public function load_migrations($path, $check_fulfillable = true)
|
||||
{
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false)
|
||||
{
|
||||
if (strpos($file, '_') !== 0 && strrpos($file, '.' . $this->php_ext) === (strlen($file) - strlen($this->php_ext) - 1))
|
||||
{
|
||||
$name = 'phpbb_db_migration_data_' . substr($file, 0, -(strlen($this->php_ext) + 1));
|
||||
// We try to find what class existed by comparing the classes declared before and after including the file.
|
||||
$declared_classes = get_declared_classes();
|
||||
|
||||
include ($path . $file);
|
||||
|
||||
$added_classes = array_diff(get_declared_classes(), $declared_classes);
|
||||
|
||||
if (
|
||||
// The phpbb_db_migrations class may not have been loaded until now, so make sure to ignore it.
|
||||
!(sizeof($added_classes) == 2 && in_array('phpbb_db_migration', $added_classes)) &&
|
||||
sizeof($added_classes) != 1
|
||||
)
|
||||
{
|
||||
throw new phpbb_db_migration_exception('MIGRATION DATA FILE INVALID', $path . $file);
|
||||
}
|
||||
|
||||
$name = array_pop($added_classes);
|
||||
|
||||
if (!in_array($name, $this->migrations))
|
||||
{
|
||||
@@ -115,11 +154,14 @@ class phpbb_db_migrator
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->migrations as $name)
|
||||
if ($check_fulfillable)
|
||||
{
|
||||
if ($this->unfulfillable($name))
|
||||
foreach ($this->migrations as $name)
|
||||
{
|
||||
throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name);
|
||||
if ($this->unfulfillable($name))
|
||||
{
|
||||
throw new phpbb_db_migration_exception('MIGRATION NOT FULFILLABLE', $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +173,8 @@ class phpbb_db_migrator
|
||||
*
|
||||
* The update step can either be a schema or a (partial) data update. To
|
||||
* check if update() needs to be called again use the finished() method.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
@@ -207,9 +251,11 @@ class phpbb_db_migrator
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->process_data_step($migration);
|
||||
$state['migration_data_done'] = true;
|
||||
$state['migration_end_time'] = time();
|
||||
$state = $this->process_data_step($migration);
|
||||
|
||||
$state['migration_data_state'] = $state;
|
||||
$state['migration_data_done'] = ($state === true);
|
||||
$state['migration_end_time'] = ($state === true) ? time() : 0;
|
||||
}
|
||||
|
||||
$sql = 'UPDATE ' . $this->migrations_table . '
|
||||
@@ -222,41 +268,74 @@ class phpbb_db_migrator
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply schema changes from a migration
|
||||
*
|
||||
* Just calls db_tools->perform_schema_changes
|
||||
*
|
||||
* @param array $schema_changes from migration
|
||||
*/
|
||||
protected function apply_schema_changes($schema_changes)
|
||||
{
|
||||
$this->db_tools->perform_schema_changes($schema_changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the data step of the migration
|
||||
*
|
||||
* @param phpbb_db_migration $migration
|
||||
* @return mixed migration status or bool true if everything completed successfully
|
||||
*/
|
||||
protected function process_data_step($migration)
|
||||
{
|
||||
//$continue = false;
|
||||
$steps = $migration->update_data();
|
||||
|
||||
foreach ($steps as $step)
|
||||
{
|
||||
$continue = $this->run_step($step);
|
||||
|
||||
/*if ($continue === false)
|
||||
try
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
// Result will be null or true if everything completed correctly
|
||||
$result = $this->run_step($step);
|
||||
if ($result !== null && $result !== true)
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
catch (phpbb_db_migration_exception $e)
|
||||
{
|
||||
// We should try rolling back here
|
||||
|
||||
echo $e;
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
//return $continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a single step
|
||||
*
|
||||
* An exception should be thrown if an error occurs
|
||||
*
|
||||
* @param mixed $step
|
||||
* @return null
|
||||
*/
|
||||
protected function run_step($step)
|
||||
{
|
||||
try
|
||||
{
|
||||
$callable_and_parameters = $this->get_callable_from_step($step);
|
||||
$callable = $callable_and_parameters[0];
|
||||
$parameters = $callable_and_parameters[1];
|
||||
$callable_and_parameters = $this->get_callable_from_step($step);
|
||||
$callable = $callable_and_parameters[0];
|
||||
$parameters = $callable_and_parameters[1];
|
||||
|
||||
return call_user_func_array($callable, $parameters);
|
||||
}
|
||||
catch (phpbb_db_migration_exception $e)
|
||||
{
|
||||
echo $e;
|
||||
die();
|
||||
}
|
||||
return call_user_func_array($callable, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a callable statement from a data step
|
||||
*
|
||||
* @param mixed $step Data step from migration
|
||||
* @return array Array with parameters for call_user_func_array(), 0 is the callable, 1 is parameters
|
||||
*/
|
||||
public function get_callable_from_step($step)
|
||||
{
|
||||
$type = $step[0];
|
||||
@@ -291,6 +370,7 @@ class phpbb_db_migrator
|
||||
$callable_and_parameters = $this->get_callable_from_step($step);
|
||||
$callable = $callable_and_parameters[0];
|
||||
$sub_parameters = $callable_and_parameters[1];
|
||||
|
||||
return array(
|
||||
function ($condition) use ($callable, $sub_parameters) {
|
||||
return call_user_func_array($callable, $sub_parameters);
|
||||
@@ -325,12 +405,19 @@ class phpbb_db_migrator
|
||||
|
||||
return array(
|
||||
array($this->tools[$class], $method),
|
||||
$parameters
|
||||
$parameters,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert migration row into the database
|
||||
*
|
||||
* @param string $name Name of the migration
|
||||
* @param array $state
|
||||
* @return null
|
||||
*/
|
||||
protected function insert_migration($name, $state)
|
||||
{
|
||||
$migration_row = $state;
|
||||
@@ -346,8 +433,8 @@ class phpbb_db_migrator
|
||||
/**
|
||||
* Checks if a migration's dependencies can even theoretically be satisfied.
|
||||
*
|
||||
* @param string $name The class name of the migration
|
||||
* @return bool Whether the migration cannot be fulfilled
|
||||
* @param string $name The class name of the migration
|
||||
* @return bool Whether the migration cannot be fulfilled
|
||||
*/
|
||||
public function unfulfillable($name)
|
||||
{
|
||||
@@ -406,11 +493,6 @@ class phpbb_db_migrator
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function apply_schema_changes($schema_changes)
|
||||
{
|
||||
$this->db_tools->perform_schema_changes($schema_changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get a migration
|
||||
*
|
||||
|
Reference in New Issue
Block a user