Merge pull request #298 from sandermarechal/paginate-sql-walkers
Pagination using SQL walkers
This commit is contained in:
commit
3788d0e815
120
lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php
Normal file
120
lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\SqlWalker,
|
||||
Doctrine\ORM\Query\AST\SelectStatement;
|
||||
|
||||
/**
|
||||
* Wrap the query in order to accurately count the root objects
|
||||
*
|
||||
* Given a DQL like `SELECT u FROM User u` it will generate an SQL query like:
|
||||
* SELECT COUNT(*) (SELECT DISTINCT <id> FROM (<original SQL>))
|
||||
*
|
||||
* 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 <s.marechal@jejik.com>
|
||||
*/
|
||||
class CountOutputWalker 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
|
||||
);
|
||||
}
|
||||
}
|
@ -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 output walkers for pagination');
|
||||
}
|
||||
|
||||
$rootComponents = array();
|
||||
foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
|
||||
$isParent = array_key_exists('parent', $qComp)
|
||||
|
144
lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
Normal file
144
lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\SqlWalker,
|
||||
Doctrine\ORM\Query\AST\SelectStatement;
|
||||
|
||||
/**
|
||||
* Wrap the query in order to select root entity IDs for pagination
|
||||
*
|
||||
* Given a DQL like `SELECT u FROM User u` it will generate an SQL query like:
|
||||
* SELECT DISTINCT <id> FROM (<original SQL>) 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 <s.marechal@jejik.com>
|
||||
*/
|
||||
class LimitSubqueryOutputWalker 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;
|
||||
}
|
||||
}
|
@ -19,14 +19,10 @@
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Doctrine\ORM\Tools\Pagination\WhereInWalker;
|
||||
use Doctrine\ORM\Tools\Pagination\CountWalker;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use ArrayIterator;
|
||||
use Doctrine\ORM\QueryBuilder,
|
||||
Doctrine\ORM\Query,
|
||||
Doctrine\ORM\Query\ResultSetMapping,
|
||||
Doctrine\ORM\NoResultException;
|
||||
|
||||
/**
|
||||
* Paginator
|
||||
@ -49,6 +45,11 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
*/
|
||||
private $fetchJoinCollection;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private $useOutputWalkers;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
@ -90,6 +91,28 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
return $this->fetchJoinCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the paginator will use an output walker
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getUseOutputWalkers()
|
||||
{
|
||||
return $this->useOutputWalkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the paginator will use an output walker
|
||||
*
|
||||
* @param bool|null $useOutputWalkers
|
||||
* @return $this
|
||||
*/
|
||||
public function setUseOutputWalkers($useOutputWalkers)
|
||||
{
|
||||
$this->useOutputWalkers = $useOutputWalkers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -103,7 +126,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->useOutputWalker($countQuery)) {
|
||||
$rsm = new ResultSetMapping();
|
||||
$rsm->addScalarResult('_dctrn_count', 'count');
|
||||
|
||||
$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'));
|
||||
}
|
||||
|
||||
$countQuery->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
try {
|
||||
@ -127,9 +159,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->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'));
|
||||
}
|
||||
|
||||
$subQuery->setFirstResult($offset)->setMaxResults($length);
|
||||
|
||||
$ids = array_map('current', $subQuery->getScalarResult());
|
||||
|
||||
@ -176,5 +213,21 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
|
||||
return $cloneQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to use an output walker for the query
|
||||
*
|
||||
* @param Query $query The query.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function useOutputWalker(Query $query)
|
||||
{
|
||||
if ($this->useOutputWalkers === null) {
|
||||
return (Boolean) $query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER) == false;
|
||||
}
|
||||
|
||||
return $this->useOutputWalkers;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,64 +24,108 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->populate();
|
||||
}
|
||||
|
||||
public function testCountSimpleWithoutJoin()
|
||||
/**
|
||||
* @dataProvider useOutputWalkers
|
||||
*/
|
||||
public function testCountSimpleWithoutJoin($useOutputWalkers)
|
||||
{
|
||||
$dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u";
|
||||
$query = $this->_em->createQuery($dql);
|
||||
|
||||
$paginator = new Paginator($query);
|
||||
$this->assertEquals(3, count($paginator));
|
||||
$paginator->setUseOutputWalkers($useOutputWalkers);
|
||||
$this->assertCount(3, $paginator);
|
||||
}
|
||||
|
||||
public function testCountWithFetchJoin()
|
||||
/**
|
||||
* @dataProvider useOutputWalkers
|
||||
*/
|
||||
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);
|
||||
$this->assertEquals(3, count($paginator));
|
||||
$paginator->setUseOutputWalkers($useOutputWalkers);
|
||||
$this->assertCount(3, $paginator);
|
||||
}
|
||||
|
||||
public function testIterateSimpleWithoutJoinFetchJoinHandlingOff()
|
||||
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->setUseOutputWalkers(true);
|
||||
$this->assertCount(9, $paginator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider useOutputWalkers
|
||||
*/
|
||||
public function testIterateSimpleWithoutJoinFetchJoinHandlingOff($useOutputWalkers)
|
||||
{
|
||||
$dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u";
|
||||
$query = $this->_em->createQuery($dql);
|
||||
|
||||
$paginator = new Paginator($query, false);
|
||||
|
||||
$data = array();
|
||||
foreach ($paginator as $user) {
|
||||
$data[] = $user;
|
||||
}
|
||||
$this->assertEquals(3, count($data));
|
||||
$paginator->setUseOutputWalkers($useOutputWalkers);
|
||||
$this->assertCount(3, $paginator->getIterator());
|
||||
}
|
||||
|
||||
public function testIterateSimpleWithoutJoinFetchJoinHandlingOn()
|
||||
/**
|
||||
* @dataProvider useOutputWalkers
|
||||
*/
|
||||
public function testIterateSimpleWithoutJoinFetchJoinHandlingOn($useOutputWalkers)
|
||||
{
|
||||
$dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u";
|
||||
$query = $this->_em->createQuery($dql);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
|
||||
$data = array();
|
||||
foreach ($paginator as $user) {
|
||||
$data[] = $user;
|
||||
}
|
||||
$this->assertEquals(3, count($data));
|
||||
$paginator->setUseOutputWalkers($useOutputWalkers);
|
||||
$this->assertCount(3, $paginator->getIterator());
|
||||
}
|
||||
|
||||
public function testIterateWithFetchJoin()
|
||||
/**
|
||||
* @dataProvider useOutputWalkers
|
||||
*/
|
||||
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->setUseOutputWalkers($useOutputWalkers);
|
||||
$this->assertCount(3, $paginator->getIterator());
|
||||
}
|
||||
|
||||
$data = array();
|
||||
foreach ($paginator as $user) {
|
||||
$data[] = $user;
|
||||
}
|
||||
$this->assertEquals(3, count($data));
|
||||
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->setUseOutputWalkers(true);
|
||||
$this->assertCount(9, $paginator->getIterator());
|
||||
}
|
||||
|
||||
public function testDetectOutputWalker()
|
||||
{
|
||||
// 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 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 output walkers for pagination'
|
||||
);
|
||||
|
||||
count($paginator);
|
||||
}
|
||||
|
||||
public function populate()
|
||||
@ -102,4 +146,12 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
}
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
public function useOutputWalkers()
|
||||
{
|
||||
return array(
|
||||
array(true),
|
||||
array(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
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\CountOutputWalker');
|
||||
$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\CountOutputWalker');
|
||||
$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\CountOutputWalker');
|
||||
$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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,66 +13,82 @@ 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()
|
||||
);
|
||||
}
|
||||
|
||||
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 output walkers for pagination'
|
||||
);
|
||||
|
||||
$query->getSql();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query;
|
||||
|
||||
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\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()
|
||||
);
|
||||
}
|
||||
|
||||
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\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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user