1
0
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:
Nathan Guse
2013-01-09 14:27:01 -06:00
parent e9bcea5d82
commit e3737978f7
9 changed files with 329 additions and 204 deletions

View File

@@ -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
*