Skip to content

Commit

Permalink
Fixed DDC-657. Added type conversion to scalar result.
Browse files Browse the repository at this point in the history
  • Loading branch information
guilhermeblanco authored and beberlei committed Jan 16, 2012
1 parent d535e1c commit c73dae1
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 5 deletions.
3 changes: 3 additions & 0 deletions lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
Expand Up @@ -209,6 +209,7 @@ protected function gatherRowData(array $data, array &$cache, array &$id, array &

case (isset($this->_rsm->scalarMappings[$key])):
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['type'] = Type::getType($this->_rsm->typeMappings[$key]);
$cache[$key]['isScalar'] = true;
break;

Expand All @@ -231,6 +232,8 @@ protected function gatherRowData(array $data, array &$cache, array &$id, array &
}

if (isset($cache[$key]['isScalar'])) {
$value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);

$rowData['scalars'][$cache[$key]['fieldName']] = $value;

continue;
Expand Down
12 changes: 11 additions & 1 deletion lib/Doctrine/ORM/Query/ResultSetMapping.php
Expand Up @@ -71,6 +71,12 @@ class ResultSetMapping
*/
public $scalarMappings = array();

/**
* @ignore
* @var array Maps column names in the result set to the alias/field type to use in the mapped result.
*/
public $typeMappings = array();

/**
* @ignore
* @var array Maps entities in the result set to the alias name to use in the mapped result.
Expand Down Expand Up @@ -296,12 +302,16 @@ public function addJoinedEntityResult($class, $alias, $parentAlias, $relation)
*
* @param string $columnName The name of the column in the SQL result set.
* @param string $alias The result alias with which the scalar result should be placed in the result structure.
* @param string $type The column type
*
* @return ResultSetMapping This ResultSetMapping instance.
*
* @todo Rename: addScalar
*/
public function addScalarResult($columnName, $alias)
public function addScalarResult($columnName, $alias, $type = null)
{
$this->scalarMappings[$columnName] = $alias;
$this->typeMappings[$columnName] = $type ?: 'string';

if ( ! $this->isMixed && $this->fieldMappings) {
$this->isMixed = true;
Expand Down
12 changes: 8 additions & 4 deletions lib/Doctrine/ORM/Query/SqlWalker.php
Expand Up @@ -1084,8 +1084,10 @@ public function walkSelectExpression($selectExpression)

$col = $sqlTableAlias . '.' . $columnName;

$fieldType = $class->getTypeOfField($fieldName);

if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) {
$type = Type::getType($class->getTypeOfField($fieldName));
$type = Type::getType($fieldType);
$col = $type->convertToPHPValueSQL($col, $this->_conn->getDatabasePlatform());
}

Expand All @@ -1094,7 +1096,7 @@ public function walkSelectExpression($selectExpression)
$this->_scalarResultAliasMap[$resultAlias] = $columnAlias;

if ( ! $hidden) {
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias, $fieldType);
$this->_scalarFields[$dqlAlias][$fieldName] = $columnAlias;
}
break;
Expand All @@ -1118,7 +1120,8 @@ public function walkSelectExpression($selectExpression)
$this->_scalarResultAliasMap[$resultAlias] = $columnAlias;

if ( ! $hidden) {
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
// We cannot resolve field type here; assume 'string'.
$this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string');
}
break;

Expand All @@ -1131,7 +1134,8 @@ public function walkSelectExpression($selectExpression)
$this->_scalarResultAliasMap[$resultAlias] = $columnAlias;

if ( ! $hidden) {
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
// We cannot resolve field type here; assume 'string'.
$this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string');
}
break;

Expand Down
118 changes: 118 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/DDC657Test.php
@@ -0,0 +1,118 @@
<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;

require_once __DIR__ . '/../../../TestInit.php';

use Doctrine\Tests\Models\Generic\DateTimeModel;

/**
* @group DDC-657
*/
class DDC657Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
const NS = 'Doctrine\Tests\Models\Generic';

protected function setUp()
{
$this->useModelSet('generic');
parent::setUp();

$this->loadFixtures();
}

public function testEntitySingleResult()
{
$query = $this->_em->createQuery('SELECT d FROM ' . self::NS . '\DateTimeModel d');
$datetime = $query->setMaxResults(1)->getSingleResult();

$this->assertTrue($datetime instanceof DateTimeModel);

$this->assertTrue($datetime->datetime instanceof \DateTime);
$this->assertTrue($datetime->time instanceof \DateTime);
$this->assertTrue($datetime->date instanceof \DateTime);
}

public function testScalarResult()
{
$query = $this->_em->createQuery('SELECT d.id, d.time, d.date, d.datetime FROM ' . self::NS . '\DateTimeModel d ORDER BY d.date ASC');
$result = $query->getScalarResult();

$this->assertCount(2,$result);

$this->assertEquals('11:11:11', $result[0]['time']);
$this->assertEquals('2010-01-01', $result[0]['date']);
$this->assertEquals('2010-01-01 11:11:11', $result[0]['datetime']);

$this->assertEquals('12:12:12', $result[1]['time']);
$this->assertEquals('2010-02-02', $result[1]['date']);
$this->assertEquals('2010-02-02 12:12:12', $result[1]['datetime']);
}

public function testaTicketEntityArrayResult()
{
$query = $this->_em->createQuery('SELECT d FROM ' . self::NS . '\DateTimeModel d ORDER BY d.date ASC');
$result = $query->getArrayResult();

$this->assertCount(2,$result);

$this->assertTrue($result[0]['datetime'] instanceof \DateTime);
$this->assertTrue($result[0]['time'] instanceof \DateTime);
$this->assertTrue($result[0]['date'] instanceof \DateTime);

$this->assertTrue($result[1]['datetime'] instanceof \DateTime);
$this->assertTrue($result[1]['time'] instanceof \DateTime);
$this->assertTrue($result[1]['date'] instanceof \DateTime);
}

public function testTicketSingleResult()
{
$query = $this->_em->createQuery('SELECT d.id, d.time, d.date, d.datetime FROM ' . self::NS . '\DateTimeModel d ORDER BY d.date ASC');
$datetime = $query->setMaxResults(1)->getSingleResult();

$this->assertTrue(is_array($datetime));

$this->assertTrue($datetime['datetime'] instanceof \DateTime);
$this->assertTrue($datetime['time'] instanceof \DateTime);
$this->assertTrue($datetime['date'] instanceof \DateTime);
}

public function testTicketResult()
{
$query = $this->_em->createQuery('SELECT d.id, d.time, d.date, d.datetime FROM ' . self::NS . '\DateTimeModel d ORDER BY d.date ASC');
$result = $query->getResult();

$this->assertCount(2,$result);

$this->assertTrue($result[0]['time'] instanceof \DateTime);
$this->assertTrue($result[0]['date'] instanceof \DateTime);
$this->assertTrue($result[0]['datetime'] instanceof \DateTime);
$this->assertEquals('2010-01-01 11:11:11', $result[0]['datetime']->format('Y-m-d G:i:s'));

$this->assertTrue($result[1]['time'] instanceof \DateTime);
$this->assertTrue($result[1]['date'] instanceof \DateTime);
$this->assertTrue($result[1]['datetime'] instanceof \DateTime);
$this->assertEquals('2010-02-02 12:12:12', $result[1]['datetime']->format('Y-m-d G:i:s'));
}

public function loadFixtures()
{
$timezone = new \DateTimeZone('America/Sao_Paulo');

$dateTime1 = new DateTimeModel();
$dateTime2 = new DateTimeModel();

$dateTime1->date = new \DateTime('2010-01-01', $timezone);
$dateTime1->time = new \DateTime('2010-01-01 11:11:11', $timezone);
$dateTime1->datetime= new \DateTime('2010-01-01 11:11:11', $timezone);

$dateTime2->date = new \DateTime('2010-02-02', $timezone);
$dateTime2->time = new \DateTime('2010-02-02 12:12:12', $timezone);
$dateTime2->datetime= new \DateTime('2010-02-02 12:12:12', $timezone);

$this->_em->persist($dateTime1);
$this->_em->persist($dateTime2);

$this->_em->flush();
}
}

0 comments on commit c73dae1

Please sign in to comment.