From: Matt S Trout Date: Fri, 15 Nov 2013 10:07:47 +0000 (+0000) Subject: support expr {} in join cond X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9f9a73659ab2dbca0957049d3c0c7997512581ac;p=dbsrgits%2FDBIx-Class.git support expr {} in join cond --- diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 3233e3a..d758ed7 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -13,6 +13,7 @@ use Devel::GlobalDestruction; use Try::Tiny; use List::Util 'first'; use Scalar::Util qw/blessed weaken isweak/; +use Data::Query::ExprHelpers; use namespace::clean; @@ -1811,6 +1812,33 @@ sub _resolve_condition { } return wantarray ? (\@ret, $crosstable) : \@ret; } + elsif (blessed($cond) and $cond->isa('Data::Query::ExprBuilder')) { + my %cross; + my $as = blessed($for) ? 'me' : $as; + my $mapped = map_dq_tree { + if (is_Identifier and @{$_->{elements}} == 2) { + foreach my $check ([ foreign => $as ], [ self => $for ]) { + my ($ident, $thing) = @$check; + if ($_->{elements}[0] eq $ident) { + if ($thing and !ref($thing)) { + $cross{$thing} = 1; + return \Identifier($thing, $_->{elements}[1]); + } elsif (!defined($thing)) { + return \perl_scalar_value(undef); + } elsif ((ref($thing)||'') eq 'HASH') { + return \perl_scalar_value($thing->{$_->{elements}[1]}); + } elsif (blessed($thing)) { + return \perl_scalar_value($thing->get_column($_->{elements}[1])); + } else { + die "I have no idea what ${thing} is supposed to be"; + } + } + } + } + return $_; + } $cond->{expr}; + return (wantarray ? (\$mapped, (keys %cross == 2)) : \$mapped); + } else { $self->throw_exception ("Can't handle condition $cond for relationship '$rel_name' yet :("); } diff --git a/t/dq/join.t b/t/dq/join.t new file mode 100644 index 0000000..b6ca14b --- /dev/null +++ b/t/dq/join.t @@ -0,0 +1,35 @@ +use strict; +use warnings; + +use Test::More; +use Test::Exception; +use Test::Warn; +use lib qw(t/lib); +use DBICTest::Schema::Artist; +use Data::Query::ExprDeclare; +BEGIN { + DBICTest::Schema::Artist->has_many( + cds2 => 'DBICTest::Schema::CD', + expr { $_->foreign->artist == $_->self->artistid } + ); + DBICTest::Schema::Artist->has_many( + cds2_pre2k => 'DBICTest::Schema::CD', + expr { + $_->foreign->artist == $_->self->artistid + & $_->foreign->year < 2000 + } + ); +} +use DBICTest; +use DBIC::SqlMakerTest; + +my $schema = DBICTest->init_schema(); + +my $mccrae = $schema->resultset('Artist') + ->find({ name => 'Caterwauler McCrae' }); + +is($mccrae->cds2->count, 3, 'CDs returned from expr join'); + +is($mccrae->cds2_pre2k->count, 2, 'CDs returned from expr w/cond'); + +done_testing;