1 package DBIx::Class::ResultSet;
12 DBIx::Class::ResultSet - Responsible for fetching and creating resultset.
16 my $rs = MyApp::DB::Class->search(registered => 1);
17 my @rows = MyApp::DB::Class->search(foo => 'bar');
21 The resultset is also known as an iterator. It is responsible for handling
22 queries that may return an arbitrary number of rows, e.g. via C<search>
23 or a C<has_many> relationship.
27 =head2 new($db_class, \%$attrs)
29 The resultset constructor. Takes a table class and an attribute hash
30 (see below for more information on attributes). Does not perform
31 any queries -- these are executed as needed by the other methods.
36 my ($class, $source, $attrs) = @_;
37 #use Data::Dumper; warn Dumper(@_);
38 $class = ref $class if ref $class;
39 $attrs = { %{ $attrs || {} } };
41 $attrs->{cols} ||= [ map { "me.$_" } $source->result_class->_select_columns ];
42 $attrs->{from} ||= [ { 'me' => $source->name } ];
44 foreach my $j (ref $attrs->{join} eq 'ARRAY'
45 ? (@{$attrs->{join}}) : ($attrs->{join})) {
46 if (ref $j eq 'HASH') {
47 $seen{$_} = 1 foreach keys %$j;
52 push(@{$attrs->{from}}, $source->result_class->_resolve_join($attrs->{join}, 'me'));
54 foreach my $pre (@{$attrs->{prefetch} || []}) {
55 push(@{$attrs->{from}}, $source->result_class->_resolve_join($pre, 'me'))
57 push(@{$attrs->{cols}},
59 $source->result_class->_relationships->{$pre}->{class}->columns);
63 result_class => $source->result_class,
64 cols => $attrs->{cols},
65 cond => $attrs->{where},
66 from => $attrs->{from},
71 $new->pager if ($attrs->{page});
77 my @obj = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
78 my $new_rs = $rs->search({ foo => 3 });
80 If you need to pass in additional attributes but no additional condition,
81 call it as ->search(undef, \%attrs);
83 my @all = $class->search({}, { cols => [qw/foo bar/] }); # "SELECT foo, bar FROM $class_table"
90 #use Data::Dumper;warn Dumper(@_);
92 my $attrs = { %{$self->{attrs}} };
93 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
94 $attrs = { %{ pop(@_) } };
97 my $where = ((@_ == 1 || ref $_[0] eq "HASH") ? shift : {@_});
99 $where = (defined $attrs->{where}
100 ? { '-and' => [ $where, $attrs->{where} ] }
102 $attrs->{where} = $where;
105 my $rs = $self->new($self->{source}, $attrs);
107 return (wantarray ? $rs->all : $rs);
110 =head2 search_literal
111 my @obj = $rs->search_literal($literal_where_cond, @bind);
112 my $new_rs = $rs->search_literal($literal_where_cond, @bind);
114 Pass a literal chunk of SQL to be added to the conditional part of the
120 my ($self, $cond, @vals) = @_;
121 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
122 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
123 return $self->search(\$cond, $attrs);
128 Returns a storage-driven cursor to the given resultset.
134 my ($source, $attrs) = @{$self}{qw/source attrs/};
135 if ($attrs->{page}) {
136 $attrs->{rows} = $self->pager->entries_per_page;
137 $attrs->{offset} = $self->pager->skipped;
139 return $self->{cursor}
140 ||= $source->storage->select($self->{from}, $self->{cols},
141 $attrs->{where},$attrs);
146 Identical to search except defaults to 'LIKE' instead of '=' in condition
153 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
156 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
157 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
158 return $class->search($query, { %$attrs });
161 =head2 slice($first, $last)
163 Returns a subset of elements from the resultset.
168 my ($self, $min, $max) = @_;
169 my $attrs = { %{ $self->{attrs} || {} } };
170 $self->{source}->result_class->throw("Can't slice without where") unless $attrs->{where};
171 $attrs->{offset} = $min;
172 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
173 my $slice = $self->new($self->{source}, $attrs);
174 return (wantarray ? $slice->all : $slice);
179 Returns the next element in the resultset (undef is there is none).
185 my @row = $self->cursor->next;
186 return unless (@row);
187 return $self->_construct_object(@row);
190 sub _construct_object {
191 my ($self, @row) = @_;
192 my @cols = @{ $self->{attrs}{cols} };
194 @cols = grep { /\(/ or ! /\./ } @cols;
196 unless ($self->{attrs}{prefetch}) {
197 $new = $self->{source}->result_class->_row_to_object(\@cols, \@row);
199 my @main = splice(@row, 0, scalar @cols);
200 $new = $self->{source}->result_class->_row_to_object(\@cols, \@main);
201 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
202 my $rel_obj = $self->{source}->result_class->_relationships->{$pre};
203 my $pre_class = $self->{source}->result_class->resolve_class($rel_obj->{class});
204 my @pre_cols = $pre_class->_select_columns;
205 my @vals = splice(@row, 0, scalar @pre_cols);
206 my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
207 $self->{source}->result_class->throw("No accessor for prefetched $pre")
208 unless defined $rel_obj->{attrs}{accessor};
209 if ($rel_obj->{attrs}{accessor} eq 'single') {
210 foreach my $pri ($rel_obj->{class}->primary_columns) {
211 unless (defined $fetched->get_column($pri)) {
216 $new->{_relationship_data}{$pre} = $fetched;
217 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
218 $new->{_inflated_column}{$pre} = $fetched;
220 $self->{source}->result_class->throw("Don't know how to store prefetched $pre");
224 $new = $self->{attrs}{record_filter}->($new)
225 if exists $self->{attrs}{record_filter};
231 Performs an SQL C<COUNT> with the same query as the resultset was built
232 with to find the number of elements. If passed arguments, does a search
233 on the resultset and counts the results of that.
239 return $self->search(@_)->count if @_ && defined $_[0];
240 my $attrs = { %{ $self->{attrs} } };
241 unless ($self->{count}) {
242 # offset and order by are not needed to count
243 delete $attrs->{$_} for qw/offset order_by/;
245 my @cols = 'COUNT(*)';
246 $self->{count} = $self->{source}->storage->select_single(
247 $self->{from}, \@cols, $self->{cond}, $attrs);
249 return 0 unless $self->{count};
250 return $self->{pager}->entries_on_this_page if ($self->{pager});
251 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
258 Calls search_literal with the passed arguments, then count.
262 sub count_literal { shift->search_literal(@_)->count; }
266 Returns all elements in the resultset. Called implictly if the resultset
267 is returned in list context.
273 return map { $self->_construct_object(@$_); }
279 Resets the resultset's cursor, so you can iterate through the elements again.
285 $self->cursor->reset;
291 Resets the resultset and returns the first element.
296 return $_[0]->reset->next;
301 Deletes all elements in the resultset.
307 $_->delete for $self->all;
311 *delete_all = \&delete; # Yeah, yeah, yeah ...
315 Returns a L<Data::Page> object for the current resultset. Only makes
316 sense for queries with page turned on.
322 my $attrs = $self->{attrs};
323 delete $attrs->{offset};
324 my $rows_per_page = delete $attrs->{rows} || 10;
325 $self->{pager} ||= Data::Page->new(
326 $self->count, $rows_per_page, $attrs->{page} || 1);
327 $attrs->{rows} = $rows_per_page;
328 return $self->{pager};
331 =head2 page($page_num)
333 Returns a new resultset for the specified page.
338 my ($self, $page) = @_;
339 my $attrs = $self->{attrs};
340 $attrs->{page} = $page;
341 return $self->new($self->{source}, $attrs);
346 The resultset takes various attributes that modify its behavior.
347 Here's an overview of them:
351 Which column(s) to order the results by. This is currently passed
352 through directly to SQL, so you can give e.g. C<foo DESC> for a
357 Which columns should be retrieved.
361 Contains a list of relationships that should be joined for this query. Can also
362 contain a hash reference to refer to that relation's relations. So, if one column
363 in your class C<belongs_to> foo and another C<belongs_to> bar, you can do
364 C<< join => [qw/ foo bar /] >> to join both (and e.g. use them for C<order_by>).
365 If a foo contains many margles and you want to join those too, you can do
366 C<< join => { foo => 'margle' } >>. If you want to fetch the columns from the
367 related table as well, see C<prefetch> below.
371 Contains a list of relationships that should be fetched along with the main
372 query (when they are accessed afterwards they will have already been
373 "prefetched"). This is useful for when you know you will need the related
374 object(s), because it saves a query. Currently limited to prefetching
375 one relationship deep, so unlike C<join>, prefetch must be an arrayref.
379 This attribute can contain a arrayref of elements. Each element can be another
380 arrayref, to nest joins, or it can be a hash which represents the two sides
383 NOTE: Use this on your own risk. This allows you to shoot your foot off!
387 For a paged resultset, specifies which page to retrieve. Leave unset
388 for an unpaged resultset.
392 For a paged resultset, how many rows per page