--class-dir= * Specifies the directory where to start looking for mapped classes. * This argument is required when the annotation metadata driver is used, * otherwise it has no effect. * * --dump-sql * Specifies that instead of directly executing the SQL statements, * they should be printed to the standard output. * * --create * Specifies that the schema of the classes should be created. * * --drop * Specifies that the schema of the classes should be dropped. * * --update * Specifies that the schema of the classes should be updated. * * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.doctrine-project.org * @since 2.0 * @version $Revision: 3938 $ * @author Guilherme Blanco * @author Jonathan Wage * @author Roman Borschel */ class SchemaToolTask extends AbstractTask { /** * @inheritdoc */ public function buildDocumentation() { $schemaOption = new OptionGroup(OptionGroup::CARDINALITY_1_1, array( new Option( 'create', null, 'Creates the schema in EntityManager (create tables on Database).' . PHP_EOL . 'If defined, --drop, --update and --re-create can not be requested on same task.' ), new Option( 'drop', null, 'Drops the schema of EntityManager (drop tables on Database).' . PHP_EOL . 'Beware that the complete database is dropped by this command, '.PHP_EOL. 'even tables that are not relevant to your metadata model.' . PHP_EOL . 'If defined, --create, --update and --re-create can not be requested on same task.' ), new Option( 'update', null, 'Updates the schema in EntityManager (update tables on Database).' . PHP_EOL . 'This command does a save update, which does not delete any tables, sequences or affected foreign keys.' . PHP_EOL . 'If defined, --create, --drop and --complete-update --re-create can not be requested on same task.' ), new Option( 'complete-update', null, 'Updates the schema in EntityManager (update tables on Database).' . PHP_EOL . 'Beware that all assets of the database which are not relevant to the current metadata are dropped by this command.'.PHP_EOL. 'If defined, --create, --drop and --update --re-create can not be requested on same task.' ), new Option( 're-create', null, 'Runs --drop then --create to re-create the database.' . PHP_EOL . 'If defined, --create, --update and --drop can not be requested on same task.' ) )); $optionalOptions = new OptionGroup(OptionGroup::CARDINALITY_0_N, array( new Option('dump-sql', null, 'Instead of try to apply generated SQLs into EntityManager, output them.'), new Option('class-dir', '', 'Optional class directory to fetch for Entities.') )); $doc = $this->getDocumentation(); $doc->setName('schema-tool') ->setDescription('Processes the schema and either apply it directly on EntityManager or generate the SQL output.') ->getOptionGroup() ->addOption($schemaOption) ->addOption($optionalOptions); } /** * @inheritdoc */ public function validate() { $arguments = $this->getArguments(); $em = $this->getConfiguration()->getAttribute('em'); if ($em === null) { throw new CliException( "Attribute 'em' of CLI Configuration is not defined or it is not a valid EntityManager." ); } if (isset($arguments['re-create'])) { $arguments['drop'] = true; $arguments['create'] = true; unset($arguments['re-create']); $this->setArguments($arguments); } $isCreate = isset($arguments['create']) && $arguments['create']; $isDrop = isset($arguments['drop']) && $arguments['drop']; $isUpdate = isset($arguments['update']) && $arguments['update']; $isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update']; if ($isUpdate && ($isCreate || $isDrop || $isCompleteUpdate)) { throw new CliException( 'You cannot use --update with --create, --drop or --complete-update.' ); } if ($isCompleteUpdate && ($isCreate || $isDrop || $isUpdate)) { throw new CliException('You cannot use --complete-update with --create, --drop or --update.'); } if ( ! ($isCreate || $isDrop || $isUpdate || $isCompleteUpdate)) { throw new CliException( 'You must specify at a minimum one of the options: ' . '--create, --drop, --update, --re-create or --complete-update.' ); } $metadataDriver = $em->getConfiguration()->getMetadataDriverImpl(); if ($metadataDriver instanceof \Doctrine\ORM\Mapping\Driver\AnnotationDriver) { if (isset($arguments['class-dir'])) { $metadataDriver->addPaths((array) $arguments['class-dir']); } else { throw new CliException( 'The supplied configuration uses the annotation metadata driver. ' . "The 'class-dir' argument is required for this driver." ); } } return true; } /** * @inheritdoc */ public function run() { $arguments = $this->getArguments(); $printer = $this->getPrinter(); $isCreate = isset($arguments['create']) && $arguments['create']; $isDrop = isset($arguments['drop']) && $arguments['drop']; $isUpdate = isset($arguments['update']) && $arguments['update']; $isCompleteUpdate = isset($arguments['complete-update']) && $arguments['complete-update']; $em = $this->getConfiguration()->getAttribute('em'); $cmf = $em->getMetadataFactory(); $classes = $cmf->getAllMetadata(); if (empty($classes)) { $printer->writeln('No classes to process.', 'INFO'); return; } $tool = new SchemaTool($em); if ($isDrop) { if (isset($arguments['dump-sql'])) { foreach ($tool->getDropSchemaSql($classes) as $sql) { $printer->writeln($sql . ";"); } } else { $printer->writeln('Dropping database schema...', 'INFO'); $tool->dropSchema($classes); $printer->writeln('Database schema dropped successfully.', 'INFO'); } } if ($isCreate) { if (isset($arguments['dump-sql'])) { foreach ($tool->getCreateSchemaSql($classes) as $sql) { $printer->writeln($sql . ";"); } } else { $printer->writeln('Creating database schema...', 'INFO'); $tool->createSchema($classes); $printer->writeln('Database schema created successfully.', 'INFO'); } } if ($isUpdate || $isCompleteUpdate) { $saveMode = $isUpdate ? true : false; if (isset($arguments['dump-sql'])) { foreach ($tool->getUpdateSchemaSql($classes, $saveMode) as $sql) { $printer->writeln($sql . ";"); } } else { $printer->writeln('Updating database schema...', 'INFO'); $tool->updateSchema($classes, $saveMode); $printer->writeln('Database schema updated successfully.', 'INFO'); } } } }