checks if the complex conditions are overriden in set_from_related
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSource.pm
index 1dca0a6..4f41baa 100644 (file)
@@ -1345,11 +1345,14 @@ sub reverse_relationship_info {
   my @otherrels = $othertable->relationships();
   my $otherrelationship;
   foreach my $otherrel (@otherrels) {
-    my $otherrel_info = $othertable->relationship_info($otherrel);
+    # this may be a partial schema with the related source not being
+    # available at all
+    my $back = try { $othertable->related_source($otherrel) } or next;
 
-    my $back = $othertable->related_source($otherrel);
+    # did we get back to ourselves?
     next unless $back->source_name eq $self->source_name;
 
+    my $otherrel_info = $othertable->relationship_info($otherrel);
     my @othertestconds;
 
     if (ref $otherrel_info->{cond} eq 'HASH') {
@@ -1490,7 +1493,7 @@ sub _resolve_join {
                -alias => $as,
                -relation_chain_depth => $seen->{-relation_chain_depth} || 0,
              },
-             $self->_resolve_condition($rel_info->{cond}, $as, $alias) ];
+             $self->_resolve_condition($rel_info->{cond}, $as, $alias, $join) ];
   }
 }
 
@@ -1548,8 +1551,32 @@ sub resolve_condition {
 our $UNRESOLVABLE_CONDITION = \'1 = 0';
 
 sub _resolve_condition {
-  my ($self, $cond, $as, $for) = @_;
-  if (ref $cond eq 'HASH') {
+  my ($self, $cond, $as, $for, $rel) = @_;
+  if (ref $cond eq 'CODE') {
+
+    # heuristic for the actual relname
+    if (! defined $rel) {
+      if (!ref $as) {
+        $rel = $as;
+      }
+      elsif (!ref $for) {
+        $rel = $for;
+      }
+    }
+
+    if (! defined $rel) {
+      $self->throw_exception ('Unable to determine relationship name for condition resolution');
+    }
+
+    return $cond->({
+      self_alias => ref $for ? $as : $for,
+      foreign_alias => ref $for ? $self->related_source($rel)->resultset->current_source_alias : $as,
+      self_resultsource => $self,
+      foreign_relname => $rel,
+      self_rowobj => ref $for ? $for : undef
+    });
+
+  } elsif (ref $cond eq 'HASH') {
     my %ret;
     foreach my $k (keys %{$cond}) {
       my $v = $cond->{$k};
@@ -1593,7 +1620,7 @@ sub _resolve_condition {
   } elsif (ref $cond eq 'ARRAY') {
     return [ map { $self->_resolve_condition($_, $as, $for) } @$cond ];
   } else {
-   die("Can't handle condition $cond yet :(");
+    $self->throw_exception ("Can't handle condition $cond yet :(");
   }
 }
 
@@ -1650,6 +1677,7 @@ sub _resolve_prefetch {
         "Can't prefetch has_many ${pre} (join cond too complex)")
         unless ref($rel_info->{cond}) eq 'HASH';
       my $dots = @{[$as_prefix =~ m/\./g]} + 1; # +1 to match the ".${as_prefix}"
+
       if (my ($fail) = grep { @{[$_ =~ m/\./g]} == $dots }
                          keys %{$collapse}) {
         my ($last) = ($fail =~ /([^\.]+)$/);
@@ -1663,6 +1691,7 @@ sub _resolve_prefetch {
           . 'Use at your own risk.'
         );
       }
+
       #my @col = map { (/^self\.(.+)$/ ? ("${as_prefix}.$1") : ()); }
       #              values %{$rel_info->{cond}};
       $collapse->{".${as_prefix}${pre}"} = [ $rel_source->_pri_cols ];