resolve_condition moved to ResultSource
Matt S Trout [Sat, 14 Jan 2006 06:17:04 +0000 (06:17 +0000)]
lib/DBIx/Class/CDBICompat/ImaDBI.pm
lib/DBIx/Class/Relationship/Base.pm
lib/DBIx/Class/ResultSource.pm

index 2226ea7..4651263 100644 (file)
@@ -43,13 +43,9 @@ __PACKAGE__->mk_classdata('_transform_sql_handlers' =>
         }
         $self->throw( "No relationship to JOIN from ${from_class} to ${to_class}" )
           unless $rel_obj;
-        my $attrs = {
-          %$self,
-          _aliases => { self => $from, foreign => $to },
-          _action => 'join',
-        };
         my $join = $from_class->storage->sql_maker->_join_condition(
-          $from_class->resolve_condition($rel_obj->{cond}, $attrs) );
+          $from_class->result_source->resolve_condition(
+            $rel_obj->{cond}, $to, $from) );
         return $join;
       }
         
index 35f9067..24c766d 100644 (file)
@@ -83,81 +83,6 @@ sub relationship_info {
   shift->result_source->relationship_info(@_);
 }
 
-sub resolve_condition {
-  my ($self, $cond, $attrs) = @_;
-  if (ref $cond eq 'HASH') {
-    my %ret;
-    foreach my $key (keys %$cond) {
-      my $val = $cond->{$key};
-      if (ref $val) {
-        $self->throw("Can't handle this yet :(");
-      } else {
-        $ret{$self->_cond_key($attrs => $key)}
-          = $self->_cond_value($attrs => $key => $val);
-      }
-    }
-    return \%ret;
-  } else {
-   $self->throw("Can't handle this yet :(");
-  }
-}
-
-sub _cond_key {
-  my ($self, $attrs, $key, $alias) = @_;
-  my $action = $attrs->{_action} || '';
-  if ($action eq 'convert') {
-    unless ($key =~ s/^foreign\.//) {
-      $self->throw("Unable to convert relationship to WHERE clause: invalid key ${key}");
-    }
-    if (defined (my $alias = $attrs->{_aliases}{foreign})) {
-      return "${alias}.${key}";
-    } else {
-      return $key;
-    }
-  } elsif ($action eq 'join') {
-    return $key unless $key =~ /\./;
-    my ($type, $field) = split(/\./, $key);
-    if (my $alias = $attrs->{_aliases}{$type}) {
-      my $class = $attrs->{_classes}{$alias};
-      $self->throw("Unknown column $field on $class as $alias")
-        unless $class->has_column($field);
-      return join('.', $alias, $field);
-    } else {
-      $self->throw( "Unable to resolve type ${type}: only have aliases for ".
-            join(', ', keys %{$attrs->{_aliases} || {}}) );
-    }
-  }
-  return $self->next::method($attrs, $key);
-}
-
-sub _cond_value {
-  my ($self, $attrs, $key, $value) = @_;
-  my $action = $attrs->{_action} || '';
-  if ($action eq 'convert') {
-    unless ($value =~ s/^self\.//) {
-      $self->throw( "Unable to convert relationship to WHERE clause: invalid value ${value}" );
-    }
-    unless ($self->has_column($value)) {
-      $self->throw( "Unable to convert relationship to WHERE clause: no such accessor ${value}" );
-    }
-    return $self->get_column($value);
-  } elsif ($action eq 'join') {
-    return $key unless $key =~ /\./;
-    my ($type, $field) = split(/\./, $value);
-    if (my $alias = $attrs->{_aliases}{$type}) {
-      my $class = $attrs->{_classes}{$alias};
-      $self->throw("Unknown column $field on $class as $alias")
-        unless $class->has_column($field);
-      return join('.', $alias, $field);
-    } else {
-      $self->throw( "Unable to resolve type ${type}: only have aliases for ".
-            join(', ', keys %{$attrs->{_aliases} || {}}) );
-    }
-  }
-      
-  return $self->next::method($attrs, $key, $value)
-}
-
 =head2 search_related
 
   My::Table->search_related('relname', $cond, $attrs);
