diff --git a/src/Provider/Doctrine/Persistence/Schema/SchemaManager.php b/src/Provider/Doctrine/Persistence/Schema/SchemaManager.php index 4b640dd..c448be2 100644 --- a/src/Provider/Doctrine/Persistence/Schema/SchemaManager.php +++ b/src/Provider/Doctrine/Persistence/Schema/SchemaManager.php @@ -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 ); } diff --git a/tests/Provider/Doctrine/Persistence/Helper/PlatformHelperTest.php b/tests/Provider/Doctrine/Persistence/Helper/PlatformHelperTest.php index d564189..8f98502 100644 --- a/tests/Provider/Doctrine/Persistence/Helper/PlatformHelperTest.php +++ b/tests/Provider/Doctrine/Persistence/Helper/PlatformHelperTest.php @@ -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]; } } diff --git a/tests/Provider/Doctrine/Persistence/Schema/SchemaManagerTest.php b/tests/Provider/Doctrine/Persistence/Schema/SchemaManagerTest.php index e7b915b..e2d6187 100644 --- a/tests/Provider/Doctrine/Persistence/Schema/SchemaManagerTest.php +++ b/tests/Provider/Doctrine/Persistence/Schema/SchemaManagerTest.php @@ -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; @@ -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> + */ + 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);