From 79643e32ed3f3a6679428b5d6dc152e70fed5c13 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 3 Jun 2011 07:58:49 -0500 Subject: [PATCH 1/2] [Tools][Console] Refactoring the UpdateCommand There are two basic changes: 1) Changed --force and --dump-sql from options to a single argument. Prior, you couldn't pass both options simultaneously anyways, so making them an argument is more accurate. 2) Changed the language and formatting of the task to be more user-friendly. --- .../Command/SchemaTool/UpdateCommand.php | 88 ++++++++++++------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php index 195f5efef..a163b6f84 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php @@ -28,7 +28,8 @@ use Symfony\Component\Console\Input\InputArgument, Doctrine\ORM\Tools\SchemaTool; /** - * Command to update the database schema for a set of classes based on their mappings. + * Command to generate the SQL needed to update the database schema to match + * the current mapping information. * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.doctrine-project.org @@ -38,6 +39,7 @@ use Symfony\Component\Console\Input\InputArgument, * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel + * @author Ryan Weaver */ class UpdateCommand extends AbstractCommand { @@ -49,26 +51,39 @@ class UpdateCommand extends AbstractCommand $this ->setName('orm:schema-tool:update') ->setDescription( - 'Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.' + 'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.' ) ->setDefinition(array( + new InputArgument( + 'action', InputArgument::OPTIONAL, + 'Either "execute" (execute the SQL) or "dump-sql" (dump the SQL to the screen). If not specified, nothing is done.' + ), new InputOption( 'complete', null, InputOption::VALUE_NONE, 'If defined, all assets of the database which are not relevant to the current metadata will be dropped.' ), - new InputOption( - 'dump-sql', null, InputOption::VALUE_NONE, - 'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.' - ), - new InputOption( - 'force', null, InputOption::VALUE_NONE, - "Don't ask for the incremental update of the database, but force the operation to run." - ), - )) - ->setHelp(<<getFullName(); + $this->setHelp(<<$fullName command generates the SQL needed to +synchronize the database schema with the current mapping metadata of the +default entity manager. + +For example, if you add metadata for a new column to an entity, this command +would generate and output the SQL needed to add the new column to the database: + +$fullName dump-sql + +Alternatively, you can execute the generated queries: + +$fullName execute + +Finally, be aware that if the --complete option is passed, this +task will drop all database assets (e.g. tables, etc) that are *not* described +by the current metadata. In other words, without this option, this task leaves +untouched any "extra" tables that exist in the database, but which aren't +described by any metadata. EOT ); } @@ -78,26 +93,33 @@ EOT // Defining if update is complete or not (--complete not defined means $saveMode = true) $saveMode = ($input->getOption('complete') !== true); - if ($input->getOption('dump-sql') === true) { - $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode); - $output->write(implode(';' . PHP_EOL, $sqls) . PHP_EOL); - } else if ($input->getOption('force') === true) { - $output->write('Updating database schema...' . PHP_EOL); + $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode); + if (0 == count($sqls)) { + $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.'); + + return; + } + + $action = $input->getArgument('action'); + if ('execute' == $action) { + $output->writeln('Updating database schema...'); $schemaTool->updateSchema($metadatas, $saveMode); - $output->write('Database schema updated successfully!' . PHP_EOL); + $output->writeln(sprintf('Database schema updated successfully! "%s" queries were executed', count($sqls))); + } else if ('dump-sql' == $action) { + $output->writeln(implode(';' . PHP_EOL, $sqls)); + } else if (null === $action) { + $output->writeln('ATTENTION: This operation should not be executed in a production environment.'); + $output->writeln(' Use the incremental update to detect changes during development and use'); + $output->writeln(' the SQL DDL provided to manually update your database in production.'); + $output->writeln(''); + + $output->writeln(sprintf('The Schema-Tool would execute "%s" queries to update the database.', count($sqls))); + $output->writeln('Please run the operation by passing an argument to this command:'); + + $output->writeln(sprintf(' %s execute to execute the command', $this->getFullName())); + $output->writeln(sprintf(' %s dump-sql to dump the SQL statements to the screen', $this->getFullName())); } else { - $output->write('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL); - $output->write('Use the incremental update to detect changes during development and use' . PHP_EOL); - $output->write('this SQL DDL to manually update your database in production.' . PHP_EOL . PHP_EOL); - - $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode); - - if (count($sqls)) { - $output->write('Schema-Tool would execute ' . count($sqls) . ' queries to update the database.' . PHP_EOL); - $output->write('Please run the operation with --force to execute these queries or use --dump-sql to see them.' . PHP_EOL); - } else { - $output->write('Nothing to update. The database is in sync with the current entity metadata.' . PHP_EOL); - } + throw new \InvalidArgumentException(sprintf('The first argument - if specified - should be either "execute" or "dump-sql" ("%s" given).', $action)); } } } From 64687409155f5e547b2611db1eed4948fba847f9 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 3 Jun 2011 15:09:18 -0500 Subject: [PATCH 2/2] [Tools][Console] Reworking changes to be more backwards compatible This keeps the --dump-sql and --force options, but adds an exception if you try to use them both (which previously, only dumped the SQL but didn't tell you that it was *not* in fact also executing the queries). One additional change is the introduction of a `$name` property, which was the only way that a parent task could allow a child task to override the task's name early enough that the task's overridden name is taken to account when the parent class references it for its help message. --- .../Command/SchemaTool/UpdateCommand.php | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php index a163b6f84..ea43f770b 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php @@ -43,25 +43,32 @@ use Symfony\Component\Console\Input\InputArgument, */ class UpdateCommand extends AbstractCommand { + protected $name = 'orm:schema-tool:update'; + /** * @see Console\Command\Command */ protected function configure() { $this - ->setName('orm:schema-tool:update') + ->setName($this->name) ->setDescription( 'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.' ) ->setDefinition(array( - new InputArgument( - 'action', InputArgument::OPTIONAL, - 'Either "execute" (execute the SQL) or "dump-sql" (dump the SQL to the screen). If not specified, nothing is done.' - ), new InputOption( 'complete', null, InputOption::VALUE_NONE, 'If defined, all assets of the database which are not relevant to the current metadata will be dropped.' ), + + new InputOption( + 'dump-sql', null, InputOption::VALUE_NONE, + 'Dumps the generated SQL statements to the screen (does not execute them).' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Causes the generated SQL statements to be physically executed against your database.' + ), )); $fullName = $this->getFullName(); @@ -73,11 +80,11 @@ default entity manager. For example, if you add metadata for a new column to an entity, this command would generate and output the SQL needed to add the new column to the database: -$fullName dump-sql +$fullName --dump-sql Alternatively, you can execute the generated queries: -$fullName execute +$fullName --force Finally, be aware that if the --complete option is passed, this task will drop all database assets (e.g. tables, etc) that are *not* described @@ -100,26 +107,29 @@ EOT return; } - $action = $input->getArgument('action'); - if ('execute' == $action) { + $dumpSql = (true === $input->getOption('dump-sql')); + $force = (true === $input->getOption('force')); + if ($dumpSql && $force) { + throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).'); + } + + if ($dumpSql) { + $output->writeln(implode(';' . PHP_EOL, $sqls)); + } else if ($force) { $output->writeln('Updating database schema...'); $schemaTool->updateSchema($metadatas, $saveMode); $output->writeln(sprintf('Database schema updated successfully! "%s" queries were executed', count($sqls))); - } else if ('dump-sql' == $action) { - $output->writeln(implode(';' . PHP_EOL, $sqls)); - } else if (null === $action) { + } else { $output->writeln('ATTENTION: This operation should not be executed in a production environment.'); $output->writeln(' Use the incremental update to detect changes during development and use'); $output->writeln(' the SQL DDL provided to manually update your database in production.'); $output->writeln(''); $output->writeln(sprintf('The Schema-Tool would execute "%s" queries to update the database.', count($sqls))); - $output->writeln('Please run the operation by passing an argument to this command:'); + $output->writeln('Please run the operation by passing one of the following options:'); - $output->writeln(sprintf(' %s execute to execute the command', $this->getFullName())); - $output->writeln(sprintf(' %s dump-sql to dump the SQL statements to the screen', $this->getFullName())); - } else { - throw new \InvalidArgumentException(sprintf('The first argument - if specified - should be either "execute" or "dump-sql" ("%s" given).', $action)); + $output->writeln(sprintf(' %s --force to execute the command', $this->getFullName())); + $output->writeln(sprintf(' %s --dump-sql to dump the SQL statements to the screen', $this->getFullName())); } } }