Blog d'un passionné du web (Symfony2, HTML5, Sass, Gulp…)

Mon site freelance
Mon Facebook - Mon Twitter

Select distinct date Symfony 2 – doctrine DQL

Je me suis confronté à un petit select distinct sur Symfony. Jusque là rien de bien compliqué puisque c’est intégré à Doctrine. Néanmoins j’ai du définir cette condition  d’unicité sur une date. Pour plus de précision dans ma base de données ma date de création (via StofDoctrineExtension …)  est un DateTime est donc si on fait simple :

$qb->select("DISTINCT a.createdAt);

on aura plusieurs retours pour une même date (à des heures différentes)…
J’ai donc rajouté un filtre DATE_FORMAT non natif avec doctrine qui permettra de faire un DISTINCT sur la date uniquement :

$qb->select("DISTINCT DATE_FORMAT(a.createdAt, '%Y-%m-%d') AS date");

Le DATE_FORMAT n’est pas natif à Doctrine, vous avez plusieurs possibilités pour l’intégrer comme DoctrineExtension. On va faire plus simple avec la création de notre fontcion :


namespace AppBundle\Helpers;

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

/**
* Class DateFormatFunction
*
* Adds the hability to use the MySQL DATE_FORMAT function inside Doctrine
*
* @package Vf\Bundle\VouchedforBundle\DQL
*/
class DateFormatFunctionDQL extends FunctionNode
{

    /**
    * Holds the timestamp of the DATE_FORMAT DQL statement
    * @var $dateExpression
    */
    protected $dateExpression;

    /**
    * Holds the '% format' parameter of the DATE_FORMAT DQL statement
    * var String
    */
    protected $formatChar;

    public function getSql( SqlWalker $sqlWalker )
    {
        return 'DATE_FORMAT (' . $sqlWalker->walkArithmeticExpression( $this->dateExpression ) . ',' . $sqlWalker->walkStringPrimary( $this->formatChar ) . ')';
    }

    public function parse( Parser $parser )
    {
        $parser->Match( Lexer::T_IDENTIFIER );
        $parser->Match( Lexer::T_OPEN_PARENTHESIS );

        $this->dateExpression = $parser->ArithmeticExpression();
        $parser->Match( Lexer::T_COMMA );

        $this->formatChar = $parser->ArithmeticExpression();

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

Puis le paramétage qui va bien :

 


doctrine:
    orm:
        ...
        dql:
            datetime_functions:
                DATE_FORMAT: AppBundle\Helpers\DateFormatFunctionDQL

Voilà si vous avez des questions n’hésitez pas.

15 février 2016


Previous Post

Next Post