From 0fbb78e61a32151f471a401f2e15249b608729dc Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Sat, 21 Jan 2012 17:39:32 -0200 Subject: [PATCH] basic support, need some code refactory and improvements --- .../Internal/Hydration/AbstractHydrator.php | 12 ++++++++ .../ORM/Internal/Hydration/ObjectHydrator.php | 29 +++++++++++++++++++ lib/Doctrine/ORM/Query/SqlWalker.php | 22 ++++++++++++-- .../Tests/ORM/Functional/QueryTest.php | 2 +- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php index a5eae8b72..f8eb6b820 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -234,6 +234,18 @@ abstract class AbstractHydrator // maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping. continue 2; } + + if (isset ($this->_rsm->newObjectMappings[$key])) { + $cache[$key]['isNewObjectParameter'] = true; + } + } + + if (isset ($cache[$key]['isNewObjectParameter'])) { + $argIndex = $this->_rsm->newObjectMappings[$key]['argIndex']; + $objIndex = $this->_rsm->newObjectMappings[$key]['objIndex']; + $className = $this->_rsm->newObjectMappings[$key]['className']; + $rowData['newObjects'][$objIndex]['className'] = $className; + $rowData['newObjects'][$objIndex]['args'][$argIndex] = $cache[$key]['fieldName']; } if (isset($cache[$key]['isScalar'])) { diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index 3f48f8607..7275ffa76 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -330,6 +330,17 @@ class ObjectHydrator extends AbstractHydrator } } + // Extract "new" object constructor arguments. They're appended at the end. + if (isset($rowData['newObjects'])) { + $newObjects = $rowData['newObjects']; + + unset($rowData['newObjects']); + + if (empty($rowData)) { + ++$this->_resultCounter; + } + } + // Hydrate the data chunks foreach ($rowData as $dqlAlias => $data) { $entityName = $this->_rsm->aliasMap[$dqlAlias]; @@ -531,6 +542,24 @@ class ObjectHydrator extends AbstractHydrator $result[$resultKey][$name] = $value; } } + + // Append new object to mixed result sets + if (isset($newObjects)) { + if ( ! isset($resultKey) ) { + $resultKey = $this->_resultCounter - 1; + } + + foreach ($newObjects as $newObject) { + $args = array(); + $className = $newObject['className']; + foreach ($newObject['args'] as $index => $name) { + $args[$index] = $result[$resultKey][$name]; + } + $class = new \ReflectionClass($className); + $result[$resultKey] = $class->newInstanceArgs($args); + } + } + } /** diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index be9e59235..2fff87ff0 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -77,6 +77,13 @@ class SqlWalker implements TreeWalker */ private $sqlParamIndex = 0; + /** + * Counters for generating indexes. + * + * @var integer + */ + private $newObjectCounter; + /** * @var ParserResult */ @@ -1225,10 +1232,19 @@ class SqlWalker implements TreeWalker $sqlSelectExpressions = array(); $this->_rsm->newObjectMappings['className'] = $expr->className; - foreach ($expr->args as $e) { - $resultAliasMap = $this->scalarResultAliasMap; + $sqlSelectExpressions = array(); + $objIndex = $this->newObjectCounter ++; + foreach ($expr->args as $key => $e) { + $resultAliasMap = $this->scalarResultAliasMap; $sqlSelectExpressions[] = $this->walkSelectExpression($e); - $this->_rsm->newObjectMappings['resultAliasMap'][] = array_diff($this->scalarResultAliasMap, $resultAliasMap); + $scalarResultAliasMap = array_diff($this->scalarResultAliasMap, $resultAliasMap); + foreach ($scalarResultAliasMap as $aliasMap) { + $this->_rsm->newObjectMappings[$aliasMap] = array( + 'className' => $expr->className, + 'objIndex' => $objIndex, + 'argIndex' => $key + ); + } } $sql .= implode(', ', $sqlSelectExpressions); diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index 133b8910e..780c7e8a2 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -833,7 +833,7 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery("SELECT new Doctrine\Tests\Models\CMS\CmsUserDTO(u.name, e.email, a.city) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e JOIN u.address a ORDER BY u.name"); $result = $query->getResult(); - $this->assertEquals(3, count($result)); + $this->assertCount(3, $result); $this->markTestIncomplete();