diff --git a/src/Configuration.php b/src/Configuration.php index 5cdae81354d..d89c549937f 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -64,6 +64,14 @@ class Configuration */ private bool $disableTypeComments = false; + /** + * Whether changes in the foreign key names should lead to a schema change. + * If you opt-out of this, you need to handle name changes of foreign keys yourself. + * Databases created based on the current schema might have different foreign key names + * than those migrated from older schemas if you turn this off. + */ + private bool $compareForeignKeyNames = true; + private ?SchemaManagerFactory $schemaManagerFactory = null; public function __construct() @@ -262,4 +270,14 @@ public function setDisableTypeComments(bool $disableTypeComments): self return $this; } + + public function getCompareForeignKeyNames(): bool + { + return $this->compareForeignKeyNames; + } + + public function setCompareForeignKeyNames(bool $compareForeignKeyNames): void + { + $this->compareForeignKeyNames = $compareForeignKeyNames; + } } diff --git a/src/Connection.php b/src/Connection.php index b9756706061..28ea8cc2220 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -211,6 +211,7 @@ public function __construct( $this->platform = $params['platform']; $this->platform->setEventManager($this->_eventManager); $this->platform->setDisableTypeComments($config->getDisableTypeComments()); + $this->platform->setCompareForeignKeyNames($config->getCompareForeignKeyNames()); } $this->_expr = $this->createExpressionBuilder(); @@ -318,6 +319,7 @@ public function getDatabasePlatform() $this->platform = $this->detectDatabasePlatform(); $this->platform->setEventManager($this->_eventManager); $this->platform->setDisableTypeComments($this->_config->getDisableTypeComments()); + $this->platform->setCompareForeignKeyNames($this->_config->getCompareForeignKeyNames()); } return $this->platform; diff --git a/src/Platforms/AbstractPlatform.php b/src/Platforms/AbstractPlatform.php index 928a5a02121..6d9a8a53fd6 100644 --- a/src/Platforms/AbstractPlatform.php +++ b/src/Platforms/AbstractPlatform.php @@ -107,12 +107,26 @@ abstract class AbstractPlatform private bool $disableTypeComments = false; + private bool $compareForeignKeyNames = true; + /** @internal */ final public function setDisableTypeComments(bool $value): void { $this->disableTypeComments = $value; } + /** @internal */ + final public function setCompareForeignKeyNames(bool $compare): void + { + $this->compareForeignKeyNames = $compare; + } + + /** @internal */ + public function getCompareForeignKeyNames(): bool + { + return $this->compareForeignKeyNames; + } + /** * Sets the EventManager used by the Platform. * diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 28e7f2f73b2..f8c3e0d6e12 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -555,6 +555,13 @@ private function detectRenamedIndexes(array &$addedIndexes, array &$removedIndex */ public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) { + if ( + (!$this->platform || $this->platform->getCompareForeignKeyNames()) + && strtolower($key1->getName()) !== strtolower($key2->getName()) + ) { + return true; + } + if ( array_map('strtolower', $key1->getUnquotedLocalColumns()) !== array_map('strtolower', $key2->getUnquotedLocalColumns()) diff --git a/tests/Schema/AbstractComparatorTestCase.php b/tests/Schema/AbstractComparatorTestCase.php index a087202628f..a8224f41765 100644 --- a/tests/Schema/AbstractComparatorTestCase.php +++ b/tests/Schema/AbstractComparatorTestCase.php @@ -2,6 +2,7 @@ namespace Doctrine\DBAL\Tests\Schema; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Comparator; @@ -652,7 +653,7 @@ public function testCompareColumnCompareCaseInsensitive(): void self::assertFalse($tableDiff); } - public function testCompareIndexBasedOnPropertiesNotName(): void + public function testDetectIndexNameChange(): void { $tableA = new Table('foo'); $tableA->addColumn('id', Types::INTEGER); @@ -672,7 +673,7 @@ public function testCompareIndexBasedOnPropertiesNotName(): void ); } - public function testCompareForeignKeyBasedOnPropertiesNotName(): void + public function testDetectForeignKeyNameChange(): void { $tableA = new Table('foo'); $tableA->addColumn('id', Types::INTEGER); @@ -682,9 +683,27 @@ public function testCompareForeignKeyBasedOnPropertiesNotName(): void $tableB->addColumn('ID', Types::INTEGER); $tableB->addForeignKeyConstraint('bar', ['id'], ['id'], [], 'bar_constraint'); - $tableDiff = $this->comparator->diffTable($tableA, $tableB); + $fkA = new ForeignKeyConstraint(['id'], 'bar', ['id'], 'foo_constraint'); + $fkA->setLocalTable($tableA); + $fkB = new ForeignKeyConstraint(['id'], 'bar', ['id'], 'bar_constraint'); + $fkB->setLocalTable($tableB); + $tableDiff = new TableDiff('foo', [], [], [], [], [], [], $tableA, [$fkB], [], [$fkA]); + self::assertEquals($tableDiff, $this->comparator->compareTables($tableA, $tableB)); + } - self::assertFalse($tableDiff); + public function testCompareForeignKeyNameChangeDisabled(): void + { + $fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1'); + $fk2 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk2'); + + //Not disabled: + self::assertTrue($this->comparator->diffForeignKey($fk1, $fk2)); + + //Disabled foreign key name comparison: + $platform = $this->createMock(AbstractPlatform::class); + $platform->method('getCompareForeignKeyNames')->willReturn(false); + $comparatorDisabledFkName = new Comparator($platform); + self::assertFalse($comparatorDisabledFkName->diffForeignKey($fk1, $fk2)); } public function testCompareForeignKeyRestrictNoActionAreTheSame(): void