jchris-couchrest 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/pager.rb +89 -0
- data/spec/pager_spec.rb +94 -0
- data/spec/spec_helper.rb +4 -0
- metadata +4 -1
data/lib/pager.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# paginate though 'gcharts/mp3-trk-dom-map' view and save
|
2
|
+
|
3
|
+
# get 1000 records
|
4
|
+
# truncate so that the key of the last record is not included in the page
|
5
|
+
# that key will be the first of the next page
|
6
|
+
# (if the last key equals the first key, up the page size)
|
7
|
+
# group the results by key
|
8
|
+
# yield the group
|
9
|
+
|
10
|
+
require File.dirname(__FILE__) + '/couchrest'
|
11
|
+
|
12
|
+
module Enumerable
|
13
|
+
def group_by
|
14
|
+
inject({}) do |grouped, element|
|
15
|
+
(grouped[yield(element)] ||= []) << element
|
16
|
+
grouped
|
17
|
+
end
|
18
|
+
end unless [].respond_to?(:group_by)
|
19
|
+
end
|
20
|
+
|
21
|
+
class CouchRest
|
22
|
+
class Pager
|
23
|
+
attr_accessor :db
|
24
|
+
def initialize db
|
25
|
+
@db = db
|
26
|
+
end
|
27
|
+
|
28
|
+
def key_reduce(view, count, firstkey = nil, lastkey = nil, &block)
|
29
|
+
# start with no keys
|
30
|
+
startkey = firstkey
|
31
|
+
# lastprocessedkey = nil
|
32
|
+
keepgoing = true
|
33
|
+
|
34
|
+
while keepgoing && viewrows = request_view(view, count, startkey)
|
35
|
+
startkey = viewrows.first['key']
|
36
|
+
endkey = viewrows.last['key']
|
37
|
+
|
38
|
+
if (startkey == endkey)
|
39
|
+
# we need to rerequest to get a bigger page
|
40
|
+
# so we know we have all the rows for that key
|
41
|
+
viewrows = @db.view(view, :key => startkey)['rows']
|
42
|
+
# we need to do an offset thing to find the next startkey
|
43
|
+
# otherwise we just get stuck
|
44
|
+
lastdocid = viewrows.last['id']
|
45
|
+
fornextloop = @db.view(view, :startkey => startkey, :startkey_docid => lastdocid, :count => 2)['rows']
|
46
|
+
|
47
|
+
newendkey = fornextloop.last['key']
|
48
|
+
if (newendkey == endkey)
|
49
|
+
keepgoing = false
|
50
|
+
else
|
51
|
+
startkey = newendkey
|
52
|
+
end
|
53
|
+
rows = viewrows
|
54
|
+
else
|
55
|
+
rows = []
|
56
|
+
for r in viewrows
|
57
|
+
if (lastkey && r['key'] == lastkey)
|
58
|
+
keepgoing = false
|
59
|
+
break
|
60
|
+
end
|
61
|
+
break if (r['key'] == endkey)
|
62
|
+
rows << r
|
63
|
+
end
|
64
|
+
startkey = endkey
|
65
|
+
end
|
66
|
+
|
67
|
+
grouped = rows.group_by{|r|r['key']}
|
68
|
+
grouped.each do |k, rs|
|
69
|
+
vs = rs.collect{|r|r['value']}
|
70
|
+
yield(k,vs)
|
71
|
+
end
|
72
|
+
|
73
|
+
# lastprocessedkey = rows.last['key']
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def request_view view, count = nil, startkey = nil, endkey = nil
|
78
|
+
opts = {}
|
79
|
+
opts[:count] = count if count
|
80
|
+
opts[:startkey] = startkey if startkey
|
81
|
+
opts[:endkey] = endkey if endkey
|
82
|
+
|
83
|
+
results = @db.view(view, opts)
|
84
|
+
rows = results['rows']
|
85
|
+
rows unless rows.length == 0
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/spec/pager_spec.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe CouchRest::Pager do
|
4
|
+
before(:all) do
|
5
|
+
@cr = CouchRest.new(COUCHHOST)
|
6
|
+
begin
|
7
|
+
@cr.database(TESTDB).delete!
|
8
|
+
rescue RestClient::Request::RequestFailed
|
9
|
+
end
|
10
|
+
begin
|
11
|
+
@db = @cr.create_db(TESTDB)
|
12
|
+
rescue RestClient::Request::RequestFailed
|
13
|
+
end
|
14
|
+
@pager = CouchRest::Pager.new(@db)
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:all) do
|
18
|
+
begin
|
19
|
+
@db.delete!
|
20
|
+
rescue RestClient::Request::RequestFailed
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should store the db" do
|
25
|
+
@pager.db.should == @db
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "Pager with a view and docs" do
|
29
|
+
before(:all) do
|
30
|
+
@docs = []
|
31
|
+
100.times do |i|
|
32
|
+
@docs << ({:number => (i % 10)})
|
33
|
+
end
|
34
|
+
@db.bulk_save(@docs)
|
35
|
+
@db.save({
|
36
|
+
'_id' => '_design/magic',
|
37
|
+
'views' => {
|
38
|
+
'number' => {
|
39
|
+
'map' => 'function(doc){emit(doc.number,null)}'
|
40
|
+
}
|
41
|
+
}
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have docs" do
|
46
|
+
@docs.length.should == 100
|
47
|
+
@db.documents['rows'].length.should == 101
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a view" do
|
51
|
+
@db.view('magic/number', :count => 10)['rows'][0]['key'].should == 0
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should yield once per key" do
|
55
|
+
results = {}
|
56
|
+
@pager.key_reduce('magic/number', 20) do |k,vs|
|
57
|
+
results[k] = vs.length
|
58
|
+
end
|
59
|
+
results[0].should == 10
|
60
|
+
results[3].should == 10
|
61
|
+
end
|
62
|
+
|
63
|
+
it "with a small step size should yield once per key" do
|
64
|
+
results = {}
|
65
|
+
@pager.key_reduce('magic/number', 7) do |k,vs|
|
66
|
+
results[k] = vs.length
|
67
|
+
end
|
68
|
+
results[0].should == 10
|
69
|
+
results[3].should == 10
|
70
|
+
results[9].should == 10
|
71
|
+
end
|
72
|
+
it "with a large step size should yield once per key" do
|
73
|
+
results = {}
|
74
|
+
@pager.key_reduce('magic/number', 1000) do |k,vs|
|
75
|
+
results[k] = vs.length
|
76
|
+
end
|
77
|
+
results[0].should == 10
|
78
|
+
results[3].should == 10
|
79
|
+
results[9].should == 10
|
80
|
+
end
|
81
|
+
it "with a begin and end should only yield in the range (and leave out the lastkey)" do
|
82
|
+
results = {}
|
83
|
+
@pager.key_reduce('magic/number', 1000, 4, 7) do |k,vs|
|
84
|
+
results[k] = vs.length
|
85
|
+
end
|
86
|
+
results[0].should be_nil
|
87
|
+
results[4].should == 10
|
88
|
+
results[6].should == 10
|
89
|
+
results[7].should be_nil
|
90
|
+
results[8].should be_nil
|
91
|
+
results[9].should be_nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jchris-couchrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- J. Chris Anderson
|
@@ -41,12 +41,15 @@ extra_rdoc_files: []
|
|
41
41
|
files:
|
42
42
|
- lib/couchrest.rb
|
43
43
|
- lib/database.rb
|
44
|
+
- lib/pager.rb
|
44
45
|
- Rakefile
|
45
46
|
- README
|
46
47
|
- script/couchdir
|
47
48
|
- script/couchview
|
48
49
|
- spec/couchrest_spec.rb
|
49
50
|
- spec/database_spec.rb
|
51
|
+
- spec/pager_spec.rb
|
52
|
+
- spec/spec_helper.rb
|
50
53
|
has_rdoc: false
|
51
54
|
homepage: http://github.com/jchris/couchrest
|
52
55
|
post_install_message:
|