Fix DDC-2494
This commit is contained in:
parent
b15758bb42
commit
d685f592fe
@ -114,9 +114,8 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
}
|
||||
|
||||
// Convert field to a valid PHP value
|
||||
if (isset($cache[$column]['field'])) {
|
||||
$type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
|
||||
$value = $type->convertToPHPValue($value, $this->_platform);
|
||||
if (isset($cache[$column]['type'])) {
|
||||
$value = Type::getType($cache[$column]['type'])->convertToPHPValue($value, $this->_platform);
|
||||
}
|
||||
|
||||
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
|
||||
@ -145,44 +144,51 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
*/
|
||||
protected function hydrateColumnInfo($entityName, $column)
|
||||
{
|
||||
switch (true) {
|
||||
case (isset($this->_rsm->fieldMappings[$column])):
|
||||
$class = isset($this->declaringClasses[$column])
|
||||
? $this->declaringClasses[$column]
|
||||
: $this->class;
|
||||
|
||||
// If class is not part of the inheritance, ignore
|
||||
if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
|
||||
return null;
|
||||
}
|
||||
if (isset($this->_rsm->fieldMappings[$column])) {
|
||||
$name = $this->_rsm->fieldMappings[$column];
|
||||
$class = isset($this->declaringClasses[$column])
|
||||
? $this->declaringClasses[$column]
|
||||
: $this->class;
|
||||
|
||||
return array(
|
||||
'class' => $class,
|
||||
'name' => $this->_rsm->fieldMappings[$column],
|
||||
'field' => true,
|
||||
);
|
||||
|
||||
case (isset($this->_rsm->relationMap[$column])):
|
||||
$class = isset($this->_rsm->relationMap[$column])
|
||||
? $this->_rsm->relationMap[$column]
|
||||
: $this->class;
|
||||
|
||||
// If class is not self referencing, ignore
|
||||
if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Decide what to do with associations. It seems original code is incomplete.
|
||||
// One solution is to load the association, but it might require extra efforts.
|
||||
return array('name' => $column);
|
||||
|
||||
case (isset($this->_rsm->metaMappings[$column])):
|
||||
return array(
|
||||
'name' => $this->_rsm->metaMappings[$column]
|
||||
);
|
||||
|
||||
default:
|
||||
// If class is not part of the inheritance, ignore
|
||||
if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => $name,
|
||||
'type' => $class->fieldMappings[$name]['type']
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($this->_rsm->relationMap[$column])) {
|
||||
$class = isset($this->_rsm->relationMap[$column])
|
||||
? $this->_rsm->relationMap[$column]
|
||||
: $this->class;
|
||||
|
||||
// If class is not self referencing, ignore
|
||||
if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: Decide what to do with associations. It seems original code is incomplete.
|
||||
// One solution is to load the association, but it might require extra efforts.
|
||||
return array('name' => $column);
|
||||
}
|
||||
|
||||
if (isset($this->_rsm->metaMappings[$column])) {
|
||||
$name = $this->_rsm->metaMappings[$column];
|
||||
$type = isset($this->_rsm->typeMappings[$column])
|
||||
? $this->_rsm->typeMappings[$column]
|
||||
: null;
|
||||
|
||||
return array(
|
||||
'name' => $name,
|
||||
'type' => $type
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -1334,16 +1334,22 @@ class BasicEntityPersister
|
||||
return '';
|
||||
}
|
||||
|
||||
$columnList = array();
|
||||
$columnList = array();
|
||||
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
|
||||
$type = null;
|
||||
$isIdentifier = isset($assoc['id']) && $assoc['id'] === true;
|
||||
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
|
||||
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
|
||||
$columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
|
||||
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
|
||||
|
||||
$this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, isset($assoc['id']) && $assoc['id'] === true);
|
||||
if (isset($targetClass->fieldNames[$joinColumn['referencedColumnName']])) {
|
||||
$type = $targetClass->fieldMappings[$targetClass->fieldNames[$joinColumn['referencedColumnName']]]['type'];
|
||||
}
|
||||
|
||||
$this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type);
|
||||
}
|
||||
|
||||
return implode(', ', $columnList);
|
||||
|
@ -543,14 +543,15 @@ class ResultSetMapping
|
||||
/**
|
||||
* Adds a meta column (foreign key or discriminator column) to the result set.
|
||||
*
|
||||
* @param string $alias
|
||||
* @param string $columnName
|
||||
* @param string $fieldName
|
||||
* @param string $alias The result alias with which the meta result should be placed in the result structure.
|
||||
* @param string $columnName The name of the column in the SQL result set.
|
||||
* @param string $fieldName The name of the field on the declaring class.
|
||||
* @param bool $isIdentifierColumn
|
||||
* @param string $type The column type
|
||||
*
|
||||
* @return ResultSetMapping This ResultSetMapping instance.
|
||||
*/
|
||||
public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false)
|
||||
public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false, $type = null)
|
||||
{
|
||||
$this->metaMappings[$columnName] = $fieldName;
|
||||
$this->columnOwnerMap[$columnName] = $alias;
|
||||
@ -559,6 +560,10 @@ class ResultSetMapping
|
||||
$this->isIdentifierColumn[$alias][$columnName] = true;
|
||||
}
|
||||
|
||||
if ($type) {
|
||||
$this->typeMappings[$columnName] = $type;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
211
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
Normal file
211
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* @group DDC-2494
|
||||
*/
|
||||
class DDC2494Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
DDC2494TinyIntType::$calls = array();
|
||||
|
||||
Type::addType('ddc2494_tinyint', __NAMESPACE__ . '\DDC2494TinyIntType');
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(DDC2494Currency::CLASSNAME),
|
||||
$this->_em->getClassMetadata(DDC2494Campaign::CLASSNAME),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$currency = new DDC2494Currency(1, 2);
|
||||
|
||||
$this->_em->persist($currency);
|
||||
$this->_em->flush();
|
||||
|
||||
$campaign = new DDC2494Campaign($currency);
|
||||
|
||||
$this->_em->persist($campaign);
|
||||
$this->_em->flush();
|
||||
$this->_em->close();
|
||||
|
||||
$this->assertArrayHasKey('convertToDatabaseValue', DDC2494TinyIntType::$calls);
|
||||
$this->assertCount(3, DDC2494TinyIntType::$calls['convertToDatabaseValue']);
|
||||
|
||||
$item = $this->_em->find(DDC2494Campaign::CLASSNAME, $campaign->getId());
|
||||
|
||||
$this->assertInstanceOf(DDC2494Campaign::CLASSNAME, $item);
|
||||
$this->assertInstanceOf(DDC2494Currency::CLASSNAME, $item->getCurrency());
|
||||
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
|
||||
$this->assertInstanceOf('\Doctrine\Common\Proxy\Proxy', $item->getCurrency());
|
||||
$this->assertFalse($item->getCurrency()->__isInitialized());
|
||||
|
||||
$this->assertArrayHasKey('convertToPHPValue', DDC2494TinyIntType::$calls);
|
||||
$this->assertCount(1, DDC2494TinyIntType::$calls['convertToPHPValue']);
|
||||
|
||||
$this->assertInternalType('integer', $item->getCurrency()->getId());
|
||||
$this->assertCount(1, DDC2494TinyIntType::$calls['convertToPHPValue']);
|
||||
$this->assertFalse($item->getCurrency()->__isInitialized());
|
||||
|
||||
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
|
||||
|
||||
$this->assertInternalType('integer', $item->getCurrency()->getTemp());
|
||||
$this->assertCount(3, DDC2494TinyIntType::$calls['convertToPHPValue']);
|
||||
$this->assertTrue($item->getCurrency()->__isInitialized());
|
||||
|
||||
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2494_currency")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2494Currency
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer", type="ddc2494_tinyint")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @Column(name="temp", type="ddc2494_tinyint", nullable=false)
|
||||
*/
|
||||
protected $temp;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @OneToMany(targetEntity="DDC2494Campaign", mappedBy="currency")
|
||||
*/
|
||||
protected $campaigns;
|
||||
|
||||
public function __construct($id, $temp)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->temp = $temp;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getTemp()
|
||||
{
|
||||
return $this->temp;
|
||||
}
|
||||
|
||||
public function getCampaigns()
|
||||
{
|
||||
return $this->campaigns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2494_campaign")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2494Campaign
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\Tests\ORM\Functional\Ticket\DDC2494Currency
|
||||
*
|
||||
* @ManyToOne(targetEntity="DDC2494Currency", inversedBy="campaigns")
|
||||
* @JoinColumn(name="currency_id", referencedColumnName="id", nullable=false)
|
||||
*/
|
||||
protected $currency;
|
||||
|
||||
public function __construct(DDC2494Currency $currency)
|
||||
{
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Doctrine\Tests\ORM\Functional\Ticket\DDC2494Currency
|
||||
*/
|
||||
public function getCurrency()
|
||||
{
|
||||
return $this->currency;
|
||||
}
|
||||
}
|
||||
|
||||
class DDC2494TinyIntType extends Type
|
||||
{
|
||||
public static $calls = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
$return = (string) $value;
|
||||
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'return' => $return,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
$return = (integer) $value;
|
||||
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'return' => $return,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'ddc2494_tinyint';
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user