Skip to content

Commit 28492fa

Browse files
committed
Deprecate dropping columns referenced by constraints
1 parent 33f5589 commit 28492fa

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

UPGRADE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ awareness about deprecated code.
66
- Use of our low-overhead runtime deprecation API, details:
77
https://github.com/doctrine/deprecations/
88

9+
# Upgrade to 4.3
10+
11+
## Deprecated dropping columns referenced by constraints
12+
13+
Dropping columns that are referenced by constraints is deprecated. The constraints should be dropped first.
14+
915
# Upgrade to 4.2
1016

1117
## Support for new PDO subclasses on PHP 8.4

src/Schema/Table.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
use Doctrine\DBAL\Schema\Exception\PrimaryKeyAlreadyExists;
1515
use Doctrine\DBAL\Schema\Exception\UniqueConstraintDoesNotExist;
1616
use Doctrine\DBAL\Types\Type;
17+
use Doctrine\Deprecations\Deprecation;
1718
use LogicException;
1819

1920
use function array_merge;
2021
use function array_values;
22+
use function count;
23+
use function implode;
24+
use function in_array;
2125
use function preg_match;
2226
use function sprintf;
2327
use function strtolower;
@@ -332,6 +336,30 @@ public function dropColumn(string $name): self
332336
{
333337
$name = $this->normalizeIdentifier($name);
334338

339+
$foreignKeyConstraintNames = $this->getForeignKeyConstraintNamesByLocalColumnName($name);
340+
$uniqueConstraintNames = $this->getUniqueConstraintNamesByColumnName($name);
341+
342+
if (count($foreignKeyConstraintNames) > 0 || count($uniqueConstraintNames) > 0) {
343+
$constraints = [];
344+
345+
if (count($foreignKeyConstraintNames) > 0) {
346+
$constraints[] = 'foreign key constraints: ' . implode(', ', $foreignKeyConstraintNames);
347+
}
348+
349+
if (count($uniqueConstraintNames) > 0) {
350+
$constraints[] = 'unique constraints: ' . implode(', ', $uniqueConstraintNames);
351+
}
352+
353+
Deprecation::trigger(
354+
'doctrine/dbal',
355+
'https://github.com/doctrine/dbal/pull/6558',
356+
'Dropping columns referenced by constraints is deprecated.'
357+
. 'Column %s is used by the following constraints: %s ',
358+
$name,
359+
implode(', ', $constraints),
360+
);
361+
}
362+
335363
unset($this->_columns[$name]);
336364

337365
return $this;
@@ -800,4 +828,36 @@ private function _createIndex(
800828

801829
return new Index($indexName, $columns, $isUnique, $isPrimary, $flags, $options);
802830
}
831+
832+
/** @return list<string> */
833+
private function getForeignKeyConstraintNamesByLocalColumnName(string $columnName): array
834+
{
835+
$names = [];
836+
837+
foreach ($this->_fkConstraints as $name => $constraint) {
838+
if (! in_array($columnName, $constraint->getLocalColumns(), true)) {
839+
continue;
840+
}
841+
842+
$names[] = $name;
843+
}
844+
845+
return $names;
846+
}
847+
848+
/** @return list<string> */
849+
private function getUniqueConstraintNamesByColumnName(string $columnName): array
850+
{
851+
$names = [];
852+
853+
foreach ($this->uniqueConstraints as $name => $constraint) {
854+
if (! in_array($columnName, $constraint->getColumns(), true)) {
855+
continue;
856+
}
857+
858+
$names[] = $name;
859+
}
860+
861+
return $names;
862+
}
803863
}

tests/Schema/TableTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\DBAL\Schema\UniqueConstraint;
1616
use Doctrine\DBAL\Types\Type;
1717
use Doctrine\DBAL\Types\Types;
18+
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
1819
use LogicException;
1920
use PHPUnit\Framework\Attributes\DataProvider;
2021
use PHPUnit\Framework\TestCase;
@@ -24,6 +25,8 @@
2425

2526
class TableTest extends TestCase
2627
{
28+
use VerifyDeprecations;
29+
2730
public function testCreateWithInvalidTableName(): void
2831
{
2932
$this->expectException(Exception::class);
@@ -905,4 +908,33 @@ public function testRemoveUniqueConstraintUnknownNameThrowsException(): void
905908

906909
$table->removeUniqueConstraint('unique_constraint');
907910
}
911+
912+
public function testDropColumnWithForeignKeyConstraint(): void
913+
{
914+
$table = new Table('t1');
915+
$table->addColumn('id', Types::INTEGER);
916+
$table->addForeignKeyConstraint('t2', ['id'], ['id']);
917+
918+
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/6558');
919+
$table->dropColumn('id');
920+
}
921+
922+
public function testDropColumnWithUniqueConstraint(): void
923+
{
924+
$table = new Table('t');
925+
$table->addColumn('id', Types::INTEGER);
926+
$table->addUniqueConstraint(['id']);
927+
928+
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/6558');
929+
$table->dropColumn('id');
930+
}
931+
932+
public function testDropColumnWithoutConstraints(): void
933+
{
934+
$table = new Table('t');
935+
$table->addColumn('id', Types::INTEGER);
936+
937+
$this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/6558');
938+
$table->dropColumn('id');
939+
}
908940
}

0 commit comments

Comments
 (0)