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, $db_class, $attrs) = @_;
37 #use Data::Dumper; warn Dumper(@_);
38 $class = ref $class if ref $class;
39 $attrs = { %{ $attrs || {} } };
41 $attrs->{cols} ||= [ map { "me.$_" } $db_class->_select_columns ];
42 $attrs->{from} ||= [ { 'me' => $db_class->_table_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}}, $db_class->_resolve_join($attrs->{join}, 'me'));
54 foreach my $pre (@{$attrs->{prefetch} || []}) {
55 push(@{$attrs->{from}}, $db_class->_resolve_join($pre, 'me'))
57 push(@{$attrs->{cols}},
59 $db_class->_relationships->{$pre}->{class}->_select_columns);
63 cols => $attrs->{cols},
64 cond => $attrs->{where},
65 from => $attrs->{from},
70 $new->pager if ($attrs->{page});
76 my @obj = $rs->search({ foo => 3 }); # "... WHERE foo = 3"
77 my $new_rs = $rs->search({ foo => 3 });
79 If you need to pass in additional attributes but no additional condition,
80 call it as ->search(undef, \%attrs);
82 my @all = $class->search({}, { cols => [qw/foo bar/] }); # "SELECT foo, bar FROM $class_table"
89 #use Data::Dumper;warn Dumper(@_);
91 my $attrs = { %{$self->{attrs}} };
92 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
93 $attrs = { %{ pop(@_) } };
96 my $where = ((@_ == 1 || ref $_[0] eq "HASH") ? shift : {@_});
98 $where = (defined $attrs->{where}
99 ? { '-and' => [ $where, $attrs->{where} ] }
101 $attrs->{where} = $where;
104 my $rs = $self->new($self->{source}, $attrs);
106 return (wantarray ? $rs->all : $rs);
109 =head2 search_literal
110 my @obj = $rs->search_literal($literal_where_cond, @bind);
111 my $new_rs = $rs->search_literal($literal_where_cond, @bind);
113 Pass a literal chunk of SQL to be added to the conditional part of the
119 my ($self, $cond, @vals) = @_;
120 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
121 $attrs->{bind} = [ @{$self->{attrs}{bind}||[]}, @vals ];
122 return $self->search(\$cond, $attrs);
127 Returns a storage-driven cursor to the given resultset.
133 my ($source, $attrs) = @{$self}{qw/source attrs/};
134 if ($attrs->{page}) {
135 $attrs->{rows} = $self->pager->entries_per_page;
136 $attrs->{offset} = $self->pager->skipped;
138 return $self->{cursor}
139 ||= $source->storage->select($self->{from}, $self->{cols},
140 $attrs->{where},$attrs);
145 Identical to search except defaults to 'LIKE' instead of '=' in condition
152 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
155 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
156 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
157 return $class->search($query, { %$attrs });
160 =head2 slice($first, $last)
162 Returns a subset of elements from the resultset.
167 my ($self, $min, $max) = @_;
168 my $attrs = { %{ $self->{attrs} || {} } };
169 $self->{source}->throw("Can't slice without where") unless $attrs->{where};
170 $attrs->{offset} = $min;
171 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
172 my $slice = $self->new($self->{source}, $attrs);
173 return (wantarray ? $slice->all : $slice);
178 Returns the next element in the resultset (undef is there is none).
184 my @row = $self->cursor->next;
185 return unless (@row);
186 return $self->_construct_object(@row);
189 sub _construct_object {
190 my ($self, @row) = @_;
191 my @cols = @{ $self->{attrs}{cols} };
193 @cols = grep { /\(/ or ! /\./ } @cols;
195 unless ($self->{attrs}{prefetch}) {
196 $new = $self->{source}->_row_to_object(\@cols, \@row);
198 my @main = splice(@row, 0, scalar @cols);
199 $new = $self->{source}->_row_to_object(\@cols, \@main);
200 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
201 my $rel_obj = $self->{source}->_relationships->{$pre};
202 my $pre_class = $self->{source}->resolve_class($rel_obj->{class});
203 my @pre_cols = $pre_class->_select_columns;
204 my @vals = splice(@row, 0, scalar @pre_cols);
205 my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
206 $self->{source}->throw("No accessor for prefetched $pre")
207 unless defined $rel_obj->{attrs}{accessor};
208 if ($rel_obj->{attrs}{accessor} eq 'single') {
209 foreach my $pri ($rel_obj->{class}->primary_columns) {
210 unless (defined $fetched->get_column($pri)) {
215 $new->{_relationship_data}{$pre} = $fetched;
216 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
217 $new->{_inflated_column}{$pre} = $fetched;
219 $self->{source}->throw("Don't know how to store prefetched $pre");
223 $new = $self->{attrs}{record_filter}->($new)
224 if exists $self->{attrs}{record_filter};
230 Performs an SQL C<COUNT> with the same query as the resultset was built
231 with to find the number of elements. If passed arguments, does a search
232 on the resultset and counts the results of that.
238 return $self->search(@_)->count if @_ && defined $_[0];
239 my $attrs = { %{ $self->{attrs} } };
240 unless ($self->{count}) {
241 # offset and order by are not needed to count
242 delete $attrs->{$_} for qw/offset order_by/;
244 my @cols = 'COUNT(*)';
245 $self->{count} = $self->{source}->storage->select_single(
246 $self->{from}, \@cols, $self->{cond}, $attrs);
248 return 0 unless $self->{count};
249 return $self->{pager}->entries_on_this_page if ($self->{pager});
250 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
257 Calls search_literal with the passed arguments, then count.
261 sub count_literal { shift->search_literal(@_)->count; }
265 Returns all elements in the resultset. Called implictly if the resultset
266 is returned in list context.
272 return map { $self->_construct_object(@$_); }
278 Resets the resultset's cursor, so you can iterate through the elements again.
284 $self->cursor->reset;
290 Resets the resultset and returns the first element.
295 return $_[0]->reset->next;
300 Deletes all elements in the resultset.
306 $_->delete for $self->all;
310 *delete_all = \&delete; # Yeah, yeah, yeah ...
314 Returns a L<Data::Page> object for the current resultset. Only makes
315 sense for queries with page turned on.
321 my $attrs = $self->{attrs};
322 delete $attrs->{offset};
323 my $rows_per_page = delete $attrs->{rows} || 10;
324 $self->{pager} ||= Data::Page->new(
325 $self->count, $rows_per_page, $attrs->{page} || 1);
326 $attrs->{rows} = $rows_per_page;
327 return $self->{pager};
330 =head2 page($page_num)
332 Returns a new resultset for the specified page.
337 my ($self, $page) = @_;
338 my $attrs = $self->{attrs};
339 $attrs->{page} = $page;
340 return $self->new($self->{source}, $attrs);
345 The resultset takes various attributes that modify its behavior.
346 Here's an overview of them:
350 Which column(s) to order the results by. This is currently passed
351 through directly to SQL, so you can give e.g. C<foo DESC> for a
356 Which columns should be retrieved.
360 Contains a list of relationships that should be joined for this query. Can also
361 contain a hash reference to refer to that relation's relations. So, if one column
362 in your class C<belongs_to> foo and another C<belongs_to> bar, you can do
363 C<< join => [qw/ foo bar /] >> to join both (and e.g. use them for C<order_by>).
364 If a foo contains many margles and you want to join those too, you can do
365 C<< join => { foo => 'margle' } >>. If you want to fetch the columns from the
366 related table as well, see C<prefetch> below.
370 Contains a list of relationships that should be fetched along with the main
371 query (when they are accessed afterwards they will have already been
372 "prefetched"). This is useful for when you know you will need the related
373 object(s), because it saves a query. Currently limited to prefetching
374 one relationship deep, so unlike C<join>, prefetch must be an arrayref.
378 This attribute can contain a arrayref of elements. Each element can be another
379 arrayref, to nest joins, or it can be a hash which represents the two sides
382 NOTE: Use this on your own risk. This allows you to shoot your foot off!
386 For a paged resultset, specifies which page to retrieve. Leave unset
387 for an unpaged resultset.
391 For a paged resultset, how many rows per page