++ The Doctrine CLI The Doctrine CLI (Command Line Interface) is a tool for simplifying many common tasks 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 tasks or use the --help flag to get information on the available tasks. If you want to know more about the use of the schema tool for example you can call: doctrine orm:schema-tool --help +++ Configuration Whenever the `doctrine` command line tool is invoked it requires an instance of `Doctrine\Common\Cli\CliConfiguration` to be able to correctly work. When using ORM package, it is required to define an attribute inside Configuration: `em`. `em` must be an `EntityManager` instance that is used by ORM command-line tasks. Many tasks of the Doctrine CLI require the `em` attribute to be an `EntityManager` in order to execute. The `EntityManager` instance implicitly defines a database connection. If you invoke a task that requires an EntityManager (and/or a database connection) and the `em` attribute is not defined in your CLI Configuration instance, the task invoking will report an error for you. CLI COnfiguration instance can be in a separate file (ie. `cli-config.php`) that contains typical Doctrine bootstrap code and predefines the needed attributes mentioned above. A typical `cli-config.php` file looks as follows: [php] require_once '/path/to/lib/Doctrine/Common/ClassLoader.php'; $classLoader = new \Doctrine\Common\ClassLoader('MyProject', '/path/to/myproject/lib'); $classLoader->register(); $ormConfig = new \Doctrine\ORM\Configuration(); $ormConfig->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache); $ormConfig->setProxyDir('/path/to/myproject/lib/MyProject/Proxies'); $ormConfig->setProxyNamespace('MyProject\Proxies'); $connectionOptions = array( 'driver' => 'pdo_sqlite', 'path' => 'database.sqlite' ); $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $ormConfig); $cliConfig = new \Doctrine\Common\Cli\Configuration(); $cliConfig->setAttribute('em', $em); $cliConfig->setAttribute('globalArguments', array( 'class-dir' => '/path/to/myproject/lib/MyProject/Models/' )); It is important to define an instance of Doctrine\Common\Cli\Configuration that the doctrine.php script will ultimately use. For the required name of this variable, check the doctrine.php included in your package; the most new ones will automatically find the variable no matter what its name is, as long as it is an instance of the right class. The CLI Configuration should contain at least the 'em' attribute, set to the EntityManager. To use many tasks a 'globalOptions' array should be set. The `globalArguments` content will be passed to every command line task. For instance, to use the orm:schema-tool task to generate database tables from annotations, the class-dir global option must be set as in the example. +++ Task Overview The following tasks are currently available: * `dbal:run-sql`: Used to run arbitrary SQL on the command-line. * `orm:convert-mapping`: Used to convert between annotations/xml/yaml mapping informations as well as for class generating from xml/yaml mapping documents or for reverse engineering. * `orm:generate-proxies`: Used to generate proxy classes used by Doctrine. * `orm:run-dql`: Used to run arbitrary DQL on the command-line. * `orm:schema-tool`: Used to forward-engineer the relational database schema from existing classes and mappings. * `orm:version`: Used to show the current version of the CLI and Doctrine. ++ Database Schema Generation To generate your database schema from your Doctrine mapping files you can use the `SchemaTool` class or the `schema-tool` CLI task. 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` task. To create the schema use the `--create` option: $ php doctrine orm:schema-tool --create To drop the scheme use the `--drop` option: $ 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 --create As you would think, if you want to update your schema use the `--update` option: $ php doctrine orm:schema-tool --update All of the above tasks 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 task, remember to configure your cli-config.php properly. ++ Convert Mapping Information Doctrine comes with some special tools for working with the various supported formats for specifying mapping information. You have the ability to convert from a few different sources. * An existing database * A directory of YAML schema files * A directory of XML schema files * A directory of PHP scripts which populate `ClassMetadataInfo` instances * A directory of PHP classes defining Doctrine entities with annotations To convert a mapping source you can do everything you need with the `ClassMetadataExporter`. [php] $cme = new \Doctrine\ORM\Tools\Export\ClassMetadataExporter(); Once you have an instance you can start adding mapping sources to convert. [php] $cme->addMappingSource('/path/to/yml', 'yml'); $cme->addMappingSource('/path/to/xml', 'xml'); $cme->addMappingSource('/path/to/php', 'php'); $cme->addMappingSource('/path/to/annotations', 'annotation'); Now to convert the added mapping sources you can do so by using the exporter drivers. [php] $metadatas = $cme->getMetadatasForMappingSources(); $exporter = $cme->getExporter('yml', '/path/to/export/yml'); $exporter->setMetadatas($metadatas); $exporter->export(); This functionality functionality is also available from the command line to for example convert some YAML mapping files to XML. $ php doctrine orm:convert-mapping --from=/path/to/yml --to=xml --dest=/path/to/xml ++ Reverse Engineering You can use the same `ClassMetadataExporter` to reverse engineer a database and generate YAML, XML, etc. from your existing databases. [php] $sm = $em->getConnection()->getSchemaManager(); $cme->addMappingSource($sm, 'database'); $metadatas = $cme->getMetadatasForMappingSources(); $exporter = $cme->getExporter('yml', '/path/to/export/yml'); $exporter->setMetadatas($metadatas); $exporter->export(); From the command line it is very simple to do something like reverse engineer your existing database to set of YAML mapping files. $ php doctrine orm:convert-mapping --from=database --to=yml --dest=/path/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.