result_source is now AN ACCESSOR. w00000
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index 824c51e..ae6fb3e 100644 (file)
@@ -6,6 +6,7 @@ use overload
         '0+'     => 'count',
         fallback => 1;
 use Data::Page;
+use Storable;
 
 =head1 NAME
 
@@ -34,10 +35,10 @@ not perform any queries -- these are executed as needed by the other methods.
 
 sub new {
   my $class = shift;
-  $class->new_result(@_) if ref $class;
+  return $class->new_result(@_) if ref $class;
   my ($source, $attrs) = @_;
-  #use Data::Dumper; warn Dumper(@_);
-  $attrs = { %{ $attrs || {} } };
+  #use Data::Dumper; warn Dumper($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->related_source($pre)->columns;
     push(@{$attrs->{select}}, @pre);
     push(@{$attrs->{as}}, @pre);
   }
@@ -112,7 +113,9 @@ sub search {
   my $where = (@_ ? ((@_ == 1 || ref $_[0] eq "HASH") ? shift : {@_}) : undef());
   if (defined $where) {
     $where = (defined $attrs->{where}
-                ? { '-and' => [ $where, $attrs->{where} ] }
+                ? { '-and' =>
+                    [ map { ref $_ eq 'ARRAY' ? [ -or => $_ ] : $_ }
+                        $where, $attrs->{where} ] }
                 : $where);
     $attrs->{where} = $where;
   }
@@ -176,22 +179,17 @@ sub find {
 
 sub search_related {
   my ($self, $rel, @rest) = @_;
-  my $rel_obj = $self->{source}->result_class->_relationships->{$rel};
+  my $rel_obj = $self->{source}->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);
 }
 
@@ -268,7 +266,8 @@ sub _construct_object {
       $me{$col} = shift @row;
     }
   }
-  my $new = $self->{source}->result_class->inflate_result(\%me, \%pre);
+  my $new = $self->{source}->result_class->inflate_result(
+              $self->{source}, \%me, \%pre);
   $new = $self->{attrs}{record_filter}->($new)
     if exists $self->{attrs}{record_filter};
   return $new;
@@ -290,8 +289,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;
   }
@@ -346,19 +345,59 @@ sub first {
   return $_[0]->reset->next;
 }
 
+=head2 update(\%values)
+
+Sets the specified columns in the resultset to the supplied values
+
+=cut
+
+sub update {
+  my ($self, $values) = @_;
+  die "Values for update must be a hash" unless ref $values eq 'HASH';
+  return $self->{source}->storage->update(
+           $self->{source}->from, $values, $self->{cond});
+}
+
+=head2 update_all(\%values)
+
+Fetches all objects and updates them one at a time. ->update_all will run
+cascade triggers, ->update will not.
+
+=cut
+
+sub update_all {
+  my ($self, $values) = @_;
+  die "Values for update must be a hash" unless ref $values eq 'HASH';
+  foreach my $obj ($self->all) {
+    $obj->set_columns($values)->update;
+  }
+  return 1;
+}
+
 =head2 delete
 
-Deletes all elements in the resultset.
+Deletes the contents of the resultset from its result source.
 
 =cut
 
 sub delete {
   my ($self) = @_;
-  $_->delete for $self->all;
+  $self->{source}->storage->delete($self->{source}->from, $self->{cond});
   return 1;
 }
 
-*delete_all = \&delete; # Yeah, yeah, yeah ...
+=head2 delete_all
+
+Fetches all objects and deletes them one at a time. ->delete_all will run
+cascade triggers, ->delete will not.
+
+=cut
+
+sub delete_all {
+  my ($self) = @_;
+  $_->delete for $self->all;
+  return 1;
+}
 
 =head2 pager
 
@@ -407,7 +446,9 @@ sub new_result {
   foreach my $key (keys %{$self->{cond}||{}}) {
     $new{$1} = $self->{cond}{$key} if ($key =~ m/^(?:$alias\.)?([^\.]+)$/);
   }
-  return $self->{source}->result_class->new(\%new);
+  my $obj = $self->{source}->result_class->new(\%new);
+  $obj->result_source($self->{source}) if $obj->can('result_source');
+  $obj;
 }
 
 =head2 create(\%vals)