[Dbix-class] design issues : about database joins and multiple
inheritance
Matt S Trout
dbix-class at trout.me.uk
Fri Feb 2 09:50:27 GMT 2007
On 1 Feb 2007, at 07:23, Dami Laurent ((PJ)) wrote:
>> -----Message d'origine-----
>> De : Matt S Trout [mailto:dbix-class at trout.me.uk]
>> Envoyé : jeudi, 25. janvier 2007 11:59
>> À : dbix-class at lists.rawmode.org
>> Objet : Re: [Dbix-class] plat-form contest starting soon
>>
>>
>> Which reminds me, you and I still need to sit down and chat
>> about synergies.
>>
>> I reckon I could re-implement the documented interface of
>> DBIx::DataModel atop DBIx::Class in ~3 days and it would
>> actually be quite natural to do so, so I'm more and more
>> suspecting the differences between the projects are largely
>> in terms of how we conceptualise the interface rather than
>> how we actually see the underlying domain.
>
>
> Okay, now that plat-forms is over, let's start investigating some
> architectural points. For the discussion I will assume a database
> schema similar to the one in DBIx::Class::Manual::Example. In
> DBIx::DataModel, this would be written more or less as
>
> # Create a schema class
> DBIx::DataModel->Schema('Music');
>
> # Create table classes
> # Perl_class DB_table Primary_key
> # ---------- -------- -----------
> Music->Table(qw/Artist artist artist_id /);
> Music->Table(qw/Cd cd cd_id /);
> Music->Table(qw/Track track track_id /);
>
> # Declare UML associations
> # Class role_name multiplicity
> # ----- --------- ------------
> Music->Association([qw/Artist artist 1 /],
> [qw/Cd cds * /]);
>
> Music->Composition([qw/Cd cd 1 /],
> [qw/Track tracks 1..* /]);
>
>
> Now if I want information about all recent cds and tracks of some
> artist, I could write
>
> my $rows = $someArtist->selectFromRoles(qw/cds tracks/)
> ->(-columns => \@some_column_list,
> -where => {year => {">" => 2004}},
> -orderBy => 'year');
>
> The equivalent SQL is
>
> SELECT @some_column_list FROM cd INNER JOIN track ON
> cd.cd_id=track.cd_id
> WHERE artist_id = $someArtist->{artist_id}
> AND year > 2004
> ORDER BY year
my $rs = $artist->search_related('cds',
{ year => { '>' => 2004 } },
{ join => 'tracks', columns => \@columns, order_by => 'year',
result_class => $class }
);
(see below for discussion of auto-generating $class)
>
> and each row returned by that query will be blessed into a new class
> Music::AutoView::Cd_INNER_Track, created on the fly (if not already
> there),
> and which inherits from both classes Cd and Track. Multiple
> inheritance
> makes sense here because a row from that result set contains data
> from both
> tables (Cd and Track).
>
> Now I have two questions :
>
> 1) would such an idea (creating classes on the fly and using
> multiple inheritance) be compatible with the architecture of
> DBIx::Class ? beneficial ? disastrous ?
Well, in the example you give above I'd most likely just search
across to cds, prefetch back and call $obj->cd->$attr.
However, for more complex virtual views (e.g. cd + track + count
(times track listened to)) I've always been thinking about creating
classes on the fly - the resultset just calls
$rs->result_class->inflate_result
and doesn't care what's in there; I've used on-the-fly classes and
objects for that before now and DBIx::Class really doesn't care. As
for multiple inheritance, the entire package is built on it, so sure,
not a problem :)
I think you'd probably hook search_rs or the attr resolution process
to generate classes on the fly, though I kinda wonder if you mightn't
be better with some sort of AUTOLOAD hack than MI ... probably
depends on the use case.
> 2) as far as I understand, DBIx::Class also manipulates the
> namespace dynamically (loading classes and methods). Did you ever
> get in trouble when serializing/deserializing such classes through
> Catalyst sessions, as it just happened to me with DBIx::DataModel ?
> And if so, how did you solve it ?
So long as the class names are regular it's not really a -major-
problem, you just have to provide Storable hooks. Our big problem is
reconnecting to the $schema, which we still don't have a perfect
solution to.
--
Matt S Trout, Technical Director, Shadowcat Systems Ltd.
Offering custom development, consultancy and support contracts for
Catalyst,
DBIx::Class and BAST. Contact mst (at) shadowcatsystems.co.uk for
details.
+ Help us build a better perl ORM: http://dbix-
class.shadowcatsystems.co.uk/ +
More information about the Dbix-class
mailing list