[Dbix-class] Hiding storage details

Jess Robinson castaway at desert-island.me.uk
Tue Mar 17 14:00:13 GMT 2009


Hi Andreas,

On Mon, 16 Mar 2009, Andreas Mock wrote:

> Hi all,
>
> as part of another thread I want to extract the following question with a more meaningful subject:
>
> We do have objects (O) which consist of attribues (A) which are
> stored in a table O with columns A just as DBIC would model it.
> But we do also have sparse attributes (B) (attributes which are very often
> NULL) which are not stored as columns of the "base" table O but as rows
> of a - let's call it attribute table - where each "not null"-attribut B of O is a
> row in that table with a key consisting of a class identifier,
> an object identifier (O.id) and an attribute identifier.

Some diagrams would go a long way to explaining whats going on there.. let 
me take some guesses:

Table O:
ID   |  colour | attr2 
----------------------
1    |  red    | 2
2    | orange  | 4
3    | yellow  | 6

Table Attribute:
O_id | Class   | Value
----------------------
1    | length  | 3cm
1    | height  | 4cm
3    | length  | 2cm

Anywhere close?

> After loading this object I want to see that object in a flat way. This
> "attribute collection" shall show up as "normal" (columns) attributes
> (with accessors named like the attribute identifier).
> While using the object from the application perspective I don't want to
> know that there are some attributes stored as columns in the base table
> and some as entries in a related table.

And you'd like:

   my $row1 = $schema->resultset('O')->find(1);

$row1->colour - returns red
$row1->length - returns '3cm'

which in normal dbic would be:

$row1->attributes->find({ Class => 'length'})->Value

> Is there a way in DBIC to do this?

There's always a way.. You can add more logic to your O class, so that its 
transparent to the rest of the system.

Is there a table which defines which classes of attributes can exist? 
Without that, anyone could put any string in there, which makes adding 
accessors tricky. Even then, if someone adds a new one..

I think you'll need autoload in your O clas, aka:

   sub AUTOLOAD {
     my $self = shift;
     my $attr_name = $AUTOLOAD;
     $attr_name  =~ s/.*://;

     my $attr = $self->attributes->find({ class => $attr_name });

     die "No such attribute $attr_name" if(!$attr);

     return $attr->value;
   }

Not convinced this is the best solution.. maybe someone will come up with 
a better one now I've suggested it!

Jess




More information about the DBIx-Class mailing list