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