class Gapic::PagedEnumerable
A class to provide the Enumerable interface to the response of a paginated method. PagedEnumerable
assumes response message holds a list of resources and the token to the next page.
PagedEnumerable
provides the enumerations over the resource data, and also provides the enumerations over the pages themselves.
@example normal iteration over resources.
paged_enumerable.each { |resource| puts resource }
@example per-page iteration.
paged_enumerable.each_page { |page| puts page }
@example Enumerable over pages.
paged_enumerable.each_page do |page| page.each { |resource| puts resource } end
@example more exact operations over pages.
while some_condition() page = paged_enumerable.page do_something(page) break if paged_enumerable.next_page? paged_enumerable.next_page end
Attributes
@attribute [r] page
@return [Page] The current page object.
Public Class Methods
@private @param grpc_stub [Gapic::GRPC::Stub] The Gapic
gRPC stub object. @param method_name [Symbol] The RPC method name. @param request [Object] The request object. @param response [Object] The response object. @param operation [::GRPC::ActiveCall::Operation] The RPC operation for the response. @param options [Gapic::CallOptions] The options for making the RPC call. @param format_resource [Proc] A Proc object to format the resource object. The Proc should accept response as an
argument, and return a formatted resource object. Optional.
# File lib/gapic/paged_enumerable.rb, line 61 def initialize grpc_stub, method_name, request, response, operation, options, format_resource: nil @grpc_stub = grpc_stub @method_name = method_name @request = request @response = response @options = options @format_resource = format_resource @resource_field = nil # will be set in verify_response! verify_request! verify_response! @page = Page.new @response, @resource_field, operation, format_resource: @format_resource end
Public Instance Methods
Iterate over the resources.
@yield [Object] Gives the resource objects in the stream.
@raise [RuntimeError] if it's not started yet.
# File lib/gapic/paged_enumerable.rb, line 83 def each &block return enum_for :each unless block_given? each_page do |page| page.each(&block) end end
Iterate over the pages.
@yield [Page] Gives the pages in the stream.
@raise if it's not started yet.
# File lib/gapic/paged_enumerable.rb, line 98 def each_page return enum_for :each_page unless block_given? loop do break if @page.nil? yield @page next_page! end end
Update the response in the current page.
@return [Page] the new page object.
# File lib/gapic/paged_enumerable.rb, line 120 def next_page! unless next_page? @page = nil return @page end next_request = @request.dup next_request.page_token = @page.next_page_token @grpc_stub.call_rpc @method_name, next_request, options: @options do |next_response, next_operation| @page = Page.new next_response, @resource_field, next_operation, format_resource: @format_resource end @page end
True if it has the next page.
# File lib/gapic/paged_enumerable.rb, line 111 def next_page? @page.next_page_token? end
The page token to be used for the next RPC call.
@return [String]
# File lib/gapic/paged_enumerable.rb, line 140 def next_page_token @page.next_page_token end
The current response object, for the current page.
@return [Object]
# File lib/gapic/paged_enumerable.rb, line 149 def response @page.response end
Private Instance Methods
# File lib/gapic/paged_enumerable.rb, line 155 def verify_request! page_token = @request.class.descriptor.find do |f| f.name == "page_token" && f.type == :string end raise ArgumentError, "#{@request.class} must have a page_token field (String)" if page_token.nil? page_size = @request.class.descriptor.find do |f| f.name == "page_size" && [:int32, :int64].include?(f.type) end return unless page_size.nil? raise ArgumentError, "#{@request.class} must have a page_size field (Integer)" end
# File lib/gapic/paged_enumerable.rb, line 168 def verify_response! next_page_token = @response.class.descriptor.find do |f| f.name == "next_page_token" && f.type == :string end raise ArgumentError, "#{@response.class} must have a next_page_token field (String)" if next_page_token.nil? # Find all repeated FieldDescriptors on the response Descriptor fields = @response.class.descriptor.select do |f| f.label == :repeated && f.type == :message end repeated_field = fields.first raise ArgumentError, "#{@response.class} must have one repeated field" if repeated_field.nil? min_repeated_field_number = fields.map(&:number).min if min_repeated_field_number != repeated_field.number raise ArgumentError, "#{@response.class} must have one primary repeated field by both position and number" end # We have the correct repeated field, save the field's name @resource_field = repeated_field.name end