Skip to content

Commit c55f10e

Browse files
committed
favor Table::addPrimaryKeyConstraint() over Table::setPrimaryKey()
1 parent 1072ea6 commit c55f10e

File tree

6 files changed

+140
-15
lines changed

6 files changed

+140
-15
lines changed

phpstan-dbal3.neon

+12
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ parameters:
2222
message: '~.*getTrimExpression.*expects int.*~'
2323
path: src/Query/AST/Functions/TrimFunction.php
2424

25+
-
26+
message: '~^Call to static method unquoted\(\) on an unknown class Doctrine\\DBAL\\Schema\\Name\\Identifier\.$~'
27+
path: src/Tools/SchemaTool.php
28+
29+
-
30+
message: '~^Instantiated class Doctrine\\DBAL\\Schema\\Name\\UnqualifiedName not found\.$~'
31+
path: src/Tools/SchemaTool.php
32+
33+
-
34+
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::addPrimaryKeyConstraint\(\)\.$~'
35+
path: src/Tools/SchemaTool.php
36+
2537
- '~^Class Doctrine\\DBAL\\Platforms\\SQLitePlatform not found\.$~'
2638

2739
# To be removed in 4.0

phpstan.neon

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ parameters:
2020
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
2121
path: src/Persisters/Entity/BasicEntityPersister.php
2222

23+
-
24+
message: '~^Call to static method unquoted\(\) on an unknown class Doctrine\\DBAL\\Schema\\Name\\Identifier\.$~'
25+
path: src/Tools/SchemaTool.php
26+
27+
-
28+
message: '~^Instantiated class Doctrine\\DBAL\\Schema\\Name\\UnqualifiedName not found\.$~'
29+
path: src/Tools/SchemaTool.php
30+
31+
-
32+
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::addPrimaryKeyConstraint\(\)\.$~'
33+
path: src/Tools/SchemaTool.php
34+
2335
# Compatibility with DBAL 3
2436
# See https://github.com/doctrine/dbal/pull/3480
2537
-

src/Tools/SchemaTool.php

+23-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
use Doctrine\DBAL\Schema\AbstractAsset;
1010
use Doctrine\DBAL\Schema\AbstractSchemaManager;
1111
use Doctrine\DBAL\Schema\Index;
12+
use Doctrine\DBAL\Schema\Name\Identifier;
13+
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
14+
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
1215
use Doctrine\DBAL\Schema\Schema;
1316
use Doctrine\DBAL\Schema\Table;
1417
use Doctrine\ORM\EntityManagerInterface;
@@ -32,6 +35,7 @@
3235
use function array_flip;
3336
use function array_intersect_key;
3437
use function assert;
38+
use function class_exists;
3539
use function count;
3640
use function current;
3741
use function implode;
@@ -282,7 +286,7 @@ public function getSchemaFromMetadata(array $classes): Schema
282286
}
283287

284288
if ($pkColumns !== []) {
285-
$table->setPrimaryKey($pkColumns);
289+
self::addPrimaryKeyConstraint($table, $pkColumns);
286290
}
287291
}
288292
} else {
@@ -306,7 +310,7 @@ public function getSchemaFromMetadata(array $classes): Schema
306310
}
307311

308312
if (! $table->hasIndex('primary')) {
309-
$table->setPrimaryKey($pkColumns);
313+
self::addPrimaryKeyConstraint($table, $pkColumns);
310314
}
311315

312316
// there can be unique indexes automatically created for join column
@@ -572,7 +576,7 @@ private function gatherRelationsSql(
572576
$blacklistedFks,
573577
);
574578

575-
$theJoinTable->setPrimaryKey($primaryKeyColumns);
579+
self::addPrimaryKeyConstraint($theJoinTable, $primaryKeyColumns);
576580
}
577581
}
578582
}
@@ -923,4 +927,20 @@ private function createSchemaForComparison(Schema $toSchema): Schema
923927
$config->setSchemaAssetsFilter($previousFilter);
924928
}
925929
}
930+
931+
/** @param string[] $primaryKeyColumns */
932+
private function addPrimaryKeyConstraint(Table $table, array $primaryKeyColumns): void
933+
{
934+
if (class_exists(PrimaryKeyConstraint::class)) {
935+
$primaryKeyColumnNames = [];
936+
937+
foreach ($primaryKeyColumns as $primaryKeyColumn) {
938+
$primaryKeyColumnNames[] = new UnqualifiedName(Identifier::unquoted($primaryKeyColumn));
939+
}
940+
941+
$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, $primaryKeyColumnNames, true));
942+
} else {
943+
$table->setPrimaryKey($primaryKeyColumns);
944+
}
945+
}
926946
}

