Skip to content

Commit

Permalink
Add support to quoted entity table names, fixes #196
Browse files Browse the repository at this point in the history
  • Loading branch information
DamienHarper committed Jan 10, 2025
1 parent 7feab9d commit a6f1b93
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 10 deletions.
40 changes: 33 additions & 7 deletions src/Provider/Doctrine/Persistence/Schema/SchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,39 @@ public function resolveAuditTableName(string $entity, Configuration $configurati
*/
public function computeAuditTablename(string $entityTableName, Configuration $configuration): ?string
{
return preg_replace(
'#^([^.]+\.)?(.+)$#',
\sprintf(
'$1%s$2%s',
preg_quote($configuration->getTablePrefix(), '#'),
preg_quote($configuration->getTableSuffix(), '#')
),
$prefix = $configuration->getTablePrefix();
$suffix = $configuration->getTableSuffix();

// For performance reasons, we only process the table name with preg_replace_callback and a regex
// if the entity's table name contains a dot, a quote or a backtick
if (!str_contains($entityTableName, '.') && !str_contains($entityTableName, '"') && !str_contains($entityTableName, '`')) {
return $prefix.$entityTableName.$suffix;
}

return preg_replace_callback(
'#^(?:(["`])?([^."`]+)["`]?\.)?(["`]?)([^."`]+)["`]?$#',
static function (array $matches) use ($prefix, $suffix): string {
$schemaDelimiter = $matches[1]; // Opening schema quote/backtick
$schema = $matches[2]; // Captures raw schema name (if exists)
$tableDelimiter = $matches[3]; // Opening table quote/backtick
$tableName = $matches[4]; // Captures raw table name

$newTableName = $prefix.$tableName.$suffix;

if ('"' === $tableDelimiter || '`' === $tableDelimiter) {
$newTableName = $tableDelimiter.$newTableName.$tableDelimiter;
}

if ($schema) {
if ('"' === $schemaDelimiter || '`' === $schemaDelimiter) {
$schema = $schemaDelimiter.$schema.$schemaDelimiter;
}

return $schema.'.'.$newTableName;
}

return $newTableName;
},
$entityTableName
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public function testIsJsonSupportedForMariaDb(string $mariaDbVersion, bool $expe
*/
public static function provideMariaDbVersionCases(): iterable
{
yield '10.2.6' => ['10.2.6', false];
yield ['10.2.6', false];

yield '10.2.7' => ['10.2.7', true];
yield ['10.2.7', true];

yield '10.11.8-MariaDB-0ubuntu0.24.04.1' => ['10.11.8-MariaDB-0ubuntu0.24.04.1', true];
yield ['10.11.8-MariaDB-0ubuntu0.24.04.1', true];
}
}
38 changes: 38 additions & 0 deletions tests/Provider/Doctrine/Persistence/Schema/SchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\Attributes\Small;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -280,6 +281,43 @@ public function testUpdateAuditTable(): void
}
}

#[DataProvider('provideTableNames')]
public function testComputeAuditTableName(string $tableName, string $expectedResult): void
{
$schemaManager = new SchemaManager($this->provider);
$this->assertSame($expectedResult, $schemaManager->computeAuditTableName($tableName, $this->provider->getConfiguration()));
}

/**
* @return iterable<string, array<bool|string>>
*/
public static function provideTableNames(): iterable
{
yield ['user', 'user_audit'];

yield ['schema.user', 'schema.user_audit'];

yield ['"user"', '"user_audit"'];

yield ['`user`', '`user_audit`'];

yield ['"schema"."user"', '"schema"."user_audit"'];

yield ['"schema".user', '"schema".user_audit'];

yield ['"schema".`user`', '"schema".`user_audit`'];

yield ['schema."user"', 'schema."user_audit"'];

yield ['schema.`user`', 'schema.`user_audit`'];

yield ['`schema`."user"', '`schema`."user_audit"'];

yield ['`schema`.`user`', '`schema`.`user_audit`'];

yield ['`schema`.user', '`schema`.user_audit'];
}

private function migrate(Schema $fromSchema, Schema $toSchema, EntityManagerInterface $entityManager): void
{
$sqls = DoctrineHelper::getMigrateToSql($entityManager->getConnection(), $fromSchema, $toSchema);
Expand Down

0 comments on commit a6f1b93

Please sign in to comment.