Skip to content

Commit d3e1440

Browse files
authored
Handle quoted PK columns properly on DBAL 4 (#12208)
1 parent a9bd00a commit d3e1440

File tree

4 files changed

+74
-19
lines changed

4 files changed

+74
-19
lines changed

phpstan-baseline.neon

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3268,31 +3268,25 @@ parameters:
32683268
path: src/Tools/SchemaTool.php
32693269

32703270
-
3271-
message: '#^Parameter \#1 \$columnNames of method Doctrine\\DBAL\\Schema\\Table\:\:setPrimaryKey\(\) expects non\-empty\-list\<string\>, array\<string\> given\.$#'
3272-
identifier: argument.type
3273-
count: 1
3274-
path: src/Tools/SchemaTool.php
3275-
3276-
-
3277-
message: '#^Parameter \#1 \$value of static method Doctrine\\DBAL\\Schema\\Name\\Identifier\:\:unquoted\(\) expects non\-empty\-string, string given\.$#'
3271+
message: '#^Parameter \#2 \$columns of class Doctrine\\DBAL\\Schema\\Index constructor expects non\-empty\-list\<string\>, list\<string\> given\.$#'
32783272
identifier: argument.type
32793273
count: 1
32803274
path: src/Tools/SchemaTool.php
32813275

32823276
-
3283-
message: '#^Parameter \#2 \$columnNames of class Doctrine\\DBAL\\Schema\\PrimaryKeyConstraint constructor expects non\-empty\-list\<Doctrine\\DBAL\\Schema\\Name\\UnqualifiedName\>, list\<Doctrine\\DBAL\\Schema\\Name\\UnqualifiedName\> given\.$#'
3277+
message: '#^Parameter \#2 \$localColumnNames of method Doctrine\\DBAL\\Schema\\Table\:\:addForeignKeyConstraint\(\) expects non\-empty\-list\<string\>, list\<string\> given\.$#'
32843278
identifier: argument.type
32853279
count: 1
32863280
path: src/Tools/SchemaTool.php
32873281

32883282
-
3289-
message: '#^Parameter \#2 \$columns of class Doctrine\\DBAL\\Schema\\Index constructor expects non\-empty\-list\<string\>, list\<string\> given\.$#'
3283+
message: '#^Parameter \#2 \$primaryKeyColumns of method Doctrine\\ORM\\Tools\\SchemaTool\:\:addPrimaryKeyConstraint\(\) expects non\-empty\-array\<non\-empty\-string\>, list\<string\> given\.$#'
32903284
identifier: argument.type
3291-
count: 1
3285+
count: 2
32923286
path: src/Tools/SchemaTool.php
32933287

32943288
-
3295-
message: '#^Parameter \#2 \$localColumnNames of method Doctrine\\DBAL\\Schema\\Table\:\:addForeignKeyConstraint\(\) expects non\-empty\-list\<string\>, list\<string\> given\.$#'
3289+
message: '#^Parameter \#2 \$primaryKeyColumns of method Doctrine\\ORM\\Tools\\SchemaTool\:\:addPrimaryKeyConstraint\(\) expects non\-empty\-array\<non\-empty\-string\>, non\-empty\-list\<string\> given\.$#'
32963290
identifier: argument.type
32973291
count: 1
32983292
path: src/Tools/SchemaTool.php

phpstan-dbal3.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ parameters:
3434
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::addPrimaryKeyConstraint\(\)\.$~'
3535
path: src/Tools/SchemaTool.php
3636

37+
-
38+
message: '~^Call to static method quoted\(\) on an unknown class Doctrine\\DBAL\\Schema\\Name\\Identifier\.$~'
39+
path: src/Tools/SchemaTool.php
40+
3741
-
3842
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\ForeignKeyConstraint::get.*\.$~'
3943
identifier: method.notFound

src/Tools/SchemaTool.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use function array_flip;
4040
use function array_intersect_key;
4141
use function array_map;
42+
use function array_values;
4243
use function assert;
4344
use function class_exists;
4445
use function count;
@@ -47,6 +48,7 @@
4748
use function in_array;
4849
use function is_numeric;
4950
use function method_exists;
51+
use function preg_match;
5052
use function strtolower;
5153

5254
/**
@@ -971,20 +973,26 @@ private function createSchemaForComparison(Schema $toSchema): Schema
971973
}
972974
}
973975

974-
/** @param string[] $primaryKeyColumns */
976+
/** @param non-empty-array<non-empty-string> $primaryKeyColumns */
975977
private function addPrimaryKeyConstraint(Table $table, array $primaryKeyColumns): void
976978
{
977-
if (class_exists(PrimaryKeyConstraint::class)) {
978-
$primaryKeyColumnNames = [];
979+
if (! class_exists(PrimaryKeyConstraint::class)) {
980+
$table->setPrimaryKey(array_values($primaryKeyColumns));
979981

980-
foreach ($primaryKeyColumns as $primaryKeyColumn) {
982+
return;
983+
}
984+
985+
$primaryKeyColumnNames = [];
986+
987+
foreach ($primaryKeyColumns as $primaryKeyColumn) {
988+
if (preg_match('/^"(.+)"$/', $primaryKeyColumn, $matches) === 1) {
989+
$primaryKeyColumnNames[] = new UnqualifiedName(Identifier::quoted($matches[1]));
990+
} else {
981991
$primaryKeyColumnNames[] = new UnqualifiedName(Identifier::unquoted($primaryKeyColumn));
982992
}
983-
984-
$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, $primaryKeyColumnNames, true));
985-
} else {
986-
$table->setPrimaryKey($primaryKeyColumns);
987993
}
994+
995+
$table->addPrimaryKeyConstraint(new PrimaryKeyConstraint(null, $primaryKeyColumnNames, true));
988996
}
989997

990998
/** @return string[] */

tests/Tests/ORM/Tools/SchemaToolTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Doctrine\DBAL\Schema\Index\IndexedColumn;
1111
use Doctrine\DBAL\Schema\Index\IndexType;
1212
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
13+
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
1314
use Doctrine\DBAL\Schema\PrimaryKeyConstraintEditor;
1415
use Doctrine\DBAL\Schema\Table as DbalTable;
1516
use Doctrine\ORM\Mapping\ClassMetadata;
@@ -432,6 +433,41 @@ public function testLoadUniqueConstraintWithoutName(): void
432433
self::assertSame(['field', 'anotherField'], self::getIndexedColumns($tableIndex));
433434
}
434435

