diff options
Diffstat (limited to 'vendor/doctrine/orm/src/Tools/Pagination/CountWalker.php')
| -rw-r--r-- | vendor/doctrine/orm/src/Tools/Pagination/CountWalker.php | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Tools/Pagination/CountWalker.php b/vendor/doctrine/orm/src/Tools/Pagination/CountWalker.php new file mode 100644 index 0000000..d212943 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Pagination/CountWalker.php | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | <?php | ||
| 2 | |||
| 3 | declare(strict_types=1); | ||
| 4 | |||
| 5 | namespace Doctrine\ORM\Tools\Pagination; | ||
| 6 | |||
| 7 | use Doctrine\ORM\Query\AST\AggregateExpression; | ||
| 8 | use Doctrine\ORM\Query\AST\PathExpression; | ||
| 9 | use Doctrine\ORM\Query\AST\SelectExpression; | ||
| 10 | use Doctrine\ORM\Query\AST\SelectStatement; | ||
| 11 | use Doctrine\ORM\Query\TreeWalkerAdapter; | ||
| 12 | use RuntimeException; | ||
| 13 | |||
| 14 | use function count; | ||
| 15 | use function reset; | ||
| 16 | |||
| 17 | /** | ||
| 18 | * Replaces the selectClause of the AST with a COUNT statement. | ||
| 19 | */ | ||
| 20 | class CountWalker extends TreeWalkerAdapter | ||
| 21 | { | ||
| 22 | /** | ||
| 23 | * Distinct mode hint name. | ||
| 24 | */ | ||
| 25 | public const HINT_DISTINCT = 'doctrine_paginator.distinct'; | ||
| 26 | |||
| 27 | public function walkSelectStatement(SelectStatement $selectStatement): void | ||
| 28 | { | ||
| 29 | if ($selectStatement->havingClause) { | ||
| 30 | throw new RuntimeException('Cannot count query that uses a HAVING clause. Use the output walkers for pagination'); | ||
| 31 | } | ||
| 32 | |||
| 33 | // Get the root entity and alias from the AST fromClause | ||
| 34 | $from = $selectStatement->fromClause->identificationVariableDeclarations; | ||
| 35 | |||
| 36 | if (count($from) > 1) { | ||
| 37 | throw new RuntimeException('Cannot count query which selects two FROM components, cannot make distinction'); | ||
| 38 | } | ||
| 39 | |||
| 40 | $fromRoot = reset($from); | ||
| 41 | $rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable; | ||
| 42 | $rootClass = $this->getMetadataForDqlAlias($rootAlias); | ||
| 43 | $identifierFieldName = $rootClass->getSingleIdentifierFieldName(); | ||
| 44 | |||
| 45 | $pathType = PathExpression::TYPE_STATE_FIELD; | ||
| 46 | if (isset($rootClass->associationMappings[$identifierFieldName])) { | ||
| 47 | $pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION; | ||
| 48 | } | ||
| 49 | |||
| 50 | $pathExpression = new PathExpression( | ||
| 51 | PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, | ||
| 52 | $rootAlias, | ||
| 53 | $identifierFieldName, | ||
| 54 | ); | ||
| 55 | $pathExpression->type = $pathType; | ||
| 56 | |||
| 57 | $distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT); | ||
| 58 | $selectStatement->selectClause->selectExpressions = [ | ||
| 59 | new SelectExpression( | ||
| 60 | new AggregateExpression('count', $pathExpression, $distinct), | ||
| 61 | null, | ||
| 62 | ), | ||
| 63 | ]; | ||
| 64 | |||
| 65 | // ORDER BY is not needed, only increases query execution through unnecessary sorting. | ||
| 66 | $selectStatement->orderByClause = null; | ||
| 67 | } | ||
| 68 | } | ||
