class Fauna::Page

Helper for handling pagination over sets.

Given a client and a set, allows you to iterate as well as individually move page by page over a set.

Pages lazily load the contents of the page. Loading will occur when data, before, or after are first accessed for a new page. Additionally this will occur when calling page_before or page_after without calling one of the data methods first (as the first page must be checked to find the next page). Pages created by builders will unload any data from the current page. Pages will always proceed in the requested direction.

Explicit paging is done via the page_after and page_before methods. Iteration can be done via the each and reverse_each enumerators. A single page can be retrieved by passing a cursor and then accessing it's data.

Examples:

Paging over a class index

page = Page.new(client, Query.match(Query.index('items')))

Paging over a class index 5 at a time, mapping the refs to the data.value for each instance

page = Page.new(client, Query.match(Query.index('items')), size: 5) do |ref|
  select ['data', 'value'], get(ref)
end

# Same thing, but using builders instead

page = Page.new(client, Query.match(Query.index('items'))).with_params(size: 5).map do |ref|
  select ['data', 'value'], get(ref)
end

Paging over a class index, mapping refs to the data.value for each instance, filtering out odd numbers, and multiplying the value:

page = Page.new(client, Query.match(Query.index('items'))).map do |ref|
  select ['data', 'value'], get(ref)
end.filter do |value|
  equals modulo(value, 2), 0
end.map do |value|
  multiply value, 2
end

Attributes

params[R]

The configured params used for the current pagination.

Public Class Methods

new(client, set, params = {}, &lambda) click to toggle source

Creates a pagination helper for paging/iterating over a set.

client

Client to execute queries with.

set

A set query to paginate over.

params

A list of parameters to pass to paginate.

lambda

Optional lambda to map the generated paginate query with. The block will be run in a query context. An element from the current page will be passed into the block as an argument. See map for more info.

# File lib/fauna/page.rb, line 52
def initialize(client, set, params = {}, &lambda)
  @client = client
  @set = set
  @params = params.dup
  @fauna_funcs = []
  @postprocessing_map = nil

  @fauna_funcs << proc { |query| map(query, &lambda) } unless lambda.nil?

  unload_page
  @params.freeze
end

Public Instance Methods

==(other) click to toggle source

Returns true if other is a Page and contains the same configuration and data.

# File lib/fauna/page.rb, line 66
def ==(other)
  return false unless other.is_a? Page
  @populated == other.instance_variable_get(:@populated) &&
    @data == other.instance_variable_get(:@data) &&
    @before == other.instance_variable_get(:@before) &&
    @after == other.instance_variable_get(:@after) &&
    @client == other.instance_variable_get(:@client) &&
    @set == other.instance_variable_get(:@set) &&
    @params == other.instance_variable_get(:@params) &&
    @fauna_funcs == other.instance_variable_get(:@fauna_funcs) &&
    @postprocessing_map == other.instance_variable_get(:@postprocessing_map)
end
Also aliased as: eql?
eql?(other)
Alias for: ==
load!() click to toggle source

Explicitly loads data for the current page if it has not already been loaded.

Returns true if the data was just loaded and false if it was already loaded.

# File lib/fauna/page.rb, line 88
def load!
  if @populated
    false
  else
    load_page(get_page(@params))
    true
  end
end

Builders

↑ top

Public Instance Methods

filter(&lambda) click to toggle source

Returns a copy of the page with a fauna filter using the given lambda chained onto the paginate query.

The lambda will be passed into a filter function that wraps the generated paginate query. Additional collection functions may be combined by chaining them together.

The lambda will be run in a Fauna::Query.expr context, and passed an element from the current page as an argument.

Example of filtering out odd numbers from a set of numbers:

page.filter { |value| equals(modulo(value, 2), 0) }
# File lib/fauna/page.rb, line 174
def filter(&lambda)
  with_dup do |page|
    page.instance_variable_get(:@fauna_funcs) << proc { |query| filter(query, &lambda) }
  end
end
map(&lambda) click to toggle source

Returns a copy of the page with a fauna map using the given lambda chained onto the paginate query.

The lambda will be passed into a map function that wraps the generated paginate query. Additional collection functions may be combined by chaining them together.

The lambda will be run in a Fauna::Query.expr context, and passed an element from the current page as an argument.

Example of mapping a set of refs to their instances:

