jchris-couchrest 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|