Rajout de doctrine/orm
[zf2.biz/application_blanche.git] / vendor / doctrine / orm / lib / Doctrine / ORM / Tools / Pagination / CountWalker.php
diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php
new file mode 100644 (file)
index 0000000..0fc7e75
--- /dev/null
@@ -0,0 +1,90 @@
+<?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\TreeWalkerAdapter,
+    Doctrine\ORM\Query\AST\SelectStatement,
+    Doctrine\ORM\Query\AST\SelectExpression,
+    Doctrine\ORM\Query\AST\PathExpression,
+    Doctrine\ORM\Query\AST\AggregateExpression;
+
+/**
+ * Replaces the selectClause of the AST with a COUNT statement
+ *
+ * @category    DoctrineExtensions
+ * @package     DoctrineExtensions\Paginate
+ * @author      David Abdemoulaie <dave@hobodave.com>
+ * @copyright   Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
+ * @license     http://hobodave.com/license.txt New BSD License
+ */
+class CountWalker extends TreeWalkerAdapter
+{
+    /**
+     * Distinct mode hint name
+     */
+    const HINT_DISTINCT = 'doctrine_paginator.distinct';
+
+    /**
+     * Walks down a SelectStatement AST node, modifying it to retrieve a COUNT
+     *
+     * @param SelectStatement $AST
+     * @return void
+     */
+    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)
+                && $qComp['parent'] === null
+                && $qComp['nestingLevel'] == 0
+            ;
+            if ($isParent) {
+                $rootComponents[] = array($dqlAlias => $qComp);
+            }
+        }
+        if (count($rootComponents) > 1) {
+            throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
+        }
+        $root                = reset($rootComponents);
+        $parentName          = key($root);
+        $parent              = current($root);
+        $identifierFieldName = $parent['metadata']->getSingleIdentifierFieldName();
+
+        $pathType = PathExpression::TYPE_STATE_FIELD;
+        if (isset($parent['metadata']->associationMappings[$identifierFieldName])) {
+            $pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
+        }
+
+        $pathExpression = new PathExpression(
+            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
+            $identifierFieldName
+        );
+        $pathExpression->type = $pathType;
+
+        $distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
+        $AST->selectClause->selectExpressions = array(
+            new SelectExpression(
+                new AggregateExpression('count', $pathExpression, $distinct), null
+            )
+        );
+
+        // ORDER BY is not needed, only increases query execution through unnecessary sorting.
+        $AST->orderByClause = null;
+    }
+}
+