1 package DBIx::Class::ResultSet;
12 DBIX::Class::Recordset - Responsible for fetching and creating recordsets.
16 $rs=MyApp::DB::Class->search(registered=>1);
20 The recordset is also know as an iterator.
26 =item new <db_class> <attrs>
28 The recordset 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 record set.
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 record set.
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 record set.
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->{class}->_select_columns;
123 unless ($self->{attrs}{prefetch}) {
124 $new = $self->{class}->_row_to_object(\@cols, \@row);
126 my @main = splice(@row, 0, scalar @cols);
127 $new = $self->{class}->_row_to_object(\@cols, \@main);
128 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
129 my $rel_obj = $self->{class}->_relationships->{$pre};
130 my $pre_class = $self->{class}->resolve_class($rel_obj->{class});
131 my @pre_cols = $pre_class->_select_columns;
132 my @vals = splice(@row, 0, scalar @pre_cols);
133 my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
134 $self->{class}->throw("No accessor for prefetched $pre")
135 unless defined $rel_obj->{attrs}{accessor};
136 if ($rel_obj->{attrs}{accessor} eq 'single') {
137 foreach my $pri ($rel_obj->{class}->primary_columns) {
138 next PRE unless defined $fetched->get_column($pri);
140 $new->{_relationship_data}{$pre} = $fetched;
141 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
142 $new->{_inflated_column}{$pre} = $fetched;
144 $self->{class}->throw("Don't know how to store prefetched $pre");
148 $new = $self->{attrs}{record_filter}->($new)
149 if exists $self->{attrs}{record_filter};
155 Performs an SQL count with the same query as the resultset was built
156 with to find the number of elements.
163 my $db_class = $self->{class};
164 my $attrs = { %{ $self->{attrs} } };
165 unless ($self->{count}) {
166 # offset and order by are not needed to count
167 delete $attrs->{$_} for qw/offset order_by/;
169 my @cols = 'COUNT(*)';
170 $self->{count} = $db_class->storage->select_single($self->{from}, \@cols,
171 $self->{cond}, $attrs);
173 return 0 unless $self->{count};
174 return $self->{pager}->entries_on_this_page if ($self->{pager});
175 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
182 Returns all elements in the recordset. Is called implictly if the search
183 method is used in list context.
189 return map { $self->_construct_object(@$_); }
195 Reset this recordset's cursor, so you can iterate through the elements again.
201 $self->cursor->reset;
207 resets the recordset and returns the first element.
212 return $_[0]->reset->next;
217 Deletes all elements in the recordset.
223 $_->delete for $self->all;
227 *delete_all = \&delete; # Yeah, yeah, yeah ...
231 Returns a L<Data::Page> object for the current resultset. Only makes
232 sense for queries with page turned on.
238 my $attrs = $self->{attrs};
239 delete $attrs->{offset};
240 my $rows_per_page = delete $attrs->{rows} || 10;
241 $self->{pager} ||= Data::Page->new(
242 $self->count, $rows_per_page, $attrs->{page} || 1);
243 $attrs->{rows} = $rows_per_page;
244 return $self->{pager};
249 Returns a new recordset representing a given page.
254 my ($self, $page) = @_;
255 my $attrs = $self->{attrs};
256 $attrs->{page} = $page;
257 return $self->new($self->{class}, $attrs);
264 The recordset is responsible for handling the various attributes that
265 can be passed in with the search functions. Here's an overview of them:
271 Which column to order the results by.
275 Which cols should be retrieved on the first search.
279 Contains a list of relations that should be joined for this query. Can also
280 contain a hash referece to refer to that relation's relations.
284 This attribute can contain a arrayref of elements. each element can be another
285 arrayref, to nest joins, or it can be a hash which represents the two sides
288 *NOTE* Use this on your own risk. This allows you to shoot your foot off!
292 Should the resultset be paged? This can also be enabled by using the
297 For paged resultsset, how many rows per page
301 For paged resultsset, which page to start on.