Пользовательская функция DQL для репликации MySQL CONV - PullRequest
5 голосов
/ 30 декабря 2011

Я пытаюсь создать пользовательскую функцию DQL, чтобы позволить мне использовать строковую функцию MySQL CONV в моем DQL. Моя цель - иметь возможность выполнять битовую проверку содержимого, которое хранится в шестнадцатеричном формате. Ранее я только что выполнил запрос SQL, например:

.... where conv(`myField`,16,10) & 4096 = 4096

Однако я хочу преобразовать эти SQL-запросы в формат DQL. Чего я не могу понять, так это как добавить & & 4096 = 4096 'в анализатор. Это насколько я смог получить:

namespace Acme\TestBundle\DQL;

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

class MysqlConv extends FunctionNode
{
        public $stringFirst; 
        public $stringSecond; 
        public $stringThird; 
        public $stringFourth; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
        $parser->match(Lexer::T_IDENTIFIER); 
        $parser->match(Lexer::T_OPEN_PARENTHESIS); 
        $this->stringFirst = $parser->StringPrimary(); 
        $parser->match(Lexer::T_COMMA);
        $this->stringSecond = $parser->ArithmeticPrimary();
        $parser->match(Lexer::T_COMMA);
        $this->stringThird = $parser->ArithmeticPrimary();      
        $parser->match(Lexer::T_CLOSE_PARENTHESIS); 


    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
        return 'CONV(' . 
            $this->stringFirst->dispatch($sqlWalker) . 
        ',' . $this->stringSecond->dispatch($sqlWalker) . ',' . $this->stringThird->dispatch($sqlWalker) . ') & 4096'; 
    } 
}

Который я тогда использую так:

    return $this->getEntityManager()
            ->createQuery('SELECT c, h FROM AcmeTestBundle:Company c LEFT JOIN c.CompanyAssoc h WHERE CONV(c.myField,16,10) = 4096')
            ->getResult();

Какие-либо предложения относительно того, как лучше всего выполнить переход с SQL на DQL для функции MySQL CONV?

1 Ответ

0 голосов
/ 24 февраля 2012

K, просто чтобы помочь кому-то еще, смотрящему на это в будущем. Я понял, что моя проблема в том, что я пытался сохранить синтаксис SQL в DQL. Понимание этого было моей проблемой, позволившей мне завершить функцию DQL.

namespace Acme\TestBundle\DQL;

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

/** 
 * MysqlConvFunction ::= "CONV(StringPrimary,16,10,4096) = 4096" 
 *      returns CONV(StringPrimary,16,10) & 4096 = 4096
 */ 
class MysqlConv extends FunctionNode
{
    public $stringFirst; 
    public $stringSecond; 
    public $stringThird; 
    public $stringFourth; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
        $parser->match(Lexer::T_IDENTIFIER); 
        $parser->match(Lexer::T_OPEN_PARENTHESIS); 
        $this->stringFirst = $parser->StringPrimary(); 
        $parser->match(Lexer::T_COMMA);
        $this->stringSecond = $parser->ArithmeticPrimary();
        $parser->match(Lexer::T_COMMA);
        $this->stringThird = $parser->ArithmeticPrimary();     
        $parser->match(Lexer::T_COMMA);
        $this->stringFourth = $parser->ArithmeticPrimary();          
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);          
    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
        return 'CONV(' . 
            $this->stringFirst->dispatch($sqlWalker) . 
        ',' . $this->stringSecond->dispatch($sqlWalker) . ',' . $this->stringThird->dispatch($sqlWalker) . ') & ' . $this->stringFourth->dispatch($sqlWalker); 
    } 
}
...