Custom migrations using schema.yml revision.
<?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'); | |
} | |
} | |
?> |
<?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