[Dbix-class] Extended JOIN syntax

Peter Rabbitson rabbit+dbic at rabbit.us
Sun Jan 29 20:52:03 GMT 2012


Bernhard Graf wrote:
> I have just learned, that the JOIN syntax was improved recently, so it 
> is possible to specify more than just the equality of column values, as 
> shown in the example from DBIx::Class::Relationship::Base:
> 
> My::Schema::Artist->has_many(
>   cds_80s => 'My::Schema::CD',
>   sub {
>     my $args = shift;
> 
>     return {
>       "$args->{foreign_alias}.artist" => { -ident => 
> "$args->{self_alias}.artistid" },
>       "$args->{foreign_alias}.year"   => { '>', "1979", '<', "1990" },
>     };
>   }
> );
> 
> ...
> 
> $artist_rs->search_related('cds_80s')->next;
> 
> 
> The example above still requires the bind values to be defined 
> statically in the schema. I couldn't find any examples, about how to 
> specify bind values at execution time - e.g. likes this:
> 
> My::Schema::Artist->has_many(
>   cds_era => 'My::Schema::CD',
>   sub {
>     my $args = shift;
> 
>     return {
>       "$args->{foreign_alias}.artist" => { -ident => 
> "$args->{self_alias}.artistid" },
>       "$args->{foreign_alias}.year"   => { '>', \'?', '<', \'?' },
>     };
>   }
> );
> 
> ...
> 
> $artist_rs->search_related('cds_era', {}, {bind => ['1979', '1990'])->next;

This would be an extremely limtied interface, given that you may have
several unrelated complex join-conds, and a view in the FROM on top of
that. How would you theb know in what order would you specify the binds
in?

> 
> 
> Isn't something like this possible?
> 

It is possible, but is not yet particularly pretty. The trick is
that the coderef in question is called every time the relationship
needs to be resolved. By referencing some external package-global
you can control what the coderef will return.

The real solution is to have proper runtime join condition
specifications, something like

search( {...}, { join => {
   foo => { -foo_opts => {}, bar => { -bar_opts => {}, baz => {} } }
} });

or similar. Making this work correctly and be flexible enough to
not constrain future dev-work is tricky business, and nobody has
invested the time to write up a full-fledged plan.

So until this takes place (you are more than welcome to help by
writing a more detailed spec, preferably in the form of failing
test cases) - until then the global var approach outlined above
is the easy way out.

Hope this was a little helpful :)

Cheers




More information about the DBIx-Class mailing list