436+
public function testQuotedIdentifiers(): void
437+
{
438+
$em = $this->getTestEntityManager();
439+
$schemaTool = new SchemaTool($em);
440+
$classes = [$em->getClassMetadata(QuotedEntity::class)];
441+
442+
$schema = $schemaTool->getSchemaFromMetadata($classes);
443+
444+
self::assertTrue($schema->hasTable('quoted-table'), 'Table quoted-table should exist.');
445+
446+
$table = $schema->getTable('quoted-table');
447+
448+
self::assertTrue($table->hasIndex('IDX_AA2790FB50D14D90'));
449+
450+
// DBAL < 4.3
451+
if (! class_exists(PrimaryKeyConstraint::class)) {
452+
self::assertTrue($table->isQuoted(), 'The table name must be quoted.');
453+
self::assertTrue($table->hasIndex('primary'), 'Table should have a primary key.');
454+
455+
return;
456+
}
457+
458+
$objectName = $table->getObjectName();
459+
self::assertTrue($objectName->getUnqualifiedName()->isQuoted());
460+
self::assertSame('quoted-table', $objectName->getUnqualifiedName()->getValue());
461+
462+
$primaryKey = $table->getPrimaryKeyConstraint();
463+
self::assertNotNull($primaryKey);
464+
self::assertCount(1, $primaryKey->getColumnNames());
465+
466+
[$pkColumn] = $primaryKey->getColumnNames();
467+
self::assertTrue($pkColumn->getIdentifier()->isQuoted());
468+
self::assertSame('quoted-id', $pkColumn->getIdentifier()->getValue());
469+
}
470+
435471
/** @return string[] */
436472
private static function getIndexedColumns(DbalIndex $index): array
437473
{
@@ -674,3 +710,16 @@ public static function loadMetadata(ClassMetadata $metadata): void
674710
);
675711
}
676712
}
713+
714+
#[Entity]
715+
#[Table(name: '`quoted-table`')]
716+
#[Index(columns: ['`quoted-name`'])]
717+
class QuotedEntity
718+
{
719+
#[Id]
720+
#[Column(name: '`quoted-id`')]
721+
public int $id = 0;
722+
723+
#[Column(name: '`quoted-name`')]
724+
public string $name = '';
725+
}

0 commit comments

Comments
 (0)