1
0
mirror of synced 2024-12-13 22:56:04 +03:00

Fixed documentation for Doctrine\ORM\Tools\Pagination

This commit is contained in:
Benjamin Morel 2012-12-14 13:13:22 +00:00
parent 2524c878b6
commit ad967e8e22
6 changed files with 67 additions and 50 deletions

View File

@ -17,7 +17,7 @@ use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\AST\SelectStatement;
/**
* Wrap the query in order to accurately count the root objects
* Wraps 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>))
@ -45,13 +45,15 @@ class CountOutputWalker extends SqlWalker
private $queryComponents;
/**
* Constructor. Stores various parameters that are otherwise unavailable
* 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 $query
* @param \Doctrine\ORM\Query\ParserResult $parserResult
* @param array $queryComponents
* @param array $queryComponents
*/
public function __construct($query, $parserResult, array $queryComponents)
{
@ -63,14 +65,17 @@ class CountOutputWalker extends SqlWalker
}
/**
* Walks down a SelectStatement AST node, wrapping it in a COUNT (SELECT DISTINCT)
* 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
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
{

View File

@ -20,7 +20,7 @@ use Doctrine\ORM\Query\AST\PathExpression;
use Doctrine\ORM\Query\AST\AggregateExpression;
/**
* Replaces the selectClause of the AST with a COUNT statement
* Replaces the selectClause of the AST with a COUNT statement.
*
* @category DoctrineExtensions
* @package DoctrineExtensions\Paginate
@ -31,15 +31,18 @@ use Doctrine\ORM\Query\AST\AggregateExpression;
class CountWalker extends TreeWalkerAdapter
{
/**
* Distinct mode hint name
* Distinct mode hint name.
*/
const HINT_DISTINCT = 'doctrine_paginator.distinct';
/**
* Walks down a SelectStatement AST node, modifying it to retrieve a COUNT
* Walks down a SelectStatement AST node, modifying it to retrieve a COUNT.
*
* @param SelectStatement $AST
*
* @return void
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
{

View File

@ -18,7 +18,7 @@ use Doctrine\ORM\Query\AST\SelectStatement;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
/**
* Wrap the query in order to select root entity IDs for pagination
* Wraps 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
@ -56,13 +56,15 @@ class LimitSubqueryOutputWalker extends SqlWalker
private $maxResults;
/**
* Constructor. Stores various parameters that are otherwise unavailable
* 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 $query
* @param \Doctrine\ORM\Query\ParserResult $parserResult
* @param array $queryComponents
* @param array $queryComponents
*/
public function __construct($query, $parserResult, array $queryComponents)
{
@ -79,21 +81,24 @@ class LimitSubqueryOutputWalker extends SqlWalker
}
/**
* Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT
* Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT.
*
* @param SelectStatement $AST
*
* @return string
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
{
$innerSql = parent::walkSelectStatement($AST);
// Find out the SQL alias of the identifier column of the root entity
// 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.
// 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
// 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");
@ -132,7 +137,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
));
}
// Build the counter query
// Build the counter query.
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
implode(', ', $sqlIdentifier), $innerSql);
@ -141,7 +146,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
$this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql);
}
// Apply the limit and offset
// Apply the limit and offset.
$sql = $this->platform->modifyLimitQuery(
$sql, $this->maxResults, $this->firstResult
);
@ -158,15 +163,18 @@ class LimitSubqueryOutputWalker extends SqlWalker
}
/**
* Generate new SQL for postgresql if necessary
* Generates new SQL for postgresql if necessary.
*
* @param SelectStatement $AST
* @param array sqlIdentifier
* @param array $sqlIdentifier
* @param string $innerSql
* @param string $sql
*
* @return void
*/
public function getPostgresqlSql(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
{
// For every order by, find out the SQL alias by inspecting the ResultSetMapping
// For every order by, find out the SQL alias by inspecting the ResultSetMapping.
$sqlOrderColumns = array();
$orderBy = array();
if (isset($AST->orderByClause)) {
@ -185,8 +193,8 @@ class LimitSubqueryOutputWalker extends SqlWalker
$sqlOrderColumns = array_diff($sqlOrderColumns, $sqlIdentifier);
}
//we don't need orderBy in inner query
//However at least on 5.4.6 I'm getting a segmentation fault and thus we don't clear it for now
// We don't need orderBy in inner query.
// However at least on 5.4.6 I'm getting a segmentation fault and thus we don't clear it for now.
/*$AST->orderByClause = null;
$innerSql = parent::walkSelectStatement($AST);*/

View File

@ -25,7 +25,7 @@ use Doctrine\ORM\Query\AST\SelectExpression;
use Doctrine\ORM\Query\AST\PathExpression;
/**
* Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent
* Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent.
*
* @category DoctrineExtensions
* @package DoctrineExtensions\Paginate
@ -36,21 +36,26 @@ use Doctrine\ORM\Query\AST\PathExpression;
class LimitSubqueryWalker extends TreeWalkerAdapter
{
/**
* ID type hint
* ID type hint.
*/
const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
/**
* @var int Counter for generating unique order column aliases
* Counter for generating unique order column aliases.
*
* @var int
*/
private $_aliasCounter = 0;
/**
* Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
* of the root Entity
* of the root Entity.
*
* @param SelectStatement $AST
*
* @return void
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
{
@ -59,7 +64,7 @@ class LimitSubqueryWalker extends TreeWalkerAdapter
$selectExpressions = array();
foreach ($this->_getQueryComponents() as $dqlAlias => $qComp) {
// preserve mixed data in query for ordering
// Preserve mixed data in query for ordering.
if (isset($qComp['resultVariable'])) {
$selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias);
continue;
@ -111,8 +116,4 @@ class LimitSubqueryWalker extends TreeWalkerAdapter
$AST->selectClause->isDistinct = true;
}
}

View File

@ -25,8 +25,6 @@ use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\NoResultException;
/**
* Paginator
*
* The paginator can handle various complex scenarios with DQL.
*
* @author Pablo Díez <pablodip@gmail.com>
@ -58,8 +56,8 @@ class Paginator implements \Countable, \IteratorAggregate
/**
* Constructor.
*
* @param Query|QueryBuilder $query A Doctrine ORM query or query builder.
* @param Boolean $fetchJoinCollection Whether the query joins a collection (true by default).
* @param Query|QueryBuilder $query A Doctrine ORM query or query builder.
* @param boolean $fetchJoinCollection Whether the query joins a collection (true by default).
*/
public function __construct($query, $fetchJoinCollection = true)
{
@ -72,7 +70,7 @@ class Paginator implements \Countable, \IteratorAggregate
}
/**
* Returns the query
* Returns the query.
*
* @return Query
*/
@ -84,7 +82,7 @@ class Paginator implements \Countable, \IteratorAggregate
/**
* Returns whether the query joins a collection.
*
* @return Boolean Whether the query joins a collection.
* @return boolean Whether the query joins a collection.
*/
public function getFetchJoinCollection()
{
@ -92,7 +90,7 @@ class Paginator implements \Countable, \IteratorAggregate
}
/**
* Returns whether the paginator will use an output walker
* Returns whether the paginator will use an output walker.
*
* @return bool|null
*/
@ -102,9 +100,10 @@ class Paginator implements \Countable, \IteratorAggregate
}
/**
* Set whether the paginator will use an output walker
* Sets whether the paginator will use an output walker.
*
* @param bool|null $useOutputWalkers
*
* @return $this
*/
public function setUseOutputWalkers($useOutputWalkers)
@ -218,7 +217,7 @@ class Paginator implements \Countable, \IteratorAggregate
}
/**
* Determine whether to use an output walker for the query
* Determines whether to use an output walker for the query.
*
* @param Query $query The query.
*
@ -233,4 +232,3 @@ class Paginator implements \Countable, \IteratorAggregate
return $this->useOutputWalkers;
}
}

View File

@ -32,7 +32,7 @@ use Doctrine\ORM\Query\AST\ConditionalFactor;
use Doctrine\ORM\Query\AST\WhereClause;
/**
* Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent
* Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent.
*
* @category DoctrineExtensions
* @package DoctrineExtensions\Paginate
@ -43,17 +43,17 @@ use Doctrine\ORM\Query\AST\WhereClause;
class WhereInWalker extends TreeWalkerAdapter
{
/**
* ID Count hint name
* ID Count hint name.
*/
const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
/**
* Primary key alias for query
* Primary key alias for query.
*/
const PAGINATOR_ID_ALIAS = 'dpid';
/**
* Replaces the whereClause in the AST
* Replaces the whereClause in the AST.
*
* Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
*
@ -61,10 +61,13 @@ class WhereInWalker extends TreeWalkerAdapter
* the PAGINATOR_ID_ALIAS
*
* The total number of parameters is retrieved from
* the HINT_PAGINATOR_ID_COUNT query hint
* the HINT_PAGINATOR_ID_COUNT query hint.
*
* @param SelectStatement $AST
*
* @param SelectStatement $AST
* @return void
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
{
@ -142,4 +145,3 @@ class WhereInWalker extends TreeWalkerAdapter
}
}
}