1
0
mirror of synced 2025-03-06 21:06:16 +03:00

Merge pull request #6416 from lcobucci/fix-quote-on-inheritance

Fix quoting when using inheritance as well
This commit is contained in:
Marco Pivetta 2017-05-02 09:42:03 +02:00 committed by GitHub
commit 2c1ebc4ef1
11 changed files with 143 additions and 72 deletions

View File

@ -1803,7 +1803,7 @@ class ClassMetadataInfo implements ClassMetadata
if ($this->isIdentifierComposite) { if ($this->isIdentifierComposite) {
throw MappingException::singleIdNotAllowedOnCompositePrimaryKey($this->name); throw MappingException::singleIdNotAllowedOnCompositePrimaryKey($this->name);
} }
if ( ! isset($this->identifier[0])) { if ( ! isset($this->identifier[0])) {
throw MappingException::noIdDefined($this->name); throw MappingException::noIdDefined($this->name);
} }
@ -2303,6 +2303,10 @@ class ClassMetadataInfo implements ClassMetadata
$this->table['name'] = $table['name']; $this->table['name'] = $table['name'];
} }
if (isset($table['quoted'])) {
$this->table['quoted'] = $table['quoted'];
}
if (isset($table['schema'])) { if (isset($table['schema'])) {
$this->table['schema'] = $table['schema']; $this->table['schema'] = $table['schema'];
} }

View File

@ -82,16 +82,18 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
/** /**
* @param string $tableAlias * @param string $tableAlias
* @param string $joinColumnName * @param string $joinColumnName
* @param string $quotedColumnName
*
* @param string $type * @param string $type
* *
* @return string * @return string
*/ */
protected function getSelectJoinColumnSQL($tableAlias, $joinColumnName, $type) protected function getSelectJoinColumnSQL($tableAlias, $joinColumnName, $quotedColumnName, $type)
{ {
$columnAlias = $this->getSQLColumnAlias($joinColumnName); $columnAlias = $this->getSQLColumnAlias($joinColumnName);
$this->currentPersisterContext->rsm->addMetaResult('r', $columnAlias, $joinColumnName, false, $type); $this->currentPersisterContext->rsm->addMetaResult('r', $columnAlias, $joinColumnName, false, $type);
return $tableAlias . '.' . $joinColumnName . ' AS ' . $columnAlias; return $tableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias;
} }
} }

View File

@ -462,21 +462,14 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
? $this->getSQLTableAlias($mapping['inherited']) ? $this->getSQLTableAlias($mapping['inherited'])
: $baseTableAlias; : $baseTableAlias;
foreach ($mapping['targetToSourceKeyColumns'] as $srcColumn) { $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
$className = isset($mapping['inherited'])
? $mapping['inherited']
: $this->class->name;
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
foreach ($mapping['joinColumns'] as $joinColumn) {
$columnList[] = $this->getSelectJoinColumnSQL( $columnList[] = $this->getSelectJoinColumnSQL(
$tableAlias, $tableAlias,
$srcColumn, $joinColumn['name'],
PersisterHelper::getTypeOfColumn( $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform),
$mapping['sourceToTargetKeyColumns'][$srcColumn], PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em)
$targetClass,
$this->em
)
); );
} }
} }
@ -510,21 +503,14 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
continue; continue;
} }
foreach ($mapping['targetToSourceKeyColumns'] as $srcColumn) { $targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
$className = isset($mapping['inherited'])
? $mapping['inherited']
: $subClass->name;
$targetClass = $this->em->getClassMetadata($mapping['targetEntity']);
foreach ($mapping['joinColumns'] as $joinColumn) {
$columnList[] = $this->getSelectJoinColumnSQL( $columnList[] = $this->getSelectJoinColumnSQL(
$tableAlias, $tableAlias,
$srcColumn, $joinColumn['name'],
PersisterHelper::getTypeOfColumn( $this->quoteStrategy->getJoinColumnName($joinColumn, $subClass, $this->platform),
$mapping['sourceToTargetKeyColumns'][$srcColumn], PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em)
$targetClass,
$this->em
)
); );
} }
} }

View File

@ -89,15 +89,12 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']); $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { foreach ($assoc['joinColumns'] as $joinColumn) {
$columnList[] = $this->getSelectJoinColumnSQL( $columnList[] = $this->getSelectJoinColumnSQL(
$tableAlias, $tableAlias,
$srcColumn, $joinColumn['name'],
PersisterHelper::getTypeOfColumn( $this->quoteStrategy->getJoinColumnName($joinColumn, $subClass, $this->platform),
$assoc['sourceToTargetKeyColumns'][$srcColumn], PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em)
$targetClass,
$this->em
)
); );
} }
} }

View File

