1
0
mirror of synced 2025-01-18 14:31:40 +03:00

Add missing type mapping

Fixes DDC-3192
Refs DDC-2494

This is essentially a fix from DDC-2494 applied to SQLWalker.
The issue: type was not converted to PHP value when the result is fetched by
executing DQL query rather than using entity manager's findX(). Similar issue
for BasicEntityPersister (which is used when em's findX is executed) was fixed
in DDC-2494, but SQLWalker made the issue valid for any custom query.
This commit is contained in:
Alexander Kurilo 2014-06-26 16:42:50 +03:00
parent d98b4a5124
commit 38fcc66c16
2 changed files with 178 additions and 2 deletions

View File

@ -753,12 +753,20 @@ class SqlWalker implements TreeWalker
$owningClass = (isset($assoc['inherited'])) ? $this->em->getClassMetadata($assoc['inherited']) : $class;
$sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias);
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
$columnAlias = $this->getSQLColumnAlias($srcColumn);
$type = null;
$isIdentifier = (isset($assoc['id']) && $assoc['id'] === true);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
if (isset($targetClass->fieldNames[$targetColumn])) {
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
}
$this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, $isIdentifier, $type);
}
}

View File

@ -0,0 +1,168 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\Query;
/**
* @group DDC-2494
* @group non-cacheable
*/
class DDC3192Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
if (Type::hasType('ddc3192_currency_code')) {
$this->fail(
'Type ddc3192_currency_code exists for testing DDC-3192 only, ' .
'but it has already been registered for some reason'
);
}
Type::addType('ddc3192_currency_code', __NAMESPACE__ . '\DDC3192CurrencyCode');
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(DDC3192Currency::CLASSNAME),
$this->_em->getClassMetadata(DDC3192Transaction::CLASSNAME),
));
}
public function testIssue()
{
$currency = new DDC3192Currency('BYR');
$this->_em->persist($currency);
$this->_em->flush();
$amount = 50;
$transaction = new DDC3192Transaction($amount, $currency);
$this->_em->persist($transaction);
$this->_em->flush();
$this->_em->close();
$resultByPersister = $this->_em->find(DDC3192Transaction::CLASSNAME, $transaction->id);
// This works: DDC2494 makes persister set type mapping info to ResultSetMapping
$this->assertEquals('BYR', $resultByPersister->currency->code);
$this->_em->close();
$query = $this->_em->createQuery();
$query->setDQL('SELECT t FROM ' . DDC3192Transaction::CLASSNAME . ' t WHERE t.id = ?1');
$query->setParameter(1, $transaction->id);
$resultByQuery = $query->getSingleResult();
// This is fixed here: before the fix it used to return 974.
// because unlike the BasicEntityPersister, SQLWalker doesn't set type info
$this->assertEquals('BYR', $resultByQuery->currency->code);
}
}
/**
* @Table(name="ddc3192_currency")
* @Entity
*/
class DDC3192Currency
{
const CLASSNAME = __CLASS__;
/**
* @Id
* @Column(type="ddc3192_currency_code")
*/
public $code;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @OneToMany(targetEntity="DDC3192Transaction", mappedBy="currency")
*/
public $transactions;
public function __construct($code)
{
$this->code = $code;
}
}
/**
* @Table(name="ddc3192_transaction")
* @Entity
*/
class DDC3192Transaction
{
const CLASSNAME = __CLASS__;
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
public $id;
/**
* @var int
*
* @Column(type="integer")
*/
public $amount;
/**
* @var \Doctrine\Tests\ORM\Functional\Ticket\DDC3192Currency
*
* @ManyToOne(targetEntity="DDC3192Currency", inversedBy="transactions")
* @JoinColumn(name="currency_id", referencedColumnName="code", nullable=false)
*/
public $currency;
public function __construct($amount, DDC3192Currency $currency)
{
$this->amount = $amount;
$this->currency = $currency;
}
}
class DDC3192CurrencyCode extends Type
{
private static $map = array(
'BYR' => 974,
);
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return self::$map[$value];
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return array_search($value, self::$map);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'ddc3192_currency_code';
}
}