diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php index 797bc29a8..8c1a8fea1 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php @@ -63,6 +63,10 @@ class ConvertMappingCommand extends Console\Command\Command 'dest-path', InputArgument::REQUIRED, 'The path to generate your entities classes.' ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Force to overwrite existing mapping files.' + ), new InputOption( 'from-database', null, null, 'Whether or not to convert mapping information from existing database.' ), @@ -73,10 +77,24 @@ class ConvertMappingCommand extends Console\Command\Command new InputOption( 'num-spaces', null, InputOption::VALUE_OPTIONAL, 'Defines the number of indentation spaces', 4 - ) + ), )) ->setHelp(<<one-time command. It should not be necessary for +you to call this method multiple times, escpecially when using the --from-database +flag. + +Converting an existing databsae schema into mapping files only solves about 70-80% +of the necessary mapping information. Additionally the detection from an existing +database cannot detect inverse associations, inheritance types, +entities with foreign keys as primary keys and many of the +semantical operations on associations such as cascade. + +Hint: There is no need to convert YAML or XML mapping files to annotations +every time you make changes. All mapping drivers are first class citizens +in Doctrine 2 and can be used as runtime mapping for the ORM. EOT ); } @@ -121,6 +139,7 @@ EOT $cme = new ClassMetadataExporter(); $exporter = $cme->getExporter($toType, $destPath); + $exporter->setOverwriteExistingFiles( ($input->getOption('force') !== false) ); if ($toType == 'annotation') { $entityGenerator = new EntityGenerator(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php index f69b5167f..198db0d6c 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php @@ -85,6 +85,23 @@ class GenerateEntitiesCommand extends Console\Command\Command )) ->setHelp(<<--update-entities or --regenerate-entities flags your exisiting +code gets overwritten. The EntityGenerator will only append new code to your +file and will not delete the old code. However this approach may still be prone +to error and we suggest you use code repositories such as GIT or SVN to make +backups of your code. + +It makes sense to generate the entity code if you are using entities as Data +Access Objects only and dont put much additional logic on them. If you are +however putting much more logic on the entities you should refrain from using +the entity-generator and code your entities manually. + +Important: Even if you specified Inheritance options in your +XML or YAML Mapping files the generator cannot generate the base and +child classes for you correctly, because it doesn't know which +class is supposed to extend which. You have to adjust the entity +code manually for inheritance to work! EOT ); } diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php index 983d0f69d..467332b64 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -23,6 +23,7 @@ namespace Doctrine\ORM\Tools\Export\Driver; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Tools\Export\ExportException; /** * Abstract base class which is to be used for the Exporter drivers @@ -39,12 +40,18 @@ abstract class AbstractExporter protected $_metadata = array(); protected $_outputDir; protected $_extension; + protected $_overwriteExistingFiles = false; public function __construct($dir = null) { $this->_outputDir = $dir; } + public function setOverwriteExistingFiles($overwrite) + { + $this->_overwriteExistingFiles = $overwrite; + } + /** * Converts a single ClassMetadata instance to the exported format * and returns it @@ -110,6 +117,9 @@ abstract class AbstractExporter if ( ! is_dir($dir)) { mkdir($dir, 0777, true); } + if (file_exists($path) && !$this->_overwriteExistingFiles) { + throw ExportException::attemptOverwriteExistingFile($path); + } file_put_contents($path, $output); } } diff --git a/lib/Doctrine/ORM/Tools/Export/ExportException.php b/lib/Doctrine/ORM/Tools/Export/ExportException.php index 6e7826e44..5ba8bd26b 100644 --- a/lib/Doctrine/ORM/Tools/Export/ExportException.php +++ b/lib/Doctrine/ORM/Tools/Export/ExportException.php @@ -15,4 +15,9 @@ class ExportException extends ORMException { return new self("The mapping driver '$type' does not exist"); } + + public static function attemptOverwriteExistingFile($file) + { + return new self("Attempting to overwrite an existing file '".$file."'."); + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php b/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php index b944c26d9..c0af3a7f3 100644 --- a/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php @@ -69,6 +69,7 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase $converter = new ConvertDoctrine1Schema(__DIR__ . '/doctrine1schema'); $exporter = $cme->getExporter('yml', __DIR__ . '/convert'); + $exporter->setOverwriteExistingFiles(true); $exporter->setMetadata($converter->getMetadata()); $exporter->export(); @@ -80,8 +81,8 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase $cmf = new DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); $metadata = $cmf->getAllMetadata(); - $profileClass = $metadata[0]; - $userClass = $metadata[1]; + $profileClass = $cmf->getMetadataFor('Profile'); + $userClass = $cmf->getMetadataFor('User'); $this->assertEquals(2, count($metadata)); $this->assertEquals('Profile', $profileClass->name); @@ -96,9 +97,12 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('User', $profileClass->associationMappings['User']['targetEntity']); $this->assertEquals('username', $userClass->table['uniqueConstraints']['username']['columns'][0]); + } - unlink(__DIR__ . '/convert/User.dcm.yml'); - unlink(__DIR__ . '/convert/Profile.dcm.yml'); - rmdir(__DIR__ . '/convert'); + public function tearDown() + { + @unlink(__DIR__ . '/convert/User.dcm.yml'); + @unlink(__DIR__ . '/convert/Profile.dcm.yml'); + @rmdir(__DIR__ . '/convert'); } }