forked from nekokak/p5-Teng
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Count.pm
115 lines (80 loc) · 2.74 KB
/
Count.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package Teng::Plugin::Pager::Count;
use strict;
use warnings;
use Data::Page;
our @EXPORT = qw/search_with_pager/;
sub search_with_pager {
my ($self, $table_name, $where, $opt) = @_;
my $table = $self->schema->get_table($table_name) or Carp::croak("'$table_name' is unknown table");
my $page = $opt->{page};
my $rows = $opt->{rows};
my ($count_sql, @count_binds) = $self->sql_builder->select(
$table_name,
[\'COUNT(*)'],
$where,
$opt,
);
my $columns = $opt->{'+columns'}
? [@{$table->{columns}}, @{$opt->{'+columns'}}]
: ($opt->{columns} || $table->{columns})
;
my ($sql, @binds) = $self->sql_builder->select(
$table_name,
$columns,
$where,
+{
%$opt,
limit => $rows,
offset => $rows*($page-1),
}
);
my $count_sth = $self->dbh->prepare($count_sql) or Carp::croak $self->dbh->errstr;
$count_sth->execute(@count_binds) or Carp::croak $self->dbh->errstr;
my $total_entries = $count_sth->fetchrow_arrayref->[0];
my $sth = $self->dbh->prepare($sql) or Carp::croak $self->dbh->errstr;
$sth->execute(@binds) or Carp::croak $self->dbh->errstr;
my $itr = Teng::Iterator->new(
teng => $self,
sth => $sth,
sql => $sql,
row_class => $self->schema->get_row_class($table_name),
table => $table,
table_name => $table_name,
suppress_object_creation => $self->suppress_row_objects,
);
my $pager = Data::Page->new();
$pager->entries_per_page($rows);
$pager->current_page($page);
$pager->total_entries($total_entries);
return ([$itr->all], $pager);
}
1;
__END__
=for test_synopsis
my ($c, $dbh);
=head1 NAME
Teng::Plugin::Pager::Count - Paginate with COUNT(*)
=head1 SYNOPSIS
package MyApp::DB;
use parent qw/Teng/;
__PACKAGE__->load_plugin('Pager::Count');
package main;
my $db = MyApp::DB->new(dbh => $dbh);
my $page = $c->req->param('page') || 1;
my ($rows, $pager) = $db->search_with_pager('user' => {type => 3}, {page => $page, rows => 5});
=head1 DESCRIPTION
This is a helper class for pagination. This helper only supports B<MySQL>.
Since this plugin uses COUNT(*) for calculate total entries.
=head1 METHODS
=over 4
=item my (\@rows, $pager) = $db->search_with_pager($table, \%where, \%opts);
Select from database with pagination.
The arguments are mostly same as C<$db->search()>. But two additional options are available.
=over 4
=item $opts->{page}
Current page number.
=item $opts->{rows}
The number of entries per page.
=back
This method returns ArrayRef[Teng::Row] and instance of L<Teng::Plugin::Pager::Page>.
=back