initial commit
[namibia] / module / Utility / src / Utility / DoctrineFunction / GroupConcat.php
1 <?php
2
3 // -------------------------------------------------
4 // Complete support of GROUP_CONCAT in Doctrine2
5 // -------------------------------------------------
6 // Original Article: http://habrahabr.ru/post/181666/
7 // Automated translation to English: http://sysmagazine.com/posts/181666/
8 // Original github commit: https://github.com/denisvmedia/DoctrineExtensions/blob/d1caf21cd7c71cc557e60c26e9bf25323a194dd1/lib/DoctrineExtensions/Query/Mysql/GroupConcat.php
9
10 /**
11  * DoctrineExtensions Mysql Function Pack
12  *
13  * LICENSE
14  *
15  * This source file is subject to the new BSD license that is bundled
16  * with this package in the file LICENSE.txt.
17  * If you did not receive a copy of the license and are unable to
18  * obtain it through the world-wide-web, please send an email
19  * to kontakt@beberlei.de so I can send you a copy immediately.
20  */
21
22 namespace UVd\DoctrineFunction;
23
24 use Doctrine\ORM\Query\AST\Functions\FunctionNode,
25     Doctrine\ORM\Query\Lexer;
26
27 /**
28  * Full support for:
29  *
30  * GROUP_CONCAT([DISTINCT] expr [,expr ...]
31  *              [ORDER BY {unsigned_integer | col_name | expr}
32  *                  [ASC | DESC] [,col_name ...]]
33  *              [SEPARATOR str_val])
34  *
35  */
36 class GroupConcat extends FunctionNode
37 {
38     public $isDistinct = false;
39     public $pathExp = null;
40     public $separator = null;
41     public $orderBy = null;
42
43     public function parse(\Doctrine\ORM\Query\Parser $parser)
44     {
45         $parser->match(Lexer::T_IDENTIFIER);
46         $parser->match(Lexer::T_OPEN_PARENTHESIS);
47
48         $lexer = $parser->getLexer();
49         if ($lexer->isNextToken(Lexer::T_DISTINCT)) {
50             $parser->match(Lexer::T_DISTINCT);
51
52             $this->isDistinct = true;
53         }
54
55         // first Path Expression is mandatory
56         $this->pathExp = array();
57         $this->pathExp[] = $parser->SingleValuedPathExpression();
58
59         while ($lexer->isNextToken(Lexer::T_COMMA)) {
60             $parser->match(Lexer::T_COMMA);
61             $this->pathExp[] = $parser->StringPrimary();
62         }
63
64         if ($lexer->isNextToken(Lexer::T_ORDER)) {
65             $this->orderBy = $parser->OrderByClause();
66         }
67
68         if ($lexer->isNextToken(Lexer::T_IDENTIFIER)) {
69             if (strtolower($lexer->lookahead['value']) !== 'separator') {
70                 $parser->syntaxError('separator');
71             }
72             $parser->match(Lexer::T_IDENTIFIER);
73
74             $this->separator = $parser->StringPrimary();
75         }
76
77         $parser->match(Lexer::T_CLOSE_PARENTHESIS);
78     }
79
80     public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
81     {
82         $result = 'GROUP_CONCAT(' . ($this->isDistinct ? 'DISTINCT ' : '');
83
84         $fields = array();
85         foreach ($this->pathExp as $pathExp) {
86             $fields[] = $pathExp->dispatch($sqlWalker);
87         }
88
89         $result .= sprintf('%s', implode(', ', $fields));
90
91         if ($this->orderBy) {
92             $result .= ' ' . $sqlWalker->walkOrderByClause($this->orderBy);
93         }
94
95         if ($this->separator) {
96             $result .= ' SEPARATOR ' . $sqlWalker->walkStringPrimary($this->separator);
97         }
98
99         $result .= ')';
100
101         return $result;
102     }
103
104 }
105
106
107
108
109