page.map { |ref| get ref }
# File lib/fauna/page.rb, line 157
def map(&lambda)
  with_dup do |page|
    page.instance_variable_get(:@fauna_funcs) << proc { |query| map(query, &lambda) }
  end
end
postprocessing_map(&block) click to toggle source

Returns a copy of the page with the given ruby block set.

The block will be used to map the returned data elements from the executed fauna query. Only one postprocessing map can be configured at a time.

Intended for use when the elements in a page need to be converted within ruby (ie loading into a model). Wherever the operation can be performed from within FaunaDB, map should be used instead.

The block will be passed the each element as a parameter from the data of the page currently being loaded.

Example of loading instances into your own model:

page.postprocessing_map { |instance| YourModel.load(instance) }
# File lib/fauna/page.rb, line 194
def postprocessing_map(&block)
  with_dup do |page|
    page.instance_variable_set(:@postprocessing_map, block)
  end
end
with_params(params = {}) click to toggle source

Returns a copy of the page with the given params set.

See paginate for more details.

# File lib/fauna/page.rb, line 132
def with_params(params = {})
  with_dup do |page|
    page_params = page.instance_variable_get(:@params)

    if CURSOR_KEYS.any? { |key| params.include? key }
      # Remove previous cursor
      CURSOR_KEYS.each { |key| page_params.delete key }
    end

    # Update params
    page_params.merge!(params)
  end
end

Data

↑ top

Public Instance Methods

after() click to toggle source

After cursor for the current page.

Lazily loads the page data if it has not already been loaded.

# File lib/fauna/page.rb, line 121
def after
  load!
  @after
end
before() click to toggle source

Before cursor for the current page.

Lazily loads the page data if it has not already been loaded.

# File lib/fauna/page.rb, line 112
def before
  load!
  @before
end
data() click to toggle source

Data contained within the current page.

Lazily loads the page data if it has not already been loaded.

# File lib/fauna/page.rb, line 103
def data
  load!
  @data
end

Pagination

↑ top

Public Instance Methods

all() click to toggle source

Returns the flattened contents of the set as an array.

Ideal for when you need the full contents of a set with a known small size. If you need to iterate over a set of large or unknown size, it is recommended to use each instead.

The set is paged in the after direction.

# File lib/fauna/page.rb, line 265
def all
  each.flat_map { |x| x }
end
each() { |data| ... } click to toggle source

Returns an enumerator that iterates in the after direction.

When a block is provided, the return of the block will always be nil (to avoid loading large sets into memory).

# File lib/fauna/page.rb, line 224
def each
  return enum_for(:each) unless block_given?

  # Return current page
  yield data

  # Begin returning pages after
  page = self.page_after
  until page.nil?
    yield page.data
    page = page.page_after
  end
end
foreach!(&lambda) click to toggle source

Iterates over the entire set, applying the configured lambda in a foreach block, and discarding the result.

Ideal for performing a foreach over an entire set (like deleting all instances in a set). The set is iterated in the after direction. The foreach will be chained on top of any previously configured collection functions.

Example of deleting every instance in a set:

page.foreach! { |ref| delete ref }
# File lib/fauna/page.rb, line 278
def foreach!(&lambda)
  # Create new page with foreach block
  iter_page = with_dup do |page|
    page.instance_variable_get(:@fauna_funcs) << proc { |query| foreach(query, &lambda) }
  end

  # Apply to all pages in the set
  until iter_page.nil?
    iter_page.load!
    iter_page = iter_page.page_after
  end
  nil
end
page_after() click to toggle source

The page after the current one in the set.

Returns nil when there are no more pages after the current page. Lazily loads the current page if it has not already been loaded in order to determine the page after.

# File lib/fauna/page.rb, line 207
def page_after
  new_page(:after)
end
page_before() click to toggle source

The page before the current one in the set.

Returns nil when there are no more pages before the current page. Lazily loads the current page if it has not already been loaded in order to determine the page before.

# File lib/fauna/page.rb, line 216
def page_before
  new_page(:before)
end
reverse_each() { |data| ... } click to toggle source

Returns an enumerator that iterates in the before direction.

When a block is provided, the return of the block will always be nil (to avoid loading large sets into memory).

While the paging will occur in the reverse direction, the data returned will still be in the normal direction.

# File lib/fauna/page.rb, line 244
def reverse_each
  return enum_for(:reverse_each) unless block_given?

  # Return current page
  yield data

  # Begin returning pages before
  page = self.page_before
  until page.nil?
    yield page.data
    page = page.page_before
  end
end