← Index
NYTProf Performance Profile   « block view • line view • sub view »
For ddd2.pl
  Run on Tue May 25 16:52:24 2010
Reported on Tue May 25 16:56:48 2010

File /project/perl/lib/Data/Page.pm
Statements Executed 15
Statement Execution Time 1.62ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
0000s0sData::Page::::BEGINData::Page::BEGIN
0000s0sData::Page::::current_pageData::Page::current_page
0000s0sData::Page::::entries_on_this_pageData::Page::entries_on_this_page
0000s0sData::Page::::entries_per_pageData::Page::entries_per_page
0000s0sData::Page::::firstData::Page::first
0000s0sData::Page::::first_pageData::Page::first_page
0000s0sData::Page::::lastData::Page::last
0000s0sData::Page::::last_pageData::Page::last_page
0000s0sData::Page::::newData::Page::new
0000s0sData::Page::::next_pageData::Page::next_page
0000s0sData::Page::::previous_pageData::Page::previous_page
0000s0sData::Page::::skippedData::Page::skipped
0000s0sData::Page::::spliceData::Page::splice
0000s0sData::Page::::total_entriesData::Page::total_entries
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Data::Page;
2394µs1240µsuse Carp;
# spent 240µs making 1 call to Exporter::import
3381µs121µsuse strict;
# spent 21µs making 1 call to strict::import
43121µs10suse base 'Class::Accessor::Chained::Fast';
# spent 17.9ms making 1 call to base::import, recursion: max depth 2, time 17.9ms
5144µs1691µs__PACKAGE__->mk_accessors(qw(total_entries entries_per_page current_page));
# spent 691µs making 1 call to Class::Accessor::mk_accessors
6
731.26ms1157µsuse vars qw($VERSION);
# spent 157µs making 1 call to vars::import
815µs$VERSION = '2.00';
9
10sub new {
11 my $class = shift;
12 my $self = {};
13 bless($self, $class);
14
15 my ($total_entries, $entries_per_page, $current_page) = @_;
16 $self->total_entries($total_entries || 0);
17 $self->entries_per_page($entries_per_page || 10);
18 $self->current_page($current_page || 1);
19 return $self;
20}
21
22sub entries_per_page {
23 my $self = shift;
24 my $entries_per_page = $_[0];
25 if (@_) {
26 croak("Fewer than one entry per page!") if $entries_per_page < 1;
27 return $self->_entries_per_page_accessor(@_);
28 }
29 return $self->_entries_per_page_accessor();
30}
31
32sub current_page {
33 my $self = shift;
34 if (@_) {
35 return $self->_current_page_accessor(@_);
36 }
37 return $self->first_page unless defined $self->_current_page_accessor;
38 return $self->first_page if $self->_current_page_accessor < $self->first_page;
39 return $self->last_page if $self->_current_page_accessor > $self->last_page;
40 return $self->_current_page_accessor();
41}
42
43sub total_entries {
44 my $self = shift;
45 if (@_) {
46 return $self->_total_entries_accessor(@_);
47 }
48 return $self->_total_entries_accessor;
49}
50
51sub entries_on_this_page {
52 my $self = shift;
53
54 if ($self->total_entries == 0) {
55 return 0;
56 } else {
57 return $self->last - $self->first + 1;
58 }
59}
60
61sub first_page {
62 my $self = shift;
63
64 return 1;
65}
66
67sub last_page {
68 my $self = shift;
69
70 my $pages = $self->total_entries / $self->entries_per_page;
71 my $last_page;
72
73 if ($pages == int $pages) {
74 $last_page = $pages;
75 } else {
76 $last_page = 1 + int($pages);
77 }
78
79 $last_page = 1 if $last_page < 1;
80 return $last_page;
81}
82
83sub first {
84 my $self = shift;
85
86 if ($self->total_entries == 0) {
87 return 0;
88 } else {
89 return (($self->current_page - 1) * $self->entries_per_page) + 1;
90 }
91}
92
93sub last {
94 my $self = shift;
95
96 if ($self->current_page == $self->last_page) {
97 return $self->total_entries;
98 } else {
99 return ($self->current_page * $self->entries_per_page);
100 }
101}
102
103sub previous_page {
104 my $self = shift;
105
106 if ($self->current_page > 1) {
107 return $self->current_page - 1;
108 } else {
109 return undef;
110 }
111}
112
113sub next_page {
114 my $self = shift;
115
116 $self->current_page < $self->last_page ? $self->current_page + 1 : undef;
117}
118
119# This method would probably be better named 'select' or 'slice' or
120# something, because it doesn't modify the array the way
121# CORE::splice() does.
122sub splice {
123 my ($self, $array) = @_;
124 my $top = @$array > $self->last ? $self->last : @$array;
125 return () if $top == 0; # empty
126 return @{$array}[ $self->first - 1 .. $top - 1 ];
127}
128
129sub skipped {
130 my $self = shift;
131
132 my $skipped = $self->first - 1;
133 return 0 if $skipped < 0;
134 return $skipped;
135}
136
137115µs1;
138
139__END__
140
141=head1 NAME
142
143Data::Page - help when paging through sets of results
144
145=head1 SYNOPSIS
146
147 use Data::Page;
148
149 my $page = Data::Page->new();
150 $page->total_entries($total_entries);
151 $page->entries_per_page($entries_per_page);
152 $page->current_page($current_page);
153
154 print " First page: ", $page->first_page, "\n";
155 print " Last page: ", $page->last_page, "\n";
156 print "First entry on page: ", $page->first, "\n";
157 print " Last entry on page: ", $page->last, "\n";
158
159=head1 DESCRIPTION
160
161When searching through large amounts of data, it is often the case
162that a result set is returned that is larger than we want to display
163on one page. This results in wanting to page through various pages of
164data. The maths behind this is unfortunately fiddly, hence this
165module.
166
167The main concept is that you pass in the number of total entries, the
168number of entries per page, and the current page number. You can then
169call methods to find out how many pages of information there are, and
170what number the first and last entries on the current page really are.
171
172For example, say we wished to page through the integers from 1 to 100
173with 20 entries per page. The first page would consist of 1-20, the
174second page from 21-40, the third page from 41-60, the fourth page
175from 61-80 and the fifth page from 81-100. This module would help you
176work this out.
177
178=head1 METHODS
179
180=head2 new
181
182This is the constructor, which takes no arguments.
183
184 my $page = Data::Page->new();
185
186There is also an old, deprecated constructor, which currently takes
187two mandatory arguments, the total number of entries and the number of
188entries per page. It also optionally takes the current page number:
189
190 my $page = Data::Page->new($total_entries, $entries_per_page, $current_page);
191
192=head2 total_entries
193
194This method get or sets the total number of entries:
195
196 print "Entries:", $page->total_entries, "\n";
197
198=head2 entries_per_page
199
200This method gets or sets the total number of entries per page (which
201defaults to 10):
202
203 print "Per page:", $page->entries_per_page, "\n";
204
205=head2 current_page
206
207This method gets or sets the current page number (which defaults to 1):
208
209 print "Page: ", $page->current_page, "\n";
210
211=head2 entries_on_this_page
212
213This methods returns the number of entries on the current page:
214
215 print "There are ", $page->entries_on_this_page, " entries displayed\n";
216
217=head2 first_page
218
219This method returns the first page. This is put in for reasons of
220symmetry with last_page, as it always returns 1:
221
222 print "Pages range from: ", $page->first_page, "\n";
223
224=head2 last_page
225
226This method returns the total number of pages of information:
227
228 print "Pages range to: ", $page->last_page, "\n";
229
230=head2 first
231
232This method returns the number of the first entry on the current page:
233
234 print "Showing entries from: ", $page->first, "\n";
235
236=head2 last
237
238This method returns the number of the last entry on the current page:
239
240 print "Showing entries to: ", $page->last, "\n";
241
242=head2 previous_page
243
244This method returns the previous page number, if one exists. Otherwise
245it returns undefined:
246
247 if ($page->previous_page) {
248 print "Previous page number: ", $page->previous_page, "\n";
249 }
250
251=head2 next_page
252
253This method returns the next page number, if one exists. Otherwise
254it returns undefined:
255
256 if ($page->next_page) {
257 print "Next page number: ", $page->next_page, "\n";
258 }
259
260=head2 splice
261
262This method takes in a listref, and returns only the values which are
263on the current page:
264
265 @visible_holidays = $page->splice(\@holidays);
266
267=head2 skipped
268
269This method is useful paging through data in a database using SQL
270LIMIT clauses. It is simply $page->first - 1:
271
272 $sth = $dbh->prepare(
273 q{SELECT * FROM table ORDER BY rec_date LIMIT ?, ?}
274 );
275 $sth->execute($date, $page->skipped, $page->entries_per_page);
276
277=head1 NOTES
278
279It has been said before that this code is "too simple" for CPAN, but I
280must disagree. I have seen people write this kind of code over and
281over again and they always get it wrong. Perhaps now they will spend
282more time getting the rest of their code right...
283
284=head1 SEE ALSO
285
286Related modules which may be of interest: L<Data::Pageset>,
287L<Data::Page::Tied>, L<Data::SpreadPagination>.
288
289=head1 AUTHOR
290
291Based on code originally by Leo Lapworth, with many changes added by
292by Leon Brocard <acme@astray.com>.
293
294=head1 COPYRIGHT
295
296Copyright (C) 2000-4, Leon Brocard
297
298This module is free software; you can redistribute it or modify it
299under the same terms as Perl itself.
300
301