tests/Tests/ORM/Functional/DatabaseDriverTest.php

+57-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
99
use Doctrine\DBAL\Platforms\SQLServerPlatform;
1010
use Doctrine\DBAL\Schema\AbstractSchemaManager;
11+
use Doctrine\DBAL\Schema\Name\Identifier;
12+
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
13+
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
1114
use Doctrine\DBAL\Schema\Table;
1215
use PHPUnit\Framework\Attributes\Group;
1316

1417
use function array_change_key_case;
18+
use function class_exists;
1519
use function count;
1620
use function strtolower;
1721

@@ -36,12 +40,24 @@ public function testIssue2059(): void
3640
{
3741
$user = new Table('ddc2059_user');
3842
$user->addColumn('id', 'integer');
39-
$user->setPrimaryKey(['id']);
43+
44+
if (class_exists(PrimaryKeyConstraint::class)) {
45+
$user->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
46+
} else {
47+
$user->setPrimaryKey(['id']);
48+
}
49+
4050
$project = new Table('ddc2059_project');
4151
$project->addColumn('id', 'integer');
4252
$project->addColumn('user_id', 'integer');
4353
$project->addColumn('user', 'string');
44-
$project->setPrimaryKey(['id']);
54+
55+
if (class_exists(PrimaryKeyConstraint::class)) {
56+
$project->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
57+
} else {
58+
$project->setPrimaryKey(['id']);
59+
}
60+
4561
$project->addForeignKeyConstraint('ddc2059_user', ['user_id'], ['id']);
4662

4763
$metadata = $this->convertToClassMetadata([$project, $user], []);
@@ -54,7 +70,13 @@ public function testLoadMetadataFromDatabase(): void
5470
{
5571
$table = new Table('dbdriver_foo');
5672
$table->addColumn('id', 'integer');
57-
$table->setPrimaryKey(['id']);
73+
74+
if (class_exists(PrimaryKeyConstraint::class)) {
75+
$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
76+
} else {
77+
$table->setPrimaryKey(['id']);
78+
}
79+
5880
$table->addColumn('bar', 'string', ['notnull' => false, 'length' => 200]);
5981

6082
$this->dropAndCreateTable($table);
@@ -81,13 +103,24 @@ public function testLoadMetadataWithForeignKeyFromDatabase(): void
81103
{
82104
$tableB = new Table('dbdriver_bar');
83105
$tableB->addColumn('id', 'integer');
84-
$tableB->setPrimaryKey(['id']);
106+
107+
if (class_exists(PrimaryKeyConstraint::class)) {
108+
$tableB->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
109+
} else {
110+
$tableB->setPrimaryKey(['id']);
111+
}
85112

86113
$this->dropAndCreateTable($tableB);
87114

88115
$tableA = new Table('dbdriver_baz');
89116
$tableA->addColumn('id', 'integer');
90-
$tableA->setPrimaryKey(['id']);
117+
118+
if (class_exists(PrimaryKeyConstraint::class)) {
119+
$tableA->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
120+
} else {
121+
$tableA->setPrimaryKey(['id']);
122+
}
123+
91124
$tableA->addColumn('bar_id', 'integer');
92125
$tableA->addForeignKeyConstraint('dbdriver_bar', ['bar_id'], ['id']);
93126

@@ -127,11 +160,21 @@ public function testIgnoreManyToManyTableWithoutFurtherForeignKeyDetails(): void
127160
{
128161
$tableB = new Table('dbdriver_bar');
129162
$tableB->addColumn('id', 'integer');
130-
$tableB->setPrimaryKey(['id']);
163+
164+
if (class_exists(PrimaryKeyConstraint::class)) {
165+
$tableB->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
166+
} else {
167+
$tableB->setPrimaryKey(['id']);
168+
}
131169

132170
$tableA = new Table('dbdriver_baz');
133171
$tableA->addColumn('id', 'integer');
134-
$tableA->setPrimaryKey(['id']);
172+
173+
if (class_exists(PrimaryKeyConstraint::class)) {
174+
$tableA->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
175+
} else {
176+
$tableA->setPrimaryKey(['id']);
177+
}
135178

136179
$tableMany = new Table('dbdriver_bar_baz');
137180
$tableMany->addColumn('bar_id', 'integer');
@@ -148,7 +191,13 @@ public function testLoadMetadataFromDatabaseDetail(): void
148191
$table = new Table('dbdriver_foo');
149192

150193
$table->addColumn('id', 'integer', ['unsigned' => true]);
151-
$table->setPrimaryKey(['id']);
194+
195+
if (class_exists(PrimaryKeyConstraint::class)) {
196+
$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
197+
} else {
198+
$table->setPrimaryKey(['id']);
199+
}
200+
152201
$table->addColumn('column_unsigned', 'integer', ['unsigned' => true]);
153202
$table->addColumn('column_comment', 'string', ['length' => 16, 'comment' => 'test_comment']);
154203
$table->addColumn('column_default', 'string', ['length' => 16, 'default' => 'test_default']);

tests/Tests/ORM/Functional/Ticket/DDC2387Test.php

+18-2
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,40 @@
44

55
namespace Doctrine\Tests\ORM\Functional\Ticket;
66

7+
use Doctrine\DBAL\Schema\Name\Identifier;
8+
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
9+
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
710
use Doctrine\DBAL\Schema\Table;
811
use Doctrine\ORM\Mapping\ClassMetadata;
912
use Doctrine\Tests\ORM\Functional\DatabaseDriverTestCase;
1013
use PHPUnit\Framework\Attributes\Group;
1114

15+
use function class_exists;
16+
1217
class DDC2387Test extends DatabaseDriverTestCase
1318
{
1419
#[Group('DDC-2387')]
1520
public function testCompositeAssociationKeyDetection(): void
1621
{
1722
$product = new Table('ddc2387_product');
1823
$product->addColumn('id', 'integer');
19-
$product->setPrimaryKey(['id']);
24+
25+
if (class_exists(PrimaryKeyConstraint::class)) {
26+
$product->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
27+
} else {
28+
$product->setPrimaryKey(['id']);
29+
}
2030

2131
$attributes = new Table('ddc2387_attributes');
2232
$attributes->addColumn('product_id', 'integer');
2333
$attributes->addColumn('attribute_name', 'string');
24-
$attributes->setPrimaryKey(['product_id', 'attribute_name']);
34+
35+
if (class_exists(PrimaryKeyConstraint::class)) {
36+
$attributes->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('product_id')), new UnqualifiedName(Identifier::unquoted('attribute_name'))], true));
37+
} else {
38+
$attributes->setPrimaryKey(['product_id', 'attribute_name']);
39+
}
40+
2541
$attributes->addForeignKeyConstraint('ddc2387_product', ['product_id'], ['product_id']);
2642

2743
$metadata = $this->convertToClassMetadata([$product, $attributes], []);

tests/Tests/ORM/Functional/Ticket/GH7684Test.php

+18-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44

55
namespace Doctrine\Tests\ORM\Functional\Ticket;
66

7+
use Doctrine\DBAL\Schema\Name\Identifier;
8+
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
9+
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
710
use Doctrine\DBAL\Schema\Table;
811
use Doctrine\Tests\ORM\Functional\DatabaseDriverTestCase;
912

13+
use function class_exists;
14+
1015
/**
1116
* Verifies that associations/columns with an inline '_id' get named properly
1217
*
@@ -18,12 +23,23 @@ public function testIssue(): void
1823
{
1924
$table1 = new Table('GH7684_identity_test_table');
2025
$table1->addColumn('id', 'integer');
21-
$table1->setPrimaryKey(['id']);
26+
27+
if (class_exists(PrimaryKeyConstraint::class)) {
28+
$table1->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
29+
} else {
30+
$table1->setPrimaryKey(['id']);
31+
}
2232

2333
$table2 = new Table('GH7684_identity_test_assoc_table');
2434
$table2->addColumn('id', 'integer');
2535
$table2->addColumn('gh7684_identity_test_id', 'integer');
26-
$table2->setPrimaryKey(['id']);
36+
37+
if (class_exists(PrimaryKeyConstraint::class)) {
38+
$table2->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, [new UnqualifiedName(Identifier::unquoted('id'))], true));
39+
} else {
40+
$table2->setPrimaryKey(['id']);
41+
}
42+
2743
$table2->addForeignKeyConstraint('GH7684_identity_test', ['gh7684_identity_test_id'], ['id']);
2844

2945
$metadatas = $this->convertToClassMetadata([$table1, $table2]);

0 commit comments

Comments
 (0)