aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/db/migrator.php
diff options
context:
space:
mode:
authorNathan Guse <nathaniel.guse@gmail.com>2013-01-09 14:27:01 -0600
committerNathan Guse <nathaniel.guse@gmail.com>2013-01-09 16:44:08 -0600
commite3737978f76a962385a26de910959607d0ae0d30 (patch)
treeb97e686e13305f42d3aa22374321fbad99c1edd2 /phpBB/includes/db/migrator.php
parente9bcea5d82fd086ebcf7634ab386623f34ea8d03 (diff)
downloadforums-e3737978f76a962385a26de910959607d0ae0d30.tar
forums-e3737978f76a962385a26de910959607d0ae0d30.tar.gz
forums-e3737978f76a962385a26de910959607d0ae0d30.tar.bz2
forums-e3737978f76a962385a26de910959607d0ae0d30.tar.xz
forums-e3737978f76a962385a26de910959607d0ae0d30.zip
[feature/migrations] Fixing returns of callables and handling data state
Lots of comments and some other miscellaneous fixes. PHPBB3-9737
Diffstat (limited to 'phpBB/includes/db/migrator.php')
-rw-r--r--phpBB/includes/db/migrator.php158
1 files changed, 120 insertions, 38 deletions
diff --git a/phpBB/includes/db/migrator.php b/phpBB/includes/db/migrator.php
index 2fd795b659..2ba1eba427 100644
--- a/phpBB/includes/db/migrator.php
+++ b/phpBB/includes/db/migrator.php
@@ -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
*