datapage 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ 0.0.1 Thu Aug 25 14:10:55 BST 2011
2
+ * initial release
@@ -0,0 +1,122 @@
1
+ =begin
2
+ index:Ej
3
+
4
+ = Data/Page: Help when paging through sets of results
5
+
6
+ Last Modified: 2005-05-22 00:28:04
7
+
8
+ --
9
+
10
+ When searching through large amounts of data, it is often the case
11
+ that a result set is returned that is larger than we want to display
12
+ on one page. This results in wanting to page through various pages of
13
+ data. The maths behind this is unfortunately fiddly, hence this
14
+ module.
15
+
16
+ The main concept is that you pass in the number of total entries, the
17
+ number of entries per page, and the current page number. You can then
18
+ call methods to find out how many pages of information there are, and
19
+ what number the first and last entries on the current page really are.
20
+
21
+ For example, say we wished to page through the integers from 1 to 100
22
+ with 20 entries per page. The first page would consist of 1-20, the
23
+ second page from 21-40, the third page from 41-60, the fourth page
24
+ from 61-80 and the fifth page from 81-100. This module would help you
25
+ work this out.
26
+
27
+ == Examples
28
+
29
+ require "datapage"
30
+
31
+ page = Data::Page.new()
32
+ page.total_entries(total_entries)
33
+ page.entries_per_page(entries_per_page)
34
+ page.current_page(current_page)
35
+
36
+ puts " First page: #{page.first_page}"
37
+ puts " Last page: #{page.last_page}"
38
+ puts "First entry on page: #{page.first}"
39
+ puts " Last entry on page: #{page.last}"
40
+
41
+ == API
42
+
43
+ --- Data::Page#new ()
44
+ This is the constructor, which takes no arguments.
45
+ page = Data::Page.new()
46
+
47
+ --- Data::Page#total_entries
48
+ This method get or sets the total number of entries:
49
+ puts "Entries: #{page.total_entries}"
50
+
51
+ --- Data::Page#entries_per_page
52
+ This method get or sets the total number of entries
53
+ per page (which defaults to 10):
54
+ puts "Per page: #{page.entries_per_page}"
55
+
56
+ --- Data::Page#current_page
57
+ This method gets or sets the current page number
58
+ (which defaults to 1):
59
+ puts "Page: #{page.current_page}"
60
+
61
+ --- Data::Page#entries_on_this_page
62
+ This methods returns the number of entries on the current page:
63
+ puts "There are #{page.entries_on_this_page} entries displayed"
64
+
65
+ --- Data::Page#first_page
66
+ This method returns the first page. This is put in for reasons of
67
+ symmetry with last_page, as it always returns 1:
68
+ puts "Pages range from: #{page.first_page}"
69
+
70
+ --- Data::Page#last_page
71
+ This method returns the total number of pages of information:
72
+ puts "Pages range to: #{page.last_page}"
73
+
74
+ --- Data::Page#first
75
+ This method returns the number of the first entry on the current page:
76
+ puts "Showing entries from: #{page.first}"
77
+
78
+ --- Data::Page#last
79
+ This method returns the number of the last entry on the current page:
80
+ puts "Showing entries to: #{page.last}"
81
+
82
+ --- Data::Page#previous_page
83
+ This method returns the previous page number, if one exists. Otherwise
84
+ it returns nil:
85
+ puts "Previous page number: #{page.previous_page}" if page.previous_page
86
+
87
+ --- Data::Page#next_page
88
+ This method returns the next page number, if one exists. Otherwise
89
+ it returns nil:
90
+ puts "Next page number: #{page.next_page}" if page.next_page
91
+
92
+ --- Data::Page#splice( array )
93
+ This method takes in a array, and returns only the values which are
94
+ on the current page:
95
+ visible_holidays = page.splice(holidays);
96
+
97
+ --- Data::Page#skipped
98
+ This method is useful paging through data in a database using SQL
99
+ LIMIT clauses. It is simply page.first - 1:
100
+
101
+ --- Data::Page#change_entries_per_page
102
+ This method changes the number of entries per page and the
103
+ current page number such that the *first* item on the current
104
+ page will be present on the new page:
105
+ page.total_entries(50);
106
+ page.entries_per_page(20);
107
+ page.current_page(3);
108
+ puts page->first; # 41
109
+ page.change_entries_per_page(30);
110
+ puts page.current_page; # 2 - the page that item 41 will show in
111
+
112
+ == Notes
113
+
114
+ It has been said before that this code is "too simple" for distribution, but I
115
+ must disagree. I have seen people write this kind of code over and
116
+ over again and they always get it wrong. Perhaps now they will spend
117
+ more time getting the rest of their code right...
118
+
119
+ --
120
+
121
+ - ((<Leon Brocard|URL:http://www.astray.com/>)) -
122
+ =end
@@ -0,0 +1,8 @@
1
+ task :default => :test
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/simple.rb'
7
+ test.verbose = true
8
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "datapage"
3
+ s.version = "0.0.1"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = ["Leon Brocard"]
6
+ s.email = ["acme@astray.com"]
7
+ s.homepage = "http://github.com/acme/ruby-data-page/"
8
+ s.summary = "Data::Page helps when paging through sets of results"
9
+ s.description = "Data::Page helps when paging through sets of results"
10
+
11
+ s.required_rubygems_version = ">= 1.3.6"
12
+
13
+ s.add_development_dependency "rake", ">= 0"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
17
+ s.require_path = 'lib'
18
+
19
+ s.rdoc_options = ["--charset=UTF-8"]
20
+ end
@@ -0,0 +1,92 @@
1
+ class Data::Page
2
+ attr_reader :total_entries, :entries_per_page, :current_page
3
+ def initialize(total_entries=0, entries_per_page=10, current_page=1)
4
+ @total_entries, @entries_per_page, @current_page = total_entries, entries_per_page, current_page
5
+ end
6
+ def total_entries(*total_entries)
7
+ @total_entries = total_entries[0] if total_entries[0]
8
+ return @total_entries
9
+ end
10
+ def entries_per_page(*entries_per_page)
11
+ @entries_per_page = entries_per_page[0] if entries_per_page[0]
12
+ return @entries_per_page
13
+ end
14
+ def current_page(*current_page)
15
+ @current_page = current_page[0] if current_page[0]
16
+ return @current_page
17
+ end
18
+ def first_page
19
+ return 1
20
+ end
21
+ def last_page
22
+ pages = @total_entries.to_f / @entries_per_page.to_f
23
+ if pages == pages.floor
24
+ last_page = pages
25
+ else
26
+ last_page = 1 + pages.floor
27
+ end
28
+ if last_page < 1
29
+ last_page = 1
30
+ end
31
+ return last_page
32
+ end
33
+ def first
34
+ if @total_entries == 0
35
+ return 0
36
+ else
37
+ return ( ( @current_page - 1 ) * @entries_per_page ) + 1
38
+ end
39
+ end
40
+ def last
41
+ if @current_page == self.last_page
42
+ return @total_entries
43
+ else
44
+ return @current_page * @entries_per_page
45
+ end
46
+ end
47
+ def previous_page
48
+ if @current_page > 1
49
+ return @current_page - 1
50
+ else
51
+ return nil
52
+ end
53
+ end
54
+ def next_page
55
+ if @current_page < self.last_page
56
+ return @current_page + 1
57
+ else
58
+ return nil
59
+ end
60
+ end
61
+ def splice(array)
62
+ if array.length > self.last
63
+ top = self.last
64
+ else
65
+ top = array.length
66
+ end
67
+ if top == 0
68
+ return []
69
+ end
70
+ return array.slice(self.first-1, self.last - self.first + 1)
71
+ end
72
+ def skipped
73
+ skipped = self.first - 1
74
+ if skipped < 0
75
+ return 0
76
+ else
77
+ return skipped
78
+ end
79
+ end
80
+ def entries_on_this_page
81
+ if @total_entries == 0
82
+ return 0
83
+ else
84
+ return self.last - self.first + 1
85
+ end
86
+ end
87
+ def change_entries_per_page(new_epp)
88
+ new_page = 1 + (self.first / new_epp)
89
+ self.entries_per_page(new_epp)
90
+ self.current_page(new_page)
91
+ end
92
+ end
@@ -0,0 +1,123 @@
1
+ require "datapage"
2
+ require "test/unit"
3
+
4
+ class TestSimpleNumber < Test::Unit::TestCase
5
+
6
+ def test_simple_1
7
+ text = "# Initial test
8
+ 50 10 1 1 5 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 15 1
9
+ 50 10 2 1 5 11 20 1 2 3 10,11,12,13,14,15,16,17,18,19 10 15 1
10
+ 50 10 3 1 5 21 30 2 3 4 20,21,22,23,24,25,26,27,28,29 10 15 2
11
+ 50 10 4 1 5 31 40 3 4 5 30,31,32,33,34,35,36,37,38,39 10 15 3
12
+ 50 10 5 1 5 41 50 4 5 undef 40,41,42,43,44,45,46,47,48,49 10 15 3
13
+
14
+ # Under 10
15
+ 1 10 1 1 1 1 1 undef 1 undef 0 1 15 1
16
+ 2 10 1 1 1 1 2 undef 1 undef 0,1 2 15 1
17
+ 3 10 1 1 1 1 3 undef 1 undef 0,1,2 3 15 1
18
+ 4 10 1 1 1 1 4 undef 1 undef 0,1,2,3 4 15 1
19
+ 5 10 1 1 1 1 5 undef 1 undef 0,1,2,3,4 5 15 1
20
+ 6 10 1 1 1 1 6 undef 1 undef 0,1,2,3,4,5 6 15 1
21
+ 7 10 1 1 1 1 7 undef 1 undef 0,1,2,3,4,5,6 7 15 1
22
+ 8 10 1 1 1 1 8 undef 1 undef 0,1,2,3,4,5,6,7 8 15 1
23
+ 9 10 1 1 1 1 9 undef 1 undef 0,1,2,3,4,5,6,7,8 9 15 1
24
+ 10 10 1 1 1 1 10 undef 1 undef 0,1,2,3,4,5,6,7,8,9 10 15 1
25
+
26
+ # Over 10
27
+ 11 10 1 1 2 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 10 1
28
+ 11 10 2 1 2 11 11 1 2 undef 10 1 10 2
29
+ 12 10 1 1 2 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 10 1
30
+ 12 10 2 1 2 11 12 1 2 undef 10,11 2 10 2
31
+ 13 10 1 1 2 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 10 1
32
+ 13 10 2 1 2 11 13 1 2 undef 10,11,12 3 10 2
33
+
34
+ # Under 20
35
+ 19 10 1 1 2 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 4 1
36
+ 19 10 2 1 2 11 19 1 2 undef 10,11,12,13,14,15,16,17,18 9 4 3
37
+ 20 10 1 1 2 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 4 1
38
+ 20 10 2 1 2 11 20 1 2 undef 10,11,12,13,14,15,16,17,18,19 10 4 3
39
+
40
+ # Over 20
41
+ 21 10 1 1 3 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 19 1
42
+ 21 10 2 1 3 11 20 1 2 3 10,11,12,13,14,15,16,17,18,19 10 19 1
43
+ 21 10 3 1 3 21 21 2 3 undef 20 1 19 2
44
+ 22 10 1 1 3 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 19 1
45
+ 22 10 2 1 3 11 20 1 2 3 10,11,12,13,14,15,16,17,18,19 10 19 1
46
+ 22 10 3 1 3 21 22 2 3 undef 20,21 2 19 2
47
+ 23 10 1 1 3 1 10 undef 1 2 0,1,2,3,4,5,6,7,8,9 10 19 1
48
+ 23 10 2 1 3 11 20 1 2 3 10,11,12,13,14,15,16,17,18,19 10 19 1
49
+ 23 10 3 1 3 21 23 2 3 undef 20,21,22 3 19 2
50
+
51
+ # Zero test
52
+ 0 10 1 1 1 0 0 undef 1 undef '' 0 5 1
53
+ "
54
+ lines = text.split("\n");
55
+ lines.each do |line|
56
+ next if line.length == 0
57
+ if line.match(/^# ?(.+)/)
58
+ name = $1
59
+ # puts "name is #{name}"
60
+ next
61
+ end
62
+ # puts "[#{line}]"
63
+ vals = line.split(/\s+/).collect! {|x|
64
+ if x.match(/^undef$/)
65
+ nil
66
+ elsif x.match(/^''$/)
67
+ ''
68
+ elsif x.match(/^\d+$/)
69
+ x.to_i
70
+ else
71
+ x
72
+ end
73
+ }
74
+ # puts vals.inspect
75
+ oldpage = Data::Page.new(vals[0].to_i, vals[1].to_i, vals[2].to_i)
76
+ self._check(oldpage, name, vals);
77
+ newpage = Data::Page.new()
78
+ newpage.total_entries(vals[0].to_i)
79
+ newpage.entries_per_page(vals[1].to_i)
80
+ newpage.current_page(vals[2].to_i)
81
+ self._check(newpage, name, vals);
82
+ end
83
+ page = Data::Page.new(100, 10, 1)
84
+ assert_equal(page.total_entries, 100)
85
+ assert_equal(page.entries_per_page, 10)
86
+ assert_equal(page.current_page, 1)
87
+ assert_equal(page.first_page, 1)
88
+ assert_equal(page.last_page, 10)
89
+ assert_equal(page.first, 1)
90
+ assert_equal(page.last, 10)
91
+ assert_equal(page.previous_page, nil)
92
+ assert_equal(page.next_page, 2)
93
+ assert_equal(page.splice([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]), [1,2,3,4,5,6,7,8,9,10])
94
+ assert_equal(page.skipped, 0)
95
+ assert_equal(page.entries_on_this_page, 10)
96
+ end
97
+ def _check(page, name, vals)
98
+ # puts "check #{page.total_entries} total_entries, #{page.entries_per_page} entries_per_page, #{page.current_page} current_page"
99
+ assert_instance_of(Data::Page, page)
100
+ assert_equal(page.first_page, vals[3])
101
+ assert_equal(page.last_page, vals[4])
102
+ assert_equal(page.first, vals[5])
103
+ assert_equal(page.last, vals[6])
104
+ assert_equal(page.previous_page, vals[7])
105
+ assert_equal(page.current_page, vals[8])
106
+ assert_equal(page.next_page, vals[9])
107
+
108
+ integers = (0..vals[0]-1).to_a
109
+ integers = page.splice(integers)
110
+ integers = integers.join(',')
111
+ assert_equal(integers, vals[10].to_s)
112
+
113
+ assert_equal( page.entries_on_this_page, vals[11])
114
+
115
+ skipped = vals[5] - 1
116
+ skipped = 0 if skipped < 0
117
+ assert_equal(page.skipped, skipped );
118
+ page.change_entries_per_page( vals[12] );
119
+ assert_equal( page.current_page, vals[13] );
120
+ end
121
+ end
122
+
123
+
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: datapage
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Leon Brocard
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-25 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Data::Page helps when paging through sets of results
36
+ email:
37
+ - acme@astray.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - ChangeLog
46
+ - README.rd
47
+ - Rakefile
48
+ - datapage.gemspec
49
+ - lib/datapage.rb
50
+ - test/simple.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/acme/ruby-data-page/
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --charset=UTF-8
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 23
75
+ segments:
76
+ - 1
77
+ - 3
78
+ - 6
79
+ version: 1.3.6
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Data::Page helps when paging through sets of results
87
+ test_files: []
88
+