On 1 Feb 2007, at 07:23, Dami Laurent ((PJ)) wrote:

-----Message d'origine-----
De : Matt S Trout [mailto:[EMAIL PROTECTED]
Envoyé : jeudi, 25. janvier 2007 11:59
À : [email protected]
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 => [EMAIL PROTECTED],
                           -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 => [EMAIL PROTECTED], 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/ +



_______________________________________________
List: http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
Wiki: http://dbix-class.shadowcatsystems.co.uk/
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
Searchable Archive: http://www.mail-archive.com/[email protected]/

Reply via email to