diff --git a/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php b/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php index e3494a50a..b4be29e74 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php +++ b/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php @@ -28,15 +28,48 @@ namespace Doctrine\ORM\Internal\Hydration; * @author robo * @since 2.0 */ -class IterableResult +class IterableResult implements \Iterator { + /** + * + * @var \Doctrine\ORM\Internal\Hydration\AbstractHydrator + */ private $_hydrator; + /** + * @var bool + */ + private $_rewinded = false; + + /** + * @var int + */ + private $_key = -1; + + /** + * @var object + */ + private $_current = null; + + /** + * + * @param \Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator + */ public function __construct($hydrator) { $this->_hydrator = $hydrator; } + public function rewind() + { + if($this->_rewinded == true) { + throw new HydrationException("Can only iterate a Result once."); + } else { + $this->_current = $this->next(); + $this->_rewinded = true; + } + } + /** * Gets the next set of results. * @@ -44,6 +77,32 @@ class IterableResult */ public function next() { - return $this->_hydrator->hydrateRow(); + $this->_current = $this->_hydrator->hydrateRow(); + $this->_key++; + return $this->_current; + } + + /** + * @return mixed + */ + public function current() + { + return $this->_current; + } + + /** + * @return int + */ + public function key() + { + return $this->_key; + } + + /** + * @return bool + */ + public function valid() + { + return ($this->_current!=false); } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php index 4bf1cad54..37ae8b150 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryTest.php @@ -102,5 +102,78 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals('Symfony 2', $users[0]->articles[1]->topic); } + public function testUsingUnknownQueryParameterShouldThrowException() + { + $this->setExpectedException( + "Doctrine\ORM\Query\QueryException", + "Invalid parameter: token 2 is not defined in the query." + ); + + $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1'); + $q->setParameter(2, 'jwage'); + $user = $q->getSingleResult(); + } + + public function testMismatchingParamExpectedParamCount() + { + $this->setExpectedException( + "Doctrine\ORM\Query\QueryException", + "Invalid parameter number: number of bound variables does not match number of tokens" + ); + + $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1'); + $q->setParameter(1, 'jwage'); + $q->setParameter(2, 'jwage'); + + $user = $q->getSingleResult(); + } + + public function testInvalidInputParameterThrowsException() + { + $this->setExpectedException("InvalidArgumentException"); + + $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?'); + $q->setParameter(1, 'jwage'); + $user = $q->getSingleResult(); + } + + public function testIterateResult_IterativelyBuildUpUnitOfWork() + { + $article1 = new CmsArticle; + $article1->topic = "Doctrine 2"; + $article1->text = "This is an introduction to Doctrine 2."; + + $article2 = new CmsArticle; + $article2->topic = "Symfony 2"; + $article2->text = "This is an introduction to Symfony 2."; + + $this->_em->persist($article1); + $this->_em->persist($article2); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a"); + $articles = $query->iterate(); + + $iteratedCount = 0; + $topics = array(); + foreach($articles AS $row) { + $article = $row[0]; + $topics[] = $article->topic; + + $identityMap = $this->_em->getUnitOfWork()->getIdentityMap(); + $identityMapCount = count($identityMap['Doctrine\Tests\Models\CMS\CmsArticle']); + $this->assertTrue($identityMapCount>$iteratedCount); + + $iteratedCount++; + } + + $this->assertEquals(array("Doctrine 2", "Symfony 2"), $topics); + $this->assertEquals(2, $iteratedCount); + + $this->_em->flush(); + $this->_em->clear(); + } }