@ -764,7 +764,7 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSQLColumnAlias($columnName); $columnAlias = $this->getSQLColumnAlias($columnName);
$columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em); $columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); $quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias; $sqlSelectExpressions[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias;
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $isIdentifier, $columnType); $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $isIdentifier, $columnType);
@ -793,7 +793,8 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSQLColumnAlias($columnName); $columnAlias = $this->getSQLColumnAlias($columnName);
$columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em); $columnType = PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias; $quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $subClass, $this->platform);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias;
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $subClass->isIdentifier($columnName), $columnType); $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $subClass->isIdentifier($columnName), $columnType);
} }

View File

@ -5,6 +5,9 @@ namespace Doctrine\Tests\Models\Quote;
/** /**
* @Entity * @Entity
* @Table(name="`quote-address`") * @Table(name="`quote-address`")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({"simple" = Address::class, "full" = FullAddress::class})
*/ */
class Address class Address
{ {
@ -51,4 +54,4 @@ class Address
return $this->user; return $this->user;
} }
} }

View File

@ -0,0 +1,27 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
* @Table(name="`quote-city`")
*/
class City
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer", name="`city-id`")
*/
public $id;
/**
* @Column(name="`city-name`")
*/
public $name;
public function __construct(string $name)
{
$this->name = $name;
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
*/
class FullAddress extends Address
{
/**
* @OneToOne(targetEntity=City::class, cascade={"persist"})
* @JoinColumn(name="`city-id`", referencedColumnName="`city-id`")
*
* @var City
*/
public $city;
}

View File

@ -3,6 +3,8 @@
namespace Doctrine\Tests\ORM\Functional\Ticket; namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Quote\Address; use Doctrine\Tests\Models\Quote\Address;
use Doctrine\Tests\Models\Quote\City;
use Doctrine\Tests\Models\Quote\FullAddress;
use Doctrine\Tests\Models\Quote\Group; use Doctrine\Tests\Models\Quote\Group;
use Doctrine\Tests\Models\Quote\Phone; use Doctrine\Tests\Models\Quote\Phone;
use Doctrine\Tests\Models\Quote\User; use Doctrine\Tests\Models\Quote\User;
@ -15,17 +17,9 @@ class GH6402Test extends OrmFunctionalTestCase
{ {
protected function setUp() protected function setUp()
{ {
parent::setUp(); $this->useModelSet('quote');
try { parent::setUp();
$this->setUpEntitySchema([
Address::class,
Group::class,
Phone::class,
User::class,
]);
} catch (\Exception $exception) {
}
} }
public function testFind() public function testFind()
@ -40,8 +34,28 @@ class GH6402Test extends OrmFunctionalTestCase
{ {
$id = $this->createAddress(); $id = $this->createAddress();
$addresses = $this->_em->createQuery("SELECT a FROM " . Address::class . " a WHERE a.id = :id") $addresses = $this->_em->createQuery('SELECT a FROM ' . Address::class . ' a WHERE a.id = :id')
->setParameter("id", $id) ->setParameter('id', $id)
->getResult();
self::assertCount(1, $addresses);
self::assertNotNull($addresses[0]->user);
}
public function testFindWithSubClass()
{
$id = $this->createFullAddress();
$address = $this->_em->find(FullAddress::class, $id);
self::assertNotNull($address->user);
}
public function testQueryWithSubClass()
{
$id = $this->createFullAddress();
$addresses = $this->_em->createQuery('SELECT a FROM ' . FullAddress::class . ' a WHERE a.id = :id')
->setParameter('id', $id)
->getResult(); ->getResult();
self::assertCount(1, $addresses); self::assertCount(1, $addresses);
@ -49,18 +63,34 @@ class GH6402Test extends OrmFunctionalTestCase
} }
private function createAddress() private function createAddress()
{
$address = new Address();
$address->zip = 'bar';
$this->persistAddress($address);
return $address->id;
}
private function createFullAddress()
{
$address = new FullAddress();
$address->zip = 'bar';
$address->city = new City('London');
$this->persistAddress($address);
return $address->id;
}
private function persistAddress(Address $address)
{ {
$user = new User(); $user = new User();
$user->name = "foo"; $user->name = "foo";
$address = new Address();
$address->zip = "bar";
$user->setAddress($address); $user->setAddress($address);
$this->_em->persist($user); $this->_em->persist($user);
$this->_em->flush(); $this->_em->flush();
$this->_em->clear(); $this->_em->clear();
return $address->id;
} }
} }

View File

@ -39,8 +39,7 @@ class SelectSqlGenerationTest extends OrmTestCase
* @param array $queryHints * @param array $queryHints
* @param array $queryParams * @param array $queryParams
*/ */
public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [] public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = [], array $queryParams = [])
)
{ {
try { try {
$query = $this->_em->createQuery($dqlToBeTested); $query = $this->_em->createQuery($dqlToBeTested);
@ -78,8 +77,7 @@ class SelectSqlGenerationTest extends OrmTestCase
* @param array $queryHints * @param array $queryHints
* @param array $queryParams * @param array $queryParams
*/ */
public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = [], array $queryParams = [] public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = [], array $queryParams = [])
)
{ {
$this->expectException($expectedException); $this->expectException($expectedException);
@ -892,7 +890,7 @@ class SelectSqlGenerationTest extends OrmTestCase
} }
/** /**
* @expectedException Doctrine\ORM\Query\QueryException * @expectedException \Doctrine\ORM\Query\QueryException
*/ */
public function testOrderBySupportsSingleValuedPathExpressionInverseSide() public function testOrderBySupportsSingleValuedPathExpressionInverseSide()
{ {
@ -1991,7 +1989,7 @@ class SelectSqlGenerationTest extends OrmTestCase
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a', 'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a',
'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1, q1_."address-id" AS addressid_2, q1_."address-zip" AS addresszip_3 FROM "quote-user" q0_ INNER JOIN "quote-address" q1_ ON q0_."address-id" = q1_."address-id"' 'SELECT q0_."user-id" AS userid_0, q0_."user-name" AS username_1, q1_."address-id" AS addressid_2, q1_."address-zip" AS addresszip_3, q1_.type AS type_4 FROM "quote-user" q0_ INNER JOIN "quote-address" q1_ ON q0_."address-id" = q1_."address-id" AND q1_.type IN (\'simple\', \'full\')'
); );
$this->assertSqlGeneration( $this->assertSqlGeneration(
@ -2006,7 +2004,7 @@ class SelectSqlGenerationTest extends OrmTestCase
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u', 'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u',
'SELECT q0_."address-id" AS addressid_0, q0_."address-zip" AS addresszip_1, q1_."user-id" AS userid_2, q1_."user-name" AS username_3 FROM "quote-address" q0_ INNER JOIN "quote-user" q1_ ON q0_."user-id" = q1_."user-id"' 'SELECT q0_."address-id" AS addressid_0, q0_."address-zip" AS addresszip_1, q1_."user-id" AS userid_2, q1_."user-name" AS username_3, q0_.type AS type_4 FROM "quote-address" q0_ INNER JOIN "quote-user" q1_ ON q0_."user-id" = q1_."user-id" WHERE q0_.type IN (\'simple\', \'full\')'
); );
$this->assertSqlGeneration( $this->assertSqlGeneration(

View File

@ -225,6 +225,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
], ],
'quote' => [ 'quote' => [
Models\Quote\Address::class, Models\Quote\Address::class,
Models\Quote\City::class,
Models\Quote\FullAddress::class,
Models\Quote\Group::class, Models\Quote\Group::class,
Models\Quote\NumericEntity::class, Models\Quote\NumericEntity::class,
Models\Quote\Phone::class, Models\Quote\Phone::class,
@ -480,10 +482,20 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
} }
if (isset($this->_usedModelSets['quote'])) { if (isset($this->_usedModelSets['quote'])) {
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-address")); $conn->executeUpdate(
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-group")); sprintf(
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-phone")); 'UPDATE %s SET %s = NULL',
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier("quote-user")); $platform->quoteIdentifier("quote-address"),
$platform->quoteIdentifier('user-id')
)
);
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-users-groups'));
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-group'));
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-phone'));
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-user'));
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-address'));
$conn->executeUpdate('DELETE FROM ' . $platform->quoteIdentifier('quote-city'));
} }
if (isset($this->_usedModelSets['vct_onetoone'])) { if (isset($this->_usedModelSets['vct_onetoone'])) {
@ -616,14 +628,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
{ {
$this->setUpDBALTypes(); $this->setUpDBALTypes();
$forceCreateTables = false;
if ( ! isset(static::$_sharedConn)) { if ( ! isset(static::$_sharedConn)) {
static::$_sharedConn = TestUtil::getConnection(); static::$_sharedConn = TestUtil::getConnection();
if (static::$_sharedConn->getDriver() instanceof SqliteDriver) {
$forceCreateTables = true;
}
} }
if (isset($GLOBALS['DOCTRINE_MARK_SQL_LOGS'])) { if (isset($GLOBALS['DOCTRINE_MARK_SQL_LOGS'])) {
@ -642,7 +648,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$classes = []; $classes = [];
foreach ($this->_usedModelSets as $setName => $bool) { foreach ($this->_usedModelSets as $setName => $bool) {
if ( ! isset(static::$_tablesCreated[$setName])/* || $forceCreateTables*/) { if ( ! isset(static::$_tablesCreated[$setName])) {
foreach (static::$_modelSets[$setName] as $className) { foreach (static::$_modelSets[$setName] as $className) {
$classes[] = $this->_em->getClassMetadata($className); $classes[] = $this->_em->getClassMetadata($className);
} }