1
0
mirror of synced 2025-01-30 12:01:44 +03:00

Changes to migration.

This commit is contained in:
Jonathan.Wage 2007-09-20 20:24:38 +00:00
parent be5eb98ebf
commit d4e3567ab9
6 changed files with 147 additions and 142 deletions

View File

@ -43,7 +43,72 @@ class Doctrine_Migration
'added_indexes' => array(), 'added_indexes' => array(),
'removed_indexes' => array()); 'removed_indexes' => array());
static public function setCurrentVersion($number) public $migrationTableName = 'migration_version';
public $migrationClassesDirectory = array();
public $migrationClasses = array();
public function __construct($directory = null)
{
if ($directory != null) {
$this->migrationClassesDirectory = $directory;
$this->loadMigrationClasses();
}
}
protected function loadMigrationClasses()
{
$directory = $this->migrationClassesDirectory;
$classes = get_declared_classes();
if ($directory !== null) {
foreach ((array) $directory as $dir) {
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($it as $file) {
$e = explode('.', $file->getFileName());
if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
require_once $file->getPathName();
$requiredClass = array_diff(get_declared_classes(), $classes);
$requiredClass = end($requiredClass);
$loadedClasses[$requiredClass] = $file->getFileName();
}
}
}
}
$classes = $loadedClasses;
$parent = new ReflectionClass('Doctrine_Migration');
$loadedClasses = array();
foreach ($classes as $name => $fileName) {
$class = new ReflectionClass($name);
while ($class->isSubclassOf($parent)) {
$class = $class->getParentClass();
if ($class === false) {
break;
}
}
if ($class === false) {
continue;
}
$loadedClasses[$name] = $fileName;
}
$this->migrationClasses = $loadedClasses;
return $loadedClasses;
}
public function setCurrentVersion($number)
{ {
$conn = Doctrine_Manager::connection(); $conn = Doctrine_Manager::connection();
@ -62,7 +127,7 @@ class Doctrine_Migration
} }
} }
static public function getCurrentVersion() public function getCurrentVersion()
{ {
$conn = Doctrine_Manager::connection(); $conn = Doctrine_Manager::connection();
@ -71,93 +136,50 @@ class Doctrine_Migration
return isset($result[0]) ? $result[0]:false; return isset($result[0]) ? $result[0]:false;
} }
static public function migration($from, $to) public function migrate($from, $to)
{ {
if ($from === $to || $from === 0) { if ($from === $to) {
throw new Doctrine_Migration_Exception('You specified an invalid migration path. The from and to cannot be the same and from cannot be zero.'); throw new Doctrine_Migration_Exception('You specified an invalid migration path. The from and to cannot be the same.');
} }
$direction = $from > $to ? 'down':'up'; $direction = $from > $to ? 'down':'up';
if ($direction === 'up') { if ($direction === 'up') {
for ($i = $from + 1; $i <= $to; $i++) { for ($i = $from + 1; $i <= $to; $i++) {
self::doDirectionStep($direction, $i); $this->doMigrateStep($direction, $i);
} }
} else { } else {
for ($i = $from; $i > $to; $i--) { for ($i = $from; $i > $to; $i--) {
self::doDirectionStep($direction, $i); $this->doMigrateStep($direction, $i);
} }
} }
self::setCurrentVersion($to); $this->setCurrentVersion($to);
} }
public static function doDirectionStep($direction, $num) protected function getMigrationClass($num)
{ {
$className = 'Migration' . $num; $classes = $this->migrationClasses;
if (class_exists($className)) { foreach ($classes as $className => $fileName) {
$migrate = new $className(); $e = explode('_', $fileName);
$migrate->migrate($direction); $classMigrationNum = (int) $e[0];
} else {
throw new Doctrine_Migration_Exception('Could not find migration class: ' . $className); if ($classMigrationNum === $num) {
return new $className();
} }
} }
public static function loadMigrationClasses($directory) throw new Doctrine_Migration_Exception('Could not find migration class for migration step: '.$num);
}
public function doMigrateStep($direction, $num)
{ {
$classes = get_declared_classes(); $migrate = $this->getMigrationClass($num);
$migrate->doMigrate($direction);
if ($directory !== null) {
foreach ((array) $directory as $dir) {
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
RecursiveIteratorIterator::LEAVES_ONLY);
foreach ($it as $file) {
$e = explode('.', $file->getFileName());
if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
require_once $file->getPathName();
}
}
} }
$classes = array_diff(get_declared_classes(), $classes); public function doMigrate($direction)
}
return self::getLoadedMigrationClasses($classes);
}
public static function getLoadedMigrationClasses($classes = null)
{
if ($classes === null) {
$classes = get_declared_classes();
}
$parent = new ReflectionClass('Doctrine_Migration');
$loadedClasses = array();
foreach ($classes as $name) {
$class = new ReflectionClass($name);
while ($class->isSubclassOf($parent)) {
$class = $class->getParentClass();
if ($class === false) {
break;
}
}
if ($class === false) {
continue;
}
$loadedClasses[] = $name;
}
return $loadedClasses;
}
public function migrate($direction)
{ {
if (method_exists($this, $direction)) { if (method_exists($this, $direction)) {
$this->$direction(); $this->$direction();

View File

@ -2,18 +2,11 @@ The Doctrine Migration tools allow you to migrate databases and it issues alter
++ Writing Migration Classes ++ Writing Migration Classes
Migration classes consist of a simple class that extends from Doctrine_Migration. You can define a public up() and down() method that is meant for doing and undoing changes to a database for that migration step. Migration classes consist of a simple class that extends from Doctrine_Migration. You can define a public up() and down() method that is meant for doing and undoing changes to a database for that migration step. The class name is completely arbitrary, but the name of the file which contains the class must have a prefix containing the number it represents in the migration process. Example: XXX_representative_name.class.php
<code type="php"> <code type="php">
class MigrationTest extends Doctrine_Record // 001_add_table.class.php
{ class AddTable extends Doctrine_Migration
public function setTableDefinition()
{
$this->hasColumn('field1', 'string');
}
}
class Migration2 extends Doctrine_Migration
{ {
public function up() public function up()
{ {
@ -26,7 +19,8 @@ class Migration2 extends Doctrine_Migration
} }
} }
class Migration3 extends Doctrine_Migration // 002_add_column.class.php
class AddColumn extends Doctrine_Migration
{ {
public function up() public function up()
{ {
@ -39,7 +33,8 @@ class Migration3 extends Doctrine_Migration
} }
} }
class Migration4 extends Doctrine_Migration // 003_change_column.class.php
class ChangeColumn extends Doctrine_Migration
{ {
public function up() public function up()
{ {
@ -74,7 +69,8 @@ public function removeIndex($tableName, $indexName)
You can alter table directly in your up() and down() methods like you normally would by creating new model instances and calling save() or creating queries and deleting data. You can alter table directly in your up() and down() methods like you normally would by creating new model instances and calling save() or creating queries and deleting data.
<code type="php"> <code type="php">
class Migration1 extends Doctrine_Migration // XXX_add_user.class.php
class AddUser extends Doctrine_Migration
{ {
public function up() public function up()
{ {
@ -97,16 +93,15 @@ class Migration1 extends Doctrine_Migration
++ Performing Migrations ++ Performing Migrations
<code type="php"> <code type="php">
// Upgrade one at a time $migration = new Doctrine_Migration('migration_classes');
Doctrine_Migration::migration(1, 2); $migration->migrate(0, 1);
Doctrine_Migration::migration(2, 3); $migration->migrate(1, 2);
Doctrine_Migration::migration(3, 4); $migration->migrate(2, 3);
// Then revert back to version 1 // Then revert back to version 1
Doctrine_Migration::migration(4, 1); $migration->migrate(3, 2);
$migration->migrate(2, 1);
$migration->migrate(1, 0);
// One big upgrade echo $migration->getCurrentVersion(); // should echo 0
Doctrine_Migration::migration(1, 4);
echo Doctrine_Migration::getCurrentVersion(); // should echo 4
</code> </code>

8
models/MigrationTest.php Normal file
View File

@ -0,0 +1,8 @@
<?php
class MigrationTest extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('field1', 'string');
}
}

View File

@ -35,61 +35,15 @@ class Doctrine_Migration_TestCase extends Doctrine_UnitTestCase
public function testMigration() public function testMigration()
{ {
// Upgrade one at a time // Upgrade one at a time
Doctrine_Migration::migration(1, 2); $migration = new Doctrine_Migration('migration_classes');
Doctrine_Migration::migration(2, 3); $migration->migrate(0, 1);
Doctrine_Migration::migration(3, 4); $migration->migrate(1, 2);
// Then revert back to version 1 // Then revert back to version 1
Doctrine_Migration::migration(4, 1); $migration->migrate(2, 1);
$migration->migrate(1, 0);
// Check to make sure the current version is 1 // Check to make sure the current version is 0
$this->assertEqual(Doctrine_Migration::getCurrentVersion(), 1); $this->assertEqual($migration->getCurrentVersion(), 0);
}
}
class MigrationTest extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('field1', 'string');
}
}
class Migration2 extends Doctrine_Migration
{
public function up()
{
$this->createTable('migration_test', array('field1' => array('type' => 'string')));
}
public function down()
{
$this->dropTable('migration_test');
}
}
class Migration3 extends Doctrine_Migration
{
public function up()
{
$this->addColumn('migration_test', 'field1', 'string');
}
public function down()
{
$this->renameColumn('migration_test', 'field1', 'field2');
}
}
class Migration4 extends Doctrine_Migration
{
public function up()
{
$this->changeColumn('migration_test', 'field1', 'integer');
}
public function down()
{
$this->changeColumn('migration_test', 'field1', 'string');
} }
} }

View File

@ -0,0 +1,13 @@
<?php
class AddTable extends Doctrine_Migration
{
public function up()
{
$this->createTable('migration_test', array('field1' => array('type' => 'string')));
}
public function down()
{
$this->dropTable('migration_test');
}
}

View File

@ -0,0 +1,13 @@
<?php
class ChangeColumn extends Doctrine_Migration
{
public function up()
{
$this->changeColumn('migration_test', 'field1', 'integer');
}
public function down()
{
$this->changeColumn('migration_test', 'field1', 'string');
}
}