X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSet.pm;h=128b5546ec82bc8569d168b0859bc6810e751e67;hb=09d2e66a5d5558ef9a19dc2ec510d5dafd2fb7d8;hp=a0305c8ca7f3e55866b85ab813f58908e4ffd51e;hpb=616ca57f8cd27f475da275bbef986fdd42d4069f;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index a0305c8..128b554 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -9,9 +9,11 @@ use DBIx::Class::Carp; use DBIx::Class::ResultSetColumn; use DBIx::Class::ResultClass::HashRefInflator; use Scalar::Util qw( blessed reftype ); +use SQL::Abstract 'is_literal_value'; use DBIx::Class::_Util qw( dbic_internal_try dbic_internal_catch dump_value emit_loud_diag - fail_on_internal_wantarray fail_on_internal_call UNRESOLVABLE_CONDITION + fail_on_internal_wantarray fail_on_internal_call + UNRESOLVABLE_CONDITION DUMMY_ALIASPAIR ); use DBIx::Class::SQLMaker::Util qw( normalize_sqla_condition extract_equality_conditions ); use DBIx::Class::ResultSource::FromSpec::Util 'find_join_path_to_alias'; @@ -777,7 +779,6 @@ sub find { my $self = shift; my $attrs = (@_ > 1 && ref $_[-1] eq 'HASH' ? pop(@_) : {}); - my $rsrc = $self->result_source; my $constraint_name; if (exists $attrs->{key}) { @@ -790,6 +791,8 @@ sub find { # Parse out the condition from input my $call_cond; + my $rsrc = $self->result_source; + if (ref $_[0] eq 'HASH') { $call_cond = { %{$_[0]} }; } @@ -812,25 +815,59 @@ sub find { } # process relationship data if any + my $rel_list; + for my $key (keys %$call_cond) { if ( + # either a structure or a result-ish object length ref($call_cond->{$key}) and - my $relinfo = $rsrc->relationship_info($key) + ( $rel_list ||= { map { $_ => 1 } $rsrc->relationships } ) + ->{$key} + and + ! is_literal_value( $call_cond->{$key} ) and - # implicitly skip has_many's (likely MC) - ( ref( my $val = delete $call_cond->{$key} ) ne 'ARRAY' ) + # implicitly skip has_many's (likely MC), via the delete() + ( ref( my $foreign_val = delete $call_cond->{$key} ) ne 'ARRAY' ) ) { - my ($rel_cond, $crosstable) = $rsrc->_resolve_condition( - $relinfo->{cond}, $val, $key, $key - ); - $self->throw_exception("Complex condition via relationship '$key' is unsupported in find()") - if $crosstable or ref($rel_cond) ne 'HASH'; + # FIXME: it seems wrong that relationship conditions take precedence...? + $call_cond = { + %$call_cond, + + %{ $rsrc->_resolve_relationship_condition( + rel_name => $key, + foreign_values => ( + (! defined blessed $foreign_val) ? $foreign_val : do { + + my $f_result_class = $rsrc->related_source($key)->result_class; + + unless( $foreign_val->isa($f_result_class) ) { - # supplement condition - # relationship conditions take precedence (?) - @{$call_cond}{keys %$rel_cond} = values %$rel_cond; + $self->throw_exception( + 'Objects supplied to find() must inherit from ' + . "'$DBIx::Class::ResultSource::__expected_result_class_isa'" + ) unless $foreign_val->isa( + $DBIx::Class::ResultSource::__expected_result_class_isa + ); + + carp_unique( + "Objects supplied to find() via '$key' usually should inherit from " + . "the related ResultClass ('$f_result_class'), perhaps you've made " + . 'a mistake?' + ); + } + + +{ $foreign_val->get_columns }; + } + ), + infer_values_based_on => {}, + + # an API where these are optional would be too cumbersome, + # instead always pass in some dummy values + DUMMY_ALIASPAIR, + )->{inferred_values} }, + }; } } @@ -2496,8 +2533,10 @@ sub populate { $colinfo->{$rel}{fk_map} = { reverse %{ $rsrc->_resolve_relationship_condition( rel_name => $rel, - self_alias => "\xFE", # irrelevant - foreign_alias => "\xFF", # irrelevant + + # an API where these are optional would be too cumbersome, + # instead always pass in some dummy values + DUMMY_ALIASPAIR, )->{identity_map} || {} } }; }