1 package DBIx::Class::ResultSet;
11 my ($it_class, $db_class, $attrs) = @_;
12 #use Data::Dumper; warn Dumper(@_);
13 $it_class = ref $it_class if ref $it_class;
14 $attrs = { %{ $attrs || {} } };
16 $attrs->{cols} ||= [ map { "me.$_" } $db_class->_select_columns ];
17 $attrs->{from} ||= [ { 'me' => $db_class->_table_name } ];
19 foreach my $j (ref $attrs->{join} eq 'ARRAY'
20 ? (@{$attrs->{join}}) : ($attrs->{join})) {
21 if (ref $j eq 'HASH') {
22 $seen{$_} = 1 foreach keys %$j;
27 push(@{$attrs->{from}}, $db_class->_resolve_join($attrs->{join}, 'me'));
29 foreach my $pre (@{$attrs->{prefetch} || []}) {
30 push(@{$attrs->{from}}, $db_class->_resolve_join($pre, 'me'))
32 push(@{$attrs->{cols}},
34 $db_class->_relationships->{$pre}->{class}->_select_columns);
38 cols => $attrs->{cols} || [ $db_class->_select_columns ],
39 cond => $attrs->{where},
40 from => $attrs->{from} || $db_class->_table_name,
44 bless ($new, $it_class);
45 $new->pager if ($attrs->{page});
51 my ($db_class, $attrs) = @{$self}{qw/class attrs/};
53 $attrs->{rows} = $self->pager->entries_per_page;
54 $attrs->{offset} = $self->pager->skipped;
56 return $self->{cursor}
57 ||= $db_class->storage->select($self->{from}, $self->{cols},
58 $attrs->{where},$attrs);
62 my ($self, $min, $max) = @_;
63 my $attrs = { %{ $self->{attrs} || {} } };
64 $self->{class}->throw("Can't slice without where") unless $attrs->{where};
65 $attrs->{offset} = $min;
66 $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
67 my $slice = $self->new($self->{class}, $attrs);
68 return (wantarray ? $slice->all : $slice);
73 my @row = $self->cursor->next;
75 return $self->_construct_object(@row);
78 sub _construct_object {
79 my ($self, @row) = @_;
80 my @cols = $self->{class}->_select_columns;
82 unless ($self->{attrs}{prefetch}) {
83 $new = $self->{class}->_row_to_object(\@cols, \@row);
85 my @main = splice(@row, 0, scalar @cols);
86 $new = $self->{class}->_row_to_object(\@cols, \@main);
87 PRE: foreach my $pre (@{$self->{attrs}{prefetch}}) {
88 my $rel_obj = $self->{class}->_relationships->{$pre};
89 my $pre_class = $self->{class}->resolve_class($rel_obj->{class});
90 my @pre_cols = $pre_class->_select_columns;
91 my @vals = splice(@row, 0, scalar @pre_cols);
92 my $fetched = $pre_class->_row_to_object(\@pre_cols, \@vals);
93 $self->{class}->throw("No accessor for prefetched $pre")
94 unless defined $rel_obj->{attrs}{accessor};
95 if ($rel_obj->{attrs}{accessor} eq 'single') {
96 foreach my $pri ($rel_obj->{class}->primary_columns) {
97 next PRE unless defined $fetched->get_column($pri);
99 $new->{_relationship_data}{$pre} = $fetched;
100 } elsif ($rel_obj->{attrs}{accessor} eq 'filter') {
101 $new->{_inflated_column}{$pre} = $fetched;
103 $self->{class}->throw("Don't know how to store prefetched $pre");
107 $new = $self->{attrs}{record_filter}->($new)
108 if exists $self->{attrs}{record_filter};
114 my $db_class = $self->{class};
115 my $attrs = { %{ $self->{attrs} } };
116 unless ($self->{count}) {
117 # offset and order by are not needed to count
118 delete $attrs->{$_} for qw/offset order_by/;
120 my @cols = 'COUNT(*)';
121 $self->{count} = $db_class->storage->select_single($self->{from}, \@cols,
122 $self->{cond}, $attrs);
124 return 0 unless $self->{count};
125 return $self->{pager}->entries_on_this_page if ($self->{pager});
126 return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
133 return map { $self->_construct_object(@$_); }
139 $self->cursor->reset;
144 return $_[0]->reset->next;
149 $_->delete for $self->all;
153 *delete_all = \&delete; # Yeah, yeah, yeah ...
157 my $attrs = $self->{attrs};
158 delete $attrs->{offset};
159 my $rows_per_page = delete $attrs->{rows} || 10;
160 $self->{pager} ||= Data::Page->new(
161 $self->count, $rows_per_page, $attrs->{page} || 1);
162 $attrs->{rows} = $rows_per_page;
163 return $self->{pager};
167 my ($self, $page) = @_;
168 my $attrs = $self->{attrs};
169 $attrs->{page} = $page;
170 return $self->new($self->{class}, $attrs);
175 DBIX::Class::Recordset - Responsible for fetching and creating recordsets.
179 $rs=MyApp::DB::Class->search(registered=>1);
184 The recordset is responsible for handling the various attributes that
185 can be passed in with the search functions. Here's an overview of them:
191 Which column to order the results by.
194 Should the resultset be paged? This can also be enabled by using the
199 For paged resultsset, how many rows per page
203 For paged resultsset, which page to start on.