From: Peter Rabbitson Date: Mon, 21 Jul 2014 16:45:06 +0000 (+0200) Subject: Re-fix relcond resolver: revert 5592d633 (in turn partial revert of 03f6d1f7) X-Git-Tag: v0.082800~122 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=350e8d57bf21e4006e2a5e5c26648cb5ca4903ea Re-fix relcond resolver: revert 5592d633 (in turn partial revert of 03f6d1f7) I had the right hunch during 03f6d1f7 but could not substantiate it: the issue is that the custom coderef expects objects or nothing. Yet here and there internals pass around bare hashes of data (or sometimes even undef). Asking users to complicate their coderefs further is just not an option - it is mindbending enough as it is. So the only way to go forward is indeed to create "synthetic result objects" and pass them down the stack. This time however there is a twist - after the overhaul in 4006691d we now *can* indeed construct such objects on top of the bare DBIx::Class::Core - in other words mission fucking accomplished. This commit *may* need to be reverted in case it turns out that 4006691d is a no-go (check the test change to t/inflate/datetime_oracle.t in 12b348d9 for an example of what was taken for granted wrt direct $class-> calls) If this is the case - not all is lost. We should be able to use a hidden class with an actual source instance that we would ammend on the fly... But let's hope we will never get to this bridge :( --- diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 6a5bbc9..cc865b4 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -1786,24 +1786,46 @@ sub _resolve_relationship_condition { if !defined $args->{$_} or length ref $args->{$_}; } - my $rel_info = $self->relationship_info($args->{rel_name}); - # or $self->throw_exception( "No such relationship '$args->{rel_name}'" ); - my $exception_rel_id = "relationship '$args->{rel_name}' on source '@{[ $self->source_name ]}'"; + my $rel_info = $self->relationship_info($args->{rel_name}); + # or $self->throw_exception( "No such $exception_rel_id" ); + $self->throw_exception("No practical way to resolve $exception_rel_id between two objects") if defined $args->{self_resultobj} and defined $args->{foreign_resultobj}; + $self->throw_exception( "Argument to infer_values_based_on must be a hash" ) + if exists $args->{infer_values_based_on} and ref $args->{infer_values_based_on} ne 'HASH'; - $self->throw_exception( "Object '$args->{foreign_resultobj}' must be of class '$rel_info->{class}'" ) - if defined blessed $args->{foreign_resultobj} and ! $args->{foreign_resultobj}->isa($rel_info->{class}); + $args->{require_join_free_condition} ||= !!$args->{infer_values_based_on}; $args->{condition} ||= $rel_info->{cond}; - $self->throw_exception( "Argument to infer_values_based_on must be a hash" ) - if exists $args->{infer_values_based_on} and ref $args->{infer_values_based_on} ne 'HASH'; + if (exists $args->{self_resultobj}) { + if (defined blessed $args->{self_resultobj}) { +# $self->throw_exception( "Object '$args->{self_resultobj}' must be of class '@{[ $self->result_class ]}'" ) +# unless $args->{self_resultobj}->isa($self->result_class); + } + else { + $args->{self_resultobj} = DBIx::Class::Core->new({ + -result_source => $self, + %{ $args->{self_resultobj}||{} } + }); + } + } - $args->{require_join_free_condition} ||= !!$args->{infer_values_based_on}; + if (exists $args->{foreign_resultobj}) { + if (defined blessed $args->{foreign_resultobj}) { +# $self->throw_exception( "Object '$args->{foreign_resultobj}' must be of class '$rel_info->{class}'" ) +# unless $args->{foreign_resultobj}->isa($rel_info->{class}); + } + else { + $args->{foreign_resultobj} = DBIx::Class::Core->new({ + -result_source => $self->related_source($args->{rel_name}), + %{ $args->{foreign_resultobj}||{} } + }); + } + } my $ret; @@ -1900,11 +1922,7 @@ sub _resolve_relationship_condition { for my $i (0..$#$obj_cols) { - # FIXME - temp shim - if (! blessed $obj) { - $ret->{join_free_condition}{"$plain_alias.$plain_cols->[$i]"} = $obj->{$obj_cols->[$i]}; - } - elsif ( + if ( defined $args->{self_resultobj} and ! $obj->has_column_loaded($obj_cols->[$i])