@@ -166,6 +91,7 @@ sub _cond_value {
 
 sub search_related {
   my $self = shift;
+  die "Can't call *_related as class methods" unless ref $self;
   my $rel = shift;
   my $attrs = { };
   if (@_ > 1 && ref $_[$#_] eq 'HASH') {
@@ -178,15 +104,12 @@ sub search_related {
   $self->throw( "Invalid query: @_" ) if (@_ > 1 && (@_ % 2 == 1));
   my $query = ((@_ > 1) ? {@_} : shift);
 
-  $attrs->{_action} = 'convert'; # shouldn't we resolve the cond to something
-                                 # to merge into the AST really?
-  my ($cond) = $self->resolve_condition($rel_obj->{cond}, $attrs);
+  my ($cond) = $self->result_source->resolve_condition($rel_obj->{cond}, $rel, $self);
   $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
-  #use Data::Dumper; warn Dumper($query);
+  #use Data::Dumper; warn Dumper($cond);
   #warn $rel_obj->{class}." $meth $cond ".join(', ', @{$attrs->{bind}||[]});
-  delete $attrs->{_action};
-  return $self->result_source->schema->resultset($rel_obj->{class}
-           )->search($query, $attrs);
+  return $self->result_source->related_source($rel
+           )->resultset->search($query, $attrs);
 }
 
 =head2 count_related
@@ -207,9 +130,9 @@ sub count_related {
 =cut
 
 sub create_related {
-  my $class = shift;
+  my $self = shift;
   my $rel = shift;
-  return $class->search_related($rel)->create(@_);
+  return $self->search_related($rel)->create(@_);
 }
 
 =head2 new_related
index ec54d97..384e269 100644 (file)
@@ -79,8 +79,8 @@ sub resultset {
   return $self->resultset_class->new($self);
 }
 
-=head2 has_column                                                                
-                                                                                
+=head2 has_column
+
   if ($obj->has_column($col)) { ... }                                           
                                                                                 
 Returns 1 if the source has a column of this name, 0 otherwise.
@@ -317,38 +317,39 @@ sub resolve_join {
   } elsif (ref $join) {
     die("No idea how to resolve join reftype ".ref $join);
   } else {
-    die("No such relationship ${join}") unless $self->has_relationship($join);
-    my $type = $self->relationship_info($join)->{attrs}{join_type} || '';
+    my $rel_info = $self->relationship_info($join);
+    die("No such relationship ${join}") unless $rel_info;
+    my $type = $rel_info->{attrs}{join_type} || '';
     return [ { $join => $self->related_source($join)->from,
                -join_type => $type },
-             $self->resolve_condition($join, $alias) ];
+             $self->resolve_condition($rel_info->{cond}, $join, $alias) ];
   }
 }
 
-=head2 resolve_condition($rel, $alias|$object)
+=head2 resolve_condition($cond, $rel, $alias|$object)
 
-Returns the conditional for the specified relationship. If given an alias,
+Resolves the passed condition to a concrete query fragment. If given an alias,
 returns a join condition; if given an object, inverts that object to produce
 a related conditional from that object.
 
 =cut
 
 sub resolve_condition {
-  my ($self, $rel, $for) = @_;
-  my $cond = $self->relationship_info($rel)->{cond};
+  my ($self, $cond, $rel, $for) = @_;
   #warn %$cond;
   if (ref $cond eq 'HASH') {
     my %ret;
     while (my ($k, $v) = each %{$cond}) {
       # XXX should probably check these are valid columns
-      $k =~ s/^foreign\./${rel}./ || die "Invalid rel cond key ${k}";
+      $k =~ s/^foreign\.// || die "Invalid rel cond key ${k}";
+      $v =~ s/^self\.// || die "Invalid rel cond val ${v}";
       if (ref $for) { # Object
-        die "Invalid ref cond val ${v}" unless $v =~ m/^self\.(.*)$/;
-        $ret{$k} = $for->$1;
+        #warn "$self $k $for $v";
+        $ret{$k} = $for->get_column($v);
+        #warn %ret;
       } else {
-        $v =~ s/^self\./${for}./ || die "Invalid rel cond val ${v}";
+        $ret{"${rel}.${k}"} = "${for}.${v}";
       }
-      $ret{$k} = $v;
     }
     return \%ret;
   } else {