CouchRest::Pager for paging through views
This commit is contained in:
parent
915905ca13
commit
d2de19022e
3 changed files with 187 additions and 0 deletions
89
lib/pager.rb
Normal file
89
lib/pager.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# paginate though 'gcharts/mp3-trk-dom-map' view and save
|
||||
|
||||
# get 1000 records
|
||||
# truncate so that the key of the last record is not included in the page
|
||||
# that key will be the first of the next page
|
||||
# (if the last key equals the first key, up the page size)
|
||||
# group the results by key
|
||||
# yield the group
|
||||
|
||||
require File.dirname(__FILE__) + '/couchrest'
|
||||
|
||||
module Enumerable
|
||||
def group_by
|
||||
inject({}) do |grouped, element|
|
||||
(grouped[yield(element)] ||= []) << element
|
||||
grouped
|
||||
end
|
||||
end unless [].respond_to?(:group_by)
|
||||
end
|
||||
|
||||
class CouchRest
|
||||
class Pager
|
||||
attr_accessor :db
|
||||
def initialize db
|
||||
@db = db
|
||||
end
|
||||
|
||||
def key_reduce(view, count, firstkey = nil, lastkey = nil, &block)
|
||||
# start with no keys
|
||||
startkey = firstkey
|
||||
# lastprocessedkey = nil
|
||||
keepgoing = true
|
||||
|
||||
while keepgoing && viewrows = request_view(view, count, startkey)
|
||||
startkey = viewrows.first['key']
|
||||
endkey = viewrows.last['key']
|
||||
|
||||
if (startkey == endkey)
|
||||
# we need to rerequest to get a bigger page
|
||||
# so we know we have all the rows for that key
|
||||
viewrows = @db.view(view, :key => startkey)['rows']
|
||||
# we need to do an offset thing to find the next startkey
|
||||
# otherwise we just get stuck
|
||||
lastdocid = viewrows.last['id']
|
||||
fornextloop = @db.view(view, :startkey => startkey, :startkey_docid => lastdocid, :count => 2)['rows']
|
||||
|
||||
newendkey = fornextloop.last['key']
|
||||
if (newendkey == endkey)
|
||||
keepgoing = false
|
||||
else
|
||||
startkey = newendkey
|
||||
end
|
||||
rows = viewrows
|
||||
else
|
||||
rows = []
|
||||
for r in viewrows
|
||||
if (lastkey && r['key'] == lastkey)
|
||||
keepgoing = false
|
||||
break
|
||||
end
|
||||
break if (r['key'] == endkey)
|
||||
rows << r
|
||||
end
|
||||
startkey = endkey
|
||||
end
|
||||
|
||||
grouped = rows.group_by{|r|r['key']}
|
||||
grouped.each do |k, rs|
|
||||
vs = rs.collect{|r|r['value']}
|
||||
yield(k,vs)
|
||||
end
|
||||
|
||||
# lastprocessedkey = rows.last['key']
|
||||
end
|
||||
end
|
||||
|
||||
def request_view view, count = nil, startkey = nil, endkey = nil
|
||||
opts = {}
|
||||
opts[:count] = count if count
|
||||
opts[:startkey] = startkey if startkey
|
||||
opts[:endkey] = endkey if endkey
|
||||
|
||||
results = @db.view(view, opts)
|
||||
rows = results['rows']
|
||||
rows unless rows.length == 0
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue