Created
March 22, 2011 11:25
-
-
Save ludofleury/881081 to your computer and use it in GitHub Desktop.
Custom migrations using schema.yml revision.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class sdzDoctrineGenerateMigrationsDiffTask extends sfDoctrineBaseTask | |
{ | |
/** | |
* @see sfTask | |
*/ | |
protected function configure() | |
{ | |
$this->addOptions(array( | |
new sfCommandOption('application', null, sfCommandOption::PARAMETER_OPTIONAL, 'The application name', true), | |
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'), | |
)); | |
$this->namespace = 'sdz'; | |
$this->name = 'generate-migrations-diff'; | |
$this->briefDescription = 'Generate migration classes by producing a diff between your old and new schema.'; | |
$this->detailedDescription = <<<EOF | |
The [doctrine:generate-migrations-diff|INFO] task generates migration classes by | |
producing a diff between your old and new schema. | |
[./symfony doctrine:generate-migrations-diff|INFO] | |
EOF; | |
} | |
/** | |
* @see sfTask | |
*/ | |
protected function execute($arguments = array(), $options = array()) | |
{ | |
$databaseManager = new sfDatabaseManager($this->configuration); | |
$config = $this->getCliConfig(); | |
$this->logSection('doctrine', 'generating migration diff'); | |
if (!is_dir($config['migrations_path'])) | |
{ | |
$this->getFilesystem()->mkdirs($config['migrations_path']); | |
} | |
spl_autoload_register(array('Doctrine_Core', 'modelsAutoload')); | |
$schemaFileHistory = sfFinder::type('file')->name('*.yml')->sort_by_name()->follow_link()->in($config['migrations_path'].'/schema'); | |
if(empty($schemaFileHistory)) | |
{ | |
$this->logSection('sdz','Empty migration schema repository'); | |
$initFile = $this->prepareSchemaFile($config['yaml_schema_path']); | |
$this->commitSchemaFile($initFile, 0); | |
$this->logSection('sdz','Initialized migration schema repository'); | |
} | |
else | |
{ | |
$lastestVersion = end($schemaFileHistory); | |
$actualVersion = $this->prepareSchemaFile($config['yaml_schema_path']); | |
try | |
{ | |
$from = $lastestVersion; | |
$to = $actualVersion; | |
$migration = new Doctrine_Migration($config['migrations_path']); | |
$diff = new Doctrine_Migration_Diff($from, $to, $migration); | |
$changes = $diff->generateMigrationClasses(); | |
$numChanges = count($changes, true) - count($changes); | |
if ( ! $numChanges) | |
{ | |
throw new Doctrine_Task_Exception('Could not generate migration classes from difference (seems to be up-to-date)'); | |
} | |
else | |
{ | |
$this->logSection('sdz', 'Generated migration classes successfully from difference '.'('.$numChanges.')'); | |
} | |
$versions = sfFinder::type('file')->name('*.php')->sort_by_name()->follow_link()->in($config['migrations_path']); | |
$this->commitSchemaFile($actualVersion,count($versions)); | |
$this->logSection('sdz', 'Processed migration generation successfully'); | |
} | |
catch(Exception $e) | |
{ | |
throw $e; | |
} | |
} | |
} | |
/** | |
* | |
* @param string $file | |
* @param int $id | |
*/ | |
protected function commitSchemaFile($file, $id) | |
{ | |
$config = $this->getCliConfig(); | |
$this->logSection('file+', $file); | |
$commitPath = $config['migrations_path'].'/schema/'; | |
$commitFileName = ($id > 0 ? 'version'.$id.'.yml' : 'version0.yml'); | |
if(file_exists($commitPath.$commitFileName)) | |
{ | |
throw new Exception ('Unbable to commit : invalid id'); | |
} | |
$this->getFilesystem()->copy($file,$commitPath.$commitFileName); | |
if(!file_exists($commitPath.$commitFileName)) | |
{ | |
throw new Exception ('Unable to commit schema'); | |
} | |
$this->logSection('sdz', 'Schema '.$commitFileName.' versionned'); | |
} | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class sdzDoctrineMigrateTask extends sfDoctrineBaseTask | |
{ | |
/** | |
* @see sfTask | |
*/ | |
protected function configure() | |
{ | |
$this->addArguments(array( | |
new sfCommandArgument('version', sfCommandArgument::OPTIONAL, 'The version to migrate to'), | |
)); | |
$this->addOptions(array( | |
new sfCommandOption('application', null, sfCommandOption::PARAMETER_OPTIONAL, 'The application name', true), | |
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'), | |
new sfCommandOption('up', null, sfCommandOption::PARAMETER_NONE, 'Migrate up one version'), | |
new sfCommandOption('down', null, sfCommandOption::PARAMETER_NONE, 'Migrate down one version'), | |
new sfCommandOption('dry-run', null, sfCommandOption::PARAMETER_NONE, 'Do not persist migrations'), | |
)); | |
$this->namespace = 'sdz'; | |
$this->name = 'migrate'; | |
$this->briefDescription = 'Migrates database to current/specified version'; | |
$this->detailedDescription = <<<EOF | |
The [doctrine:migrate|INFO] task migrates the database: | |
[./symfony doctrine:migrate|INFO] | |
Provide a version argument to migrate to a specific version: | |
[./symfony doctrine:migrate 10|INFO] | |
To migration up or down one migration, use the [--up|COMMENT] or [--down|COMMENT] options: | |
[./symfony doctrine:migrate --down|INFO] | |
If your database supports rolling back DDL statements, you can run migrations | |
in dry-run mode using the [--dry-run|COMMENT] option: | |
[./symfony doctrine:migrate --dry-run|INFO] | |
EOF; | |
} | |
/** | |
* @see sfTask | |
*/ | |
protected function execute($arguments = array(), $options = array()) | |
{ | |
$config = $this->getCliConfig(); | |
$reposiroty = sfFinder::type('file')->name('*.yml')->sort_by_name()->follow_link()->in($config['migrations_path'].'/schema'); | |
if(empty($reposiroty)) | |
{ | |
$this->logSection('sdz','Empty migration repository : initializing migrations'); | |
$task = new sdzDoctrineGenerateMigrationsDiffTask($this->dispatcher, $this->formatter); | |
$task->setCommandApplication($this->commandApplication); | |
$task->setConfiguration($this->configuration); | |
$ret = $task->run(); | |
} | |
else | |
{ | |
$databaseManager = new sfDatabaseManager($this->configuration); | |
$migration = new Doctrine_Migration($config['migrations_path']); | |
$from = $version = $migration->getCurrentVersion(); | |
foreach($reposiroty as $stableVersion) | |
{ | |
$stableVersions[] = str_replace(array($config['migrations_path'].'/schema/version','.yml'),'',$stableVersion); | |
} | |
$currentVersionIndex = array_search($from,$stableVersions); | |
# is_numeric still not safe for handy/debug reasons | |
if (is_numeric($arguments['version'])) | |
{ | |
$version = $arguments['version']; | |
} | |
else if ($options['up']) | |
{ | |
if($currentVersionIndex < count($stableVersions)) | |
{ | |
$version = $stableVersions[$currentVersionIndex+1]; | |
} | |
} | |
else if ($options['down']) | |
{ | |
if(0 < $currentVersionIndex) | |
{ | |
$version = $stableVersions[$currentVersionIndex-1]; | |
} | |
} | |
else | |
{ | |
$version = $migration->getLatestVersion(); | |
} | |
if ($from == $version) | |
{ | |
$this->logSection('doctrine', sprintf('Already at migration version %s', $version)); | |
return; | |
} | |
$this->logSection('doctrine', sprintf('Migrating from version %s to %s%s', $from, $version, $options['dry-run'] ? ' (dry run)' : '')); | |
try | |
{ | |
$migration->migrate($version, $options['dry-run']); | |
} | |
catch (Exception $e) | |
{ | |
} | |
// render errors | |
if ($migration->hasErrors()) | |
{ | |
if ($this->commandApplication && $this->commandApplication->withTrace()) | |
{ | |
$this->logSection('doctrine', 'The following errors occurred:'); | |
foreach ($migration->getErrors() as $error) | |
{ | |
$this->commandApplication->renderException($error); | |
} | |
} | |
else | |
{ | |
$this->logBlock(array_merge( | |
array('The following errors occurred:', ''), | |
array_map(create_function('$e', 'return \' - \'.$e->getMessage();'), $migration->getErrors()) | |
), 'ERROR_LARGE'); | |
} | |
return 1; | |
} | |
$this->logSection('doctrine', 'Migration complete'); | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment