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 ($it_class, $db_class, $attrs) = @_;
35 #use Data::Dumper; warn Dumper(@_);
36 $it_class = ref $it_class if ref $it_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,
67 bless ($new, $it_class);
68 $new->pager if ($attrs->{page});
74 Return a storage driven cursor to the given resultset.
80 my ($db_class, $attrs) = @{$self}{qw/class attrs/};
82 $attrs->{rows} = $self->pager->entries_per_page;
83 $attrs->{offset} = $self->pager->skipped;
85 return $self->{cursor}
86 ||= $db_class->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->{class}->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->{class}, $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->{class}->_row_to_object(\@cols, \@row);
128 my @main = splice(@row, 0, scalar @cols);
129 $new = $self->{class}->_row_to_object(\@cols, \@main);
130 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
131 my $rel_obj = $self->{class}->_relationships->{$pre};
132 my $pre_class = $self->{class}->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->{class}->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->{class}->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 $db_class = $self->{class};
169 my $attrs = { %{ $self->{attrs} } };
170 unless ($self->{count}) {
171 # offset and order by are not needed to count
172 delete $attrs->{$_} for qw/offset order_by/;
174 my @cols = 'COUNT(*)';
175 $self->{count} = $db_class->storage->select_single($self->{from}, \@cols,
176 $self->{cond}, $attrs);
178 return 0 unless $self->{count};
179 return $self->{pager}->entries_on_this_page if ($self->{pager});
180 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
187 Returns all elements in the resultset. Is called implictly if the search
188 method is used in list context.
194 return map { $self->_construct_object(@$_); }
200 Reset this resultset's cursor, so you can iterate through the elements again.
206 $self->cursor->reset;
212 resets the resultset and returns the first element.
217 return $_[0]->reset->next;
222 Deletes all elements in the resultset.
228 $_->delete for $self->all;
232 *delete_all = \&delete; # Yeah, yeah, yeah ...
236 Returns a L<Data::Page> object for the current resultset. Only makes
237 sense for queries with page turned on.
243 my $attrs = $self->{attrs};
244 delete $attrs->{offset};
245 my $rows_per_page = delete $attrs->{rows} || 10;
246 $self->{pager} ||= Data::Page->new(
247 $self->count, $rows_per_page, $attrs->{page} || 1);
248 $attrs->{rows} = $rows_per_page;
249 return $self->{pager};
254 Returns a new resultset representing a given page.
259 my ($self, $page) = @_;
260 my $attrs = $self->{attrs};
261 $attrs->{page} = $page;
262 return $self->new($self->{class}, $attrs);
269 The resultset is responsible for handling the various attributes that
270 can be passed in with the search functions. Here's an overview of them:
276 Which column to order the results by.
280 Which cols should be retrieved on the first search.
284 Contains a list of relations that should be joined for this query. Can also
285 contain a hash referece to refer to that relation's relations.
289 This attribute can contain a arrayref of elements. each element can be another
290 arrayref, to nest joins, or it can be a hash which represents the two sides
293 *NOTE* Use this on your own risk. This allows you to shoot your foot off!
297 Should the resultset be paged? This can also be enabled by using the
302 For paged resultsset, how many rows per page
306 For paged resultsset, which page to start on.