From 96398ba30fe16e48e00d39fdf3ad5aaaafdb7b09 Mon Sep 17 00:00:00 2001 From: vershnik Date: Wed, 30 Sep 2015 11:34:58 +0200 Subject: [PATCH] remove indexes overruled by primary key There can be unique indexes automatically created for join column. If join column is also primary key we should keep only primary key on this column. Oracle does not allow having both unique index and primary key on the same column, it is useless for mysql too. (Previously it was done by DBAL, but now it allows duplicate indexes) --- lib/Doctrine/ORM/Tools/SchemaTool.php | 13 ++++ .../Tests/ORM/Tools/SchemaToolTest.php | 66 ++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index b8e62739b..99e96c5ac 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -247,12 +247,14 @@ class SchemaTool } $pkColumns = array(); + foreach ($class->identifier as $identifierField) { if (isset($class->fieldMappings[$identifierField])) { $pkColumns[] = $this->quoteStrategy->getColumnName($identifierField, $class, $this->platform); } elseif (isset($class->associationMappings[$identifierField])) { /* @var $assoc \Doctrine\ORM\Mapping\OneToOne */ $assoc = $class->associationMappings[$identifierField]; + foreach ($assoc['joinColumns'] as $joinColumn) { $pkColumns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); } @@ -263,6 +265,17 @@ class SchemaTool $table->setPrimaryKey($pkColumns); } + // there can be unique indexes automatically created for join column + // if join column is also primary key we should keep only primary key on this column + // so, remove indexes overruled by primary key + $primaryKey = $table->getIndex('primary'); + + foreach ($table->getIndexes() as $idxKey => $existingIndex) { + if ($primaryKey->overrules($existingIndex)) { + $table->dropIndex($idxKey); + } + } + if (isset($class->table['indexes'])) { foreach ($class->table['indexes'] as $indexName => $indexData) { if( ! isset($indexData['flags'])) { diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php index 2bd9916ce..fd2cd20f7 100644 --- a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php @@ -122,10 +122,9 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase */ public function testSchemaHasProperIndexesFromUniqueConstraintAnnotation() { - $em = $this->_getTestEntityManager(); + $em = $this->_getTestEntityManager(); $schemaTool = new SchemaTool($em); - - $classes = [ + $classes = [ $em->getClassMetadata(__NAMESPACE__ . '\\UniqueConstraintAnnotationModel'), ]; @@ -138,6 +137,25 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase $this->assertTrue($table->hasIndex('primary')); $this->assertTrue($table->hasIndex('uniq_hash')); } + + public function testRemoveUniqueIndexOverruledByPrimaryKey() + { + $em = $this->_getTestEntityManager(); + $schemaTool = new SchemaTool($em); + $classes = [ + $em->getClassMetadata(__NAMESPACE__ . '\\FirstEntity'), + $em->getClassMetadata(__NAMESPACE__ . '\\SecondEntity') + ]; + + $schema = $schemaTool->getSchemaFromMetadata($classes); + + $this->assertTrue($schema->hasTable('first_entity'), "Table first_entity should exist."); + + $indexes = $schema->getTable('first_entity')->getIndexes(); + + $this->assertCount(1, $indexes, "there should be only one index"); + $this->assertTrue(current($indexes)->isPrimary(), "index should be primary"); + } } /** @@ -187,3 +205,45 @@ class UniqueConstraintAnnotationModel */ private $hash; } + +/** + * @Entity + * @Table(name="first_entity") + */ +class FirstEntity +{ + /** + * @Id + * @Column(name="id") + */ + public $id; + + /** + * @OneToOne(targetEntity="SecondEntity") + * @JoinColumn(name="id", referencedColumnName="fist_entity_id") + */ + public $secondEntity; + + /** + * @Column(name="name") + */ + public $name; +} + +/** + * @Entity + * @Table(name="second_entity") + */ +class SecondEntity +{ + /** + * @Id + * @Column(name="fist_entity_id") + */ + public $fist_entity_id; + + /** + * @Column(name="name") + */ + public $name; +} \ No newline at end of file