diff --git a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php index ceacc9638..95d548daf 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php +++ b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php @@ -67,6 +67,7 @@ class ResultSetMappingBuilder extends ResultSetMapping } $this->addFieldResult($alias, $platform->getSQLResultCasing($columnName), $propertyName); } + $this->addAssocationMappings($alias, $classMetadata->getAssociationMappings()); } /** @@ -96,5 +97,23 @@ class ResultSetMappingBuilder extends ResultSetMapping } $this->addFieldResult($alias, $platform->getSQLResultCasing($columnName), $propertyName); } + $this->addAssocationMappings($alias, $classMetadata->getAssociationMappings()); + } + + protected function addAssocationMappings($alias, $associationMappings) + { + $platform = $this->em->getConnection()->getDatabasePlatform(); + foreach ($associationMappings AS $associationMapping) { + if (isset($associationMapping['joinColumns'])) { + foreach ($associationMapping['joinColumns'] AS $joinColumn) { + $columnName = $joinColumn['name']; + $renamedColumnName = isset($renamedColumns[$columnName]) ? $renamedColumns[$columnName] : $columnName; + if (isset($this->metaMappings[$renamedColumnName])) { + throw new \InvalidArgumentException("The column '$renamedColumnName' conflicts with another column in the mapper."); + } + $this->addMetaResult($alias, $platform->getSQLResultCasing($renamedColumnName), $platform->getSQLResultCasing($columnName)); + } + } + } } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php index f997c6c01..c8347d66d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php @@ -52,6 +52,48 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertTrue($users[0] instanceof CmsUser); $this->assertEquals('Roman', $users[0]->name); } + + public function testBasicNativeQueryWithMetaResult() + { + $user = new CmsUser; + $user->name = 'Roman'; + $user->username = 'romanb'; + $user->status = 'dev'; + + $addr = new CmsAddress; + $addr->country = 'germany'; + $addr->zip = 10827; + $addr->city = 'Berlin'; + + + $user->setAddress($addr); + + $this->_em->persist($user); + $this->_em->flush(); + + $this->_em->clear(); + + $rsm = new ResultSetMapping; + $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsAddress', 'a'); + $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('id'), 'id'); + $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('country'), 'country'); + $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('zip'), 'zip'); + $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('city'), 'city'); + $rsm->addMetaResult('a', $this->platform->getSQLResultCasing('user_id'), 'user_id'); + + $query = $this->_em->createNativeQuery('SELECT a.id, a.country, a.zip, a.city, a.user_id FROM cms_addresses a WHERE a.id = ?', $rsm); + $query->setParameter(1, $addr->id); + + $addresses = $query->getResult(); + + $this->assertEquals(1, count($addresses)); + $this->assertTrue($addresses[0] instanceof CmsAddress); + $this->assertEquals($addr->country, $addresses[0]->country); + $this->assertEquals($addr->zip, $addresses[0]->zip); + $this->assertEquals($addr->city, $addresses[0]->city); + $this->assertEquals($addr->street, $addresses[0]->street); + $this->assertTrue($addresses[0]->user instanceof CmsUser); + } public function testJoinedOneToManyNativeQuery() { @@ -193,6 +235,20 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $phones = $users[0]->getPhonenumbers(); $this->assertEquals(424242, $phones[0]->phonenumber); $this->assertTrue($phones[0]->getUser() === $users[0]); + + $this->_em->clear(); + + $rsm = new ResultSetMappingBuilder($this->_em); + $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p'); + $query = $this->_em->createNativeQuery('SELECT p.* FROM cms_phonenumbers p WHERE p.phonenumber = ?', $rsm); + $query->setParameter(1, $phone->phonenumber); + $phone = $query->getSingleResult(); + +// \Doctrine\Common\Util\Debug::dump($phone); +// die(); + + $this->assertNotNull($phone->getUser()); + $this->assertEquals($user->name, $phone->getUser()->getName()); } public function testJoinedOneToOneNativeQueryWithRSMBuilder() @@ -235,6 +291,17 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals('germany', $users[0]->getAddress()->getCountry()); $this->assertEquals(10827, $users[0]->getAddress()->getZipCode()); $this->assertEquals('Berlin', $users[0]->getAddress()->getCity()); + + $this->_em->clear(); + + $rsm = new ResultSetMappingBuilder($this->_em); + $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', 'a'); + $query = $this->_em->createNativeQuery('SELECT a.* FROM cms_addresses a WHERE a.id = ?', $rsm); + $query->setParameter(1, $addr->getId()); + $address = $query->getSingleResult(); + + $this->assertNotNull($address->getUser()); + $this->assertEquals($user->name, $address->getUser()->getName()); } /**