From: Andy Grundman Date: Mon, 29 Aug 2005 19:16:19 +0000 (+0000) Subject: Made pager a method on ResultSet, added rs->page(num) to page an ordinary RS, made... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=3c5b25c5328c41ff6fb062bf2aed446263cf01ec;p=dbsrgits%2FDBIx-Class-Historic.git Made pager a method on ResultSet, added rs->page(num) to page an ordinary RS, made rs->count store it's value --- diff --git a/lib/DBIx/Class/CDBICompat/Pager.pm b/lib/DBIx/Class/CDBICompat/Pager.pm index cd01047..ea53529 100644 --- a/lib/DBIx/Class/CDBICompat/Pager.pm +++ b/lib/DBIx/Class/CDBICompat/Pager.pm @@ -9,8 +9,7 @@ sub page { my $class = shift; my $it = $class->search(@_); - my $pager = $class->_page_object; - return ( $pager, $it ); + return ( $it->pager, $it ); } 1; diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 72ea52f..28131b3 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -5,6 +5,7 @@ use warnings; use overload '0+' => 'count', fallback => 1; +use Data::Page; sub new { my ($it_class, $db_class, $attrs) = @_; @@ -16,6 +17,8 @@ sub new { class => $db_class, cols => $cols, cond => $attrs->{where}, + count => undef, + pager => undef, attrs => $attrs }; return bless ($new, $it_class); } @@ -23,6 +26,10 @@ sub new { 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); @@ -48,18 +55,19 @@ sub next { 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 { @@ -86,4 +94,22 @@ sub delete { *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; diff --git a/lib/DBIx/Class/Table.pm b/lib/DBIx/Class/Table.pm index 451b0bd..42631de 100644 --- a/lib/DBIx/Class/Table.pm +++ b/lib/DBIx/Class/Table.pm @@ -16,8 +16,6 @@ __PACKAGE__->mk_classdata('table_alias'); # FIXME: Doesn't actually do anything __PACKAGE__->mk_classdata('_resultset_class' => 'DBIx::Class::ResultSet'); -__PACKAGE__->mk_classdata('_page_object'); - sub iterator_class { shift->_resultset_class(@_) } =head1 NAME @@ -116,25 +114,8 @@ sub search { } $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); } @@ -195,17 +176,6 @@ sub find_or_create { 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 diff --git a/t/07pager.t b/t/07pager.t index 04b8b28..de8dbaf 100644 --- a/t/07pager.t +++ b/t/07pager.t @@ -13,11 +13,12 @@ my $it = DBICTest::CD->search( 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" ); @@ -26,32 +27,22 @@ $it->next; 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" ); diff --git a/t/15limit.t b/t/15limit.t index 7eb548b..edad740 100644 --- a/t/15limit.t +++ b/t/15limit.t @@ -3,7 +3,7 @@ use Test::More; 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); @@ -28,3 +28,20 @@ my @cds = DBICTest::CD->search( {}, 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" );