1
0
Fork 0
mirror of https://github.com/Oreolek/kohana-migrations.git synced 2024-06-16 15:01:08 +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:
Matt Button 2010-12-30 03:22:32 +00:00
parent 09e3e57368
commit de7711942f
3 changed files with 127 additions and 27 deletions

View file

@ -21,6 +21,24 @@ class Minion_Migration_Manager {
*/
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
*
@ -64,6 +82,30 @@ class Minion_Migration_Manager {
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
*
@ -97,14 +139,14 @@ class Minion_Migration_Manager {
* @param array Set of locations to update, empty array means all
* @param array Versions for specified locations
* @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
*/
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);
$db = $this->_get_db_instance();
foreach($migrations as $location)
foreach($migrations as $path => $location)
{
$method = $location['direction'] ? 'up' : 'down';
@ -125,7 +167,7 @@ class Minion_Migration_Manager {
$class = Minion_Migration_Util::get_class_from_migration($migration);
$this->_db->query(NULL, 'START TRANSACTION');
$db->query(NULL, 'START TRANSACTION');
try
{
@ -133,18 +175,22 @@ class Minion_Migration_Manager {
$instance = new $class;
$instance->$method($this->_db);
$instance->$method($db);
}
catch(Exception $e)
{
$this->_db->query(NULL, 'ROLLBACK');
$db->query(NULL, 'ROLLBACK');
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']);
}
@ -214,4 +260,20 @@ class Minion_Migration_Manager {
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);
}
}

View file

@ -40,6 +40,11 @@
* No value taken, if this is specified then instead of executing the SQL it
* 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>
*/
class Minion_Task_Db_Migrate extends Minion_Task
@ -59,7 +64,8 @@ class Minion_Task_Db_Migrate extends Minion_Task
'environment',
'versions',
'locations',
'dry-run'
'dry-run',
'quiet'
);
/**
@ -75,32 +81,33 @@ class Minion_Task_Db_Migrate extends Minion_Task
$environment = Arr::get($config, 'environment', 'development');
$specified_locations = Arr::get($config, 'locations', 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);
$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 = 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
$manager
// Sync the available migrations with those in the db
->sync_migration_files()
// Run migrations for specified locations & versions, and if it's
// a dry run don't log results to DB
->run_migration($locations, $targets, $this->_default_direction, ! $dry_run);
->set_dry_run($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;
}
/**

View 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; ?>