2

我打算将 IfFunction 添加到 DQL 但它不起作用:

//My DQL Class
<?php

namespace Application\HappyBundle\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\Lexer;

/**
 * IFFunction ::= "IF" "( "ArithmeticPrimary" , "ArithmeticPrimary" ,  "ArithmeticPrimary" )"
 */
class IFFunction extends FunctionNode
{
    // (1)
    public $firstNumericExpression = null;
    public $secondNumericExpression = null;
    public $thirdNumericExpression = null;

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {

        $parser->match(Lexer::T_IDENTIFIER); // (2)
        $parser->match(Lexer::T_OPEN_PARENTHESIS); // (3)
        $this->firstNumericExpression = $parser->ArithmeticPrimary(); // (4)
        $parser->match(Lexer::T_COMMA); // (5)
        $this->secondNumericExpression = $parser->ArithmeticPrimary(); // (6)
        $parser->match(Lexer::T_COMMA); // (5)
        //$parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
        $this->thirdNumericExpression = $parser->ArithmeticPrimary(); // (6)
        $parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)

    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return 'IF(' .
            $this->firstNumericExpression->dispatch($sqlWalker) . ', ' .
            $this->secondNumericExpression->dispatch($sqlWalker) . ', ' .
            $this->thirdNumericExpression->dispatch($sqlWalker) .
        ')';
    }
}

//在config.yml中声明

        dql:
            datetime_functions:
                timediff: Application\HappyBundle\DQL\TimeDiff  
                addtime: Application\HappyBundle\DQL\AddTime    
            numeric_functions:
                IF: Application\HappyBundle\DQL\IFFunction            

DQL功能的添加工作,但是当我打算做例如:

SELECT IF(1<2,'oui','non');

如果我像这样放置 If 函数,则 char '<' 有错误

SELECT IF('1<2','oui','non');

这是工作,但不是评估第一个条件:(

如果有人有想法...谢谢您的帮助。

4

1 回答 1

6

我找到了解决方案,问题出在解析器上,它必须包含这样的 ConditionnalExpression 来评估:

class IfFunction extends FunctionNode
{
    private $expr = array();

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->expr[] = $parser->ConditionalExpression();

        for ($i = 0; $i < 2; $i++)
        {
            $parser->match(Lexer::T_COMMA);
            $this->expr[] = $parser->ArithmeticExpression();
        }

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return sprintf('IF(%s, %s, %s)',
            $sqlWalker->walkConditionalExpression($this->expr[0]),
            $sqlWalker->walkArithmeticPrimary($this->expr[1]),
            $sqlWalker->walkArithmeticPrimary($this->expr[2]));
    }
}
于 2013-09-25T10:56:41.047 回答