1
0
Fork 0
mirror of https://github.com/Oreolek/kohana-migrations.git synced 2024-06-16 15:01:08 +03:00

Starting to refactor stuff.

Renaming locations -> groups
Cut down the size of fetch_required_migrations()
This commit is contained in:
Matt Button 2011-02-17 20:43:04 +00:00
parent 8b550a43d4
commit e0fe87f443
15 changed files with 203 additions and 404 deletions

View file

@ -34,11 +34,11 @@ abstract class Minion_Migration_Base {
public function get_database_connection()
{
$config = Kohana::config('minion/migration');
$location = $this->_info['location'];
$group = $this->_info['group'];
if (isset($config->location_connection[$location]))
if (isset($config->group_connection[$group]))
{
return $config->location_connection[$location];
return $config->group_connection[$group];
}
return Database::$default;

View file

@ -14,7 +14,7 @@ class Minion_Migration_Exception extends Kohana_Exception {
public function __construct($message, array $migration, array $variables = array(), $code = 0)
{
$variables[':migration-id'] = $migration['id'];
$variables[':migration-location'] = $migration['location'];
$variables[':migration-group'] = $migration['group'];
$this->_migration = $migration;

View file

@ -116,49 +116,49 @@ class Minion_Migration_Manager {
}
/**
* Run migrations in the specified locations so as to reach specified targets
* Run migrations in the specified groups so as to reach specified targets
*
* There are three methods for specifying target versions:
*
* 1. Pass them in with the array of locations, i.e.
* 1. Pass them in with the array of groups, i.e.
*
* array(
* location => target_version
* group => target_version
* )
*
* 2. Pass them in separately, with param1 containing an array of
* locations like:
* groups like:
*
* array(
* location,
* location2,
* group,
* group2,
* )
*
* And param2 containing an array structured in the same way as in #1
*
* 3. Perform a mix of the above two methods
*
* It may seem odd to use two arrays to specify locations and versions, but
* it's this way to allow users to upgrade / downgrade all locations while
* migrating a specific location to a specific version
* It may seem odd to use two arrays to specify groups and versions, but
* it's this way to allow users to upgrade / downgrade all groups while
* migrating a specific group to a specific version
*
* If no locations are specified then migrations from all locations will be
* If no groups are specified then migrations from all groups will be
* run and be brought up to the latest available version
*
* @param array Set of locations to update, empty array means all
* @param array Versions for specified locations
* @param array Set of groups to update, empty array means all
* @param array Versions for specified groups
* @param boolean The default direction (up/down) for migrations without a specific version
* @return array Array of all migrations that were successfully applied
*/
public function run_migration(array $locations = array(), $versions = array(), $default_direction = TRUE)
public function run_migration(array $groups = array(), $versions = array(), $default_direction = TRUE)
{
$migrations = $this->_model->fetch_required_migrations($locations, $versions, $default_direction);
$migrations = $this->_model->fetch_required_migrations($groups, $versions, $default_direction);
foreach ($migrations as $path => $location)
foreach ($migrations as $path => $group)
{
$method = $location['direction'] ? 'up' : 'down';
$method = $group['direction'] ? 'up' : 'down';
foreach ($location['migrations'] as $migration)
foreach ($group['migrations'] as $migration)
{
$filename = Minion_Migration_Util::get_filename_from_migration($migration);
@ -198,7 +198,7 @@ class Minion_Migration_Manager {
}
else
{
$this->_model->mark_migration($migration, $location['direction']);
$this->_model->mark_migration($migration, $group['direction']);
}
$this->_executed_migrations[] = $migration;

View file

@ -30,7 +30,7 @@ class Minion_Migration_Util {
{
$migration = Minion_Migration_Util::get_migration_from_filename($file);
$migrations[$migration['location'].':'.$migration['timestamp']] = $migration;
$migrations[$migration['group'].':'.$migration['timestamp']] = $migration;
}
}
@ -43,10 +43,10 @@ class Minion_Migration_Util {
* Returns an array like:
*
* array(
* 'location' => 'mylocation',
* 'group' => 'mygroup',
* 'timestamp' => '1293214439',
* 'description' => 'initial-setup',
* 'id' => 'mylocation:1293214439'
* 'id' => 'mygroup:1293214439'
* );
*
* @param string The migration's filename
@ -57,33 +57,33 @@ class Minion_Migration_Util {
$migration = array();
// Get rid of the file's "migrations/" prefix, the file extension and then
// the filename itself. The "location" is essentially a slash delimited
// the filename itself. The "group" is essentially a slash delimited
// path from the migrations folder to the migration file
$migration['location'] = dirname(substr($file, 11, -strlen(EXT)));
$migration['group'] = dirname(substr($file, 11, -strlen(EXT)));
list($migration['timestamp'], $migration['description'])
= explode('_', basename($file, EXT), 2);
$migration['id'] = $migration['location'].':'.$migration['timestamp'];
$migration['id'] = $migration['group'].':'.$migration['timestamp'];
return $migration;
}
/**
* Gets a migration file from its timestamp, description and location
* Gets a migration file from its timestamp, description and group
*
* @param integer|array The migration's ID or an array of timestamp, description
* @param string The migration location
* @param string The migration group
* @return string Path to the migration file
*/
public static function get_filename_from_migration(array $migration)
{
$location = $migration['location'];
$group = $migration['group'];
$migration = $migration['timestamp'].'_'.$migration['description'];
$location = ( ! empty($location)) ? (rtrim($location, '/').'/') : '';
$group = ( ! empty($group)) ? (rtrim($group, '/').'/') : '';
return $location.$migration.EXT;
return $group.$migration.EXT;
}
/**
@ -101,7 +101,7 @@ class Minion_Migration_Util {
}
else
{
$migration = str_replace('/', ' ', $migration['location']).'_'.$migration['timestamp'];
$migration = str_replace('/', ' ', $migration['group']).'_'.$migration['timestamp'];
}
return 'Migration_'.str_replace(array(' ', '-'), '_', ucwords($migration));

View file

@ -5,15 +5,15 @@
*
* Available config options are:
*
* --location=path/to/migration/location
* --group=path/to/migration/group
*
* This is a required config option, use it specify in which location the
* This is a required config option, use it specify in which group the
* migration should be stored. Due to the nature of the cascading filesystem
* minion doesn't automatically know where a migration is stored so make sure
* you pass in the full path to your migrations folder, e.g.
*
* # The location of the migrations folder is modules/myapp/migrations/myapp/
* --location=modules/myapp/migrations/myapp/
* # The group of the migrations folder is modules/myapp/migrations/myapp/
* --group=modules/myapp/migrations/myapp/
*
* On nix based systems you should be able to tab complete the path
*
@ -34,7 +34,7 @@ class Minion_Task_Db_Generate extends Minion_Task
* @var array
*/
protected $_config = array(
'location',
'group',
'description'
);
@ -45,19 +45,19 @@ class Minion_Task_Db_Generate extends Minion_Task
*/
public function execute(array $config)
{
if (empty($config['location']) OR empty($config['description']))
if (empty($config['group']) OR empty($config['description']))
{
return 'Please provide --location and --description'.PHP_EOL.
return 'Please provide --group and --description'.PHP_EOL.
'See help for more info'.PHP_EOL;
}
$location = rtrim(realpath($config['location']), '/').'/';
$group = rtrim(realpath($config['group']), '/').'/';
$description = $config['description'];
// {year}{month}{day}{hour}{minute}{second}
$time = date('YmdHis');
$class = $this->_generate_classname($location, $time);
$file = $this->_generate_filename($location, $time, $description);
$class = $this->_generate_classname($group, $time);
$file = $this->_generate_filename($group, $time, $description);
$data = Kohana::FILE_SECURITY.View::factory('minion/task/db/generate/template')
@ -71,20 +71,20 @@ class Minion_Task_Db_Generate extends Minion_Task
}
/**
* Generate a class name from the location
* Generate a class name from the group
*
* @param string location
* @param string group
* @param string Timestamp
* @return string Class name
*/
protected function _generate_classname($location, $time)
protected function _generate_classname($group, $time)
{
// Chop up everything up until the relative path
$location = substr($location, strrpos($location, 'migrations/') + 11);
$group = substr($group, strrpos($group, 'migrations/') + 11);
$class = ucwords(str_replace('/', ' ', $location));
$class = ucwords(str_replace('/', ' ', $group));
// If location is empty then we want to avoid double underscore in the
// If group is empty then we want to avoid double underscore in the
// class name
if ( ! empty($class))
{
@ -97,18 +97,18 @@ class Minion_Task_Db_Generate extends Minion_Task
}
/**
* Generates a filename from the location, time and description
* Generates a filename from the group, time and description
*
* @param string Location to store migration
* @param string Timestamp
* @param string Description
* @return string Filename
*/
public function _generate_filename($location, $time, $description)
public function _generate_filename($group, $time, $description)
{
$description = substr(strtolower($description), 0, 100);
return $location.$time.'_'.preg_replace('~[^a-z]+~', '-', $description).EXT;
return $group.$time.'_'.preg_replace('~[^a-z]+~', '-', $description).EXT;
}
}

View file

@ -7,10 +7,10 @@
*
* Available config options are:
*
* --versions=[location:]version
* --versions=[group:]version
*
* Used to specify the version to migrate the database to. The location prefix
* is used to specify the target version of an individual location. Version
* Used to specify the version to migrate the database to. The group prefix
* is used to specify the target version of an individual group. Version
* specifies the target version, which can be either:
*
* * A migration version (migrates up/down to that version)
@ -19,16 +19,16 @@
*
* An example of a migration version is 20101229015800
*
* If you specify TRUE / FALSE without a location then the default migration
* direction for locations without a specified version will be up / down respectively.
* If you specify TRUE / FALSE without a group then the default migration
* direction for groups without a specified version will be up / down respectively.
*
* If you're only specifying a migration version then you *must* specify a location
* If you're only specifying a migration version then you *must* specify a group
*
* --locations=location[,location2[,location3...]]
* --groups=group[,group2[,group3...]]
*
* A list of locations (under the migrations folder in the cascading
* A list of groups (under the migrations folder in the cascading
* filesystem) that will be used to source migration files. By default
* migrations will be loaded from all available locations
* migrations will be loaded from all available groups
*
* --dry-run
*
@ -57,7 +57,7 @@ class Minion_Task_Db_Migrate extends Minion_Task
*/
protected $_config = array(
'versions',
'locations',
'groups',
'dry-run',
'quiet'
);
@ -72,13 +72,13 @@ class Minion_Task_Db_Migrate extends Minion_Task
$k_config = Kohana::config('minion/migration');
// Grab user input, using sensible defaults
$specified_locations = Arr::get($config, 'locations', NULL);
$specified_groups = Arr::get($config, 'groups', NULL);
$versions = Arr::get($config, 'versions', NULL);
$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);
$groups = $this->_parse_groups($specified_groups);
$db = Database::instance();
$model = new Model_Minion_Migration($db);
@ -96,8 +96,8 @@ class Minion_Task_Db_Migrate extends Minion_Task
try
{
// Run migrations for specified locations & versions
$manager->run_migration($locations, $targets, $this->_default_direction);
// Run migrations for specified groups & versions
$manager->run_migration($groups, $targets, $this->_default_direction);
}
catch(Minion_Migration_Exception $e)
{
@ -112,39 +112,39 @@ class Minion_Task_Db_Migrate extends Minion_Task
->set('quiet', $quiet)
->set('dry_run_sql', $manager->get_dry_run_sql())
->set('executed_migrations', $manager->get_executed_migrations())
->set('location_versions', $model->fetch_current_versions());
->set('group_versions', $model->fetch_current_versions());
return $view;
}
/**
* Parses a comma delimited set of locations and returns an array of them
* Parses a comma delimited set of groups and returns an array of them
*
* @param string Comma delimited string of locations
* @param string Comma delimited string of groups
* @return array Locations
*/
protected function _parse_locations($location)
protected function _parse_groups($group)
{
if (is_array($location))
return $location;
if (is_array($group))
return $group;
$location = trim($location);
$group = trim($group);
if (empty($location))
if (empty($group))
return array();
$locations = array();
$location = explode(',', trim($location, ','));
$groups = array();
$group = explode(',', trim($group, ','));
if ( ! empty($location))
if ( ! empty($group))
{
foreach ($location as $a_location)
foreach ($group as $a_group)
{
$locations[] = trim($a_location, '/');
$groups[] = trim($a_group, '/');
}
}
return $locations;
return $groups;
}
/**
@ -156,7 +156,7 @@ class Minion_Task_Db_Migrate extends Minion_Task
*
* FALSE
*
* {location}:(TRUE|FALSE|{migration_id})
* {group}:(TRUE|FALSE|{migration_id})
*
* @param string Target version(s) specified by user
* @return array Versions
@ -179,9 +179,9 @@ class Minion_Task_Db_Migrate extends Minion_Task
if (is_array($target))
{
list($location, $version) = $target;
list($group, $version) = $target;
$targets[$location] = $version;
$targets[$group] = $version;
}
else
{

View file

@ -1,7 +1,7 @@
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Displays the current status of migrations in all locations
* Displays the current status of migrations in all groups
*
* This task takes no config options
*
@ -21,7 +21,7 @@ class Minion_Task_Db_Status extends Minion_Task {
$view = new View('minion/task/db/status');
$view->locations = $model->get_location_statuses();
$view->groups = $model->get_group_statuses();
echo $view;
}

View file

@ -59,27 +59,27 @@ class Model_Minion_Migration extends Model
}
/**
* Gets the status of all locations, whether they're in the db or not.
* Gets the status of all groups, whether they're in the db or not.
*
* @return array
*/
public function get_location_statuses()
public function get_group_statuses()
{
// Start out using all the installed locations
$locations = $this->fetch_current_versions('location', 'id');
// Start out using all the installed groups
$groups = $this->fetch_current_versions('group', 'id');
$available = $this->available_migrations();
foreach ($available as $migration)
{
if (array_key_exists($migration['id'], $locations))
if (array_key_exists($migration['id'], $groups))
{
continue;
}
$locations[$migration['location']] = NULL;
$groups[$migration['group']] = NULL;
}
return $locations;
return $groups;
}
/**
@ -109,7 +109,7 @@ class Model_Minion_Migration extends Model
*/
protected function _select()
{
return DB::select('*', DB::expr('CONCAT(`location`, ":", CAST(`timestamp` AS CHAR)) AS `id`'))->from($this->_table);
return DB::select('*', DB::expr('CONCAT(`group`, ":", CAST(`timestamp` AS CHAR)) AS `id`'))->from($this->_table);
}
/**
@ -120,8 +120,8 @@ class Model_Minion_Migration extends Model
*/
public function add_migration(array $migration)
{
DB::insert($this->_table, array('timestamp', 'location', 'description'))
->values(array($migration['timestamp'], $migration['location'], $migration['description']))
DB::insert($this->_table, array('timestamp', 'group', 'description'))
->values(array($migration['timestamp'], $migration['group'], $migration['description']))
->execute($this->_db);
return $this;
@ -133,21 +133,21 @@ class Model_Minion_Migration extends Model
* @param string Migration ID
* @return array Migration info
*/
public function get_migration($location, $timestamp = NULL)
public function get_migration($group, $timestamp = NULL)
{
if ($timestamp === NULL)
{
if (empty($location) OR strpos(':', $location) === FALSE)
if (empty($group) OR strpos(':', $group) === FALSE)
{
throw new Kohana_Exception('Invalid migration id :id', array(':id' => $location));
throw new Kohana_Exception('Invalid migration id :id', array(':id' => $group));
}
list($location, $timestamp) = explode(':', $location);
list($group, $timestamp) = explode(':', $group);
}
return $this->_select()
->where('timestamp', '=', (string) $timestamp)
->where('location', '=', (string) $location)
->where('group', '=', (string) $group)
->execute($this->_db)
->current();
}
@ -163,16 +163,16 @@ class Model_Minion_Migration extends Model
if (is_array($migration))
{
$timestamp = $migration['timestamp'];
$location = $migration['location'];
$group = $migration['group'];
}
else
{
list($timestamp, $location) = explode(':', $migration);
list($timestamp, $group) = explode(':', $migration);
}
DB::delete($this->_table)
->where('timestamp', '=', $timestamp)
->where('location', '=', $location)
->where('group', '=', $group)
->execute($this->_db);
return $this;
@ -202,7 +202,7 @@ class Model_Minion_Migration extends Model
DB::update($this->_table)
->set($set)
->where('timestamp', '=', $current['timestamp'])
->where('location', '=', $current['location'])
->where('group', '=', $current['group'])
->execute($this->_db);
}
@ -221,7 +221,7 @@ class Model_Minion_Migration extends Model
DB::update($this->_table)
->set(array('applied' => (int) $applied))
->where('timestamp', '=', $migration['timestamp'])
->where('location', '=', $migration['location'])
->where('group', '=', $migration['group'])
->execute($this->_db);
return $this;
@ -240,14 +240,14 @@ class Model_Minion_Migration extends Model
}
/**
* Fetches the latest version for all installed locations
* Fetches the latest version for all installed groups
*
* If a location does not have any applied migrations then no result will be
* If a group does not have any applied migrations then no result will be
* returned for it
*
* @return Kohana_Database_Result
*/
public function fetch_current_versions($key = 'location', $value = NULL)
public function fetch_current_versions($key = 'group', $value = NULL)
{
// Little hack needed to do an order by before a group by
return DB::select()
@ -257,176 +257,89 @@ class Model_Minion_Migration extends Model
->order_by('timestamp', 'DESC'),
'temp_table'
))
->group_by('location')
->group_by('group')
->execute($this->_db)
->as_array($key, $value);
}
/**
* Fetches a list of locations
* Fetches a list of groups
*
* @return array
*/
public function fetch_locations($location_as_key = FALSE)
public function fetch_groups($group_as_key = FALSE)
{
return DB::select()
->from($this->_table)
->group_by('location')
->group_by('group')
->execute($this->_db)
->as_array($location_as_key ? 'location' : NULL, 'location');
->as_array($group_as_key ? 'group' : NULL, 'group');
}
/**
* Fetch a list of migrations that need to be applied in order to reach the
* required version
*
* @param string Migration's location
* @param string Target migration id
* @param boolean Default direction of versionless migrations
* @param string The groups to get migrations for
* @param mixed Target version
*/
public function fetch_required_migrations($locations = NULL, $target_version = TRUE, $default_direction = TRUE)
public function fetch_required_migrations($group = NULL, $target = TRUE)
{
if ( ! empty($locations) AND ! is_array($locations))
{
$locations = array(
$locations => is_array($target_version)
? $default_direction
: $target_version
);
}
$migrations = array();
// Get an array of the latest migrations, with the location name as the
// array key
$migrations = $this->fetch_current_versions('location');
$query = $this->_select();
// The user wants to run all available migrations
if (empty($locations))
if (is_bool($target))
{
// Fetch a mirrored array of locations => locations
$locations = $this->fetch_locations(TRUE);
}
// If the calling script has been lazy and given us a numerically
// indexed array of locations then we need to convert it to a mirrored
// array
// We will decide the target version for these within the loop below
elseif ( ! Arr::is_assoc($locations))
{
foreach ($locations as $_pos => $location)
// If we want to limit this migration to certain groups
if ($group !== NULL)
{
unset($locations[$_pos]);
$locations[$location] = $location;
}
}
// Merge locations with specified target versions
if ( ! empty($target_version) AND is_array($target_version))
{
$locations = $target_version + $locations;
}
$migrations_to_apply = array();
// What follows is a bit of icky code, but there aren't many "nice" ways around it
// Basically we need to get a list of migrations that need to be performed, but
// the ordering of the migrations varies depending on whether we're wanting to
// migrate up or migrate down. As such, we can't just apply a generic "order by x"
// condition, we have to run an individual query for each location
// Again, icky, but this appears to be the only "sane" way of doing it with multiple
// locations
// If you have a better way of doing this, please let me know :)
foreach ($locations as $location => $target)
{
// By default all migrations go "up"
$migrations_to_apply[$location]['direction'] = TRUE;
$migrations_to_apply[$location]['migrations'] = array();
$query = $this->_select()->where('location', '=', $location);
// If this migration was auto-selected from the db then use the
// default migration direction
if ($target === $location)
{
$target = is_bool($target_version)
? $target_version
: (bool) $default_direction;
}
// If the user is rolling this location to either extreme up or
// extreme down
if (is_bool($target))
{
// We're "undoing" all applied migrations, i.e. rolling back
if ($target === FALSE)
if (is_array($group))
{
$migrations_to_apply[$location]['direction'] = FALSE;
$query
->where('applied', '=', 1)
->order_by('timestamp', 'DESC');
$query->where('group', 'IN', $group);
}
// We're rolling forward
else
{
$query
->where('applied', '=', 0)
->order_by('timestamp', 'ASC');
$query->where('group', '=', $group);
}
}
// Else if the user explicitly specified a target version of some kind
// If we're migrating up
if ($target === TRUE)
{
$query
->where('applied', '=', 0)
->order_by('timestamp', 'ASC');
}
// If we're migrating down
else
{
$timestamp = $target;
$current_timestamp = isset($migrations[$location])
? $migrations[$location]['timestamp']
: NULL;
// If the current version is the requested version then nothing
// needs to be done
if ($current_timestamp === $timestamp)
{
continue;
}
// If they haven't applied any migrations for this location
// yet and are justwhere wanting to apply all migrations
// (i.e. roll forward)
if ($current_timestamp === NULL)
{
$query
->and_where('timestamp', '<=', $timestamp)
->order_by('timestamp', 'ASC');
}
// If we need to move forward
elseif ($timestamp > $current_timestamp)
{
$query
->and_where('timestamp', '<=', $timestamp)
->and_where('applied', '=', 0)
->order_by('timestamp', 'ASC');
}
// If we want to roll back
elseif ($timestamp < $current_timestamp)
{
$query
->and_where('timestamp', '<', $current_timestamp)
->and_where('timestamp', '>', $timestamp)
->and_where('applied', '=', 1)
->order_by('timestamp', 'DESC');
$migrations_to_apply[$location]['direction'] = FALSE;
}
$query
->where('applied', '>', 0)
->order_by('timestamp', 'DESC');
}
}
else
{
list($target, $up) = $this->resolve_target($group, $target);
$migrations_to_apply[$location]['migrations'] = $query->execute($this->_db)->as_array();
$query->where('group', '=', $group);
unset($query);
if ($up)
{
$query
->where('timestamp', '<=', $target)
->where('applied', '=', 0)
->order_by('timestamp', 'ASC');
}
else
{
$query
->where('timestamp', '>', $target)
->order_by('timestamp', 'DESC');
}
}
return $migrations_to_apply;
return $query->execute($this->_db)->as_array();
}
}

View file

@ -2,8 +2,8 @@
return array(
// A mapping of location_connections => db_connection to use
'location_connection' => array(
// A mapping of group_connections => db_connection to use
'group_connection' => array(
),
);

View file

@ -1,8 +1,8 @@
CREATE TABLE `minion_migrations` (
`timestamp` varchar(14) NOT NULL,
`description` varchar(100) NOT NULL,
`location` varchar(100) NOT NULL,
`group` varchar(100) NOT NULL,
`applied` tinyint(1) DEFAULT '0',
PRIMARY KEY (`timestamp`,`location`),
PRIMARY KEY (`timestamp`,`group`),
UNIQUE KEY `MIGRATION_ID` (`timestamp`,`description`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<test_minion_migrations timestamp="20101215164400" description="create-tables" location="app" applied="1" />
<test_minion_migrations timestamp="20101215165000" description="add-name-column-to-members" location="app" applied="0" />
<test_minion_migrations timestamp="20101216000000" description="add-index-on-name" location="app" applied="0" />
<test_minion_migrations timestamp="20101216080000" description="remove-password-salt-column" location="app" applied="1" />
<test_minion_migrations timestamp="20101215164400" description="create-tables" group="app" applied="1" />
<test_minion_migrations timestamp="20101215165000" description="add-name-column-to-members" group="app" applied="0" />
<test_minion_migrations timestamp="20101216000000" description="add-index-on-name" group="app" applied="0" />
<test_minion_migrations timestamp="20101216080000" description="remove-password-salt-column" group="app" applied="1" />
<test_minion_migrations timestamp="20101215164500" description="create-table" location="dblogger" applied="1" />
<test_minion_migrations timestamp="20101225000000" description="remove-unique-index" location="dblogger" applied="1" />
<test_minion_migrations timestamp="20101226112100" description="add-pk" location="dblogger" applied="0" />
<test_minion_migrations timestamp="20101215164500" description="create-table" group="dblogger" applied="1" />
<test_minion_migrations timestamp="20101225000000" description="remove-unique-index" group="dblogger" applied="1" />
<test_minion_migrations timestamp="20101226112100" description="add-pk" group="dblogger" applied="0" />
</dataset>

View file

@ -39,7 +39,7 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
public function getDataSet()
{
return $this->createFlatXMLDataSet(
Kohana::find_file('tests/test_data', 'minion/migration/model', 'xml')
Kohana::find_file('tests/datasets', 'minion/migration/model', 'xml')
);
}
@ -78,7 +78,7 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
public function test_fetch_current_versions()
{
$versions = $this->getModel()
->fetch_current_versions('location', 'timestamp');
->fetch_current_versions('group', 'timestamp');
$this->assertSame(
array (
@ -89,120 +89,6 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
);
}
/**
* Provides test data for test_fetch_required_migrations
*
* @return array Test data
*/
public function provider_fetch_required_migrations()
{
return array(
// Test a call with no params (i.e. upgrade everything to latest)
array(
array (
'app' => array(
'direction' => true,
'migrations' => array(
array (
'timestamp' => '20101215165000',
'description' => 'add-name-column-to-members',
'location' => 'app',
'applied' => '0',
'id' => 'app:20101215165000'
),
array (
'timestamp' => '20101216000000',
'description' => 'add-index-on-name',
'location' => 'app',
'applied' => '0',
'id' => 'app:20101216000000'
),
),
),
'dblogger' => array(
'direction' => true,
'migrations' => array(
array (
'timestamp' => '20101226112100',
'description' => 'add-pk',
'location' => 'dblogger',
'applied' => '0',
'id' => 'dblogger:20101226112100'
),
),
),
),
NULL,
TRUE,
TRUE
),
array(
array(
'app' => array(
'direction' => FALSE,
'migrations' => array(
array(
'timestamp' => '20101216080000',
'description' => 'remove-password-salt-column',
'location' => 'app',
'applied' => '1',
'id' => 'app:20101216080000'
),
array(
'timestamp' => '20101215164400',
'description' => 'create-tables',
'location' => 'app',
'applied' => '1',
'id' => 'app:20101215164400'
),
)
),
'dblogger' => array(
'direction' => FALSE,
'migrations' => array(
array(
'timestamp' => '20101225000000',
'description' => 'remove-unique-index',
'location' => 'dblogger',
'applied' => '1',
'id' => 'dblogger:20101225000000'
),
array(
'timestamp' => '20101215164500',
'description' => 'create-table',
'location' => 'dblogger',
'applied' => '1',
'id' => 'dblogger:20101215164500'
),
)
),
),
NULL,
FALSE,
TRUE
),
);
}
/**
* Tests that fetch_required_migrations() produces an accurate list of
* migrations that need applying.
*
* @test
* @covers Model_Minion_Migration::fetch_required_migrations
* @dataProvider provider_fetch_required_migrations
* @param array Expected output
* @param NULL|string|array Input Locations
* @param bool|string|array Input Target
* @param bool Input default direction
*/
public function test_fetch_required_migrations($expected, $locations, $target, $default_direction)
{
$results = $this->getModel()
->fetch_required_migrations($locations, $target, $default_direction);
$this->assertSame($expected, $results);
}
/**
* Provides test data for test_get_migration
@ -216,7 +102,7 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
array(
'timestamp' => '20101215164400',
'description' => 'create-tables',
'location' => 'app',
'group' => 'app',
'applied' => '1',
'id' => 'app:20101215164400'
),
@ -234,14 +120,14 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
* @covers Model_Minion_Migration::get_migration
* @dataProvider provider_get_migration
* @param array Expected migration
* @param string The migration's location
* @param string The migration's group
* @param string The migration's timestamp
*/
public function test_get_migration($expected, $location, $timestamp)
public function test_get_migration($expected, $group, $timestamp)
{
$this->assertSame(
$expected,
$this->getModel()->get_migration($location, $timestamp)
$this->getModel()->get_migration($group, $timestamp)
);
}
@ -267,9 +153,9 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
* @dataProvider provider_get_migration_throws_exception_on_invalid_input
* @expectedException Kohana_Exception
*/
public function test_get_migration_throws_exception_on_invalid_input($location, $timestamp)
public function test_get_migration_throws_exception_on_invalid_input($group, $timestamp)
{
$this->getModel()->get_migration($location, $timestamp);
$this->getModel()->get_migration($group, $timestamp);
}
/**
@ -284,13 +170,13 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
array(
'timestamp' => '20101215165000',
'description' => 'add-name-column-to-members',
'location' => 'app',
'group' => 'app',
'applied' => '1',
'id' => 'app:20101215165000',
),
array(
'timestamp' => '20101215165000',
'location' => 'app',
'group' => 'app',
'description' => 'add-name-column-to-members',
),
TRUE
@ -299,13 +185,13 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
array(
'timestamp' => '20101215165000',
'description' => 'add-name-column-to-members',
'location' => 'app',
'group' => 'app',
'applied' => '0',
'id' => 'app:20101215165000',
),
array(
'timestamp' => '20101215165000',
'location' => 'app',
'group' => 'app',
'description' => 'add-name-column-to-members',
),
FALSE
@ -332,7 +218,7 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase
$this->assertSame(
$expected,
$model->get_migration($migration['location'], $migration['timestamp'])
$model->get_migration($migration['group'], $migration['timestamp'])
);
}
}

View file

@ -19,15 +19,15 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase {
return array(
array(
array(
'myapp:015151051' => array('location' => 'myapp', 'description' => 'setup', 'timestamp' => '015151051', 'id' => 'myapp:015151051'),
'myapp:015161051' => array('location' => 'myapp', 'description' => 'add-comments', 'timestamp' => '015161051', 'id' => 'myapp:015161051'),
'myapp:015151051' => array('group' => 'myapp', 'description' => 'setup', 'timestamp' => '015151051', 'id' => 'myapp:015151051'),
'myapp:015161051' => array('group' => 'myapp', 'description' => 'add-comments', 'timestamp' => '015161051', 'id' => 'myapp:015161051'),
),
array(
'migrations/myapp' => array(
'migrations/myapp/015151051_setup.php'
=> '/var/www/app/locations/myapp/migrations/myapp/015151051_setup.php',
=> '/var/www/app/groups/myapp/migrations/myapp/015151051_setup.php',
'migrations/myapp/015161051_add-comments.php'
=> '/var/www/app/locations/myapp/migrations/myapp/015161051_add-comments.php',
=> '/var/www/app/groups/myapp/migrations/myapp/015161051_add-comments.php',
),
)
),
@ -62,7 +62,7 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase {
return array(
array(
array(
'location' => 'myapp',
'group' => 'myapp',
'description' => 'initial-setup',
'timestamp' => '1293214439',
'id' => 'myapp:1293214439',
@ -101,7 +101,7 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase {
array(
'myapp/1293214439_initial-setup.php',
array(
'location' => 'myapp',
'group' => 'myapp',
'timestamp' => '1293214439',
'description' => 'initial-setup',
'id' => 'myapp:1293214439'
@ -120,13 +120,13 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase {
* @dataProvider provider_get_filename_from_migration
* @param string Expected output
* @param mixed Migration id
* @param mixed location
* @param mixed group
*/
public function test_get_filename_from_migration($expected, $migration, $location)
public function test_get_filename_from_migration($expected, $migration, $group)
{
$this->assertSame(
$expected,
Minion_Migration_Util::get_filename_from_migration($migration, $location)
Minion_Migration_Util::get_filename_from_migration($migration, $group)
);
}
@ -144,7 +144,7 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase {
),
array(
'Migration_Kohana_201012290258',
array('location' => 'kohana', 'timestamp' => '201012290258'),
array('group' => 'kohana', 'timestamp' => '201012290258'),
),
);
}

View file

@ -1,21 +1,21 @@
<?php if( ! $quiet): ?>
Executed <?php echo count($executed_migrations); ?> migrations
Current versions of locations:
<?php foreach($location_versions as $location): ?>
* <?php echo $location['location'] ?> : <?php echo $location['timestamp'] ?> (<?php echo $location['description']; ?>)
Current versions of groups:
<?php foreach($group_versions as $group): ?>
* <?php echo $group['group'] ?> : <?php echo $group['timestamp'] ?> (<?php echo $group['description']; ?>)
<?php endforeach; ?>
<?php if($dry_run): ?>
This was a dry run, if it was a real run the following SQL would've been executed:
<?php endif; ?>
<?php endif; ?>
<?php foreach($dry_run_sql as $location => $migrations): ?>
<?php foreach($dry_run_sql as $group => $migrations): ?>
<?php $location_padding = str_repeat('#', strlen($location)); ?>
##################<?php echo $location_padding ?>##
# Begin Location: <?php echo $location; ?> #
##################<?php echo $location_padding ?>##
<?php $group_padding = str_repeat('#', strlen($group)); ?>
##################<?php echo $group_padding ?>##
# Begin Location: <?php echo $group; ?> #
##################<?php echo $group_padding ?>##
<?php foreach($migrations as $timestamp => $sql): ?>
# Begin <?php echo $timestamp; ?>
@ -29,8 +29,8 @@ This was a dry run, if it was a real run the following SQL would've been execute
<?php endforeach; ?>
################<?php echo $location_padding ?>##
# End Location: <?php echo $location; ?> #
################<?php echo $location_padding ?>##
################<?php echo $group_padding ?>##
# End Location: <?php echo $group; ?> #
################<?php echo $group_padding ?>##
<?php endforeach; ?>

View file

@ -1,4 +1,4 @@
<?php foreach($locations as $location => $status): ?>
* <?php echo $location ?> <?php echo ($status !== NULL ? $status : 'Not installed'); ?>
<?php foreach($groups as $group => $status): ?>
* <?php echo $group ?> <?php echo ($status !== NULL ? $status : 'Not installed'); ?>
<?php endforeach; ?>