my $class = shift;\r
\r
my $it = $class->search(@_);\r
- my $pager = $class->_page_object;\r
- return ( $pager, $it );\r
+ return ( $it->pager, $it );\r
}\r
\r
1;\r
use overload
'0+' => 'count',
fallback => 1;
+use Data::Page;
sub new {
my ($it_class, $db_class, $attrs) = @_;
class => $db_class,
cols => $cols,
cond => $attrs->{where},
+ count => undef,
+ pager => undef,
attrs => $attrs };
return bless ($new, $it_class);
}
sub cursor {
my ($self) = @_;
my ($db_class, $attrs) = @{$self}{qw/class attrs/};
+ if ($attrs->{page}) {
+ $attrs->{rows} = $self->pager->entries_per_page;
+ $attrs->{offset} = $self->pager->skipped;
+ }
return $self->{cursor}
||= $db_class->storage->select($db_class->_table_name, $self->{cols},
$attrs->{where},$attrs);
sub count {
my ($self) = @_;
my $db_class = $self->{class};
-
- # offset and order by are not needed to count
my $attrs = { %{ $self->{attrs} } };
- delete $attrs->{$_} for qw/offset order_by/;
-
- my @cols = 'COUNT(*)';
- my ($c) = $db_class->storage->select_single($db_class->_table_name, \@cols,
- $self->{cond}, $attrs);
- return 0 unless $c;
- return ( $attrs->{rows} && $attrs->{rows} < $c )
+ unless ($self->{count}) {
+ # offset and order by are not needed to count
+ delete $attrs->{$_} for qw/offset order_by/;
+
+ my @cols = 'COUNT(*)';
+ $self->{count} = $db_class->storage->select_single($db_class->_table_name, \@cols,
+ $self->{cond}, $attrs);
+ }
+ return 0 unless $self->{count};
+ return ( $attrs->{rows} && $attrs->{rows} < $self->{count} )
? $attrs->{rows}
- : $c;
+ : $self->{count};
}
sub all {
*delete_all = \&delete; # Yeah, yeah, yeah ...
+sub pager {
+ my ($self) = @_;
+ my $attrs = $self->{attrs};
+ delete $attrs->{offset};
+ my $rows_per_page = delete $attrs->{rows} || 10;
+ $self->{pager} ||= Data::Page->new(
+ $self->count, $rows_per_page, $attrs->{page} || 1);
+ $attrs->{rows} = $rows_per_page;
+ return $self->{pager};
+}
+
+sub page {
+ my ($self, $page) = @_;
+ my $attrs = $self->{attrs};
+ $attrs->{page} = $page;
+ return $self->new($self->{class}, $attrs);
+}
+
1;
__PACKAGE__->mk_classdata('_resultset_class' => 'DBIx::Class::ResultSet');
-__PACKAGE__->mk_classdata('_page_object');
-
sub iterator_class { shift->_resultset_class(@_) }
=head1 NAME
}
$attrs->{where} = (@_ == 1 || ref $_[0] eq "HASH" ? shift: {@_});
- # for pagination, we create the resultset with no limit and slice it later
- my $page = {};
- if ( $attrs->{page} ) {
- map { $page->{$_} = $attrs->{$_} } qw/rows page/;
- delete $attrs->{$_} for qw/rows offset page/;
- }
-
my $rs = $class->resultset($attrs);
- if ( $page->{page} ) {
- my $pager = Data::Page->new(
- $rs->count,
- $page->{rows} || 10,
- $page->{page} || 1 );
- $class->_page_object( $pager );
- return $rs->slice( $pager->skipped,
- $pager->skipped + $pager->entries_per_page - 1 );
- }
-
return (wantarray ? $rs->all : $rs);
}
sub columns { return keys %{shift->_columns}; }
-=item page
-
- $pager = $class->page;
-
-Returns a Data::Page object for the most recent search that was performed
-using the page parameter.
-
-=cut
-
-sub page { shift->_page_object }
-
1;
=back
rows => 3,
page => 1 }
);
-my $pager = DBICTest::CD->page;
-is( $pager->entries_on_this_page, 3, "entries_on_this_page ok" );
+is( $it->pager->entries_on_this_page, 3, "entries_on_this_page ok" );
-is( $pager->next_page, 2, "next_page ok" );
+is( $it->pager->next_page, 2, "next_page ok" );
+
+is( $it->count, 3, "count on paged rs ok" );
is( $it->next->title, "Caterwaulin' Blues", "iterator->next ok" );
is( $it->next, undef, "next past end of page ok" );
-# second page, testing with array
+# second page, testing with array
my @page2 = DBICTest::CD->search(
{},
{ order_by => 'title',
rows => 3,
page => 2 }
);
-$pager = DBICTest::CD->page;
-
-is( $pager->entries_on_this_page, 2, "entries on second page ok" );
is( $page2[0]->title, "Generic Manufactured Singles", "second page first title ok" );
-# based on a failing criteria submitted by waswas
-# requires SQL::Abstract >= 1.20
+# page a standard resultset
$it = DBICTest::CD->search(
- { title => [
- -and =>
- {
- -like => '%bees'
- },
- {
- -not_like => 'Forkful%'
- }
- ]
- },
- { rows => 5 }
+ {},
+ { order_by => 'title',
+ rows => 3 }
);
-is( $it->count, 1, "complex abstract count ok" );
+my $page = $it->page(2);
+
+is( $page->next->title, "Generic Manufactured Singles", "second page of standard resultset ok" );
BEGIN {
eval "use DBD::SQLite";
- plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 5);
+ plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 6);
}
use lib qw(t/lib);
order_by => 'year' }
);
is( $cds[0]->title, "Spoonful of bees", "offset ok" );
+
+# based on a failing criteria submitted by waswas
+# requires SQL::Abstract >= 1.20
+$it = DBICTest::CD->search(
+ { title => [
+ -and =>
+ {
+ -like => '%bees'
+ },
+ {
+ -not_like => 'Forkful%'
+ }
+ ]
+ },
+ { rows => 5 }
+);
+is( $it->count, 1, "complex abstract count ok" );