Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

UNIX_TIMESTAMP, ROUND и другие DQL запросы через queryBuilder в Symfony 2

Anna | 31.05.2014 | нет комментариев

Как вестимо у Symfony 2 в Doctrine 2 из «коробки» нет поддержки некоторых стандартных функций Mysql, таких как UNIX_TIMESTAMP либо ROUND и еще несколько других. В первую очередь статья для того Дабы осознать как дополнять DQL своими функциями. Но перед написанием как следует «попрогрить» и по «гитхабить», а внезапно теснее кто-то написал, советую не городить велосипеды и воспользоваться теснее готовыми наработками, скажем GitHub MysqlDoctrineFunctions.

Статья огромнее подходит для новичков.

Выходит, задание! Сделать функцию ROUND, приступим:

Первое что нам необходимо это сделать изложение нашего способа через FunctionNode изDoctrine\ORM\Query\AST\Functions\FunctionNode.
Сотворим в нашем Bundle папку с наименованием DQL (дозволено безусловно обозвать как желательно).
У меня это выглядит так: src/Acme/SimpleBundle/DQL

Создаем в этой директории файл с наименованием скажем Round.php, получаетсяsrc/Acme/SimpleBundle/DQL/Round.php
Содержимое:

namespace Acme\SimpleBundle\DQL;

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

class Round extends FunctionNode
{
    protected $roundExp;
    protected $roundPrecission;

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return 'ROUND(' .
            $sqlWalker->walkArithmeticExpression($this->roundExp) . ','.
            $sqlWalker->walkArithmeticExpression($this->roundPrecission)
        .')';
    }

    /**
     * parse - allows DQL to breakdown the DQL string into a processable structure
     * @param \Doctrine\ORM\Query\Parser $parser
     */
    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->roundExp = $parser->ArithmeticExpression(); // Указываем первое значение функции
        $parser->match(Lexer::T_COMMA); // Добавим разграничитель
        $this->roundPrecission = $parser->ArithmeticExpression(); // И добавим второе значение

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

Нам необходимо реализовать две функции, функция getSql как и ясно из наименования вернет в ORM подготовленный SQL, а parse предуготовлена для парсинга переменных передаваемых в запрос, скажем round(sum,2)

Для того Дабы передавать параметры в функцию, нам нужно определить внутренние переменные, в данном примере это:

    protected $roundExp;
    protected $roundPrecission;

   // Дабы было ясно то это выглядит так  round(roundExp, roundPrecission)

Дальше нам нужно подсказать доктрине где искать наши функции, для этого укажем в config.yml в сегментыdoctrine: что у нас есть дополнения к стандартному DQL, у меня это выглядит так:

doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        charset:  UTF8

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true

        dql:
          string_functions:
            unix_timestamp: \Acme\SimpleBundle\DQL\UnixTimestamp
          numeric_functions:
            round: \Acme\SimpleBundle\DQL\Round

Сейчас при выполнении запроса вида:

$queryBuilder->andWhere("ROUND (sum) , 1) = :condition");

Концепция полезет в наши функции и составит верный запрос в Mysql.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB