Made pager a method on ResultSet, added rs->page(num) to page an ordinary RS, made...
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSet.pm
1 package DBIx::Class::ResultSet;
2
3 use strict;
4 use warnings;
5 use overload
6         '0+'     => 'count',
7         fallback => 1;
8 use Data::Page;
9
10 sub new {
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 || {} } };
15   my $cols = [ $db_class->_select_columns ];
16   my $new = {
17     class => $db_class,
18     cols => $cols,
19     cond => $attrs->{where},
20     count => undef,
21     pager => undef,
22     attrs => $attrs };
23   return bless ($new, $it_class);
24 }
25
26 sub cursor {
27   my ($self) = @_;
28   my ($db_class, $attrs) = @{$self}{qw/class attrs/};
29   if ($attrs->{page}) {
30     $attrs->{rows} = $self->pager->entries_per_page;
31     $attrs->{offset} = $self->pager->skipped;
32   }
33   return $self->{cursor}
34     ||= $db_class->storage->select($db_class->_table_name, $self->{cols},
35           $attrs->{where},$attrs);
36 }
37
38 sub slice {
39   my ($self, $min, $max) = @_;
40   my $attrs = { %{ $self->{attrs} || {} } };
41   $self->{class}->throw("Can't slice without where") unless $attrs->{where};
42   $attrs->{offset} = $min;
43   $attrs->{rows} = ($max ? ($max - $min + 1) : 1);
44   my $slice = $self->new($self->{class}, $attrs);
45   return (wantarray ? $slice->all : $slice);
46 }
47
48 sub next {
49   my ($self) = @_;
50   my @row = $self->cursor->next;
51   return unless (@row);
52   return $self->{class}->_row_to_object($self->{cols}, \@row);
53 }
54
55 sub count {
56   my ($self) = @_;
57   my $db_class = $self->{class};
58   my $attrs = { %{ $self->{attrs} } };
59   unless ($self->{count}) {
60     # offset and order by are not needed to count
61     delete $attrs->{$_} for qw/offset order_by/;
62         
63     my @cols = 'COUNT(*)';
64     $self->{count} = $db_class->storage->select_single($db_class->_table_name, \@cols,
65                                               $self->{cond}, $attrs);
66   }
67   return 0 unless $self->{count};
68   return ( $attrs->{rows} && $attrs->{rows} < $self->{count} ) 
69     ? $attrs->{rows} 
70     : $self->{count};
71 }
72
73 sub all {
74   my ($self) = @_;
75   return map { $self->{class}->_row_to_object($self->{cols}, $_); }
76            $self->cursor->all;
77 }
78
79 sub reset {
80   my ($self) = @_;
81   $self->cursor->reset;
82   return $self;
83 }
84
85 sub first {
86   return $_[0]->reset->next;
87 }
88
89 sub delete {
90   my ($self) = @_;
91   $_->delete for $self->all;
92   return 1;
93 }
94
95 *delete_all = \&delete; # Yeah, yeah, yeah ...
96
97 sub pager {
98   my ($self) = @_;
99   my $attrs = $self->{attrs};
100   delete $attrs->{offset};
101   my $rows_per_page = delete $attrs->{rows} || 10;
102   $self->{pager} ||= Data::Page->new(
103     $self->count, $rows_per_page, $attrs->{page} || 1);
104   $attrs->{rows} = $rows_per_page;
105   return $self->{pager};
106 }
107
108 sub page {
109   my ($self, $page) = @_;
110   my $attrs = $self->{attrs};
111   $attrs->{page} = $page;
112   return $self->new($self->{class}, $attrs);
113 }
114
115 1;