From 8af0f9d0711a7dcba8364e86c29cc3cc6e426010 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Mon, 14 Nov 2011 16:07:37 -0200 Subject: [PATCH] added support for Inherited Named Queries --- .../ORM/Mapping/ClassMetadataFactory.php | 23 ++++ .../ORM/Mapping/ClassMetadataInfo.php | 13 +- .../ORM/Functional/Ticket/DDC1404Test.php | 129 ++++++++++++++++++ .../Tests/ORM/Mapping/ClassMetadataTest.php | 2 +- 4 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 239022b0f..19d319dbe 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -312,6 +312,10 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface if ($parent && $parent->containsForeignIdentifier) { $class->containsForeignIdentifier = true; } + + if ($parent && !empty ($parent->namedQueries)) { + $this->addInheritedNamedQueries($class, $parent); + } $class->setParentClasses($visited); @@ -428,6 +432,25 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface $subClass->addInheritedAssociationMapping($mapping); } } + + /** + * Adds inherited named queries to the subclass mapping. + * + * @since 2.2 + * @param Doctrine\ORM\Mapping\ClassMetadata $subClass + * @param Doctrine\ORM\Mapping\ClassMetadata $parentClass + */ + private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass) + { + foreach ($parentClass->namedQueries as $name => $query) { + if (!isset ($subClass->namedQueries[$name])) { + $subClass->addNamedQuery(array( + 'name' => $query['name'], + 'query' => $query['query'] + )); + } + } + } /** * Completes the ID generator mapping. If "auto" is specified we choose the generator diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 592367ab7..b8c4ef2f1 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -685,7 +685,7 @@ class ClassMetadataInfo implements ClassMetadata if ( ! isset($this->namedQueries[$queryName])) { throw MappingException::queryNotFound($this->name, $queryName); } - return $this->namedQueries[$queryName]; + return $this->namedQueries[$queryName]['dql']; } /** @@ -1448,8 +1448,15 @@ class ClassMetadataInfo implements ClassMetadata if (isset($this->namedQueries[$queryMapping['name']])) { throw MappingException::duplicateQueryMapping($this->name, $queryMapping['name']); } - $query = str_replace('__CLASS__', $this->name, $queryMapping['query']); - $this->namedQueries[$queryMapping['name']] = $query; + + $name = $queryMapping['name']; + $query = $queryMapping['query']; + $dql = str_replace('__CLASS__', $this->name, $query); + $this->namedQueries[$name] = array( + 'name' => $name, + 'query' => $query, + 'dql' => $dql + ); } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php new file mode 100644 index 000000000..49a282772 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php @@ -0,0 +1,129 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1404ParentEntity'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1404ChildEntity'), + )); + + $this->loadFixtures(); + + } catch (Exception $exc) { + } + } + + public function testTicket() + { + $repository = $this->_em->getRepository(__NAMESPACE__ . '\DDC1404ChildEntity'); + $queryAll = $repository->createNamedQuery('all'); + $queryFirst = $repository->createNamedQuery('first'); + $querySecond = $repository->createNamedQuery('second'); + + + $this->assertEquals('SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\DDC1404ChildEntity p', $queryAll->getDQL()); + $this->assertEquals('SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\DDC1404ChildEntity p WHERE p.id = 1', $queryFirst->getDQL()); + $this->assertEquals('SELECT p FROM Doctrine\Tests\ORM\Functional\Ticket\DDC1404ChildEntity p WHERE p.id = 2', $querySecond->getDQL()); + + + $this->assertEquals(sizeof($queryAll->getResult()), 2); + $this->assertEquals(sizeof($queryFirst->getResult()), 1); + $this->assertEquals(sizeof($querySecond->getResult()), 1); + } + + + public function loadFixtures() + { + $c1 = new DDC1404ChildEntity("ChildEntity 1"); + $c2 = new DDC1404ChildEntity("ChildEntity 2"); + + $this->_em->persist($c1); + $this->_em->persist($c2); + + $this->_em->flush(); + } + +} + +/** + * @MappedSuperclass + * + * @NamedQueries({ + * @NamedQuery(name="all", query="SELECT p FROM __CLASS__ p"), + * @NamedQuery(name="first", query="SELECT p FROM __CLASS__ p WHERE p.id = 1"), + * }) + */ +class DDC1404ParentEntity +{ + + /** + * @Id + * @Column(type="integer") + * @GeneratedValue() + */ + protected $id; + + /** + * @return integer + */ + public function getId() + { + return $this->id; + } + +} + +/** + * @Entity + * + * @NamedQueries({ + * @NamedQuery(name="first", query="SELECT p FROM __CLASS__ p WHERE p.id = 1"), + * @NamedQuery(name="second", query="SELECT p FROM __CLASS__ p WHERE p.id = 2") + * }) + */ +class DDC1404ChildEntity extends DDC1404ParentEntity +{ + + /** + * @column(type="string") + */ + private $name; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index fed31d9c5..55726e387 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -54,7 +54,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('phonenumbers', $oneOneMapping['fieldName']); $this->assertEquals('Doctrine\Tests\Models\CMS\Bar', $oneOneMapping['targetEntity']); $this->assertTrue($cm->isReadOnly); - $this->assertEquals(array('dql' => 'foo'), $cm->namedQueries); + $this->assertEquals(array('dql' => array('name'=>'dql','query'=>'foo','dql'=>'foo')), $cm->namedQueries); } public function testFieldIsNullable()