Skip to content

Commit

Permalink
Allow to opt-out of foreign key name comparison (fixes doctrine#6518)
Browse files Browse the repository at this point in the history
  • Loading branch information
uncaught committed Sep 6, 2024
1 parent 57c98da commit d041e23
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 7 deletions.
18 changes: 18 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
}
}
2 changes: 2 additions & 0 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
5 changes: 4 additions & 1 deletion src/Schema/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,10 @@ private function detectRenamedIndexes(array &$addedIndexes, array &$removedIndex
*/
public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2)
{
if (strtolower($key1->getName()) !== strtolower($key2->getName())) {
if (
(!$this->platform || $this->platform->getCompareForeignKeyNames())
&& strtolower($key1->getName()) !== strtolower($key2->getName())
) {
return true;
}

Expand Down
23 changes: 17 additions & 6 deletions tests/Schema/AbstractComparatorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -686,15 +687,25 @@ public function testDetectForeignKeyNameChange(): void
$fkA->setLocalTable($tableA);
$fkB = new ForeignKeyConstraint(['id'], 'bar', ['id'], 'bar_constraint');
$fkB->setLocalTable($tableB);
$tableDiff = new TableDiff(
tableName: 'foo',
fromTable: $tableA,
addedForeignKeys: [$fkB],
removedForeignKeys: [$fkA],
);
$tableDiff = new TableDiff('foo', [], [], [], [], [], [], $tableA, [$fkB], [], [$fkA]);
self::assertEquals($tableDiff, $this->comparator->compareTables($tableA, $tableB));
}

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
{
$fk1 = new ForeignKeyConstraint(['foo'], 'bar', ['baz'], 'fk1', ['onDelete' => 'NO ACTION']);
Expand Down

0 comments on commit d041e23

Please sign in to comment.