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

page[R]

@attribute [r] page

@return [Page] The current page object.

Public Class Methods

new(grpc_stub, method_name, request, response, operation, options, format_resource: nil) click to toggle source

@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

each(&block) click to toggle source

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
each_page() { |page| ... } click to toggle source

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
next_page()
Alias for: next_page!
next_page!() click to toggle source

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
Also aliased as: next_page
next_page?() click to toggle source

True if it has the next page.

# File lib/gapic/paged_enumerable.rb, line 111
def next_page?
  @page.next_page_token?
end
next_page_token() click to toggle source

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
response() click to toggle source

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

verify_request!() click to toggle source
# 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
verify_response!() click to toggle source
# 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