2012-08-14 15 views
5

Odkryłem, że typy tablic Doctrine używają serializacji/unserializacji i przechowują dane wewnątrz "prostych" pól, takich jak tekst, liczba całkowita.Tablice Doctrine i Postgres

Ale mam projekt z bazą danych PostgreSQL z niektórymi polami jako tablice (głównie tekst). Chcę użyć tej bazy danych w Doctrine. Czy istnieje sposób, aby sobie z tym poradzić?

Dzięki

EDIT:

PS: Teraz wiem, że SQL tablice mogą być dobrą praktyką, dzięki Craig Ringer.

Może mogę utworzyć niestandardowy typ. Czy jest ktoś, kto już to zrobił?

EDIT 2:

Problem pół rozwiązany:

<?php 
namespace mysite\MyBundle\Types; 

use Doctrine\DBAL\Types\Type; 
use Doctrine\DBAL\Platforms\AbstractPlatform; 

/** 
    * My custom postgres text array datatype. 
*/ 
class TEXTARRAY extends Type 
{ 
    const TEXTARRAY = 'textarray'; // modify to match your type name 

    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) 
    { 
     return $platform->getDoctrineTypeMapping('TEXTARRAY'); 
    } 

    public function convertToPHPValue($value, AbstractPlatform $platform) 
    { 
    // This is executed when the value is read from the database. Make your conversions here, optionally using the $platform. 
     return explode('","', trim($value, '{""}')); 
    } 

    public function convertToDatabaseValue($value, AbstractPlatform $platform) 
    { 
    // This is executed when the value is written to the database. Make your conversions here, optionally using the $platform. 

     settype($value, 'array'); // can be called with a scalar or array 
     $result = array(); 
     foreach ($set as $t) { 
      if (is_array($t)) { 
       $result[] = to_pg_array($t); 
      } else { 
       $t = str_replace('"', '\\"', $t); // escape double quote 
       if (! is_numeric($t)) // quote only non-numeric values 
        $t = '"' . $t . '"'; 
       $result[] = $t; 
      } 
     } 
     return '{' . implode(",", $result) . '}'; // format  

    } 

    public function getName() 
    { 
     return self::TEXTARRAY; // modify to match your constant name 
    } 
} 

a kontroler

<?php 

namespace mysite\MyBundle; 

use Symfony\Component\HttpKernel\Bundle\Bundle; 
use Doctrine\ORM\EntityManager; 
use Doctrine\DBAL\Types\Type; 

class mysiteMyBundle extends Bundle 
{ 
    public function boot() { 
     Type::addType('textarray', 'mysite\MyBundle\Types\TextArray'); 
     $em = $this->container->get('doctrine.orm.default_entity_manager'); 
     $conn = $em->getConnection(); 
     $conn->getDatabasePlatform()->registerDoctrineTypeMapping('TEXTARRAY', 'textarray'); 
    } 
} 

wiem chcesz szukać wewnątrz tych tablic z zapytaniami, jak 'myword' = dowolny (myarrayfield) ... Czy ktoś ma jakąś wskazówkę?

Ktoś na kanale # doctrine2 powiedział mojemu zbudować funkcję zwyczaj DQL, więc tutaj jest:

<?php 
use Doctrine\ORM\Query\Lexer; 
use Doctrine\ORM\Query\AST\Functions\FunctionNode; 

class ANY extends FunctionNode { 

    public $field; 


    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { 
     return 'ANY(' . 
      $this->field->dispatch($sqlWalker) . ')'; 
    } 

    public function parse(\Doctrine\ORM\Query\Parser $parser) { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->field = $parser->StringPrimary(); 
     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 
} 

Ale ja budować moje zapytania z konstruktora zapytań, z tablicy zawierającej rzeczy jak

$arr[] = $qb->expr()->like($alias.".".$field, $qb->expr()->literal('%'.trim($val).'%')); 

i łączenia ich z

if(count($arr) > 0) $qb->Where(new Expr\Orx($arr)); 
else unset($arr); 

Tak, jak korzystać z funkcji? : \

+2

Macierze SQL są w rzeczywistości * naprawdę * poręczną denormalizacją, która może być ogromnym zwiększeniem wydajności, gdy jest używana mądrze i ostrożnie. Po prostu nie powinny być używane bez uzasadnionych powodów, są mniej przenośne, itp. –

Odpowiedz

4

Wewnątrz QueryBuilder można wykorzystać swoje funkcje niestandardowe po prostu je pisząc:

$qb->where("ANY(a.b)"); 

Niektóre dalsze informacje:

  1. Możesz dodać typy niestandardowe do „doktryna” sekcji config w Twoja aplikacja Symfony.
  2. To samo dotyczy niestandardowej funkcji DQL.

Zobacz komendę "config: dump-reference DoctrineBundle" w CLI dla składni w Symfony 2.1, w przeciwnym razie na stronie symfony.com.