protected function execute(InputInterface $input, OutputInterface $output) { $db = \Database::connection(); $em = $db->getEntityManager(); $cacheDriver = $em->getConfiguration()->getMetadataCacheImpl(); $cacheDriver->flushAll(); $tool = new \Doctrine\ORM\Tools\SchemaTool($em); $schemas = []; /** * @var $sm MySqlSchemaManager */ $sm = $db->getSchemaManager(); $dbSchema = $sm->createSchema(); // core xml tables $schemas[] = Schema::getCoreXMLSchema(); // core entities $sm = new DatabaseStructureManager($em); $entities = $sm->getMetadatas(); $schemas[] = $tool->getSchemaFromMetadata($entities); // core, application and package block types $env = Environment::get(); $list = new BlockTypeList(); $list->includeInternalBlockTypes(); foreach ($list->get() as $bt) { $r = $env->getRecord(DIRNAME_BLOCKS . '/' . $bt->getBlockTypeHandle() . '/' . FILENAME_BLOCK_DB, $bt->getPackageHandle()); if ($r->exists()) { $parser = Schema::getSchemaParser(simplexml_load_file($r->file)); $parser->setIgnoreExistingTables(false); $schemas[] = $parser->parse($db); } } // packages $packages = Package::getInstalledList(); foreach ($packages as $pkg) { $xmlFile = $pkg->getPackagePath() . '/' . FILENAME_BLOCK_DB; if (file_exists($xmlFile)) { $parser = Schema::getSchemaParser(simplexml_load_file($xmlFile)); $parser->setIgnoreExistingTables(false); $schemas[] = $parser->parse($db); } } // Finalize output. $comparator = new \Doctrine\DBAL\Schema\Comparator(); $saveQueries = array(); foreach ($schemas as $schema) { $schemaDiff = $comparator->compare($dbSchema, $schema); $saveQueries = array_merge($saveQueries, $schemaDiff->toSaveSql($db->getDatabasePlatform())); } $saveQueries = $this->filterQueries($saveQueries); if (count($saveQueries)) { $output->writeln(t2('%s query found', '%s queries found', count($saveQueries))); $i = 1; foreach ($saveQueries as $query) { $output->writeln(sprintf('%s: %s', $i, $query)); $i++; } } else { $output->writeln(t('No differences found between schema and database.')); } }
/** * Generates a new migration file and returns the path to it. * * If $diffAgainstCurrent is TRUE, it generates a migration file with the * diff between current DB structure and the found mapping metadata. * * Otherwise an empty migration skeleton is generated. * * @param boolean $diffAgainstCurrent * @return string Path to the new file */ public function generateAndExecutePartialMigrationFor($tables = array(), $package = null, $diffAgainstCurrent = TRUE) { $configuration = $this->getMigrationConfiguration(); $up = NULL; $down = NULL; if ($diffAgainstCurrent === TRUE) { $connection = $this->entityManager->getConnection(); $platform = $connection->getDatabasePlatform(); $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); if (empty($metadata)) { return 'No mapping information to process.'; } $tool = new \Doctrine\ORM\Tools\SchemaTool($this->entityManager); $fromSchema = $connection->getSchemaManager()->createSchema(); $toSchema = $tool->getSchemaFromMetadata($metadata); $fromSchema = $this->filterSchema($fromSchema, $tables); $toSchema = $this->filterSchema($toSchema, $tables); $up = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateToSql($toSchema, $platform)); $down = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateFromSql($toSchema, $platform)); if (!$up && !$down) { return 'No changes detected in your mapping information.'; } } if (!is_null($package) && $this->packageManager->isPackageActive($package)) { $package = $this->packageManager->getPackage($package); $migrationsPath = $package->getPackagePath() . "Migrations/" . ucfirst($platform->getName()) . "/"; $configuration->setMigrationsDirectory($migrationsPath); } $migrationFile = $this->writeMigrationClassToFile($configuration, $up, $down); preg_match("/Version([0-9]+)\\.php/", $migrationFile, $matches); $version = $matches[1]; $this->executeMigration($version); }
/** * Generates a new migration file and returns the path to it. * * If $diffAgainstCurrent is TRUE, it generates a migration file with the * diff between current DB structure and the found mapping metadata. * * Otherwise an empty migration skeleton is generated. * * @param boolean $diffAgainstCurrent * @return string Path to the new file */ public function generateMigration($diffAgainstCurrent = true) { $configuration = $this->getMigrationConfiguration(); $up = null; $down = null; if ($diffAgainstCurrent === true) { $connection = $this->entityManager->getConnection(); $platform = $connection->getDatabasePlatform(); $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); if (empty($metadata)) { return 'No mapping information to process.'; } $tool = new \Doctrine\ORM\Tools\SchemaTool($this->entityManager); $fromSchema = $connection->getSchemaManager()->createSchema(); $toSchema = $tool->getSchemaFromMetadata($metadata); $up = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateToSql($toSchema, $platform)); $down = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateFromSql($toSchema, $platform)); if (!$up && !$down) { return 'No changes detected in your mapping information.'; } } return $this->writeMigrationClassToFile($configuration, $up, $down); }
/** * Uninstalls the database tables for all given entity classes contained * within the $metadatas array. Returns true if there were tables that were * dropped and false otherwise. * * @param array $metadatas * * @return bool */ public function uninstallDatabaseFor(array $metadatas) { if (count($metadatas) > 0) { $em = $this->getEntityManager(); $conn = $em->getConnection(); $sm = $conn->getSchemaManager(); $cmf = $em->getMetadataFactory(); $tool = new \Doctrine\ORM\Tools\SchemaTool($em); $newSchema = $tool->getSchemaFromMetadata($metadatas); // We'll let Doctrine resolve the correct drop order for the tables // because of which we use the schema migration method to drop the // tables. By letting Doctrine resolve the drop order we avoid // DB server constraint violation errors (e.g. in MySQL). $fromSchema = $sm->createSchema(); $toSchema = clone $fromSchema; foreach ($newSchema->getTables() as $newTable) { if ($toSchema->hasTable($newTable->getName())) { $toSchema->dropTable($newTable->getName()); } } $sqls = $fromSchema->getMigrateToSql($toSchema, $conn->getDatabasePlatform()); if (count($sqls) > 0) { foreach ($sqls as $sql) { $conn->executeQuery($sql); } return true; } } return false; }
/** * @test */ public function doctrineEmbeddablesAreActuallyEmbedded() { /* @var $entityManager \Doctrine\Common\Persistence\ObjectManager */ $entityManager = $this->objectManager->get('Doctrine\\Common\\Persistence\\ObjectManager'); $schemaTool = new \Doctrine\ORM\Tools\SchemaTool($entityManager); $metaData = $entityManager->getClassMetadata('TYPO3\\Flow\\Tests\\Functional\\Persistence\\Fixtures\\TestEntity'); $this->assertTrue($metaData->hasField('embedded.value'), 'ClassMetadata does not contain embedded value'); $schema = $schemaTool->getSchemaFromMetadata(array($metaData)); $this->assertTrue($schema->getTable('persistence_testentity')->hasColumn('embedded_value'), 'Database schema does not contain embedded value field'); $embeddable = new TestEmbeddable('someValue'); $testEntity = new TestEntity(); $testEntity->setEmbedded($embeddable); $this->testEntityRepository->add($testEntity); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); /* @var $testEntity TestEntity */ $testEntity = $this->testEntityRepository->findAll()->getFirst(); $this->assertEquals('someValue', $testEntity->getEmbedded()->getValue()); }
/** * Returns true if generating a migration is required, else false * * @return bool * @throws \Doctrine\ORM\ORMException */ public function generateMigrationIsRequired() { $configuration = $this->getMigrationConfiguration(); $up = null; $down = null; $connection = $this->entityManager->getConnection(); $platform = $connection->getDatabasePlatform(); $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata(); if (empty($metadata)) { $this->logger->error('No mapping information to process.'); } $tool = new \Doctrine\ORM\Tools\SchemaTool($this->entityManager); $fromSchema = $connection->getSchemaManager()->createSchema(); $toSchema = $tool->getSchemaFromMetadata($metadata); $up = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateToSql($toSchema, $platform)); $down = $this->buildCodeFromSql($configuration, $fromSchema->getMigrateFromSql($toSchema, $platform)); if (!$up && !$down) { return false; } return true; }