Command/UpdateSchemaDoctrineCommand.php
changeset 25 11fd79666374
child 42 0e57c730bb18
equal deleted inserted replaced
24:cd389bf882f1 25:11fd79666374
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace IRI\Bundle\WikiTagBundle\Command;
       
    13 
       
    14 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
       
    15 use Symfony\Component\DependencyInjection\ContainerInterface;
       
    16 use Symfony\Component\Console\Input\InputArgument;
       
    17 use Symfony\Component\Console\Input\InputOption;
       
    18 use Symfony\Component\Console\Input\InputInterface;
       
    19 use Symfony\Component\Console\Output\OutputInterface;
       
    20 use Symfony\Component\Console\Output\Output;
       
    21 use Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand;
       
    22 use Doctrine\ORM\Tools\SchemaTool;
       
    23 use Symfony\Bundle\DoctrineBundle\Command\Proxy\DoctrineCommandHelper;
       
    24 
       
    25 
       
    26 /**
       
    27  * Command to generate the SQL needed to update the database schema to match
       
    28  * the current mapping information.
       
    29  *
       
    30  * This file is a direct adaptation of the Symfony\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand
       
    31  *
       
    32  */
       
    33 class UpdateSchemaDoctrineCommand extends UpdateCommand implements ContainerAwareInterface
       
    34 {
       
    35     protected function configure()
       
    36     {
       
    37         parent::configure();
       
    38 
       
    39         $this
       
    40             ->setName('wikitag:schema:update')
       
    41             ->setDescription('Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata')
       
    42             ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
       
    43             ->setHelp(<<<EOT
       
    44 The <info>doctrine:schema:update</info> command generates the SQL needed to
       
    45 synchronize the database schema with the current mapping metadata of the
       
    46 default entity manager.
       
    47 
       
    48 For example, if you add metadata for a new column to an entity, this command
       
    49 would generate and output the SQL needed to add the new column to the database:
       
    50 
       
    51 <info>php app/console doctrine:schema:update --dump-sql</info>
       
    52 
       
    53 Alternatively, you can execute the generated queries:
       
    54 
       
    55 <info>php app/console doctrine:schema:update --force</info>
       
    56 
       
    57 You can also update the database schema for a specific entity manager:
       
    58 
       
    59 <info>php app/console doctrine:schema:update --em=default</info>
       
    60 EOT
       
    61         );
       
    62     }
       
    63 
       
    64     protected function execute(InputInterface $input, OutputInterface $output)
       
    65     {
       
    66         DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
       
    67 
       
    68         parent::execute($input, $output);
       
    69     }
       
    70     
       
    71    /**
       
    72     * @var ContainerInterface
       
    73     */
       
    74     private $container;
       
    75     
       
    76     protected function getContainer()
       
    77     {
       
    78         if (null === $this->container) {
       
    79             $this->container = $this->getApplication()->getKernel()->getContainer();
       
    80         }
       
    81     
       
    82         return $this->container;
       
    83     }
       
    84     
       
    85     /**
       
    86      * @see ContainerAwareInterface::setContainer()
       
    87      */
       
    88     public function setContainer(ContainerInterface $container = null)
       
    89     {
       
    90         $this->container = $container;
       
    91     }
       
    92     
       
    93     
       
    94     protected function filterUpdateSchema($sqls)
       
    95     {
       
    96     
       
    97         // get service
       
    98         $schema_utils = $this->getContainer()->get("wikitag.shema_utils");
       
    99     
       
   100         $res_sqls = $schema_utils->filter_foreign_key($sqls);
       
   101         $res_sqls = $schema_utils->filter_index_creation($res_sqls);
       
   102     
       
   103     
       
   104         return $res_sqls;
       
   105     }
       
   106     
       
   107     protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
       
   108     {
       
   109         // Defining if update is complete or not (--complete not defined means $saveMode = true)
       
   110         $saveMode = ($input->getOption('complete') !== true);
       
   111     
       
   112         $sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
       
   113         $sqls = $this->filterUpdateSchema($sqls);
       
   114         if (0 == count($sqls)) {
       
   115             $output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');
       
   116     
       
   117             return;
       
   118         }
       
   119     
       
   120         $dumpSql = (true === $input->getOption('dump-sql'));
       
   121         $force = (true === $input->getOption('force'));
       
   122         if ($dumpSql && $force) {
       
   123             throw new \InvalidArgumentException('You can pass either the --dump-sql or the --force option (but not both simultaneously).');
       
   124         }
       
   125     
       
   126         if ($dumpSql) {
       
   127             $output->writeln(implode(';' . PHP_EOL, $sqls));
       
   128         } else if ($force) {
       
   129             $output->writeln('Updating database schema...');
       
   130             
       
   131             $emHelper = $this->getHelper('em');
       
   132             
       
   133             $conn = $emHelper->getEntityManager()->getConnection();
       
   134             
       
   135             foreach ($sqls as $sql) {
       
   136                 $conn->executeQuery($sql);
       
   137             }
       
   138             $output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" queries were executed', count($sqls)));
       
   139         } else {
       
   140             $output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
       
   141             $output->writeln('           Use the incremental update to detect changes during development and use');
       
   142             $output->writeln('           the SQL DDL provided to manually update your database in production.');
       
   143             $output->writeln('');
       
   144     
       
   145             $output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
       
   146             $output->writeln('Please run the operation by passing one of the following options:');
       
   147     
       
   148             $output->writeln(sprintf('    <info>%s --force</info> to execute the command', $this->getName()));
       
   149             $output->writeln(sprintf('    <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
       
   150         }
       
   151     }
       
   152     
       
   153     
       
   154 }