Utilizando funções de um banco de dados específico com o Doctrine2 e o Symfony2

Um dos ganhos de performance do Doctrine2 é devido a sua DQL conter apenas as funções que são comuns a todos os bancos de dados.

Para utilizarmos funções específicas de cada banco de dados (por exemplo, a função IFNULL do MySQL ou a função NVL do Oracle), o Doctrine nos permite adicioná-las através de extensões.

Segue aqui um exemplo para adicionar uma função YEAR, que retorna o ano de uma data fornecida, utilizando a função EXTRACT do Oracle:

Primeiro adicione um diretório que irá conter a sua função, por exemplo DoctrineExtensions\Query\Oracle.

Dentro deste diretório vamos criar a classe Year.php, que irá conter a nossa função:


<php
namespace DoctrineExtensions\Query\Oracle;

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

class Year extends FunctionNode
{
    private $date;

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return sprintf(
                'EXTRACT(YEAR FROM %s)',
                $sqlWalker->walkArithmeticPrimary($this->date));
    }

    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);
    }
}

A classe Year deve estender a classe FunctionNode, que requer que sejam implementados dois métodos: getSql e parse. Informações mais detalhadas podem ser encontradas no artigo do cookbook do Doctrine "DQL user defined functions"

Registrando a função

Agora, só precisamos disponibilizar a função YEAR ao DQL do Doctrine. Para isso, é necessário registrá-la, através das configurações do Doctrine no arquivo app/config/config.yml, sob a chave dql. Logo abaixo da chave dql, você deve definir a chave do tipo da sua função, que pode ser: string_functions, numeric_functions ou datetime_functions. Em seguida, vem a chave com o nome da sua função e a localização da respectiva classe:


# Doctrine Configuration
doctrine:
  orm:
    dql:
      datetime_functions:
        year: DoctrineExtensions\Query\Oracle\Year

Dica: Antes de escrever a sua função, verifique se ela já existe no repo DoctrineExtensions, que contém uma coleção de funções, com várias contribuições.

Mais sobre

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s