From edd5d14b06f03187bc512c8c1c066539ee3ceed0 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Tue, 6 Mar 2012 16:24:44 +0100 Subject: [PATCH 1/8] Pagination using SQL walkers A CountSqlWalker and LimitSubquerySqlWalker have been implemented. By default the Paginator will use these SQL walkers. When a query already uses custom SQL walkers, the Paginator will fall back to the existing TreeWalker implementations. Improvements: * Support for more complex DQL queries using named mixed results with GROUP BY and HAVING. For example: SELECT g, u, COUNT(u.id) AS userCount FROM Entity\Group g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0 * Support for entities with composite primary keys in the CountSqlWalker and LimitSubquerySqlWalker. Only the WhereInWalker still needs to be updated for full composite primary key support. But someone smarter than me needs to look at that and figure out how to build a WHERE IN query that can select rows based on multiple columns. --- .../ORM/Tools/Pagination/CountSqlWalker.php | 120 +++++++++++++++ .../Pagination/LimitSubquerySqlWalker.php | 144 ++++++++++++++++++ .../ORM/Tools/Pagination/Paginator.php | 68 ++++++++- .../Tests/ORM/Functional/PaginationTest.php | 49 ++++++ .../Tools/Pagination/CountSqlWalkerTest.php | 48 ++++++ .../Pagination/LimitSubquerySqlWalkerTest.php | 33 ++++ 6 files changed, 458 insertions(+), 4 deletions(-) create mode 100644 lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php create mode 100644 lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php b/lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php new file mode 100644 index 000000000..51e6c2e4b --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php @@ -0,0 +1,120 @@ + FROM ()) + * + * Works with composite keys but cannot deal with queries that have multiple + * root entities (e.g. `SELECT f, b from Foo, Bar`) + * + * @author Sander Marechal + */ +class CountSqlWalker extends SqlWalker +{ + /** + * @var Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $platform; + + /** + * @var Doctrine\ORM\Query\ResultSetMapping + */ + private $rsm; + + /** + * @var array + */ + private $queryComponents; + + /** + * Constructor. Stores various parameters that are otherwise unavailable + * because Doctrine\ORM\Query\SqlWalker keeps everything private without + * accessors. + * + * @param Doctrine\ORM\Query $query + * @param Doctrine\ORM\Query\ParserResult $parserResult + * @param array $queryComponents + */ + public function __construct($query, $parserResult, array $queryComponents) + { + $this->platform = $query->getEntityManager()->getConnection()->getDatabasePlatform(); + $this->rsm = $parserResult->getResultSetMapping(); + $this->queryComponents = $queryComponents; + + parent::__construct($query, $parserResult, $queryComponents); + } + + /** + * Walks down a SelectStatement AST node, wrapping it in a COUNT (SELECT DISTINCT) + * + * Note that the ORDER BY clause is not removed. Many SQL implementations (e.g. MySQL) + * are able to cache subqueries. By keeping the ORDER BY clause intact, the limitSubQuery + * that will most likely be executed next can be read from the native SQL cache. + * + * @param SelectStatement $AST + * @return string + */ + public function walkSelectStatement(SelectStatement $AST) + { + $sql = parent::walkSelectStatement($AST); + + // Find out the SQL alias of the identifier column of the root entity + // It may be possible to make this work with multiple root entities but that + // would probably require issuing multiple queries or doing a UNION SELECT + // so for now, It's not supported. + + // Get the root entity and alias from the AST fromClause + $from = $AST->fromClause->identificationVariableDeclarations; + if (count($from) > 1) { + throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction"); + } + + $rootClass = $from[0]->rangeVariableDeclaration->abstractSchemaName; + $rootAlias = $from[0]->rangeVariableDeclaration->aliasIdentificationVariable; + + // Get the identity properties from the metadata + $rootIdentifier = $this->queryComponents[$rootAlias]['metadata']->identifier; + + // For every identifier, find out the SQL alias by combing through the ResultSetMapping + $sqlIdentifier = array(); + foreach ($rootIdentifier as $property) { + foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) { + if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) { + $sqlIdentifier[$property] = $alias; + } + } + } + + if (count($rootIdentifier) != count($sqlIdentifier)) { + throw new \RuntimeException(sprintf( + 'Not all identifier properties can be found in the ResultSetMapping: %s', + implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier))) + )); + } + + // Build the counter query + return sprintf('SELECT %s AS _dctrn_count FROM (SELECT DISTINCT %s FROM (%s) AS _dctrn_result) AS _dctrn_table', + $this->platform->getCountExpression('*'), + implode(', ', $sqlIdentifier), + $sql + ); + } +} diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php new file mode 100644 index 000000000..cbea28c65 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php @@ -0,0 +1,144 @@ + FROM () LIMIT x OFFSET y + * + * Works with composite keys but cannot deal with queries that have multiple + * root entities (e.g. `SELECT f, b from Foo, Bar`) + * + * @author Sander Marechal + */ +class LimitSubquerySqlWalker extends SqlWalker +{ + /** + * @var Doctrine\DBAL\Platforms\AbstractPlatform + */ + private $platform; + + /** + * @var Doctrine\ORM\Query\ResultSetMapping + */ + private $rsm; + + /** + * @var array + */ + private $queryComponents; + + /** + * @var int + */ + private $firstResult; + + /** + * @var int + */ + private $maxResults; + + /** + * Constructor. Stores various parameters that are otherwise unavailable + * because Doctrine\ORM\Query\SqlWalker keeps everything private without + * accessors. + * + * @param Doctrine\ORM\Query $query + * @param Doctrine\ORM\Query\ParserResult $parserResult + * @param array $queryComponents + */ + public function __construct($query, $parserResult, array $queryComponents) + { + $this->platform = $query->getEntityManager()->getConnection()->getDatabasePlatform(); + $this->rsm = $parserResult->getResultSetMapping(); + $this->queryComponents = $queryComponents; + + // Reset limit and offset + $this->firstResult = $query->getFirstResult(); + $this->maxResults = $query->getMaxResults(); + $query->setFirstResult(null)->setMaxResults(null); + + parent::__construct($query, $parserResult, $queryComponents); + } + + /** + * Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT + * + * @param SelectStatement $AST + * @return string + */ + public function walkSelectStatement(SelectStatement $AST) + { + $sql = parent::walkSelectStatement($AST); + + // Find out the SQL alias of the identifier column of the root entity + // It may be possible to make this work with multiple root entities but that + // would probably require issuing multiple queries or doing a UNION SELECT + // so for now, It's not supported. + + // Get the root entity and alias from the AST fromClause + $from = $AST->fromClause->identificationVariableDeclarations; + if (count($from) !== 1) { + throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction"); + } + + $rootClass = $from[0]->rangeVariableDeclaration->abstractSchemaName; + $rootAlias = $from[0]->rangeVariableDeclaration->aliasIdentificationVariable; + + // Get the identity properties from the metadata + $metadata = $this->queryComponents[$rootAlias]['metadata']; + $rootIdentifier = $metadata->identifier; + + // For every identifier, find out the SQL alias by combing through the ResultSetMapping + $sqlIdentifier = array(); + foreach ($rootIdentifier as $property) { + foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) { + if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) { + $sqlIdentifier[$property] = $alias; + } + } + } + + if (count($rootIdentifier) != count($sqlIdentifier)) { + throw new \RuntimeException(sprintf( + 'Not all identifier properties can be found in the ResultSetMapping: %s', + implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier))) + )); + } + + // Build the counter query + $sql = sprintf('SELECT DISTINCT %s FROM (%s) AS _dctrn_result', + implode(', ', $sqlIdentifier), $sql); + + // Apply the limit and offset + $sql = $this->platform->modifyLimitQuery( + $sql, $this->maxResults, $this->firstResult + ); + + // Add the columns to the ResultSetMapping. It's not really nice but + // it works. Preferably I'd clear the RSM or simply create a new one + // but that is not possible from inside the output walker, so we dirty + // up the one we have. + foreach ($sqlIdentifier as $property => $alias) { + $this->rsm->addScalarResult($alias, $property); + } + + return $sql; + } +} diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php index 760d7de13..fbd004b3c 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php +++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php @@ -21,9 +21,12 @@ namespace Doctrine\ORM\Tools\Pagination; use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\Query; +use Doctrine\ORM\Query\ResultSetMapping; use Doctrine\ORM\NoResultException; use Doctrine\ORM\Tools\Pagination\WhereInWalker; +use Doctrine\ORM\Tools\Pagination\WhereInSqlWalker; use Doctrine\ORM\Tools\Pagination\CountWalker; +use Doctrine\ORM\Tools\Pagination\CountSqlWalker; use Countable; use IteratorAggregate; use ArrayIterator; @@ -49,6 +52,11 @@ class Paginator implements \Countable, \IteratorAggregate */ private $fetchJoinCollection; + /** + * @var bool|null + */ + private $useSqlWalkers; + /** * @var int */ @@ -90,6 +98,28 @@ class Paginator implements \Countable, \IteratorAggregate return $this->fetchJoinCollection; } + /** + * Returns whether the paginator will use an SQL TreeWalker + * + * @return bool|null + */ + public function getUseSqlWalkers() + { + return $this->useSqlWalkers; + } + + /** + * Set whether the paginator will use an SQL TreeWalker + * + * @param bool|null $useSqlWalkers + * @return $this + */ + public function setUseSqlWalkers($useSqlWalkers) + { + $this->useSqlWalkers = $useSqlWalkers; + return $this; + } + /** * {@inheritdoc} */ @@ -103,7 +133,16 @@ class Paginator implements \Countable, \IteratorAggregate $countQuery->setHint(CountWalker::HINT_DISTINCT, true); } - $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); + if ($this->useSqlWalker($countQuery)) { + $rsm = new ResultSetMapping(); + $rsm->addScalarResult('_dctrn_count', 'count'); + + $countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $countQuery->setResultSetMapping($rsm); + } else { + $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); + } + $countQuery->setFirstResult(null)->setMaxResults(null); try { @@ -127,9 +166,14 @@ class Paginator implements \Countable, \IteratorAggregate if ($this->fetchJoinCollection) { $subQuery = $this->cloneQuery($this->query); - $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')) - ->setFirstResult($offset) - ->setMaxResults($length); + + if ($this->useSqlWalker($subQuery)) { + $subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + } else { + $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')); + } + + $subQuery->setFirstResult($offset)->setMaxResults($length); $ids = array_map('current', $subQuery->getScalarResult()); @@ -176,5 +220,21 @@ class Paginator implements \Countable, \IteratorAggregate return $cloneQuery; } + + /** + * Determine whether to use an SQL TreeWalker for the query + * + * @param Query $query The query. + * + * @return bool + */ + private function useSqlWalker(Query $query) + { + if ($this->useSqlWalkers === null) { + return (Boolean) $query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER) == false; + } + + return $this->useSqlWalkers; + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php index 990353519..cc5354dce 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php @@ -30,6 +30,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); + $paginator->setUseSqlWalkers(false); $this->assertEquals(3, count($paginator)); } @@ -39,15 +40,27 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); + $paginator->setUseSqlWalkers(false); $this->assertEquals(3, count($paginator)); } + public function testCountComplexWithSqlWalker() + { + $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; + $query = $this->_em->createQuery($dql); + + $paginator = new Paginator($query); + $paginator->setUseSqlWalkers(true); + $this->assertEquals(9, count($paginator)); + } + public function testIterateSimpleWithoutJoinFetchJoinHandlingOff() { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, false); + $paginator->setUseSqlWalkers(false); $data = array(); foreach ($paginator as $user) { @@ -62,6 +75,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); + $paginator->setUseSqlWalkers(false); $data = array(); foreach ($paginator as $user) { @@ -76,6 +90,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); + $paginator->setUseSqlWalkers(false); $data = array(); foreach ($paginator as $user) { @@ -84,6 +99,40 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals(3, count($data)); } + public function testIterateComplexWithSqlWalker() + { + $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; + $query = $this->_em->createQuery($dql); + + $paginator = new Paginator($query); + $paginator->setUseSqlWalkers(true); + + $data = array(); + foreach ($paginator as $user) { + $data[] = $user; + } + $this->assertEquals(9, count($data)); + } + + public function testDetectSqlWalker() + { + // This query works using the SQL walkers but causes an exception using the TreeWalker + $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; + $query = $this->_em->createQuery($dql); + + // If the Paginator detects the custom SQL walker it should fall back to using the + // Tree walkers for pagination, which leads to an exception. If the query works, the SQL walkers were used + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Query\SqlWalker'); + $paginator = new Paginator($query); + + try { + count($paginator); + $this->fail('Paginator did not detect custom SQL walker'); + } catch (\PHPUnit_Framework_Error_Notice $e) { + $this->assertEquals('Undefined index: userCount', $e->getMessage()); + } + } + public function populate() { for ($i = 0; $i < 3; $i++) { diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php new file mode 100644 index 000000000..79f9e6f6d --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php @@ -0,0 +1,48 @@ +entityManager->createQuery( + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setHint(CountWalker::HINT_DISTINCT, true); + $query->setFirstResult(null)->setMaxResults(null); + + $this->assertEquals( + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT b0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, b0_.author_id AS author_id4, b0_.category_id AS category_id5 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id) AS _dctrn_result) AS _dctrn_table", $query->getSql() + ); + } + + public function testCountQuery_MixedResultsWithName() + { + $query = $this->entityManager->createQuery( + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setHint(CountWalker::HINT_DISTINCT, true); + $query->setFirstResult(null)->setMaxResults(null); + + $this->assertEquals( + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result) AS _dctrn_table", $query->getSql() + ); + } + + public function testCountQuery_Having() + { + $query = $this->entityManager->createQuery( + 'SELECT g, u, count(u.id) AS userCount FROM Doctrine\Tests\ORM\Tools\Pagination\Group g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setFirstResult(null)->setMaxResults(null); + + $this->assertEquals( + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id1 FROM (SELECT count(u0_.id) AS sclr0, g1_.id AS id1, u0_.id AS id2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr0 > 0) AS _dctrn_result) AS _dctrn_table", $query->getSql() + ); + } +} + diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php new file mode 100644 index 000000000..8bf3b7a18 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php @@ -0,0 +1,33 @@ +entityManager->createQuery( + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); + $limitQuery = clone $query; + $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + + $this->assertEquals( + "SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) AS _dctrn_result", $limitQuery->getSql() + ); + } + + public function testCountQuery_MixedResultsWithName() + { + $query = $this->entityManager->createQuery( + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + $limitQuery = clone $query; + $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + + $this->assertEquals( + "SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result", $limitQuery->getSql() + ); + } +} + From d2501a9e4a43126c8ac65ce91d56849d1d205610 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Wed, 7 Mar 2012 08:42:09 +0100 Subject: [PATCH 2/8] Throw exception when using the CountWalker with a HAVING query --- .../ORM/Tools/Pagination/CountWalker.php | 4 ++++ .../Tests/ORM/Functional/PaginationTest.php | 12 ++++++------ .../ORM/Tools/Pagination/CountWalkerTest.php | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php b/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php index 10df1c3e1..3070437d3 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php @@ -43,6 +43,10 @@ class CountWalker extends TreeWalkerAdapter */ public function walkSelectStatement(SelectStatement $AST) { + if ($AST->havingClause) { + throw new \RuntimeException('Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination'); + } + $rootComponents = array(); foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) { $isParent = array_key_exists('parent', $qComp) diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php index cc5354dce..119f73b7e 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php @@ -125,12 +125,12 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Query\SqlWalker'); $paginator = new Paginator($query); - try { - count($paginator); - $this->fail('Paginator did not detect custom SQL walker'); - } catch (\PHPUnit_Framework_Error_Notice $e) { - $this->assertEquals('Undefined index: userCount', $e->getMessage()); - } + $this->setExpectedException( + 'RuntimeException', + 'Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination' + ); + + count($paginator); } public function populate() diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php index 816339df0..907f6577d 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php @@ -74,5 +74,21 @@ class CountWalkerTest extends PaginationTestCase "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() ); } + + public function testCountQuery_HavingException() + { + $query = $this->entityManager->createQuery( + "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0" + ); + $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); + $query->setFirstResult(null)->setMaxResults(null); + + $this->setExpectedException( + 'RuntimeException', + 'Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination' + ); + + $query->getSql(); + } } From 2f817b30c3290d6fe1b4d53a0c186c61ac8a803c Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Wed, 7 Mar 2012 08:52:00 +0100 Subject: [PATCH 3/8] Use a dataProvider to test both TreeWalker and SqlWalker pagination --- .../Tests/ORM/Functional/PaginationTest.php | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php index 119f73b7e..c1e8b8b3d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php @@ -24,23 +24,29 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->populate(); } - public function testCountSimpleWithoutJoin() + /** + * @dataProvider useSqlWalkers + */ + public function testCountSimpleWithoutJoin($useSqlWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers(false); + $paginator->setUseSqlWalkers($useSqlWalkers); $this->assertEquals(3, count($paginator)); } - public function testCountWithFetchJoin() + /** + * @dataProvider useSqlWalkers + */ + public function testCountWithFetchJoin($useSqlWalkers) { $dql = "SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers(false); + $paginator->setUseSqlWalkers($useSqlWalkers); $this->assertEquals(3, count($paginator)); } @@ -54,13 +60,16 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals(9, count($paginator)); } - public function testIterateSimpleWithoutJoinFetchJoinHandlingOff() + /** + * @dataProvider useSqlWalkers + */ + public function testIterateSimpleWithoutJoinFetchJoinHandlingOff($useSqlWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, false); - $paginator->setUseSqlWalkers(false); + $paginator->setUseSqlWalkers($useSqlWalkers); $data = array(); foreach ($paginator as $user) { @@ -69,13 +78,16 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals(3, count($data)); } - public function testIterateSimpleWithoutJoinFetchJoinHandlingOn() + /** + * @dataProvider useSqlWalkers + */ + public function testIterateSimpleWithoutJoinFetchJoinHandlingOn($useSqlWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); - $paginator->setUseSqlWalkers(false); + $paginator->setUseSqlWalkers($useSqlWalkers); $data = array(); foreach ($paginator as $user) { @@ -84,13 +96,16 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals(3, count($data)); } - public function testIterateWithFetchJoin() + /** + * @dataProvider useSqlWalkers + */ + public function testIterateWithFetchJoin($useSqlWalkers) { $dql = "SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); - $paginator->setUseSqlWalkers(false); + $paginator->setUseSqlWalkers($useSqlWalkers); $data = array(); foreach ($paginator as $user) { @@ -151,4 +166,12 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase } $this->_em->flush(); } + + public function useSqlWalkers() + { + return array( + array(true), + array(false), + ); + } } From c9d962b12ad9911a1ab5167c6e2e5bf2a785b141 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Wed, 7 Mar 2012 08:57:51 +0100 Subject: [PATCH 4/8] Fix indentation --- .../Tools/Pagination/CountSqlWalkerTest.php | 12 ++++---- .../ORM/Tools/Pagination/CountWalkerTest.php | 20 ++++++------- .../Pagination/LimitSubquerySqlWalkerTest.php | 8 +++--- .../Pagination/LimitSubqueryWalkerTest.php | 8 +++--- .../Tools/Pagination/WhereInWalkerTest.php | 28 +++++++++---------- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php index 79f9e6f6d..0b4b1a2c2 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php @@ -10,38 +10,38 @@ class CountSqlWalkerTest extends PaginationTestCase public function testCountQuery() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT b0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, b0_.author_id AS author_id4, b0_.category_id AS category_id5 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id) AS _dctrn_result) AS _dctrn_table", $query->getSql() + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT b0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, b0_.author_id AS author_id4, b0_.category_id AS category_id5 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id) AS _dctrn_result) AS _dctrn_table", $query->getSql() ); } public function testCountQuery_MixedResultsWithName() { $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result) AS _dctrn_table", $query->getSql() + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result) AS _dctrn_table", $query->getSql() ); } public function testCountQuery_Having() { $query = $this->entityManager->createQuery( - 'SELECT g, u, count(u.id) AS userCount FROM Doctrine\Tests\ORM\Tools\Pagination\Group g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0'); + 'SELECT g, u, count(u.id) AS userCount FROM Doctrine\Tests\ORM\Tools\Pagination\Group g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0'); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id1 FROM (SELECT count(u0_.id) AS sclr0, g1_.id AS id1, u0_.id AS id2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr0 > 0) AS _dctrn_result) AS _dctrn_table", $query->getSql() + "SELECT COUNT(*) AS _dctrn_count FROM (SELECT DISTINCT id1 FROM (SELECT count(u0_.id) AS sclr0, g1_.id AS id1, u0_.id AS id2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr0 > 0) AS _dctrn_result) AS _dctrn_table", $query->getSql() ); } } diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php index 907f6577d..2495ecfaf 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php @@ -13,65 +13,65 @@ class CountWalkerTest extends PaginationTestCase public function testCountQuery() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() + "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() ); } public function testCountQuery_MixedResultsWithName() { $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT count(DISTINCT a0_.id) AS sclr0 FROM Author a0_", $query->getSql() + "SELECT count(DISTINCT a0_.id) AS sclr0 FROM Author a0_", $query->getSql() ); } public function testCountQuery_KeepsGroupBy() { $query = $this->entityManager->createQuery( - 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b GROUP BY b.id'); + 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b GROUP BY b.id'); $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ GROUP BY b0_.id", $query->getSql() + "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ GROUP BY b0_.id", $query->getSql() ); } public function testCountQuery_RemovesOrderBy() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a ORDER BY a.name'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a ORDER BY a.name'); $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() + "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() ); } public function testCountQuery_RemovesLimits() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( - "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() + "SELECT count(DISTINCT b0_.id) AS sclr0 FROM BlogPost b0_ INNER JOIN Category c1_ ON b0_.category_id = c1_.id INNER JOIN Author a2_ ON b0_.author_id = a2_.id", $query->getSql() ); } diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php index 8bf3b7a18..78d2880c5 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php @@ -9,24 +9,24 @@ class LimitSubquerySqlWalkerTest extends PaginationTestCase public function testLimitSubquery() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); $this->assertEquals( - "SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) AS _dctrn_result", $limitQuery->getSql() + "SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) AS _dctrn_result", $limitQuery->getSql() ); } public function testCountQuery_MixedResultsWithName() { $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); $this->assertEquals( - "SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result", $limitQuery->getSql() + "SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result", $limitQuery->getSql() ); } } diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php index f166dddb3..2fd6046dd 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php @@ -12,24 +12,24 @@ class LimitSubqueryWalkerTest extends PaginationTestCase public function testLimitSubquery() { $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); + 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')); $this->assertEquals( - "SELECT DISTINCT m0_.id AS id0 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id", $limitQuery->getSql() + "SELECT DISTINCT m0_.id AS id0 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id", $limitQuery->getSql() ); } public function testCountQuery_MixedResultsWithName() { $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $limitQuery = clone $query; $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')); $this->assertEquals( - "SELECT DISTINCT a0_.id AS id0, sum(a0_.name) AS sclr1 FROM Author a0_", $limitQuery->getSql() + "SELECT DISTINCT a0_.id AS id0, sum(a0_.name) AS sclr1 FROM Author a0_", $limitQuery->getSql() ); } } diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php index 330e64ed1..b813c625b 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php @@ -13,98 +13,98 @@ class WhereInWalkerTest extends PaginationTestCase public function testWhereInQuery_NoWhere() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testCountQuery_MixedResultsWithName() { $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a' + 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testWhereInQuery_SingleWhere() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testWhereInQuery_MultipleWhereWithAnd() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 AND 2 = 2' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 AND 2 = 2' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testWhereInQuery_MultipleWhereWithOr() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 OR 2 = 2' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 OR 2 = 2' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testWhereInQuery_MultipleWhereWithMixed_1() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE (1 = 1 OR 2 = 2) AND 3 = 3' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE (1 = 1 OR 2 = 2) AND 3 = 3' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } public function testWhereInQuery_MultipleWhereWithMixed_2() { $query = $this->entityManager->createQuery( - 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 AND 2 = 2 OR 3 = 3' + 'SELECT u, g FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g WHERE 1 = 1 AND 2 = 2 OR 3 = 3' ); $whereInQuery = clone $query; $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker')); $whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10); $this->assertEquals( - "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() + "SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql() ); } From ad871e8b266f49b9b551a7cc25d474704ca5bdf5 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Thu, 8 Mar 2012 09:41:35 +0100 Subject: [PATCH 5/8] Cleaned up `use` statements --- lib/Doctrine/ORM/Tools/Pagination/Paginator.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php index fbd004b3c..c854aeba6 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php +++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php @@ -19,17 +19,10 @@ namespace Doctrine\ORM\Tools\Pagination; -use Doctrine\ORM\QueryBuilder; -use Doctrine\ORM\Query; -use Doctrine\ORM\Query\ResultSetMapping; -use Doctrine\ORM\NoResultException; -use Doctrine\ORM\Tools\Pagination\WhereInWalker; -use Doctrine\ORM\Tools\Pagination\WhereInSqlWalker; -use Doctrine\ORM\Tools\Pagination\CountWalker; -use Doctrine\ORM\Tools\Pagination\CountSqlWalker; -use Countable; -use IteratorAggregate; -use ArrayIterator; +use Doctrine\ORM\QueryBuilder, + Doctrine\ORM\Query, + Doctrine\ORM\Query\ResultSetMapping, + Doctrine\ORM\NoResultException; /** * Paginator From 47964a1605b7c39791d998df6ad9a87fdf5d45f5 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Thu, 8 Mar 2012 09:48:41 +0100 Subject: [PATCH 6/8] Use `assertCount` for simpler tests --- .../Tests/ORM/Functional/PaginationTest.php | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php index c1e8b8b3d..b99e5ee08 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php @@ -34,7 +34,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query); $paginator->setUseSqlWalkers($useSqlWalkers); - $this->assertEquals(3, count($paginator)); + $this->assertCount(3, $paginator); } /** @@ -47,7 +47,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query); $paginator->setUseSqlWalkers($useSqlWalkers); - $this->assertEquals(3, count($paginator)); + $this->assertCount(3, $paginator); } public function testCountComplexWithSqlWalker() @@ -57,7 +57,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query); $paginator->setUseSqlWalkers(true); - $this->assertEquals(9, count($paginator)); + $this->assertCount(9, $paginator); } /** @@ -70,12 +70,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query, false); $paginator->setUseSqlWalkers($useSqlWalkers); - - $data = array(); - foreach ($paginator as $user) { - $data[] = $user; - } - $this->assertEquals(3, count($data)); + $this->assertCount(3, $paginator->getIterator()); } /** @@ -88,12 +83,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query, true); $paginator->setUseSqlWalkers($useSqlWalkers); - - $data = array(); - foreach ($paginator as $user) { - $data[] = $user; - } - $this->assertEquals(3, count($data)); + $this->assertCount(3, $paginator->getIterator()); } /** @@ -106,12 +96,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query, true); $paginator->setUseSqlWalkers($useSqlWalkers); - - $data = array(); - foreach ($paginator as $user) { - $data[] = $user; - } - $this->assertEquals(3, count($data)); + $this->assertCount(3, $paginator->getIterator()); } public function testIterateComplexWithSqlWalker() @@ -121,12 +106,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $paginator = new Paginator($query); $paginator->setUseSqlWalkers(true); - - $data = array(); - foreach ($paginator as $user) { - $data[] = $user; - } - $this->assertEquals(9, count($data)); + $this->assertCount(9, $paginator->getIterator()); } public function testDetectSqlWalker() From 53ff31293643d5884c3b705066f4cb5fe32832cf Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Mon, 12 Mar 2012 08:33:35 +0100 Subject: [PATCH 7/8] Renamed *SqlWalker to *OutputWalker --- ...untSqlWalker.php => CountOutputWalker.php} | 2 +- .../ORM/Tools/Pagination/CountWalker.php | 2 +- ...lker.php => LimitSubqueryOutputWalker.php} | 2 +- .../ORM/Tools/Pagination/Paginator.php | 32 ++++++------ .../Tests/ORM/Functional/PaginationTest.php | 50 +++++++++---------- ...lkerTest.php => CountOutputWalkerTest.php} | 8 +-- .../ORM/Tools/Pagination/CountWalkerTest.php | 2 +- ....php => LimitSubqueryOutputWalkerTest.php} | 6 +-- 8 files changed, 52 insertions(+), 52 deletions(-) rename lib/Doctrine/ORM/Tools/Pagination/{CountSqlWalker.php => CountOutputWalker.php} (99%) rename lib/Doctrine/ORM/Tools/Pagination/{LimitSubquerySqlWalker.php => LimitSubqueryOutputWalker.php} (98%) rename tests/Doctrine/Tests/ORM/Tools/Pagination/{CountSqlWalkerTest.php => CountOutputWalkerTest.php} (92%) rename tests/Doctrine/Tests/ORM/Tools/Pagination/{LimitSubquerySqlWalkerTest.php => LimitSubqueryOutputWalkerTest.php} (87%) diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php b/lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php similarity index 99% rename from lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php rename to lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php index 51e6c2e4b..47df1192f 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/CountSqlWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php @@ -27,7 +27,7 @@ use Doctrine\ORM\Query\SqlWalker, * * @author Sander Marechal */ -class CountSqlWalker extends SqlWalker +class CountOutputWalker extends SqlWalker { /** * @var Doctrine\DBAL\Platforms\AbstractPlatform diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php b/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php index 3070437d3..2f80f7f63 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php @@ -44,7 +44,7 @@ class CountWalker extends TreeWalkerAdapter public function walkSelectStatement(SelectStatement $AST) { if ($AST->havingClause) { - throw new \RuntimeException('Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination'); + throw new \RuntimeException('Cannot count query that uses a HAVING clause. Use the output walkers for pagination'); } $rootComponents = array(); diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php similarity index 98% rename from lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php rename to lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index cbea28c65..e703ea0b8 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubquerySqlWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -27,7 +27,7 @@ use Doctrine\ORM\Query\SqlWalker, * * @author Sander Marechal */ -class LimitSubquerySqlWalker extends SqlWalker +class LimitSubqueryOutputWalker extends SqlWalker { /** * @var Doctrine\DBAL\Platforms\AbstractPlatform diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php index c854aeba6..566ecdf12 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php +++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php @@ -48,7 +48,7 @@ class Paginator implements \Countable, \IteratorAggregate /** * @var bool|null */ - private $useSqlWalkers; + private $useOutputWalkers; /** * @var int @@ -92,24 +92,24 @@ class Paginator implements \Countable, \IteratorAggregate } /** - * Returns whether the paginator will use an SQL TreeWalker + * Returns whether the paginator will use an output walker * * @return bool|null */ - public function getUseSqlWalkers() + public function getUseOutputWalkers() { - return $this->useSqlWalkers; + return $this->useOutputWalkers; } /** - * Set whether the paginator will use an SQL TreeWalker + * Set whether the paginator will use an output walker * - * @param bool|null $useSqlWalkers + * @param bool|null $useOutputWalkers * @return $this */ - public function setUseSqlWalkers($useSqlWalkers) + public function setUseOutputWalkers($useOutputWalkers) { - $this->useSqlWalkers = $useSqlWalkers; + $this->useOutputWalkers = $useOutputWalkers; return $this; } @@ -126,11 +126,11 @@ class Paginator implements \Countable, \IteratorAggregate $countQuery->setHint(CountWalker::HINT_DISTINCT, true); } - if ($this->useSqlWalker($countQuery)) { + if ($this->useOutputWalker($countQuery)) { $rsm = new ResultSetMapping(); $rsm->addScalarResult('_dctrn_count', 'count'); - $countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); $countQuery->setResultSetMapping($rsm); } else { $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker')); @@ -160,8 +160,8 @@ class Paginator implements \Countable, \IteratorAggregate if ($this->fetchJoinCollection) { $subQuery = $this->cloneQuery($this->query); - if ($this->useSqlWalker($subQuery)) { - $subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + if ($this->useOutputWalker($subQuery)) { + $subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); } else { $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker')); } @@ -215,19 +215,19 @@ class Paginator implements \Countable, \IteratorAggregate } /** - * Determine whether to use an SQL TreeWalker for the query + * Determine whether to use an output walker for the query * * @param Query $query The query. * * @return bool */ - private function useSqlWalker(Query $query) + private function useOutputWalker(Query $query) { - if ($this->useSqlWalkers === null) { + if ($this->useOutputWalkers === null) { return (Boolean) $query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER) == false; } - return $this->useSqlWalkers; + return $this->useOutputWalkers; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php index b99e5ee08..c30ecb2a1 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php @@ -25,104 +25,104 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase } /** - * @dataProvider useSqlWalkers + * @dataProvider useOutputWalkers */ - public function testCountSimpleWithoutJoin($useSqlWalkers) + public function testCountSimpleWithoutJoin($useOutputWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers($useSqlWalkers); + $paginator->setUseOutputWalkers($useOutputWalkers); $this->assertCount(3, $paginator); } /** - * @dataProvider useSqlWalkers + * @dataProvider useOutputWalkers */ - public function testCountWithFetchJoin($useSqlWalkers) + public function testCountWithFetchJoin($useOutputWalkers) { $dql = "SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers($useSqlWalkers); + $paginator->setUseOutputWalkers($useOutputWalkers); $this->assertCount(3, $paginator); } - public function testCountComplexWithSqlWalker() + public function testCountComplexWithOutputWalker() { $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers(true); + $paginator->setUseOutputWalkers(true); $this->assertCount(9, $paginator); } /** - * @dataProvider useSqlWalkers + * @dataProvider useOutputWalkers */ - public function testIterateSimpleWithoutJoinFetchJoinHandlingOff($useSqlWalkers) + public function testIterateSimpleWithoutJoinFetchJoinHandlingOff($useOutputWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, false); - $paginator->setUseSqlWalkers($useSqlWalkers); + $paginator->setUseOutputWalkers($useOutputWalkers); $this->assertCount(3, $paginator->getIterator()); } /** - * @dataProvider useSqlWalkers + * @dataProvider useOutputWalkers */ - public function testIterateSimpleWithoutJoinFetchJoinHandlingOn($useSqlWalkers) + public function testIterateSimpleWithoutJoinFetchJoinHandlingOn($useOutputWalkers) { $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); - $paginator->setUseSqlWalkers($useSqlWalkers); + $paginator->setUseOutputWalkers($useOutputWalkers); $this->assertCount(3, $paginator->getIterator()); } /** - * @dataProvider useSqlWalkers + * @dataProvider useOutputWalkers */ - public function testIterateWithFetchJoin($useSqlWalkers) + public function testIterateWithFetchJoin($useOutputWalkers) { $dql = "SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query, true); - $paginator->setUseSqlWalkers($useSqlWalkers); + $paginator->setUseOutputWalkers($useOutputWalkers); $this->assertCount(3, $paginator->getIterator()); } - public function testIterateComplexWithSqlWalker() + public function testIterateComplexWithOutputWalker() { $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; $query = $this->_em->createQuery($dql); $paginator = new Paginator($query); - $paginator->setUseSqlWalkers(true); + $paginator->setUseOutputWalkers(true); $this->assertCount(9, $paginator->getIterator()); } - public function testDetectSqlWalker() + public function testDetectOutputWalker() { - // This query works using the SQL walkers but causes an exception using the TreeWalker + // This query works using the output walkers but causes an exception using the TreeWalker $dql = "SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0"; $query = $this->_em->createQuery($dql); - // If the Paginator detects the custom SQL walker it should fall back to using the - // Tree walkers for pagination, which leads to an exception. If the query works, the SQL walkers were used + // If the Paginator detects the custom output walker it should fall back to using the + // Tree walkers for pagination, which leads to an exception. If the query works, the output walkers were used $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Query\SqlWalker'); $paginator = new Paginator($query); $this->setExpectedException( 'RuntimeException', - 'Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination' + 'Cannot count query that uses a HAVING clause. Use the output walkers for pagination' ); count($paginator); @@ -147,7 +147,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); } - public function useSqlWalkers() + public function useOutputWalkers() { return array( array(true), diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php similarity index 92% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php rename to tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php index 0b4b1a2c2..9dd0b33e6 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountSqlWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php @@ -5,13 +5,13 @@ namespace Doctrine\Tests\ORM\Tools\Pagination; use Doctrine\ORM\Query; use Doctrine\ORM\Tools\Pagination\CountWalker; -class CountSqlWalkerTest extends PaginationTestCase +class CountOutputWalkerTest extends PaginationTestCase { public function testCountQuery() { $query = $this->entityManager->createQuery( 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); @@ -24,7 +24,7 @@ class CountSqlWalkerTest extends PaginationTestCase { $query = $this->entityManager->createQuery( 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); @@ -37,7 +37,7 @@ class CountSqlWalkerTest extends PaginationTestCase { $query = $this->entityManager->createQuery( 'SELECT g, u, count(u.id) AS userCount FROM Doctrine\Tests\ORM\Tools\Pagination\Group g LEFT JOIN g.users u GROUP BY g.id HAVING userCount > 0'); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountSqlWalker'); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php index 2495ecfaf..405b63a1f 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php @@ -85,7 +85,7 @@ class CountWalkerTest extends PaginationTestCase $this->setExpectedException( 'RuntimeException', - 'Cannot count query that uses a HAVING clause. Use the SQL walkers for pagination' + 'Cannot count query that uses a HAVING clause. Use the output walkers for pagination' ); $query->getSql(); diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php similarity index 87% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php rename to tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index 78d2880c5..712fb5f62 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubquerySqlWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -4,14 +4,14 @@ namespace Doctrine\Tests\ORM\Tools\Pagination; use Doctrine\ORM\Query; -class LimitSubquerySqlWalkerTest extends PaginationTestCase +class LimitSubqueryOutputWalkerTest extends PaginationTestCase { public function testLimitSubquery() { $query = $this->entityManager->createQuery( 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertEquals( "SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) AS _dctrn_result", $limitQuery->getSql() @@ -23,7 +23,7 @@ class LimitSubquerySqlWalkerTest extends PaginationTestCase $query = $this->entityManager->createQuery( 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubquerySqlWalker'); + $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker'); $this->assertEquals( "SELECT DISTINCT id0 FROM (SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_) AS _dctrn_result", $limitQuery->getSql() From 43f97a9abc0780d81d1cff92fcac3d331d629284 Mon Sep 17 00:00:00 2001 From: Sander Marechal Date: Mon, 12 Mar 2012 08:39:28 +0100 Subject: [PATCH 8/8] CountOutputWalker does not need CountWalker::HINT_DISTINCT --- .../Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php index 9dd0b33e6..550abaafb 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php @@ -3,7 +3,6 @@ namespace Doctrine\Tests\ORM\Tools\Pagination; use Doctrine\ORM\Query; -use Doctrine\ORM\Tools\Pagination\CountWalker; class CountOutputWalkerTest extends PaginationTestCase { @@ -12,7 +11,6 @@ class CountOutputWalkerTest extends PaginationTestCase $query = $this->entityManager->createQuery( 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p JOIN p.category c JOIN p.author a'); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); - $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals( @@ -25,7 +23,6 @@ class CountOutputWalkerTest extends PaginationTestCase $query = $this->entityManager->createQuery( 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker'); - $query->setHint(CountWalker::HINT_DISTINCT, true); $query->setFirstResult(null)->setMaxResults(null); $this->assertEquals(