1 package DBIx::Class::ResultSet;
12 DBIX::Class::ResultSet - Responsible for fetching and creating resultset.
16 $rs=MyApp::DB::Class->search(registered=>1);
20 The resultset is also known as an iterator.
26 =item new <db_class> <attrs>
28 The resultset constructor. Takes a db class and an
29 attribute hash (see below for more info on attributes)
34 my ($class, $db_class, $attrs) = @_;
35 #use Data::Dumper; warn Dumper(@_);
36 $class = ref $class if ref $class;
37 $attrs = { %{ $attrs || {} } };
39 $attrs->{cols} ||= [ map { "me.$_" } $db_class->_select_columns ];
40 $attrs->{from} ||= [ { 'me' => $db_class->_table_name } ];
42 foreach my $j (ref $attrs->{join} eq 'ARRAY'
43 ? (@{$attrs->{join}}) : ($attrs->{join})) {
44 if (ref $j eq 'HASH') {
45 $seen{$_} = 1 foreach keys %$j;
50 push(@{$attrs->{from}}, $db_class->_resolve_join($attrs->{join}, 'me'));
52 foreach my $pre (@{$attrs->{prefetch} || []}) {
53 push(@{$attrs->{from}}, $db_class->_resolve_join($pre, 'me'))
55 push(@{$attrs->{cols}},
57 $db_class->_relationships->{$pre}->{class}->_select_columns);
61 cols => $attrs->{cols} || [ $db_class->_select_columns ],
62 cond => $attrs->{where},
63 from => $attrs->{from} || $db_class->_table_name,
68 $new->pager if ($attrs->{page});
74 Return a storage driven cursor to the given resultset.
80 my ($source, $attrs) = @{$self}{qw/source attrs/};
82 $attrs->{rows} = $self->pager->entries_per_page;
83 $attrs->{offset} = $self->pager->skipped;
85 return $self->{cursor}
86 ||= $source->storage->select($self->{from}, $self->{cols},
87 $attrs->{where},$attrs);
90 =item slice <first> <last>
92 return a number of elements from the given resultset.
97 my ($self, $min, $max) = @_;
98 my $attrs = { %{ $self->{attrs} || {} } };
99 $self->{source}->throw("Can't slice without where") unless $attrs->{where};
100 $attrs->{offset} = $min;
101 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
102 my $slice = $self->new($self->{source}, $attrs);
103 return (wantarray ? $slice->all : $slice);
108 Returns the next element in this resultset.
114 my @row = $self->cursor->next;
115 return unless (@row);
116 return $self->_construct_object(@row);
119 sub _construct_object {
120 my ($self, @row) = @_;
121 my @cols = @{ $self->{attrs}{cols} };
123 @cols = grep { /\(/ or ! /\./ } @cols;
125 unless ($self->{attrs}{prefetch}) {
126 $new = $self->{source}->_row_to_object(\@cols, \@row);
128 my @main = splice(@row, 0, scalar @cols);
129 $new = $self->{source}->_row_to_object(\@cols, \@main);
130 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
131 my $rel_obj = $self->{source}->_relationships->{$pre};
132 my $pre_class = $self->{source}->resolve_class($rel_obj->{class});
133 my @pre_cols = $pre_class->_select_columns;
134 my @vals = splice(@row, 0, scalar @pre_cols);
135 my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
136 $self->{source}->throw("No accessor for prefetched $pre")
137 unless defined $rel_obj->{attrs}{accessor};
138 if ($rel_obj->{attrs}{accessor} eq 'single') {
139 foreach my $pri ($rel_obj->{class}->primary_columns) {
140 unless (defined $fetched->get_column($pri)) {
145 $new->{_relationship_data}{$pre} = $fetched;
146 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
147 $new->{_inflated_column}{$pre} = $fetched;
149 $self->{source}->throw("Don't know how to store prefetched $pre");
153 $new = $self->{attrs}{record_filter}->($new)
154 if exists $self->{attrs}{record_filter};
160 Performs an SQL count with the same query as the resultset was built
161 with to find the number of elements.
168 my $attrs = { %{ $self->{attrs} } };
169 unless ($self->{count}) {
170 # offset and order by are not needed to count
171 delete $attrs->{$_} for qw/offset order_by/;
173 my @cols = 'COUNT(*)';
174 $self->{count} = $self->{source}->storage->select_single(
175 $self->{from}, \@cols, $self->{cond}, $attrs);
177 return 0 unless $self->{count};
178 return $self->{pager}->entries_on_this_page if ($self->{pager});
179 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
186 Returns all elements in the resultset. Is called implictly if the search
187 method is used in list context.
193 return map { $self->_construct_object(@$_); }
199 Reset this resultset's cursor, so you can iterate through the elements again.
205 $self->cursor->reset;
211 resets the resultset and returns the first element.
216 return $_[0]->reset->next;
221 Deletes all elements in the resultset.
227 $_->delete for $self->all;
231 *delete_all = \&delete; # Yeah, yeah, yeah ...
235 Returns a L<Data::Page> object for the current resultset. Only makes
236 sense for queries with page turned on.
242 my $attrs = $self->{attrs};
243 delete $attrs->{offset};
244 my $rows_per_page = delete $attrs->{rows} || 10;
245 $self->{pager} ||= Data::Page->new(
246 $self->count, $rows_per_page, $attrs->{page} || 1);
247 $attrs->{rows} = $rows_per_page;
248 return $self->{pager};
253 Returns a new resultset representing a given page.
258 my ($self, $page) = @_;
259 my $attrs = $self->{attrs};
260 $attrs->{page} = $page;
261 return $self->new($self->{source}, $attrs);
268 The resultset is responsible for handling the various attributes that
269 can be passed in with the search functions. Here's an overview of them:
275 Which column to order the results by.
279 Which cols should be retrieved on the first search.
283 Contains a list of relations that should be joined for this query. Can also
284 contain a hash referece to refer to that relation's relations.
288 This attribute can contain a arrayref of elements. each element can be another
289 arrayref, to nest joins, or it can be a hash which represents the two sides
292 *NOTE* Use this on your own risk. This allows you to shoot your foot off!
296 Should the resultset be paged? This can also be enabled by using the
301 For paged resultsset, how many rows per page
305 For paged resultsset, which page to start on.