Browse files

Fixed DDC-657. Added type conversion to scalar result.

  • Loading branch information...
1 parent 52ee848 commit ea14bcff4a2a78bf774e8847b6645dca112f9757 @guilhermeblanco guilhermeblanco committed Jan 13, 2012
View
3 lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
@@ -210,6 +210,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;
@@ -232,6 +233,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;
View
12 lib/Doctrine/ORM/Query/ResultSetMapping.php
@@ -73,6 +73,12 @@ class ResultSetMapping
/**
* @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.
*/
public $entityMappings = array();
@@ -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';
@beberlei
Doctrine member

Why is not $type = 'string'? saves one line and some opcodes.

@guilhermeblanco
Doctrine member

Done. fdb2b9c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
if ( ! $this->isMixed && $this->fieldMappings) {
$this->isMixed = true;
View
12 lib/Doctrine/ORM/Query/SqlWalker.php
@@ -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());
}
@@ -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;
@@ -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'.
@FabioBatSilva
Doctrine member

@guilhermeblanco, maybe would be better omit the third parameter.
That already has a default value (string) inside of addScalarResult.

@guilhermeblanco
Doctrine member

I prefer to be descriptive here. Anyone evaluating Walker to implement his custom Walker would benefit of having a more descriptive scenario.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $this->_rsm->addScalarResult($columnAlias, $resultAlias, 'string');
}
break;
@@ -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;
View
118 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);
@stloyd
stloyd added a note Jan 16, 2012

Why not use assertInstanceOf() here, above and below ?

@guilhermeblanco
Doctrine member

Done. fdb2b9c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $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 ea14bcf

Please sign in to comment.