diff --git a/classes/minion/migration/util.php b/classes/minion/migration/util.php index e8930df..ed86f2f 100644 --- a/classes/minion/migration/util.php +++ b/classes/minion/migration/util.php @@ -30,10 +30,7 @@ class Minion_Migration_Util { { $migration = Minion_Migration_Util::get_migration_from_filename($file); - $migrations[$migration['id']] = array( - 'file' => $file, - 'location' => $migration['location'] - ); + $migrations[$migration['location'].':'.$migration['timestamp']] = $migration; } } @@ -46,11 +43,10 @@ class Minion_Migration_Util { * Returns an array like: * * array( - * 'location' => 'mylocation', - * 'id' => '1293214439_initial-setup', - * 'file' => 'migrations/mylocation/1293214439_initial-setup.php', + * 'location' => 'mylocation', * 'timestamp' => '1293214439', * 'description' => 'initial-setup', + * 'id' => 'mylocation:1293214439' * ); * * @param string The migration's filename @@ -64,11 +60,11 @@ class Minion_Migration_Util { // the filename itself. The "location" is essentially a slash delimited // path from the migrations folder to the migration file $migration['location'] = dirname(substr($file, 11, -strlen(EXT))); - $migration['id'] = basename($file, EXT); - $migration['file'] = $file; list($migration['timestamp'], $migration['description']) - = explode('_', $migration['id'], 2); + = explode('_', basename($file, EXT), 2); + + $migration['id'] = $migration['location'].':'.$migration['timestamp']; return $migration; } @@ -80,16 +76,34 @@ class Minion_Migration_Util { * @param string The migration location * @return string Path to the migration file */ - public static function get_filename_from_migration($migration, $location) + public static function get_filename_from_migration(array $migration) { - if(is_array($migration)) - { - $location = $migration['location']; - $migration = $migration['id']; - } + $location = $migration['location']; + $migration = $migration['timestamp'].'_'.$migration['description']; $location = ! empty($location) ? rtrim($location, '/').'/' : ''; return $location.$migration.EXT; } + + /** + * Allows you to work out the class name from either an array of migration + * info, or from a migration id + * + * @param string|array The migration's ID or array of migration data + * @return string The migration class name + */ + public static function get_class_from_migration($migration) + { + if(is_string($migration)) + { + $migration = str_replace(array(':', '/'), ' ', $migration); + } + else + { + $migration = str_replace('/', ' ', $migration['location']).'_'.$migration['timestamp']; + } + + return 'Migration_'.str_replace(' ', '_', ucwords($migration)); + } } diff --git a/classes/minion/task/db/migrate.php b/classes/minion/task/db/migrate.php index 856a770..c3a96b2 100644 --- a/classes/minion/task/db/migrate.php +++ b/classes/minion/task/db/migrate.php @@ -18,14 +18,16 @@ * is used to specify the target version of an individual location. Version * specifies the target version, which can be either: * - * * A migration id (migrates up/down to that version) + * * A migration version (migrates up/down to that version) * * TRUE (runs all migrations to get to the latest version) * * FALSE (undoes all appled migrations) * - * An example of a migration ID is 1293506456_add-index-to-orders + * 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 + * direction for locations without a specified version will be up / down respectively. + * + * If you're only specifying a migration version then you *must* specify a location * * --locations=location[,location2[,location3...]] * @@ -176,5 +178,4 @@ class Minion_Task_Db_Migrate extends Minion_Task throw new Kohana_Exception('Invalid target version :version', array(':version' => $version)); } - } diff --git a/classes/model/minion/migration.php b/classes/model/minion/migration.php index 18fecec..e78ff03 100644 --- a/classes/model/minion/migration.php +++ b/classes/model/minion/migration.php @@ -37,7 +37,7 @@ class Model_Minion_Migration extends Model */ protected function _select() { - return DB::select('*', DB::expr('CONCAT(CAST(`timestamp` AS CHAR), "_", `description`) AS `id`'))->from($this->_table); + return DB::select('*', DB::expr('CONCAT(`location`, ":", CAST(`timestamp` AS CHAR)) AS `id`'))->from($this->_table); } /** @@ -167,10 +167,8 @@ class Model_Minion_Migration extends Model // Else if the user explicitly specified a target version of some kind else { - list($timestamp, $description) = explode('_', $target, 2); - - $current_timestamp = - isset($migrations[$location]) + $timestamp = $target; + $current_timestamp = isset($migrations[$location]) ? $migrations[$location]['timestamp'] : NULL; diff --git a/tests/minion/migration/model.php b/tests/minion/migration/model.php index 71e0c35..bd0619c 100644 --- a/tests/minion/migration/model.php +++ b/tests/minion/migration/model.php @@ -54,12 +54,12 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase public function test_fetch_current_versions() { $versions = $this->getModel() - ->fetch_current_versions('location', 'id'); + ->fetch_current_versions('location', 'timestamp'); $this->assertSame( array ( - 'app' => '1293543858_remove-password-salt-column', - 'dblogger' => '1293544858_remove-unique-index', + 'app' => '1293543858', + 'dblogger' => '1293544858', ), $versions ); @@ -80,18 +80,18 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase 'direction' => true, 'migrations' => array( array ( - 'timestamp' => '1293543800', + 'timestamp' => '1293543800', 'description' => 'add-name-column-to-members', - 'location' => 'app', - 'applied' => '0', - 'id' => '1293543800_add-name-column-to-members', + 'location' => 'app', + 'applied' => '0', + 'id' => 'app:1293543800' ), array ( - 'timestamp' => '1293543828', + 'timestamp' => '1293543828', 'description' => 'add-index-on-name', - 'location' => 'app', - 'applied' => '0', - 'id' => '1293543828_add-index-on-name', + 'location' => 'app', + 'applied' => '0', + 'id' => 'app:1293543828' ), ), ), @@ -99,11 +99,11 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase 'direction' => true, 'migrations' => array( array ( - 'timestamp' => '1293544908', + 'timestamp' => '1293544908', 'description' => 'add-pk', - 'location' => 'dblogger', - 'applied' => '0', - 'id' => '1293544908_add-pk', + 'location' => 'dblogger', + 'applied' => '0', + 'id' => 'dblogger:1293544908' ), ), ), @@ -122,14 +122,14 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase 'description' => 'remove-password-salt-column', 'location' => 'app', 'applied' => '1', - 'id' => '1293543858_remove-password-salt-column' + 'id' => 'app:1293543858' ), array( 'timestamp' => '1293543728', 'description' => 'create-tables', 'location' => 'app', 'applied' => '1', - 'id' => '1293543728_create-tables', + 'id' => 'app:1293543728' ), ) ), @@ -141,14 +141,14 @@ class Minion_Migration_ModelTest extends Kohana_Unittest_Database_TestCase 'description' => 'remove-unique-index', 'location' => 'dblogger', 'applied' => '1', - 'id' => '1293544858_remove-unique-index', + 'id' => 'dblogger:1293544858' ), array( 'timestamp' => '1293543858', 'description' => 'create-table', 'location' => 'dblogger', 'applied' => '1', - 'id' => '1293543858_create-table', + 'id' => 'dblogger:1293543858' ), ) ), diff --git a/tests/minion/migration/util.php b/tests/minion/migration/util.php index 6598764..bff6f78 100644 --- a/tests/minion/migration/util.php +++ b/tests/minion/migration/util.php @@ -17,8 +17,8 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase { return array( array( array( - '015151051_setup' => array('file' => 'migrations/myapp/015151051_setup.php', 'location' => 'myapp'), - '015161051_add-comments' => array('file' => 'migrations/myapp/015161051_add-comments.php', 'location' => 'myapp'), + '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'), ), array( 'migrations/myapp' => array( @@ -60,9 +60,7 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase { return array( array( array( - 'location' => 'myapp', - 'id' => '1293214439_initial-setup', - 'file' => 'migrations/myapp/1293214439_initial-setup.php', + 'location' => 'myapp', 'description' => 'initial-setup', 'timestamp' => '1293214439', ), @@ -99,7 +97,12 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase { return array( array( 'myapp/1293214439_initial-setup.php', - '1293214439_initial-setup', + array( + 'location' => 'myapp', + 'timestamp' => '1293214439', + 'description' => 'initial-setup', + 'id' => 'myapp:1293214439' + ), 'myapp', ), ); @@ -111,7 +114,7 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase { * * @test * @covers Minion_Migration_Util::convert_migration_to_filename - * @dataProvider provider_convert_migration_to_filename + * @dataProvider provider_get_filename_from_migration * @param string Expected output * @param mixed Migration id * @param mixed location @@ -123,4 +126,41 @@ class Minion_Migration_UtilTest extends Kohana_Unittest_TestCase { Minion_Migration_Util::get_filename_from_migration($migration, $location) ); } + + /** + * Provides test data for test_get_class_from_migration + * + * @return array Test Data + */ + public function provider_get_class_from_migration() + { + return array( + array( + 'Migration_Kohana_201012290258', + 'kohana:201012290258', + ), + array( + 'Migration_Kohana_201012290258', + array('location' => 'kohana', 'timestamp' => '201012290258'), + ), + ); + } + + /** + * Tests that Minion_Migration_Util::get_class_from_migration can generate + * a class name from information about a migration + * + * @test + * @covers Minion_Migration_Util::get_class_from_migration + * @dataProvider provider_get_class_from_migration + * @param string Expected output + * @param string|array Migration info + */ + public function test_get_class_from_migration($expected, $migration) + { + $this->assertSame( + $expected, + Minion_Migration_Util::get_class_from_migration($migration) + ); + } }