File Coverage

blib/lib/Teng/Plugin/Pager.pm
Criterion Covered Total %
statement 39 39 100.0
branch 10 14 71.4
condition 2 3 66.6
subroutine 8 8 100.0
pod 1 1 100.0
total 60 65 92.3


line stmt bran cond sub pod time code
1             package Teng::Plugin::Pager;
2 1     1   775 use strict;
  1         3  
  1         33  
3 1     1   5 use warnings;
  1         2  
  1         27  
4 1     1   5 use utf8;
  1         2  
  1         8  
5 1     1   21 use Carp ();
  1         2  
  1         13  
6 1     1   4 use DBI;
  1         2  
  1         39  
7 1     1   5 use Teng::Iterator;
  1         2  
  1         65  
8 1     1   446 use Data::Page::NoTotalEntries 0.02;
  1         645  
  1         363  
9              
10             our @EXPORT = qw/search_with_pager/;
11              
12             sub search_with_pager {
13 4     4 1 12319 my ($self, $table_name, $where, $opt) = @_;
14              
15 4 50       13 my $table = $self->schema->get_table($table_name) or Carp::croak("'$table_name' is unknown table");
16              
17 4         7 my $page = $opt->{page};
18 4         14 my $rows = $opt->{rows};
19 4         8 for (qw/page rows/) {
20 8 50       19 Carp::croak("missing mandatory parameter: $_") unless exists $opt->{$_};
21             }
22              
23             my $columns = $opt->{'+columns'}
24 1         4 ? [@{$table->{columns}}, @{$opt->{'+columns'}}]
  1         4  
25             : ($opt->{columns} || $table->{columns})
26 4 100 66     26 ;
27              
28 4         13 my ($sql, @binds) = $self->sql_builder->select(
29             $table_name,
30             $columns,
31             $where,
32             +{
33             %$opt,
34             limit => $rows + 1,
35             offset => $rows*($page-1),
36             }
37             );
38              
39 4 50       1668 my $sth = $self->dbh->prepare($sql) or Carp::croak $self->dbh->errstr;
40 4 50       372 $sth->execute(@binds) or Carp::croak $self->dbh->errstr;
41              
42 4         18 my $ret = [ Teng::Iterator->new(
43             teng => $self,
44             sth => $sth,
45             sql => $sql,
46             row_class => $self->schema->get_row_class($table_name),
47             table => $table,
48             table_name => $table_name,
49             suppress_object_creation => $self->suppress_row_objects,
50             )->all];
51              
52 4 100       30 my $has_next = ( $rows + 1 == scalar(@$ret) ) ? 1 : 0;
53 4 100       15 if ($has_next) { pop @$ret }
  3         5  
54              
55 4         19 my $pager = Data::Page::NoTotalEntries->new(
56             entries_per_page => $rows,
57             current_page => $page,
58             has_next => $has_next,
59             entries_on_this_page => scalar(@$ret),
60             );
61              
62 4         83 return ($ret, $pager);
63             }
64              
65             1;
66             __END__
67              
68             =for test_synopsis
69             my ($dbh, $c);
70              
71             =head1 NAME
72              
73             Teng::Plugin::Pager - Pager
74              
75             =head1 SYNOPSIS
76              
77             package MyApp::DB;
78             use parent qw/Teng/;
79             __PACKAGE__->load_plugin('Pager');
80              
81             package main;
82             my $db = MyApp::DB->new(dbh => $dbh);
83             my $page = $c->req->param('page') || 1;
84             my ($rows, $pager) = $db->search_with_pager('user' => {type => 3}, {page => $page, rows => 5});
85              
86             =head1 DESCRIPTION
87              
88             This is a helper for pagination.
89              
90             This pager fetches "entries_per_page + 1" rows. And detect "this page has a next page or not".
91              
92             =head1 METHODS
93              
94             =over 4
95              
96             =item my (\@rows, $pager) = $db->search_with_pager($table_name, \%where, \%opts)
97              
98             Select from database with pagination.
99              
100             The arguments are mostly same as C<$db->search()>. But two additional options are available.
101              
102             =over 4
103              
104             =item $opts->{page}
105              
106             Current page number.
107              
108             =item $opts->{rows}
109              
110             The number of entries per page.
111              
112             =back
113              
114             This method returns ArrayRef[Teng::Row] and instance of L<Data::Page::NoTotalEntries>.
115              
116             =back