Blog


FUNCIONES DQL DEFINIDAS POR EL USUARIO PARA DOCTRINE EN SYMFONY2

01 / 10 / 2013 Symfony

No todas las funciones SQL están implementadas en DQL de Doctrine, sino solo aquellas más comunes entre los distintos proveedores de SQL. Sin embargo, puede darse el caso de que necesitemos en nuestro desarrollo Symfony, una función específica de MySQL que no tenga soporte DQL, como puede ser DATE() o YEAR() por poner un par de ejemplos de funciones para trabajar con fechas.

DQL permite al usuario extender sus capacidades registrando nuevas funciones que pueden ser utilizadas en las consultas. Estas funciones pueden ser de tres tipos, aquellas que devuelven un valor numérico, las que devuelven una cadena y las que devuelven una fecha.

A modo de ejemplo, vamos a ver cómo definir la función DATE() de MySQL para poder usarla en las consultas que construyamos en nuestros desarrollos Symfony. Lo primero será crear una clase PHP que extienda FunctionNode, con los métodos getSql y parse, que parsean y devuelven la cadena que se utilizará en la consulta, y que guardaremos en la carpeta DQL del bundle que corresponda en nuestro proyecto.


<?php

namespace Vabadus\AdminBundle\DQL;

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

/**
 * "DATE" "(" SimpleArithmeticExpression ")".
 */
class DateFunction extends FunctionNode
{
    public $date;

    /**
     * @override
     */
    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return "DATE(" . $sqlWalker->walkArithmeticPrimary($this->date) . ")";
    }

    /**
     * @override
     */
    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->date = $parser->ArithmeticPrimary();

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

Una vez que hemos definido nuestra función, necesitaremos registrarla en la configuración de nuestro proyecto Symfony para poder utilizarla. Para ello, añadimos lo siguiente en nuestro fichero app/config/config.yml:


doctrine:
    orm:
        # ...
        entity_managers:
            default:
                # ...
                dql:
                    datetime_functions:
                        date: VabadusAdminBundle\DQL\DateFunction



ARTÍCULOS RELACIONADOS