Commit e2f7f32a authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre Committed by Stan Hu
Browse files

Add support for Bitbucket pagination when fetching collections

parent 8ac128bf600a
module Bitbucket
class Collection < Enumerator
def initialize(paginator)
super() do |yielder|
loop do
paginator.next.each { |item| yielder << item }
end
end
lazy
end
def method_missing(method, *args)
return super unless self.respond_to?(method)
self.send(method, *args) do |item|
block_given? ? yield(item) : item
end
end
end
end
module Bitbucket
class Page
attr_reader :attrs, :items
def initialize(raw, type)
@attrs = parse_attrs(raw)
@items = parse_values(raw, representation_class(type))
end
def next?
attrs.fetch(:next, false)
end
def next
attrs.fetch(:next)
end
private
def parse_attrs(raw)
attrs = %w(size page pagelen next previous)
attrs.map { |attr| { attr.to_sym => raw[attr] } }.reduce(&:merge)
end
def parse_values(raw, representation_class)
return [] if raw['values'].nil? || !raw['values'].is_a?(Array)
raw['values'].map { |hash| representation_class.new(hash) }
end
def representation_class(type)
class_name = "Bitbucket::Representation::#{type.to_s.camelize}"
class_name.constantize
end
end
end
module Bitbucket
class Paginator
PAGE_LENGTH = 50 # The minimum length is 10 and the maximum is 100.
def initialize(connection, url, type)
@connection = connection
@type = type
@url = url
@page = nil
connection.query(pagelen: PAGE_LENGTH, sort: :created_on)
end
def next
raise StopIteration unless has_next_page?
@page = fetch_next_page
@page.items
end
private
attr_reader :connection, :page, :url, :type
def has_next_page?
page.nil? || page.next?
end
def page_url
page.nil? ? url : page.next
end
def fetch_next_page
parsed_response = connection.get(page_url)
Page.new(parsed_response, type)
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment