diff --git a/src/Symfony/Framework/DoctrineBundle/Command/BuildDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/BuildDoctrineCommand.php new file mode 100644 index 0000000000..d2d31e6306 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/BuildDoctrineCommand.php @@ -0,0 +1,139 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Build command allows you to easily build and re-build your Doctrine development environment + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + * @author Kris Wallsmith + */ +class BuildDoctrineCommand extends DoctrineCommand +{ + const + BUILD_ENTITIES = 1, + BUILD_DB = 16, + + OPTION_ENTITIES = 1, + OPTION_DB = 16, + OPTION_ALL = 31; + + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:build') + ->setDescription('Build task for easily re-building your Doctrine development environment.') + ->addOption('all', null, null, 'Build everything and reset the database') + ->addOption('entities', null, null, 'Build model classes') + ->addOption('db', null, null, 'Drop database, create database and create schema.') + ->addOption('and-load', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'Load data fixtures') + ->addOption('and-append', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'Load data fixtures and append to existing data') + ->addOption('and-update-schema', null, null, 'Update schema after rebuilding all classes') + ->addOption('connection', null, null, 'The connection to use.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if (!$mode = $this->calculateMode($input)) + { + throw new \InvalidArgumentException(sprintf("You must include one or more of the following build options:\n--%s\n\nSee this task's help page for more information:\n\n php console help doctrine:build", join(', --', array_keys($this->getBuildOptions())))); + } + + if (self::BUILD_ENTITIES == (self::BUILD_ENTITIES & $mode)) + { + $this->runCommand('doctrine:build-entities'); + } + + if (self::BUILD_DB == (self::BUILD_DB & $mode)) + { + $this->runCommand('doctrine:schema-tool', array('--re-create' => true, '--connection' => $input->getOption('connection'))); + } + + if ($input->getOption('and-update-schema')) + { + $this->runCommand('doctrine:schema-tool', array('--update' => true, '--connection' => $input->getOption('connection'))); + $this->runCommand('doctrine:schema-tool', array('--complete-update' => true, '--connection' => $input->getOption('connection'))); + } + + if ($input->hasOption('and-load')) + { + $dirOrFile = $input->getOption('and-load'); + $this->runCommand('doctrine:load-data-fixtures', + array('--dir_or_file' => $dirOrFile, '--append' => false) + ); + } + else if ($input->hasOption('and-append')) + { + $dirOrFile = $input->getOption('and-append'); + $this->runCommand('doctrine:load-data-fixtures', array('--dir_or_file' => $dirOrFile, '--append' => true)); + } + } + + /** + * Calculates a bit mode based on the supplied options. + * + * @param InputInterface $input + * @return integer + */ + protected function calculateMode(InputInterface $input) + { + $mode = 0; + foreach ($this->getBuildOptions() as $name => $value) + { + if ($input->getOption($name) === true) + { + $mode = $mode | $value; + } + } + + return $mode; + } + + /** + * Returns an array of valid build options. + * + * @return array An array of option names and their mode + */ + protected function getBuildOptions() + { + $options = array(); + foreach ($this->getDefinition()->getOptions() as $option) + { + if (defined($constant = __CLASS__.'::OPTION_'.str_replace('-', '_', strtoupper($option->getName())))) + { + $options[$option->getName()] = constant($constant); + } + } + + return $options; + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/BuildEntitiesDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/BuildEntitiesDoctrineCommand.php new file mode 100644 index 0000000000..d4ec8cb9e0 --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/BuildEntitiesDoctrineCommand.php @@ -0,0 +1,66 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Build all Bundle entity classes from mapping information. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class BuildEntitiesDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:build-entities') + ->setDescription('Build all Bundle entity classes from mapping information.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + foreach ($this->container->getParameter('kernel.bundle_dirs') as $bundle => $path) + { + $bundles = glob($path.'/*Bundle'); + foreach ($bundles as $p) + { + if (!is_dir($metadataPath = $p.'/Resources/config/doctrine/metadata')) + { + continue; + } + $opts = array(); + $opts['--from'] = $metadataPath; + $opts['--to'] = 'annotation'; + $opts['--dest'] = realpath($path.'/..'); + $this->runCommand('doctrine:convert-mapping', $opts); + } + } + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/DatabaseToolDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/DatabaseToolDoctrineCommand.php new file mode 100644 index 0000000000..df9b5d7fef --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/Command/DatabaseToolDoctrineCommand.php @@ -0,0 +1,127 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * Database tool allows you to easily drop and create your configured databases. + * + * @package symfony + * @subpackage console + * @author Fabien Potencier + * @author Jonathan H. Wage + */ +class DatabaseToolDoctrineCommand extends DoctrineCommand +{ + /** + * @see Command + */ + protected function configure() + { + $this + ->setName('doctrine:database-tool') + ->setDescription('Create and drop the configured databases.') + ->addOption('re-create', null, null, 'Drop and re-create your databases.') + ->addOption('drop', null, null, 'Drop your databases.') + ->addOption('create', null, null, 'Create your databases.') + ->addOption('connection', null, null, 'The connection name to work on.') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if ($input->getOption('re-create')) + { + $input->setOption('drop', true); + $input->setOption('create', true); + } + if (!$input->getOption('drop') && !$input->getOption('create')) + { + throw new \InvalidArgumentException('You must specify one of the --drop and --create options or both.'); + } + $found = false; + $connections = $this->getDoctrineConnections(); + foreach ($connections as $name => $connection) + { + if ($input->getOption('connection') && $name != $input->getOption('connection')) + { + continue; + } + if ($input->getOption('drop')) + { + $this->dropDatabaseForConnection($connection, $output); + } + if ($input->getOption('create')) + { + $this->createDatabaseForConnection($connection, $output); + } + $found = true; + } + if ($found === false) + { + if ($input->getOption('connection')) + { + throw new \InvalidArgumentException(sprintf('Could not find a connection named %s', $input->getOption('connection'))); + } + else + { + throw new \InvalidArgumentException(sprintf('Could not find any configured connections', $input->getOption('connection'))); + } + } + } + + protected function dropDatabaseForConnection(Connection $connection, OutputInterface $output) + { + $params = $connection->getParams(); + $name = isset($params['path']) ? $params['path']:$params['dbname']; + + try { + $connection->getSchemaManager()->dropDatabase($name); + $output->writeln(sprintf('Dropped database for connection named %s', $name)); + } catch (\Exception $e) { + $output->writeln(sprintf('Could not drop database for connection named %s', $name)); + $output->writeln(sprintf('%s', $e->getMessage())); + } + } + + protected function createDatabaseForConnection(Connection $connection, OutputInterface $output) + { + $params = $connection->getParams(); + $name = isset($params['path']) ? $params['path']:$params['dbname']; + + unset($params['dbname']); + + $tmpConnection = \Doctrine\DBAL\DriverManager::getConnection($params); + + try { + $tmpConnection->getSchemaManager()->createDatabase($name); + $output->writeln(sprintf('Created database for connection named %s', $name)); + } catch (\Exception $e) { + $output->writeln(sprintf('Could not create database for connection named %s', $name)); + $output->writeln(sprintf('%s', $e->getMessage())); + } + + $tmpConnection->close(); + } +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php index 55fe976d80..8aedf8b22f 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/DoctrineCommand.php @@ -3,11 +3,13 @@ namespace Symfony\Framework\DoctrineBundle\Command; use Symfony\Framework\WebBundle\Command\Command; +use Symfony\Components\Console\Input\ArrayInput; use Symfony\Components\Console\Input\InputArgument; use Symfony\Components\Console\Input\InputOption; use Symfony\Components\Console\Input\InputInterface; use Symfony\Components\Console\Output\OutputInterface; use Symfony\Components\Console\Output\Output; +use Symfony\Framework\WebBundle\Console\Application; use Symfony\Framework\WebBundle\Util\Filesystem; use Doctrine\Common\Cli\Configuration; use Doctrine\Common\Cli\CliController as DoctrineCliController; @@ -30,16 +32,19 @@ use Doctrine\Common\Cli\CliController as DoctrineCliController; */ abstract class DoctrineCommand extends Command { - protected $cli; + protected + $cli, + $em; protected function getDoctrineCli() { if ($this->cli === null) { $configuration = new Configuration(); - $configuration->setAttribute('em', $this->container->getDoctrine_Orm_EntityManagerService()); $this->cli = new DoctrineCliController($configuration); } + $em = $this->em ? $this->em : $this->container->getDoctrine_Orm_EntityManagerService(); + $this->cli->getConfiguration()->setAttribute('em', $em); return $this->cli; } @@ -60,7 +65,7 @@ abstract class DoctrineCommand extends Command return $this->getDoctrineCli()->run(array_merge(array('doctrine', $name), $builtOptions)); } - public function buildDoctrineCliTaskOptions(InputInterface $input, array $options) + protected function buildDoctrineCliTaskOptions(InputInterface $input, array $options) { $taskOptions = array(); foreach ($options as $option) @@ -72,4 +77,49 @@ abstract class DoctrineCommand extends Command } return $options; } + + protected function runCommand($name, array $input = array()) + { + $arguments = array(); + $arguments = array_merge(array($name), $input); + $input = new ArrayInput($arguments); + $application = new Application($this->container->getKernelService()); + $application->setAutoExit(false); + $application->run($input); + } + + /** + * TODO: Better way to do these functions? + */ + protected function getDoctrineConnections() + { + $connections = array(); + $ids = $this->container->getServiceIds(); + foreach ($ids as $id) + { + preg_match('/doctrine.dbal.(.*)_connection/', $id, $matches); + if ($matches) + { + $name = $matches[1]; + $connections[$name] = $this->container->getService($id); + } + } + return $connections; + } + + protected function getDoctrineEntityManagers() + { + $entityManagers = array(); + $ids = $this->container->getServiceIds(); + foreach ($ids as $id) + { + preg_match('/doctrine.orm.(.*)_entity_manager/', $id, $matches); + if ($matches) + { + $name = $matches[1]; + $entityManagers[$name] = $this->container->getService($id); + } + } + return $entityManagers; + } } \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php index 61ee1634fb..3411729463 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/LoadDataFixturesDoctrineCommand.php @@ -41,7 +41,7 @@ class LoadDataFixturesDoctrineCommand extends DoctrineCommand $this ->setName('doctrine:load-data-fixtures') ->setDescription('Load data fixtures to your database.') - ->addOption('dir_or_file', null, null, 'The directory or file to load data fixtures from.') + ->addOption('dir_or_file', null, InputOption::PARAMETER_OPTIONAL | InputOption::PARAMETER_IS_ARRAY, 'The directory or file to load data fixtures from.') ->addOption('append', null, InputOption::PARAMETER_OPTIONAL, 'Whether or not to append the data fixtures.', false) ; } @@ -51,37 +51,11 @@ class LoadDataFixturesDoctrineCommand extends DoctrineCommand */ protected function execute(InputInterface $input, OutputInterface $output) { - $em = $this->container->getDoctrine_ORM_EntityManagerService(); - if (!$input->getOption('append')) - { - $classes = array(); - $metadatas = $em->getMetadataFactory()->getAllMetadata(); - - foreach ($metadatas as $metadata) - { - if (!$metadata->isMappedSuperclass) - { - $classes[] = $metadata; - } - } - $cmf = $em->getMetadataFactory(); - $classes = $this->getCommitOrder($em, $classes); - for ($i = count($classes) - 1; $i >= 0; --$i) - { - $class = $classes[$i]; - if ($cmf->hasMetadataFor($class->name)) - { - try { - $em->createQuery('DELETE FROM '.$class->name.' a')->execute(); - } catch (Exception $e) {} - } - } - } - + $defaultEm = $this->container->getDoctrine_ORM_EntityManagerService(); $dirOrFile = $input->getOption('dir_or_file'); if ($dirOrFile) { - $paths = $dirOrFile; + $paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile); } else { $paths = array(); $bundleDirs = $this->container->getKernelService()->getBundleDirs(); @@ -112,23 +86,86 @@ class LoadDataFixturesDoctrineCommand extends DoctrineCommand $files = array_merge($files, $found); } + $ems = array(); + $emEntities = array(); $files = array_unique($files); - foreach ($files as $file) { + $em = $defaultEm; + $output->writeln(sprintf('Loading data fixtures from "%s"', $file)); + $before = array_keys(get_defined_vars()); include($file); $after = array_keys(get_defined_vars()); $new = array_diff($after, $before); - $entities = array_values($new); - unset($entities[array_search('before', $entities)]); - foreach ($entities as $entity) { - $em->persist($$entity); + $params = $em->getConnection()->getParams(); + $emName = isset($params['path']) ? $params['path']:$params['dbname']; + + $ems[$emName] = $em; + $emEntities[$emName] = array(); + $variables = array_values($new); + + foreach ($variables as $variable) + { + $value = $$variable; + if (!is_object($value) || $value instanceof \Doctrine\ORM\EntityManager) + { + continue; + } + $emEntities[$emName][] = $value; + } + foreach ($ems as $emName => $em) + { + if (!$input->getOption('append')) + { + $output->writeln(sprintf('Purging data from entity manager named "%s"', $emName)); + $this->purgeEntityManager($em); + } + + $entities = $emEntities[$emName]; + $numEntities = count($entities); + $output->writeln(sprintf('Persisting "%s" '.($numEntities > 1 ? 'entities' : 'entity').'', count($entities))); + + foreach ($entities as $entity) + { + $output->writeln(sprintf('Persisting "%s" entity:', get_class($entity))); + $output->writeln(''); + $output->writeln(var_dump($entity)); + + $em->persist($entity); + } + $output->writeln('Flushing entity manager'); + $em->flush(); } - $em->flush(); } } + protected function purgeEntityManager(EntityManager $em) + { + $classes = array(); + $metadatas = $em->getMetadataFactory()->getAllMetadata(); + + foreach ($metadatas as $metadata) + { + if (!$metadata->isMappedSuperclass) + { + $classes[] = $metadata; + } + } + $cmf = $em->getMetadataFactory(); + $classes = $this->getCommitOrder($em, $classes); + for ($i = count($classes) - 1; $i >= 0; --$i) + { + $class = $classes[$i]; + if ($cmf->hasMetadataFor($class->name)) + { + try { + $em->createQuery('DELETE FROM '.$class->name.' a')->execute(); + } catch (Exception $e) {} + } + } + } + protected function getCommitOrder(EntityManager $em, array $classes) { $calc = new CommitOrderCalculator; @@ -154,4 +191,4 @@ class LoadDataFixturesDoctrineCommand extends DoctrineCommand return $calc->getCommitOrder(); } -} +} \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php index 343929a056..edcd95a6ef 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/RunDqlDoctrineCommand.php @@ -40,6 +40,7 @@ class RunDqlDoctrineCommand extends DoctrineCommand ->setDescription('Executes arbitrary DQL directly from the command line.') ->addOption('dql', null, null, 'The DQL query to run.') ->addOption('depth', null, null, 'The depth to output the data to.') + ->addOption('connection', null, null, 'The connection to use.') ; } diff --git a/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php index 44c393264c..a0bb433a9a 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/RunSqlDoctrineCommand.php @@ -41,6 +41,7 @@ class RunSqlDoctrineCommand extends DoctrineCommand ->addOption('sql', null, null, 'The SQL query to run.') ->addOption('file', null, null, 'Path to a SQL file to run.') ->addOption('depth', null, null, 'The depth to output the data to.') + ->addOption('connection', null, null, 'The connection to use.') ; } diff --git a/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php b/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php index 7154852c29..f6c6ef5659 100644 --- a/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php +++ b/src/Symfony/Framework/DoctrineBundle/Command/SchemaToolDoctrineCommand.php @@ -44,6 +44,7 @@ class SchemaToolDoctrineCommand extends DoctrineCommand ->addOption('complete-update', null, null, 'Complete update and drop anything that is not in your schema.') ->addOption('re-create', null, null, 'Drop and re-create your database schema.') ->addOption('dump-sql', null, null, 'Dump the SQL instead of executing it.') + ->addOption('connection', null, null, 'The connection to use.') ; } @@ -55,8 +56,33 @@ class SchemaToolDoctrineCommand extends DoctrineCommand $options = $this->buildDoctrineCliTaskOptions($input, array( 'create', 'drop', 'update', 'complete-update', 're-create', 'dump-sql' )); + $entityDirs = $this->container->getParameter('doctrine.orm.entity_dirs'); $options['class-dir'] = implode(', ', $entityDirs); - $this->runDoctrineCliTask('orm:schema-tool', $options); + + $found = false; + $ems = $this->getDoctrineEntityManagers(); + foreach ($ems as $name => $em) + { + if ($input->getOption('connection') && $name !== $input->getOption('connection')) + { + continue; + } + $this->em = $em; + $this->runDoctrineCliTask('orm:schema-tool', $options); + $found = true; + } + + if ($found === false) + { + if ($input->getOption('connection')) + { + $output->writeln(sprintf('Could not find a connection named %s', $input->getOption('connection'))); + } + else + { + $output->writeln(sprintf('Could not find any configured connections', $input->getOption('connection'))); + } + } } } \ No newline at end of file diff --git a/src/Symfony/Framework/DoctrineBundle/README b/src/Symfony/Framework/DoctrineBundle/README new file mode 100644 index 0000000000..3bdd04cd1f --- /dev/null +++ b/src/Symfony/Framework/DoctrineBundle/README @@ -0,0 +1,191 @@ +DoctrineBundle +-------------- + +This document describes some of the functionality provided by the +**DoctrineBundle**. Doctrine 2 is a first class citizen in Symfony 2 and is +tightly integrated. Continue reading to learn how to use Doctrine 2 with the +latest Symfony 2! + +## Configuration + +This section will help you with configuring your Symfony 2 project to enable +the Doctrine DBAL and ORM services. + +### Database Abstraction Layer + +You can configure your database abstraction layer simply configuration a few +pieces of information about your database. If you only have one database you can +do the following: + + [yml] + doctrine.dbal: + dbname: symfony_guestbook + user: root + password: ~ + +Or if you have multiple connections and want to customize the configuration of the +connection further you can use the following: + + [yml] + doctrine.dbal: + default_connection: default + connections: + default: + driver: PDOSqlite # PDOSqlite, PDOMySql, PDOMsSql, PDOOracle, PDOPgSql, OCI8 + dbname: symfony + user: root + password: null + host: localhost + port: ~ + path: %kernel.data_dir%/symfony.sqlite + event_manager_class: Doctrine\Common\EventManager + configuration_class: Doctrine\DBAL\Configuration + wrapper_class: ~ + options: [] + +### Object Relational Mapper + +If you want to enable the Doctrine 2 ORM you can do so with the following: + + doctrine.orm: + default_entity_manager: default + metadata_driver: xml # xml, yml, annotation + cache_driver: apc # array, apc, memcache, xcache + entity_managers: + default: + connection: default + +It's pretty simple, you can specify which entity managers you want to instantiate +for which connections and also configure some other information about the ORM +like what type of mapping files to use or what cache driver to use. + +## Creating a Bundle + +To get started we need to create a new bundle: + + $ php console init:bundle "Bundle\\GuestbookBundle" + Initializing bundle "GuestbookBundle" in "/path/to/symfony-sandbox/src/Bundle" + +Now basically the most important thing to know about using Doctrine 2 with Symfony +is where to put your mapping information files, where your entity classes are and +a few commands to help move things faster! + +## Mapping Information + +You can place all your mapping information inside a bundle. Below is an example +path for the **GuestbookBundle** we created above: + + /path/to/symfony-sandbox/src/Bundle/GuestbookBundle/Resources/config/doctrine/metadata + +Any files found in here that have a suffix of **.dcm.xml** (or whatever +mapping_driver you picked) are used as your entities mapping information. + +In the **GuestbookBundle** we have a file named **Bundle.GuestbookBundle.Entities.Entry.dcm.xml** +which contains the following XML: + + + + + + + + + + + + + + + + + + + + +## Building Entities + +Doctrine can help you a little bit by generating the entity classes for your +mapping information with the command: + + $ php console doctrine:build-entities + +Now if you have a look in the bundles **Entities** directory you will see a new +file named **Entry.php** with some code like the following: + + [php] + // Bundle/GuestbookBundle/Entities/Entry.php + + namespace Bundle\GuestbookBundle\Entities; + + /** + * @Entity + * @Table(name="guestbook_entry") + */ + class Entry + { + /** + * @Column(name="created_at", type="datetime") + */ + private $createdAt; + + /** + * @Column(name="name", type="string", length=255) + */ + private $name; + + // ... + +> **NOTE** +> If you modify your mapping information and re-run the build entities command +> it will modify the classes and update them based on the mapping information. + +## Commands + +The Doctrine 2 CLI is integrated with the Symfony 2 CLI so we have all the common +commands we need to make working with Doctrine 2 just as easy and fast as before! + + $ php console list doctrine + + Available commands for the "doctrine" namespace: + :build Build task for easily re-building your Doctrine development environment. + :build-entities Build all Bundle entity classes from mapping information. + :clear-cache Clear cache from configured query, result and metadata drivers. (doctrine:cc) + :convert-mapping Convert mapping information between supported formats. + :database-tool Create and drop the configured databases. + :ensure-production-settings Verify that Doctrine is properly configured for a production environment. + :generate-proxies Generates proxy classes for entity classes. + :load-data-fixtures Load data fixtures to your database. + :run-dql Executes arbitrary DQL directly from the command line. + :run-sql Executes arbitrary SQL from a file or directly from the command line. + :schema-tool Processes the schema and either apply it directly on EntityManager or generate the SQL output. + :version Displays the current installed Doctrine version. + +The development workflow is very similar to how it is in Symfony 1.4. You can modify +your mapping information and use **doctrine:build --all** to re-build your +environment: + + php console doctrine:build --all + +The recommend way to work is to re-build your entities and update your database +schema: + + php console doctrine:build --entities --and-update-schema + +Now any changes you made in your mapping information will be reflected in the +according databases! Here are all the available options for the **build** task: + + $ php console help doctrine:build + Usage: + Symfony doctrine:build [--all] [--all-classes] [--entities] [--db] [--and-load[="..."]] [--and-append[="..."]] [--and-update-schema] [--dump-sql] [--connection] + + Options: + --all Build everything and reset the database + --entities Build model classes + --db Drop database, create database and create schema. + --and-load Load data fixtures (multiple values allowed) + --and-append Load data fixtures and append to existing data (multiple values allowed) + --and-update-schema Update schema after rebuilding all classes + --connection The connection to use. \ No newline at end of file