++ The Doctrine Console The Doctrine Console is a Command Line Interface tool for simplifying many common commands during the development of a project that uses Doctrine. +++ Installation If you installed Doctrine 2 through PEAR, the `doctrine` command line tool should already be available to you. If you use Doctrine through SVN or a release package you need to copy the `doctrine` and `doctrine.php` files from the `tools/sandbox` or `bin` folder, respectively, to a location of your choice, for example a `tools` folder of your project. In addition you may need to edit `doctrine.php` and adjust some paths to the new environment. You may want to add require_once() statement at the top of doctrine.php to set up the include_path for Doctrine classes. +++ Getting Help Type `doctrine` on the command line and you should see an overview of the available commands or use the --help flag to get information on the available commands. If you want to know more about the use of generate entities for example, you can call: doctrine orm:generate-entities --help +++ Configuration Whenever the `doctrine` command line tool is invoked, it is only able to access Commands that were defined by developer. Dependency Injection (DI) is the responsable to inject support into this utility, but it is up to the developer define it. The Doctrine CLI tool from the bin/ folder already defines all the DBAL and ORM commands shipped with Doctrine. All the commands of the Doctrine Console require either the `db` or the `em` helpers to be defined in order to work correctly. Doctrine Console requires the definition of a HelperSet that is the DI tool to be injected in the Console. In case of a project that is dealing exclusively with DBAL, the ConnectionHelper is required: [php] $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($conn) )); $cli->setHelperSet($helperSet); When dealing with the ORM package, the EntityManagerHelper is required: [php] $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) )); $cli->setHelperSet($helperSet); The HelperSet instance has to be generated in a separate file (ie. `cli-config.php`) that contains typical Doctrine bootstrap code and predefines the needed HelperSet attributes mentioned above. A typical `cli-config.php` file looks as follows: [php] require_once __DIR__ . '/../../lib/Doctrine/Common/ClassLoader.php'; $classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__); $classLoader->register(); $classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__); $classLoader->register(); $config = new \Doctrine\ORM\Configuration(); $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache); $config->setProxyDir(__DIR__ . '/Proxies'); $config->setProxyNamespace('Proxies'); $connectionOptions = array( 'driver' => 'pdo_sqlite', 'path' => 'database.sqlite' ); $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config); $helperSet = new \Symfony\Components\Console\Helper\HelperSet(array( 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) )); It is important to define a correct HelperSet that doctrine.php script will ultimately use. The Doctrine Binary will automatically find the first instance of HelperSet in the global variable namespace and use this. You can also add your own commands on-top of the Doctrine supported tools. To include a new command on Doctrine Console, you need to do: [php] $cli->addCommand(new \MyProject\Tools\Console\Commands\MyCustomCommand()); Additionally, include multiple commands (and overriding previously defined ones) is possible through the command: [php] $cli->addCommands(array( new \MyProject\Tools\Console\Commands\MyCustomCommand(), new \MyProject\Tools\Console\Commands\SomethingCommand(), new \MyProject\Tools\Console\Commands\AnotherCommand(), new \MyProject\Tools\Console\Commands\OneMoreCommand(), )); +++ Command Overview The following Commands are currently available: * `help` Displays help for a command (?) * `list` Lists commands * `dbal:import` Import SQL file(s) directly to Database. * `dbal:run-sql` Executes arbitrary SQL directly from the command line. * `orm:clear-cache:metadata` Clear all metadata cache of the various cache drivers. * `orm:clear-cache:query` Clear all query cache of the various cache drivers. * `orm:clear-cache:result` Clear result cache of the various cache drivers. * `orm:convert-d1-schema` Converts Doctrine 1.X schema into a Doctrine 2.X schema. * `orm:convert-mapping` Convert mapping information between supported formats. * `orm:ensure-production-settings` Verify that Doctrine is properly configured for a production environment. * `orm:generate-entities` Generate entity classes and method stubs from your mapping information. * `orm:generate-proxies` Generates proxy classes for entity classes. * `orm:generate-repositories` Generate repository classes from your mapping information. * `orm:run-dql` Executes arbitrary DQL directly from the command line. * `orm:schema-tool:create` Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output. * `orm:schema-tool:drop` Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output. * `orm:schema-tool:update` Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output. ++ Database Schema Generation To generate your database schema from your Doctrine mapping files you can use the `SchemaTool` class or the `schema-tool` Console Command. When using the SchemaTool class directly, create your schema using the `createSchema()` method. First create an instance of the `SchemaTool` and pass it an instance of the `EntityManager` that you want to use to create the schema. This method receives an array of `ClassMetadataInfo` instances. [php] $tool = new \Doctrine\ORM\Tools\SchemaTool($em); $classes = array( $em->getClassMetadata('Entities\User'), $em->getClassMetadata('Entities\Profile') ); $tool->createSchema($classes); To drop the schema you can use the `dropSchema()` method. [php] $tool->dropSchema($classes); This drops all the tables that are currently used by your metadata model. When you are changing your metadata alot during development you might want to drop the complete database instead of only the tables of the current model to clean up with orphaned tables. [php] $tool->dropSchema($classes, \Doctrine\ORM\Tools\SchemaTool::DROP_DATABASE); You can also use database introspection to update your schema easily with the `updateSchema()` method. It will compare your existing database schema to the passed array of `ClassMetdataInfo` instances. [php] $tool->updateSchema($classes); If you want to use this functionality from the command line you can use the `schema-tool` command. To create the schema use the `create` command: $ php doctrine orm:schema-tool:create To drop the schema use the `drop` command: $ php doctrine orm:schema-tool:drop If you want to drop and then recreate the schema then use both options: $ php doctrine orm:schema-tool:drop $ php doctrine orm:schema-tool:create As you would think, if you want to update your schema use the `update` command: $ php doctrine orm:schema-tool:update All of the above commands also accept a `--dump-sql` option that will output the SQL for the ran operation. $ php doctrine orm:schema-tool:create --dump-sql Before using the orm:schema-tool commands, remember to configure your cli-config.php properly. > **NOTE** > > When using the Annotation Mapping Driver you have to either setup your autoloader in the cli-config.php > correctly to find all the entities, or you can use the second argument of the `EntityManagerHelper` to > specifiy all the paths of your entities (or mapping files), i.e. > `new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em, $mappingPaths);` ++ Convert Mapping Information To convert some mapping information between the various supported formats you can use the `ClassMetadataExporter` to get exporter instances for the different formats: [php] $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter(); Once you have a instance you can use it to get an exporter. For example, the yml exporter: [php] $exporter = $cme->getExporter('yml', '/path/to/export/yml'); Now you can export some `ClassMetadata` instances: [php] $classes = array( $em->getClassMetadata('Entities\User'), $em->getClassMetadata('Entities\Profile') ); $exporter->setMetadata($classes); $exporter->export(); This functionality is also available from the command line to convert your loaded mapping information to another format. The `orm:convert-mapping` command accepts two arguments, the type to convert to and the path to generate it: $ php doctrine orm:convert-mapping xml /path/to/mapping-path-converted-to-xml ++ Reverse Engineering You can use the `DatabaseDriver` to reverse engineer a database to an array of `ClassMetadataInfo` instances and generate YAML, XML, etc. from them. First you need to retrieve the metadata instances with the `DatabaseDriver`: [php] $em->getConfiguration()->setMetadataDriverImpl( new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( $em->getConnection()->getSchemaManager() ) ); $cmf = new DisconnectedClassMetadataFactory($em); $metadata = $cmf->getAllMetadata(); Now you can get an exporter instance and export the loaded metadata to yml: [php] $exporter = $cme->getExporter('yml', '/path/to/export/yml'); $exporter->setMetadata($metadatas); $exporter->export(); You can also reverse engineer a database using the `orm:convert-mapping` command: $ php doctrine orm:convert-mapping --from-database yml /path/to/mapping-path-converted-to-yml > **CAUTION** > Reverse Engineering is not always working perfectly depending on special cases. > It will only detect Many-To-One relations (even if they are One-To-One) and > will try to create entities from Many-To-Many tables. It also has problems > with naming of foreign keys that have multiple column names. Any Reverse Engineered > Database-Schema needs considerable manual work to become a useful domain model.