couchrest_model/lib/couchrest/helper/pager.rb

103 lines
2.7 KiB
Ruby
Raw Normal View History

2008-09-12 06:14:34 +02:00
module CouchRest
2008-09-12 06:09:39 +02:00
class Pager
attr_accessor :db
def initialize db
@db = db
end
2009-01-05 06:00:36 +01:00
def all_docs(limit=100, &block)
2008-09-12 06:09:39 +02:00
startkey = nil
oldend = nil
2009-01-05 06:00:36 +01:00
while docrows = request_all_docs(limit+1, startkey)
2008-09-12 06:09:39 +02:00
startkey = docrows.last['key']
2009-01-05 06:00:36 +01:00
docrows.pop if docrows.length > limit
2008-09-12 06:09:39 +02:00
if oldend == startkey
break
end
yield(docrows)
oldend = startkey
end
end
2009-01-05 06:00:36 +01:00
def key_reduce(view, limit=2000, firstkey = nil, lastkey = nil, &block)
2008-09-12 06:09:39 +02:00
# start with no keys
startkey = firstkey
# lastprocessedkey = nil
keepgoing = true
2009-01-05 06:00:36 +01:00
while keepgoing && viewrows = request_view(view, limit, startkey)
2008-09-12 06:09:39 +02:00
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']
2009-01-05 06:00:36 +01:00
fornextloop = @db.view(view, :startkey => startkey, :startkey_docid => lastdocid, :limit => 2)['rows']
2008-09-12 06:09:39 +02:00
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
key = :begin
values = []
rows.each do |r|
if key != r['key']
# we're on a new key, yield the old first and then reset
yield(key, values) if key != :begin
key = r['key']
values = []
end
# keep accumulating
values << r['value']
end
yield(key, values)
end
end
private
2009-01-05 06:00:36 +01:00
def request_all_docs limit, startkey = nil
2008-09-12 06:09:39 +02:00
opts = {}
2009-01-05 06:00:36 +01:00
opts[:limit] = limit if limit
2008-09-12 06:09:39 +02:00
opts[:startkey] = startkey if startkey
results = @db.documents(opts)
rows = results['rows']
rows unless rows.length == 0
end
2009-01-05 06:00:36 +01:00
def request_view view, limit = nil, startkey = nil, endkey = nil
2008-09-12 06:09:39 +02:00
opts = {}
2009-01-05 06:00:36 +01:00
opts[:limit] = limit if limit
2008-09-12 06:09:39 +02:00
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