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 unless (defined $fetched->get_column($pri)) {
143 $new->{_relationship_data}{$pre} = $fetched;
144 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
145 $new->{_inflated_column}{$pre} = $fetched;
147 $self->{class}->throw("Don't know how to store prefetched $pre");
151 $new = $self->{attrs}{record_filter}->($new)
152 if exists $self->{attrs}{record_filter};
158 Performs an SQL count with the same query as the resultset was built
159 with to find the number of elements.
166 my $db_class = $self->{class};
167 my $attrs = { %{ $self->{attrs} } };
168 unless ($self->{count}) {
169 # offset and order by are not needed to count
170 delete $attrs->{$_} for qw/offset order_by/;
172 my @cols = 'COUNT(*)';
173 $self->{count} = $db_class->storage->select_single($self->{from}, \@cols,
174 $self->{cond}, $attrs);
176 return 0 unless $self->{count};
177 return $self->{pager}->entries_on_this_page if ($self->{pager});
178 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
185 Returns all elements in the recordset. Is called implictly if the search
186 method is used in list context.
192 return map { $self->_construct_object(@$_); }
198 Reset this recordset's cursor, so you can iterate through the elements again.
204 $self->cursor->reset;
210 resets the recordset and returns the first element.
215 return $_[0]->reset->next;
220 Deletes all elements in the recordset.
226 $_->delete for $self->all;
230 *delete_all = \&delete; # Yeah, yeah, yeah ...
234 Returns a L<Data::Page> object for the current resultset. Only makes
235 sense for queries with page turned on.
241 my $attrs = $self->{attrs};
242 delete $attrs->{offset};
243 my $rows_per_page = delete $attrs->{rows} || 10;
244 $self->{pager} ||= Data::Page->new(
245 $self->count, $rows_per_page, $attrs->{page} || 1);
246 $attrs->{rows} = $rows_per_page;
247 return $self->{pager};
252 Returns a new recordset representing a given page.
257 my ($self, $page) = @_;
258 my $attrs = $self->{attrs};
259 $attrs->{page} = $page;
260 return $self->new($self->{class}, $attrs);
267 The recordset is responsible for handling the various attributes that
268 can be passed in with the search functions. Here's an overview of them:
274 Which column to order the results by.
278 Which cols should be retrieved on the first search.
282 Contains a list of relations that should be joined for this query. Can also
283 contain a hash referece to refer to that relation's relations.
287 This attribute can contain a arrayref of elements. each element can be another
288 arrayref, to nest joins, or it can be a hash which represents the two sides
291 *NOTE* Use this on your own risk. This allows you to shoot your foot off!
295 Should the resultset be paged? This can also be enabled by using the
300 For paged resultsset, how many rows per page
304 For paged resultsset, which page to start on.