Doctrine 2 mysql FIELD function in order by

前端 未结 4 801
轮回少年
轮回少年 2020-11-29 11:08

I\'m trying to use the MySQL FIELD function in an order by clause in a query. I\'m assuming that Doctrine 2 doesn\'t support the FIELD function out of the box - is that true

4条回答
  •  广开言路
    2020-11-29 11:48

    You could add support for the FIELD() DQL function but instead implement it as standard SQL CASE .. WHEN expression. This way your function would work both on MySQL and Sqlite, which is particularly useful if you are like me and like to run your unit tests on in-memory sqlite.

    This class is largely based on the work by Jeremy Hicks (I simply changed the getSql() method)

    class Field extends FunctionNode
    {
        private $field = null;
        private $values = array();
    
        public function parse(\Doctrine\ORM\Query\Parser $parser)
        {
            $parser->match(Lexer::T_IDENTIFIER);
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
    
            // Do the field.
            $this->field = $parser->ArithmeticPrimary();
    
            // Add the strings to the values array. FIELD must
            // be used with at least 1 string not including the field.
    
            $lexer = $parser->getLexer();
    
            while (count($this->values) < 1 ||
                    $lexer->lookahead['type'] != Lexer::T_CLOSE_PARENTHESIS) {
                $parser->match(Lexer::T_COMMA);
                $this->values[] = $parser->ArithmeticPrimary();
            }
    
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    
        public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
        {
            $query = '(CASE ' . $this->field->dispatch($sqlWalker);
            for ($i=0, $limiti=count($this->values); $i < $limiti; $i++) {
                $query .= ' WHEN ' . $this->values[$i]->dispatch($sqlWalker) . ' THEN     ' . $i;
            }
                $query .= ' END)';
    
            return $query;
        }
    }
    

提交回复
热议问题