From 7f309a20f803c490638ffb7e1c48b25c4aeb2f82 Mon Sep 17 00:00:00 2001 From: Stephen Lewis Date: Thu, 2 Jan 2020 18:58:09 +0000 Subject: [PATCH] Quote table names that also are reserved keywords Essentially, purging the database in DELETE mode prior to fixture load fails if any fixture entities use tables names with reserved words (e.g. 'User' in Postgres, or in the test case 'Group' in sqlite). The change makes ORMPurger->getTableName() use the same method as AbstractPlatform::getTruncateTableSQL() uses to get the table name (quoted as necessary). Test case uses sqlite reserved word 'Group' as an example and checks returned table name is quoted correctly. --- .../Common/DataFixtures/Purger/ORMPurger.php | 12 +++-- .../DataFixtures/Purger/ORMPurgerTest.php | 15 ++++++ .../Common/DataFixtures/TestEntity/Group.php | 49 +++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 tests/Doctrine/Tests/Common/DataFixtures/TestEntity/Group.php diff --git a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php index 6aa24105..1be4d48c 100644 --- a/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php +++ b/lib/Doctrine/Common/DataFixtures/Purger/ORMPurger.php @@ -6,11 +6,13 @@ use Doctrine\Common\DataFixtures\Sorter\TopologicalSorter; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Schema\Identifier; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use function array_reverse; use function array_search; use function count; +use function implode; use function is_callable; use function method_exists; use function preg_match; @@ -246,11 +248,15 @@ private function getAssociationTables(array $classes, AbstractPlatform $platform */ private function getTableName($class, $platform) { - if (isset($class->table['schema']) && ! method_exists($class, 'getSchemaName')) { - return $class->table['schema'] . '.' . $this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform); + if (method_exists($class, 'getSchemaName')) { + $identifier[] = $class->getSchemaName(); + } elseif (isset($class->table['schema'])) { + $identifier[] = $class->table['schema']; } - return $this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform); + $identifier[] = $class->getTableName(); + + return (new Identifier(implode('.', $identifier)))->getQuotedName($platform); } /** diff --git a/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerTest.php b/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerTest.php index 29b407af..257d6fc2 100644 --- a/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerTest.php +++ b/tests/Doctrine/Tests/Common/DataFixtures/Purger/ORMPurgerTest.php @@ -15,6 +15,7 @@ class ORMPurgerTest extends BaseTest public const TEST_ENTITY_USER = TestEntity\User::class; public const TEST_ENTITY_USER_WITH_SCHEMA = TestEntity\UserWithSchema::class; public const TEST_ENTITY_QUOTED = TestEntity\Quoted::class; + public const TEST_ENTITY_GROUP = TestEntity\Group::class; public function testGetAssociationTables() { @@ -54,4 +55,18 @@ public function testTableNameWithSchema() $tableName = $method->invokeArgs($purger, [$metadata, $platform]); $this->assertStringStartsWith('test_schema', $tableName); } + + public function testGetTableNameQuoted() : void + { + $em = $this->getMockAnnotationReaderEntityManager(); + $metadata = $em->getClassMetadata(self::TEST_ENTITY_GROUP); + $platform = $em->getConnection()->getDatabasePlatform(); + $purger = new ORMPurger($em); + $class = new ReflectionClass(ORMPurger::class); + $method = $class->getMethod('getTableName'); + $method->setAccessible(true); + $tableName = $method->invokeArgs($purger, [$metadata, $platform]); + $this->assertStringStartsWith('"', $tableName); + $this->assertStringEndsWith('"', $tableName); + } } diff --git a/tests/Doctrine/Tests/Common/DataFixtures/TestEntity/Group.php b/tests/Doctrine/Tests/Common/DataFixtures/TestEntity/Group.php new file mode 100644 index 00000000..aa590ace --- /dev/null +++ b/tests/Doctrine/Tests/Common/DataFixtures/TestEntity/Group.php @@ -0,0 +1,49 @@ +id = $id; + } + + public function getId() : ?int + { + return $this->id; + } + + public function setCode($code) : void + { + $this->code = $code; + } + + public function getCode() : ?string + { + return $this->code; + } +}