mirror of
https://github.com/Oreolek/kohana-migrations.git
synced 2024-06-26 03:40:54 +03:00
Changing migration system so that the migration manager is responsible for organising dry-runs
This makes more sense from a structural point of view, and reduces the complexity of the db:migrate code. Can now successfully do a dry run with query output :) Also added a view so as to display task results.
This commit is contained in:
parent
09e3e57368
commit
de7711942f
|
@ -21,6 +21,24 @@ class Minion_Migration_Manager {
|
||||||
*/
|
*/
|
||||||
protected $_model;
|
protected $_model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this is a dry run migration
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
protected $_dry_run = FALSE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of SQL queries that were generated on the dry run
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $_dry_run_sql = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of migrations that were executed
|
||||||
|
*/
|
||||||
|
protected $_executed_migrations = array();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the object, allows injection of a Database connection
|
* Constructs the object, allows injection of a Database connection
|
||||||
*
|
*
|
||||||
|
@ -64,6 +82,30 @@ class Minion_Migration_Manager {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the manager should execute a dry run instead of a real run
|
||||||
|
*
|
||||||
|
* @param boolean Whether we should do a dry run
|
||||||
|
* @return Minion_Migration_Manager
|
||||||
|
*/
|
||||||
|
public function set_dry_run($dry_run)
|
||||||
|
{
|
||||||
|
$this->_dry_run = (bool) $dry_run;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruturns a set of queries that would've been executed had dry run not been
|
||||||
|
* enabled. If dry run was not enabled, this returns an empty array
|
||||||
|
*
|
||||||
|
* @return array SQL Queries
|
||||||
|
*/
|
||||||
|
public function get_dry_run_sql()
|
||||||
|
{
|
||||||
|
return $this->_dry_run_sql;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run migrations in the specified locations so as to reach specified targets
|
* Run migrations in the specified locations so as to reach specified targets
|
||||||
*
|
*
|
||||||
|
@ -97,14 +139,14 @@ class Minion_Migration_Manager {
|
||||||
* @param array Set of locations to update, empty array means all
|
* @param array Set of locations to update, empty array means all
|
||||||
* @param array Versions for specified locations
|
* @param array Versions for specified locations
|
||||||
* @param boolean The default direction (up/down) for migrations without a specific version
|
* @param boolean The default direction (up/down) for migrations without a specific version
|
||||||
* @param boolean Whether successful migrations should be recorded
|
|
||||||
* @return array Array of all migrations that were successfully applied
|
* @return array Array of all migrations that were successfully applied
|
||||||
*/
|
*/
|
||||||
public function run_migration(array $locations = array(), $versions = array(), $default_direction = TRUE, $record_success = TRUE)
|
public function run_migration(array $locations = array(), $versions = array(), $default_direction = TRUE)
|
||||||
{
|
{
|
||||||
$migrations = $this->_model->fetch_required_migrations($locations, $versions, $default_direction);
|
$migrations = $this->_model->fetch_required_migrations($locations, $versions, $default_direction);
|
||||||
|
$db = $this->_get_db_instance();
|
||||||
|
|
||||||
foreach($migrations as $location)
|
foreach($migrations as $path => $location)
|
||||||
{
|
{
|
||||||
$method = $location['direction'] ? 'up' : 'down';
|
$method = $location['direction'] ? 'up' : 'down';
|
||||||
|
|
||||||
|
@ -125,7 +167,7 @@ class Minion_Migration_Manager {
|
||||||
|
|
||||||
$class = Minion_Migration_Util::get_class_from_migration($migration);
|
$class = Minion_Migration_Util::get_class_from_migration($migration);
|
||||||
|
|
||||||
$this->_db->query(NULL, 'START TRANSACTION');
|
$db->query(NULL, 'START TRANSACTION');
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -133,18 +175,22 @@ class Minion_Migration_Manager {
|
||||||
|
|
||||||
$instance = new $class;
|
$instance = new $class;
|
||||||
|
|
||||||
$instance->$method($this->_db);
|
$instance->$method($db);
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
$this->_db->query(NULL, 'ROLLBACK');
|
$db->query(NULL, 'ROLLBACK');
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_db->query('COMMIT');
|
$db->query(NULL, 'COMMIT');
|
||||||
|
|
||||||
if($record_success)
|
if($this->_dry_run)
|
||||||
|
{
|
||||||
|
$this->_dry_run_sql[$path][$migration['timestamp']] = $db->reset_query_stack();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$this->_model->mark_migration($migration, $location['direction']);
|
$this->_model->mark_migration($migration, $location['direction']);
|
||||||
}
|
}
|
||||||
|
@ -214,4 +260,20 @@ class Minion_Migration_Manager {
|
||||||
|
|
||||||
return Minion_Migration_Util::compile_migrations_from_files($files);
|
return Minion_Migration_Util::compile_migrations_from_files($files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a database connection for running the migrations
|
||||||
|
*
|
||||||
|
* @return Kohana_Database Database connection
|
||||||
|
*/
|
||||||
|
protected function _get_db_instance()
|
||||||
|
{
|
||||||
|
// If this isn't a dry run then just use the normal database connection
|
||||||
|
if( ! $this->_dry_run)
|
||||||
|
return $this->_db;
|
||||||
|
|
||||||
|
$db_group = array_search($this->_db, Database::$instances);
|
||||||
|
|
||||||
|
return Minion_Migration_Database::faux_instance($db_group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,11 @@
|
||||||
* No value taken, if this is specified then instead of executing the SQL it
|
* No value taken, if this is specified then instead of executing the SQL it
|
||||||
* will be printed to the console
|
* will be printed to the console
|
||||||
*
|
*
|
||||||
|
* --quiet
|
||||||
|
*
|
||||||
|
* Suppress all unnessacery output. If --dry-run is enabled then only dry run
|
||||||
|
* SQL will be output
|
||||||
|
*
|
||||||
* @author Matt Button <matthew@sigswitch.com>
|
* @author Matt Button <matthew@sigswitch.com>
|
||||||
*/
|
*/
|
||||||
class Minion_Task_Db_Migrate extends Minion_Task
|
class Minion_Task_Db_Migrate extends Minion_Task
|
||||||
|
@ -59,7 +64,8 @@ class Minion_Task_Db_Migrate extends Minion_Task
|
||||||
'environment',
|
'environment',
|
||||||
'versions',
|
'versions',
|
||||||
'locations',
|
'locations',
|
||||||
'dry-run'
|
'dry-run',
|
||||||
|
'quiet'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,32 +81,33 @@ class Minion_Task_Db_Migrate extends Minion_Task
|
||||||
$environment = Arr::get($config, 'environment', 'development');
|
$environment = Arr::get($config, 'environment', 'development');
|
||||||
$specified_locations = Arr::get($config, 'locations', NULL);
|
$specified_locations = Arr::get($config, 'locations', NULL);
|
||||||
$versions = Arr::get($config, 'versions', NULL);
|
$versions = Arr::get($config, 'versions', NULL);
|
||||||
$dry_run = isset($config['dry-run']);
|
$dry_run = array_key_exists('dry-run', $config);
|
||||||
|
$quiet = array_key_exists('quiet', $config);
|
||||||
|
|
||||||
$targets = $this->_parse_target_versions($versions);
|
$targets = $this->_parse_target_versions($versions);
|
||||||
$locations = $this->_parse_locations($specified_locations);
|
$locations = $this->_parse_locations($specified_locations);
|
||||||
|
|
||||||
|
$db_group = $k_config['db_connections'][$environment];
|
||||||
|
$db = Database::instance($db_group);
|
||||||
|
$model = new Model_Minion_Migration($db);
|
||||||
|
|
||||||
$db = Database::instance($k_config['db_connections'][$environment]);
|
$manager = new Minion_Migration_Manager($db, $model);
|
||||||
|
|
||||||
if($dry_run)
|
$manager
|
||||||
{
|
|
||||||
$manager = new Minion_Migration_Manager(
|
|
||||||
Minion_Migration_Database::instance($k_config['db_connections'][$environment]),
|
|
||||||
new Model_Minion_Migration($db)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$manager = new Minion_Migration_Manager($db);
|
|
||||||
}
|
|
||||||
|
|
||||||
$results = $manager
|
|
||||||
// Sync the available migrations with those in the db
|
// Sync the available migrations with those in the db
|
||||||
->sync_migration_files()
|
->sync_migration_files()
|
||||||
// Run migrations for specified locations & versions, and if it's
|
|
||||||
// a dry run don't log results to DB
|
->set_dry_run($dry_run)
|
||||||
->run_migration($locations, $targets, $this->_default_direction, ! $dry_run);
|
|
||||||
|
// Run migrations for specified locations & versions
|
||||||
|
->run_migration($locations, $targets, $this->_default_direction);
|
||||||
|
|
||||||
|
$view = View::factory('minion/task/db/migrate')
|
||||||
|
->set('dry_run', $dry_run)
|
||||||
|
->set('quiet', $quiet)
|
||||||
|
->set('dry_run_sql', $manager->get_dry_run_sql());
|
||||||
|
|
||||||
|
echo $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
31
views/minion/task/db/migrate.php
Normal file
31
views/minion/task/db/migrate.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php if($dry_run): ?>
|
||||||
|
<?php if( ! $quiet): ?>
|
||||||
|
|
||||||
|
This was a dry run, SQL is as follows:
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php foreach($dry_run_sql as $location => $migrations): ?>
|
||||||
|
<?php $location_padding = str_repeat('#', strlen($location)); ?>
|
||||||
|
##################<?php echo $location_padding ?>##
|
||||||
|
# Begin Location: <?php echo $location; ?> #
|
||||||
|
##################<?php echo $location_padding ?>##
|
||||||
|
|
||||||
|
<?php foreach($migrations as $timestamp => $sql): ?>
|
||||||
|
# Begin <?php echo $timestamp; ?>
|
||||||
|
|
||||||
|
<?php foreach($sql as $query): ?>
|
||||||
|
|
||||||
|
<?php echo $query;?>;
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
# End <?php echo $timestamp; ?>
|
||||||
|
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
################<?php echo $location_padding ?>##
|
||||||
|
# End Location: <?php echo $location; ?> #
|
||||||
|
################<?php echo $location_padding ?>##
|
||||||
|
<?php endforeach; ?>
|
||||||
|
|
||||||
|
<?php endif; ?>
|
||||||
|
|
Loading…
Reference in a new issue