Posts Tagged ‘Doctrine’

Método findAll do ORM Doctrine não permite ordenação

Postado em 05 jan 2009
Categoria(s) Doctrine

Diariamente eu trabalho com o framework symfony 1.1 usando como ORM o Doctrine, mas são muitas as decepções com o Doctrine. Ele não é um ORM que propícia um desenvolvimento ágil.

Hoje eu precisei fazer uma consulta retornando todos os registros da tabela e ordenando pelo nome, tentei usar o método findAll do Doctrine, mas ele não permite informar uma coluna para ordenação, ou seja, o básico do básico ele não faz muito bem. Onde fica o desenvolvimento ágil em tudo isso? :-( Precisei fazer uma gambiarra usando o método findByDql para conseguir realizar a minha consulta.

Eu pretendia fazer algo do tipo:

1
2
3
4
5
6
7
8
9
$states = Doctrine::getTable('DState')->findAll()->orderBy('short');
 
ou
 
$states = Doctrine::getTable('DState')->orderBy('short')->findAll();
 
ou
 
$states = Doctrine::getTable('DState')->findAll(array('order' => 'short'));

Nada disso funciona, o método findAll não consegue trabalhar com ordenação. Não vejo vantagens em usar esse método se não posso trabalhar com a ordenação dos resultados.

Tive que fazer a seguinte gambiarra usando o método findByDql para conseguir executar a consulta de forma mais prática e ágil:

1
$states = Doctrine::getTable('DState')->findByDql('id is not null order by short');

Eu precisei criar um where que funciona para tudo e depois especificar a ordenação.

  • Share/Bookmark

A Falta de padronização dos retornos dos métodos de consulta do ORM Doctrine são irritantes

Postado em 05 dez 2008
Categoria(s) Doctrine

A Falta de padronização dos retornos dos métodos de consulta do Doctrine são irritantes, no ORM Doctrine as consultas realizadas com Doctrine_Query e o método findByDql retornam valores diferentes.

O Doctrine_Query retorna false, caso não satisfaça a condição where, já o método findByDql retorna um array vazio.

Essa falta de padronização é muito ruim.

Por exemplo:

1
2
3
4
$q = new Doctrine_Query();
$q->from('Status')->where('name = ?', 'exemplo');
$r = $q->execute();
var_dump($r);

Essa forma de consulta retorna false, caso name = ‘exemplo’ não exista. Eu acho esse retorno correto, ou null.

Mas o método findByDql tem um retorno fora de padrão, retornando um array vazio.

Por exemplo:

1
2
$status = Doctrine::getTable('Status')->findByDql("name = 'exemplo'");
var_dump($status);

O ruim é ter que usar essas tecnologias despadronizadas. :-(
Mais um ponto negativo para o Doctrine.

  • Share/Bookmark

symfony usar o object_select_tag para retornar os valores ordenados

Postado em 02 dez 2008
Categoria(s) Symfony

Esses tempos estava usando o object_select_tag (é uma mão na roda), mas precisava trazer os resultados em ordem crescente. Foi ae que eu descobri que existe uma opção peer_method onde é possível definir o método no model para retornar a lista de resultados.

Eu não curto o Propel, prefiro bem mais o Doctrine. Desta forma esse exemplo é baseado usando o Doctrine:

No template:

1
2
3
4
5
6
7
<?php echo object_select_tag(isset($filters['Status']) ? $filters['Status'] : null, null, array (
  'include_blank' => true,
  'related_class' => 'Status',
  'text_method' => '__toString',
  'control_name' => 'filters[Status]',
  'peer_method' => 'getSorted'
)) ?>

No model StatusTable.class.php:

1
2
3
4
5
6
7
public static function getSorted()
{
  $q = new Doctrine_Query();
  $q->from('Status')->orderBy('name ASC');
 
  return $q->execute();
}

No código acima que é possível definir a forma de ordenação e qual coluna que deve ser usada para ordenar.

Agora falta criar o método __toString no model Status.class.php:

1
2
3
4
public function __toString()
{
  return $this->name;
}

O método __toString e usado para imprimir os valores no combo box.

Pronto! ;-)

  • Share/Bookmark

Fazendo unit test usando Doctrine no symfony 1.1

Postado em 01 set 2008
Categoria(s) Symfony

Algumas vezes é necessário fazer testes de unidades para verificar o funcionamento da camada de model no symfony.

Você pode criar um arquivo no diretório test/unit do seu projeto, por exemplo: meutesteTest.php.

Nesse arquivo você deve inicializar as configurações do symfony e banco de dados, da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
require_once(dirname(__FILE__).'/../../../config/ProjectConfiguration.class.php');
$configuration = new ProjectConfiguration();
include($configuration->getSymfonyLibDir().'/vendor/lime/lime.php');
$appcfg = $configuration->getApplicationConfiguration('cron', 'dev', true);
$databaseManager = new sfDatabaseManager($appcfg);
 
$t = new lime_test(1, new lime_output_color());
 
try {
 
  $produtos = Doctrine::getTable('produtos')->find(1);
 
  $t->pass("Consulta realizada com sucesso.");
 
} catch (Exception $e) {
 
  $t->fail("Consulta falhou.");
 
}

Para rodar o teste de unidade execute:

symfony test:unit meuteste

O symfony irá executar o teste de unidade e mostrar se foi realizado com sucesso ou sem sucesso.

  • Share/Bookmark

Executando qualquer tipo de consulta no Doctrine

Postado em 07 mai 2008
Categoria(s) Doctrine

Depois de procurar bastante, consegui descobrir como executar qualquer tipo de consulta usando o ORM Doctrine.

Eu precisava usar algumas funções específicas do PostgreSQL, o Doctrine não implementa todas as funções do PostgreSQL, o Doctrine faz isso para manter a compatibilidade entre todos os banco de dados que ele dá suporte. Algumas funções só funcionam em um determinado banco de dados.

O exemplo que eu vou ilustrar abaixo foi construído em cima do framework symfony, mas deve ser muito semelhate se você estiver trabalhando direto com o Doctrine.

O Doctrine foi construído em cima do PDO (http://br.php.net/manual/pt_BR/book.pdo.php), desta forma nós podemos pegar a instância do Doctrine e realizar uma consulta usando o PDO.

Por exemplo:

1
2
3
4
5
6
7
8
9
 
$manager = Doctrine_Manager::getInstance();
$dbh = $manager->getCurrentConnection();
 
$sql = "SELECT sua_funcao_do_banco(?)";
 
$sth = $dbh->prepare($sql);
$sth->execute(array(10));
$r = $sth->fetch(PDO::FETCH_ASSOC);

Vamos entender como tudo funciona:

1
2
3
 
$manager = Doctrine_Manager::getInstance();
$dbh = $manager->getCurrentConnection();

O código acima pega a conexão atual com o banco de dados e usa ela para fazer a consulta.

1
2
 
$sql = "SELECT sua_funcao_do_banco(?)";

O SQL que você quer executar, pode ser qualquer sql que rode no seu banco de dados. Note o “?” esse cara informa que será passado um parâmetro.

1
2
3
4
 
$sth = $dbh->prepare($sql);
$sth->execute(array(10));
$r = $sth->fetch(PDO::FETCH_ASSOC);

Essas linhas preparam o SQL, executando e substituindo o “?” do SQL pelo valor no array, no caso array(10).

Por fim é executando o fetch para pegar apenas um resultado, se a consulta retorna-se mais que um resultado você poderia fazer um fetchAll.

A linha PDO::FETCH_ASSOC informa como você quer que os dados sejam retornados em array, objeto e outros. Dá uma olhada aqui: http://br.php.net/manual/pt_BR/pdostatement.fetch.php

Pronto! Agora e só usar a variável $r para trabalhar com os dados retornados da consulta.

  • Share/Bookmark