Class: Fauna::Page
- Inherits:
-
Object
- Object
- Fauna::Page
- Defined in:
- lib/fauna/page.rb
Overview
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(Ref('indexes/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(Ref('indexes/items')), size: 5) do |ref|
select ['data', 'value'], get(ref)
end
# Same thing, but using builders instead
page = Page.new(client, Query.match(Ref('indexes/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(Ref('indexes/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
Instance Attribute Summary collapse
-
#params ⇒ Object
readonly
The configured params used for the current pagination.
Instance Method Summary collapse
-
#==(other) ⇒ Object
(also: #eql?)
Returns
true
ifother
is a Page and contains the same configuration and data. -
#after ⇒ Object
After cursor for the current page.
-
#all ⇒ Object
Returns the flattened contents of the set as an array.
-
#before ⇒ Object
Before cursor for the current page.
-
#data ⇒ Object
Data contained within the current page.
-
#dup ⇒ Object
:nodoc:.
-
#each {|data| ... } ⇒ Object
Returns an enumerator that iterates in the
after
direction. -
#filter(&lambda) ⇒ Object
Returns a copy of the page with a fauna
filter
using the given lambda chained onto the paginate query. -
#foreach!(&lambda) ⇒ Object
Iterates over the entire set, applying the configured lambda in a foreach block, and discarding the result.
-
#initialize(client, set, params = {}, &lambda) ⇒ Page
constructor
Creates a pagination helper for paging/iterating over a set.
-
#load! ⇒ Object
Explicitly loads data for the current page if it has not already been loaded.
-
#map(&lambda) ⇒ Object
Returns a copy of the page with a fauna
map
using the given lambda chained onto the paginate query. -
#page_after ⇒ Object
The page after the current one in the set.
-
#page_before ⇒ Object
The page before the current one in the set.
-
#postprocessing_map(&block) ⇒ Object
Returns a copy of the page with the given ruby block set.
-
#reverse_each {|data| ... } ⇒ Object
Returns an enumerator that iterates in the
before
direction. -
#with_params(params = {}) ⇒ Object
Returns a copy of the page with the given
params
set.
Constructor Details
#initialize(client, set, params = {}, &lambda) ⇒ Page
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.
52 53 54 55 56 57 58 59 60 61 62 63 |
# 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 |
Instance Attribute Details
#params ⇒ Object (readonly)
The configured params used for the current pagination.
82 83 84 |
# File 'lib/fauna/page.rb', line 82 def params @params end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
Returns true
if other
is a Page and contains the same configuration and data.
66 67 68 69 70 71 72 73 74 75 76 77 |
# 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 |
#after ⇒ Object
After cursor for the current page.
Lazily loads the page data if it has not already been loaded.
121 122 123 124 |
# File 'lib/fauna/page.rb', line 121 def after load! @after end |
#all ⇒ Object
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.
265 266 267 |
# File 'lib/fauna/page.rb', line 265 def all each.flat_map { |x| x } end |
#before ⇒ Object
Before cursor for the current page.
Lazily loads the page data if it has not already been loaded.
112 113 114 115 |
# File 'lib/fauna/page.rb', line 112 def before load! @before end |
#data ⇒ Object
Data contained within the current page.
Lazily loads the page data if it has not already been loaded.
103 104 105 106 |
# File 'lib/fauna/page.rb', line 103 def data load! @data end |
#dup ⇒ Object
:nodoc:
292 293 294 295 296 297 |
# File 'lib/fauna/page.rb', line 292 def dup # :nodoc: page = super page.instance_variable_set(:@params, @params.dup) page.instance_variable_set(:@fauna_funcs, @fauna_funcs.dup) page end |
#each {|data| ... } ⇒ Object
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).
224 225 226 227 228 229 230 231 232 233 234 235 236 |
# 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 |
#filter(&lambda) ⇒ Object
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 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) }
174 175 176 177 178 |
# 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 |
#foreach!(&lambda) ⇒ Object
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 }
278 279 280 281 282 283 284 285 286 287 288 289 290 |
# 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 |
#load! ⇒ Object
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.
88 89 90 91 92 93 94 95 |
# File 'lib/fauna/page.rb', line 88 def load! if @populated false else load_page(get_page(@params)) true end end |
#map(&lambda) ⇒ Object
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 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 }
157 158 159 160 161 |
# 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 |
#page_after ⇒ Object
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.
207 208 209 |
# File 'lib/fauna/page.rb', line 207 def page_after new_page(:after) end |
#page_before ⇒ Object
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.
216 217 218 |
# File 'lib/fauna/page.rb', line 216 def page_before new_page(:before) end |
#postprocessing_map(&block) ⇒ Object
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) }
194 195 196 197 198 |
# File 'lib/fauna/page.rb', line 194 def postprocessing_map(&block) with_dup do |page| page.instance_variable_set(:@postprocessing_map, block) end end |
#reverse_each {|data| ... } ⇒ Object
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.
244 245 246 247 248 249 250 251 252 253 254 255 256 |
# 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 |
#with_params(params = {}) ⇒ Object
Returns a copy of the page with the given params
set.
See paginate for more details.
132 133 134 135 136 137 138 139 140 141 142 143 144 |
# 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 |