diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index f325ca55085..07aa119f32b 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -542,58 +542,35 @@ public function getDropDatabaseSQL() } /** - * + * Get SQL to drop the tables defined by the passed classes. + * * @param array $classes * @return array */ public function getDropSchemaSQL(array $classes) { - $sm = $this->_em->getConnection()->getSchemaManager(); - - $sql = array(); - $orderedTables = array(); - - foreach ($classes AS $class) { - if ($class->isIdGeneratorSequence() && !$class->isMappedSuperclass && $class->name == $class->rootEntityName && $this->_platform->supportsSequences()) { - $sql[] = $this->_platform->getDropSequenceSQL($class->sequenceGeneratorDefinition['sequenceName']); - } - } - - $commitOrder = $this->_getCommitOrder($classes); - $associationTables = $this->_getAssociationTables($commitOrder); - - // Drop association tables first - foreach ($associationTables as $associationTable) { - if (!in_array($associationTable, $orderedTables)) { - $orderedTables[] = $associationTable; - } - } - - // Drop tables in reverse commit order - for ($i = count($commitOrder) - 1; $i >= 0; --$i) { - $class = $commitOrder[$i]; - - if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName) - || $class->isMappedSuperclass) { - continue; - } - - if (!in_array($class->getTableName(), $orderedTables)) { - $orderedTables[] = $class->getTableName(); - } - } + $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform); + $schema = $this->getSchemaFromMetadata($classes); - $dropTablesSql = array(); - foreach ($orderedTables AS $tableName) { - /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ - $foreignKeys = $sm->listTableForeignKeys($tableName); - foreach ($foreignKeys AS $foreignKey) { - $sql[] = $this->_platform->getDropForeignKeySQL($foreignKey, $tableName); + $sm = $this->_em->getConnection()->getSchemaManager(); + $fullSchema = $sm->createSchema(); + foreach ($fullSchema->getTables() AS $table) { + if (!$schema->hasTable($table->getName())) { + foreach ($table->getForeignKeys() AS $foreignKey) { + /* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */ + if ($schema->hasTable($foreignKey->getForeignTableName())) { + $visitor->acceptForeignKey($table, $foreignKey); + } + } + } else { + $visitor->acceptTable($table); + foreach ($table->getForeignKeys() AS $foreignKey) { + $visitor->acceptForeignKey($table, $foreignKey); + } } - $dropTablesSql[] = $this->_platform->getDropTableSQL($tableName); } - return array_merge($sql, $dropTablesSql); + return $visitor->getQueries(); } /** @@ -636,44 +613,4 @@ public function getUpdateSchemaSql(array $classes, $saveMode=false) return $schemaDiff->toSql($this->_platform); } } - - private function _getCommitOrder(array $classes) - { - $calc = new CommitOrderCalculator; - - // Calculate dependencies - foreach ($classes as $class) { - $calc->addClass($class); - - foreach ($class->associationMappings as $assoc) { - if ($assoc['isOwningSide']) { - $targetClass = $this->_em->getClassMetadata($assoc['targetEntity']); - - if ( ! $calc->hasClass($targetClass->name)) { - $calc->addClass($targetClass); - } - - // add dependency ($targetClass before $class) - $calc->addDependency($targetClass, $class); - } - } - } - - return $calc->getCommitOrder(); - } - - private function _getAssociationTables(array $classes) - { - $associationTables = array(); - - foreach ($classes as $class) { - foreach ($class->associationMappings as $assoc) { - if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) { - $associationTables[] = $assoc['joinTable']['name']; - } - } - } - - return $associationTables; - } } diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php index 3a14056eb36..797c202f6dd 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php @@ -50,4 +50,19 @@ public function testSingleTableInheritance(Schema $schema) $this->assertFalse($table->getColumn('pricePerHour')->getNotnull()); $this->assertFalse($table->getColumn('maxPrice')->getNotnull()); } + + /** + * @group DBAL-115 + */ + public function testDropPartSchemaWithForeignKeys() + { + if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) { + $this->markTestSkipped("Foreign Key test"); + } + + $sql = $this->_schemaTool->getDropSchemaSQL(array( + $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyManager'), + )); + $this->assertEquals(3, count($sql)); + } } \ No newline at end of file