Re-fix relcond resolver: revert 5592d633 (in turn partial revert of 03f6d1f7)
Peter Rabbitson [Mon, 21 Jul 2014 16:45:06 +0000 (18:45 +0200)]
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 :(

lib/DBIx/Class/ResultSource.pm

index 6a5bbc9..cc865b4 100644 (file)
@@ -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])