Skip to content

Commit 8c2e64f

Browse files
committed
Use the parser in AbstractAsset::_setName()
1 parent be2c22a commit 8c2e64f

17 files changed

+495
-367
lines changed

src/Schema/AbstractAsset.php

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
namespace Doctrine\DBAL\Schema;
66

77
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Schema\Exception\InvalidObjectName;
9+
use Doctrine\DBAL\Schema\Exception\UnsupportedQualifier;
10+
use Doctrine\DBAL\Schema\Name\Parser;
11+
use Doctrine\DBAL\Schema\Name\Parser\Identifier;
812

913
use function array_map;
14+
use function count;
1015
use function crc32;
1116
use function dechex;
12-
use function explode;
1317
use function implode;
14-
use function str_contains;
1518
use function str_replace;
1619
use function strtolower;
1720
use function strtoupper;
@@ -35,23 +38,53 @@ abstract class AbstractAsset
3538

3639
protected bool $_quoted = false;
3740

41+
/** @var list<Identifier> */
42+
private array $identifiers = [];
43+
3844
/**
3945
* Sets the name of this asset.
4046
*/
4147
protected function _setName(string $name): void
4248
{
43-
if ($this->isIdentifierQuoted($name)) {
44-
$this->_quoted = true;
45-
$name = $this->trimQuotes($name);
49+
if ($name !== '') {
50+
$parser = new Parser();
51+
52+
try {
53+
$identifiers = $parser->parse($name);
54+
} catch (Parser\Exception $e) {
55+
throw InvalidObjectName::new($e);
56+
}
57+
} else {
58+
$identifiers = [];
4659
}
4760

48-
if (str_contains($name, '.')) {
49-
$parts = explode('.', $name);
50-
$this->_namespace = $parts[0];
51-
$name = $parts[1];
61+
switch (count($identifiers)) {
62+
case 0:
63+
$this->_name = '';
64+
$this->_quoted = false;
65+
$this->_namespace = null;
66+
$this->identifiers = [];
67+
68+
return;
69+
case 1:
70+
$namespace = null;
71+
$name = $identifiers[0];
72+
break;
73+
74+
case 2:
75+
/** @psalm-suppress PossiblyUndefinedArrayOffset */
76+
[$namespace, $name] = $identifiers;
77+
break;
78+
79+
default:
80+
throw UnsupportedQualifier::new();
5281
}
5382

54-
$this->_name = $name;
83+
$this->identifiers = $identifiers;
84+
85+
$this->_name = $name->getValue();
86+
$this->_quoted = $name->isQuoted();
87+
$this->_namespace = $namespace?->getValue();
5588
}
5689

5790
/**
@@ -123,16 +156,20 @@ public function getName(): string
123156
}
124157

125158
/**
126-
* Gets the quoted representation of this asset but only if it was defined with one. Otherwise
127-
* return the plain unquoted value as inserted.
159+
* Returns the quoted representation of this asset's name. If the name is unquoted, it is normalized according to
160+
* the platform's unquoted name normalization rules.
128161
*/
129162
public function getQuotedName(AbstractPlatform $platform): string
130163
{
131-
$keywords = $platform->getReservedKeywordsList();
132-
$parts = explode('.', $this->getName());
133-
foreach ($parts as $k => $v) {
134-
$parts[$k] = $this->_quoted || $keywords->isKeyword($v) ? $platform->quoteSingleIdentifier($v) : $v;
135-
}
164+
$parts = array_map(static function (Identifier $identifier) use ($platform): string {
165+
$value = $identifier->getValue();
166+
167+
if (! $identifier->isQuoted()) {
168+
$value = $platform->normalizeUnquotedIdentifier($value);
169+
}
170+
171+
return $platform->quoteSingleIdentifier($value);
172+
}, $this->identifiers);
136173

137174
return implode('.', $parts);
138175
}

src/Schema/AbstractSchemaManager.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,7 @@ protected function _getPortableTableColumnList(string $table, string $database,
671671
foreach ($tableColumns as $tableColumn) {
672672
$column = $this->_getPortableTableColumnDefinition($tableColumn);
673673

674-
$name = strtolower($column->getQuotedName($this->platform));
675-
$list[$name] = $column;
674+
$list[strtolower($column->getName())] = $column;
676675
}
677676

678677
return $list;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Schema\Exception;
6+
7+
use Doctrine\DBAL\Schema\Name\Parser;
8+
use Doctrine\DBAL\Schema\SchemaException;
9+
use InvalidArgumentException;
10+
11+
/** @psalm-immutable */
12+
final class InvalidObjectName extends InvalidArgumentException implements SchemaException
13+
{
14+
public static function new(Parser\Exception $parserException): self
15+
{
16+
return new self('Unable to parse object name.', 0, $parserException);
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Schema\Exception;
6+
7+
use Doctrine\DBAL\Schema\SchemaException;
8+
use InvalidArgumentException;
9+
10+
/** @psalm-immutable */
11+
final class UnsupportedQualifier extends InvalidArgumentException implements SchemaException
12+
{
13+
public static function new(): self
14+
{
15+
return new self('UnsupportedQualifier');
16+
}
17+
}

tests/Functional/Schema/SQLiteSchemaManagerTest.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,13 @@ public function testShorthandInForeignKeyReferenceWithMultipleColumns(): void
384384

385385
self::assertSame(
386386
[
387-
'CREATE TABLE track (trackid INTEGER DEFAULT NULL, trackname CLOB DEFAULT NULL COLLATE "BINARY",'
388-
. ' trackartist INTEGER DEFAULT NULL, FOREIGN KEY (trackartist) REFERENCES artist (artistid, isrc) ON'
389-
. ' UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)',
390-
'CREATE INDEX IDX_D6E3F8A6FB96D8BC ON track (trackartist)',
387+
'CREATE TABLE "track" ('
388+
. '"trackid" INTEGER DEFAULT NULL,'
389+
. ' "trackname" CLOB DEFAULT NULL COLLATE "BINARY",'
390+
. ' "trackartist" INTEGER DEFAULT NULL,'
391+
. ' FOREIGN KEY ("trackartist") REFERENCES "artist" ("artistid", "isrc")'
392+
. ' ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)',
393+
'CREATE INDEX "IDX_D6E3F8A6FB96D8BC" ON "track" ("trackartist")',
391394
],
392395
$createTableTrackSql,
393396
);

tests/Functional/Schema/SchemaManagerFunctionalTestCase.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ public function testIntrospectReservedKeywordTableViaListTableDetails(): void
12931293
{
12941294
$this->createReservedKeywordTables();
12951295

1296-
$user = $this->schemaManager->introspectTable('"user"');
1296+
$user = $this->schemaManager->introspectTable('user');
12971297
self::assertCount(2, $user->getColumns());
12981298
self::assertCount(2, $user->getIndexes());
12991299
self::assertCount(1, $user->getForeignKeys());
@@ -1316,8 +1316,12 @@ private function createReservedKeywordTables(): void
13161316
{
13171317
$platform = $this->connection->getDatabasePlatform();
13181318

1319-
$this->dropTableIfExists($platform->quoteSingleIdentifier('user'));
1320-
$this->dropTableIfExists($platform->quoteSingleIdentifier('group'));
1319+
$this->dropTableIfExists($platform->quoteSingleIdentifier(
1320+
$platform->normalizeUnquotedIdentifier('user'),
1321+
));
1322+
$this->dropTableIfExists($platform->quoteSingleIdentifier(
1323+
$platform->normalizeUnquotedIdentifier('group'),
1324+
));
13211325

13221326
$schema = new Schema();
13231327

0 commit comments

Comments
 (0)