add_relationship, relationship_info, relationships moved to ResultSource
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index 1e5ba7f..a33e22f 100644 (file)
@@ -6,6 +6,7 @@ use overload
         '0+'     => 'count',
         fallback => 1;
 use Data::Page;
+use Storable;
 
 =head1 NAME
 
@@ -37,7 +38,7 @@ sub new {
   $class->new_result(@_) if ref $class;
   my ($source, $attrs) = @_;
   #use Data::Dumper; warn Dumper(@_);
-  $attrs = { %{ $attrs || {} } };
+  $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
   my %seen;
   my $alias = ($attrs->{alias} ||= 'me');
   if (!$attrs->{select}) {
@@ -58,15 +59,15 @@ sub new {
         $seen{$j} = 1;
       }
     }
-    push(@{$attrs->{from}}, $source->result_class->_resolve_join($join, $attrs->{alias}));
+    push(@{$attrs->{from}}, $source->resolve_join($join, $attrs->{alias}));
   }
   $attrs->{group_by} ||= $attrs->{select} if delete $attrs->{distinct};
   foreach my $pre (@{delete $attrs->{prefetch} || []}) {
-    push(@{$attrs->{from}}, $source->result_class->_resolve_join($pre, $attrs->{alias}))
+    push(@{$attrs->{from}}, $source->resolve_join($pre, $attrs->{alias}))
       unless $seen{$pre};
     my @pre = 
       map { "$pre.$_" }
-      $source->result_class->_relationships->{$pre}->{class}->columns;
+      $source->result_class->relationship_info($pre)->{class}->columns;
     push(@{$attrs->{select}}, @pre);
     push(@{$attrs->{as}}, @pre);
   }
@@ -176,22 +177,17 @@ sub find {
 
 sub search_related {
   my ($self, $rel, @rest) = @_;
-  my $rel_obj = $self->{source}->result_class->_relationships->{$rel};
+  my $rel_obj = $self->{source}->result_class->relationship_info($rel);
   $self->{source}->result_class->throw(
     "No such relationship ${rel} in search_related")
       unless $rel_obj;
-  my $r_class = $self->{source}->result_class->resolve_class($rel_obj->{class});
-  my $source = $r_class->result_source;
-  $source = bless({ %{$source} }, ref $source || $source);
-  $source->storage($self->{source}->storage);
-  $source->result_class($r_class);
   my $rs = $self->search(undef, { join => $rel });
-  #use Data::Dumper; warn Dumper($rs);
-  return $source->resultset_class->new(
-           $source, { %{$rs->{attrs}},
-                      alias => $rel,
-                      select => undef(),
-                      as => undef() }
+  return $self->{source}->schema->resultset($rel_obj->{class}
+           )->search( undef,
+             { %{$rs->{attrs}},
+               alias => $rel,
+               select => undef(),
+               as => undef() }
            )->search(@rest);
 }
 
@@ -290,8 +286,8 @@ sub count {
     my $attrs = { %{ $self->{attrs} },
                   select => { 'count' => '*' },
                   as => [ 'count' ] };
-    # offset, order by and page are not needed to count
-    delete $attrs->{$_} for qw/rows offset order_by page pager/;
+    # offset, order by and page are not needed to count. record_filter is cdbi
+    delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
         
     ($self->{count}) = (ref $self)->new($self->{source}, $attrs)->cursor->next;
   }
@@ -424,6 +420,22 @@ sub create {
   return $self->new_result($attrs)->insert;
 }
 
+=head2 find_or_create(\%vals)
+
+  $class->find_or_create({ key => $val, ... });                                 
+                                                                                
+Searches for a record matching the search condition; if it doesn't find one,    
+creates one and returns that instead.                                           
+                                                                                
+=cut
+
+sub find_or_create {
+  my $self     = shift;
+  my $hash     = ref $_[0] eq "HASH" ? shift: {@_};
+  my $exists   = $self->find($hash);
+  return defined($exists) ? $exists : $self->create($hash);
+}
+
 =head1 ATTRIBUTES
 
 The resultset takes various attributes that modify its behavior.