Nuked _select_columns, the last vestige of class-based evil
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
index a33e22f..cfe45ce 100644 (file)
@@ -2,8 +2,10 @@ package DBIx::Class::ResultSet;
 
 use strict;
 use warnings;
+use Carp qw/croak/;
 use overload
         '0+'     => 'count',
+        'bool'   => sub { 1; },
         fallback => 1;
 use Data::Page;
 use Storable;
@@ -35,16 +37,17 @@ 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(@_);
+  #use Data::Dumper; warn Dumper($attrs);
   $attrs = Storable::dclone($attrs || {}); # { %{ $attrs || {} } };
   my %seen;
   my $alias = ($attrs->{alias} ||= 'me');
-  if (!$attrs->{select}) {
+  if ($attrs->{cols} || !$attrs->{select}) {
+    delete $attrs->{as} if $attrs->{cols};
     my @cols = ($attrs->{cols}
                  ? @{delete $attrs->{cols}}
-                 : $source->result_class->_select_columns);
+                 : $source->columns);
     $attrs->{select} = [ map { m/\./ ? $_ : "${alias}.$_" } @cols ];
   }
   $attrs->{as} ||= [ map { m/^$alias\.(.*)$/ ? $1 : $_ } @{$attrs->{select}} ];
@@ -67,7 +70,7 @@ sub new {
       unless $seen{$pre};
     my @pre = 
       map { "$pre.$_" }
-      $source->result_class->relationship_info($pre)->{class}->columns;
+      $source->related_source($pre)->columns;
     push(@{$attrs->{select}}, @pre);
     push(@{$attrs->{as}}, @pre);
   }
@@ -113,7 +116,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;
   }
@@ -177,7 +182,7 @@ sub find {
 
 sub search_related {
   my ($self, $rel, @rest) = @_;
-  my $rel_obj = $self->{source}->result_class->relationship_info($rel);
+  my $rel_obj = $self->{source}->relationship_info($rel);
   $self->{source}->result_class->throw(
     "No such relationship ${rel} in search_related")
       unless $rel_obj;
@@ -264,7 +269,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;
@@ -281,7 +287,7 @@ on the resultset and counts the results of that.
 sub count {
   my $self = shift;
   return $self->search(@_)->count if @_ && defined $_[0];
-  die "Unable to ->count with a GROUP BY" if defined $self->{attrs}{group_by};
+  croak "Unable to ->count with a GROUP BY" if defined $self->{attrs}{group_by};
   unless (defined $self->{count}) {
     my $attrs = { %{ $self->{attrs} },
                   select => { 'count' => '*' },
@@ -342,19 +348,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) = @_;
+  croak "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) = @_;
+  croak "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
 
@@ -366,7 +412,7 @@ sense for queries with page turned on.
 sub pager {
   my ($self) = @_;
   my $attrs = $self->{attrs};
-  die "Can't create pager for non-paged rs" unless $self->{page};
+  croak "Can't create pager for non-paged rs" unless $self->{page};
   $attrs->{rows} ||= 10;
   $self->count;
   return $self->{pager} ||= Data::Page->new(
@@ -403,7 +449,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)
@@ -496,11 +544,13 @@ for an unpaged resultset.
 
 For a paged resultset, how many rows per page
 
-=head2 group_by
+=head2 group_by (listref)
 
-A list of columns to group by (note that 'count' doesn't work on grouped
+A listref of columns to group by (note that 'count' doesn't work on grouped
 resultsets)
 
+  group_by => [qw/ column1 column2 ... /]
+
 =head2 distinct
 
 Set to 1 to group by all columns