Class: Dynomite::Item::Query::Relation
- Inherits:
-
Object
- Object
- Dynomite::Item::Query::Relation
- Extended by:
- Memoist
- Defined in:
- lib/dynomite/item/query/relation.rb,
lib/dynomite/item/query/relation/ids.rb,
lib/dynomite/item/query/relation/math.rb,
lib/dynomite/item/query/relation/chain.rb,
lib/dynomite/item/query/relation/delete.rb,
lib/dynomite/item/query/relation/where_field.rb,
lib/dynomite/item/query/relation/where_group.rb,
lib/dynomite/item/query/relation/comparision_map.rb,
lib/dynomite/item/query/relation/comparision_expression.rb
Overview
Builds up the query with methods like where and eventually executes Query or Scan.
Defined Under Namespace
Modules: Chain, ComparisionMap, Delete, Ids, Math Classes: ComparisionExpression, WhereField, WhereGroup
Instance Attribute Summary collapse
-
#index ⇒ Object
Returns the value of attribute index.
-
#query ⇒ Object
Returns the value of attribute query.
-
#source ⇒ Object
Returns the value of attribute source.
Instance Method Summary collapse
-
#all ⇒ Object
Allows all to chain itself.
- #build_item(i, run_callback: true) ⇒ Object
- #each(&block) ⇒ Object
-
#initialize(source) ⇒ Relation
constructor
A new instance of Relation.
-
#last ⇒ Object
Enumerable provides .first but does not provide .last Note, cannot use: scan_index_forward(false).limit(1).first Since that will not work for queries that do not have a sort key.
- #pages ⇒ Object (also: #each_page)
- #raw_pages ⇒ Object (also: #each_raw_page)
- #raw_warn_scan ⇒ Object
- #to_params ⇒ Object
Methods included from Delete
#delete_all, #delete_by, #destroy_all, #destroy_by
Methods included from Ids
#empty?, #exists?, #ids, #pluck
Methods included from Math
Methods included from Chain
#attribute_exists, #attribute_not_exists, #attribute_type, #begins_with, #consistent_read, #contains, #excluding, #exclusive_start_key, #force_scan, #index_name, #limit, #not, #or, #project, #scan_index_backward, #scan_index_forward, #size_fn, #warn_on_scan, #where
Constructor Details
#initialize(source) ⇒ Relation
Returns a new instance of Relation.
13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/dynomite/item/query/relation.rb', line 13 def initialize(source) @source = source # source is the model class. IE: Post User etc @query = { where: [], attribute_exists: [], attribute_not_exists: [], attribute_type: [], begins_with: [], contains: [], size_fn: [], } @index = 0 end |
Instance Attribute Details
#index ⇒ Object
Returns the value of attribute index.
12 13 14 |
# File 'lib/dynomite/item/query/relation.rb', line 12 def index @index end |
#query ⇒ Object
Returns the value of attribute query.
12 13 14 |
# File 'lib/dynomite/item/query/relation.rb', line 12 def query @query end |
#source ⇒ Object
Returns the value of attribute source.
12 13 14 |
# File 'lib/dynomite/item/query/relation.rb', line 12 def source @source end |
Instance Method Details
#all ⇒ Object
Allows all to chain itself. This allows.
Post.where(category: "Electronics").all
Post.limit(1).all
Post.all.all # also works, side effect
112 113 114 |
# File 'lib/dynomite/item/query/relation.rb', line 112 def all self end |
#build_item(i, run_callback: true) ⇒ Object
82 83 84 85 86 87 |
# File 'lib/dynomite/item/query/relation.rb', line 82 def build_item(i, run_callback: true) item = @source.new(i) # IE: Post.new(i) item.new_record = false item.run_callbacks :find if run_callback item end |
#each(&block) ⇒ Object
35 36 37 |
# File 'lib/dynomite/item/query/relation.rb', line 35 def each(&block) items.each(&block) end |
#last ⇒ Object
Enumerable provides .first but does not provide .last Note, cannot use:
scan_index_forward(false).limit(1).first
Since that will not work for queries that do not have a sort key. Users need to use query directly if they want to find the last item more efficiently.
94 95 96 97 98 99 100 |
# File 'lib/dynomite/item/query/relation.rb', line 94 def last warn_scan <<~EOL WARN: Dynomite::Item::Query::Relation#last is slow. Consider using query directly if you have a primary key that as a sort key. EOL to_a.last # force load of lazy enumerator. slow end |
#pages ⇒ Object Also known as: each_page
44 45 46 47 48 |
# File 'lib/dynomite/item/query/relation.rb', line 44 def pages raw_pages.map do |raw_page| raw_page.items.map.map(&method(:build_item)) end end |
#raw_pages ⇒ Object Also known as: each_raw_page
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/dynomite/item/query/relation.rb', line 51 def raw_pages params = to_params # total_limit is the total limit across all pages # For the AWS API call itself use the default limit and allow AWS to scan 1MB for page total_limit = params.delete(:limit) total_count = 0 Enumerator.new do |y| last_evaluated_key = :start while last_evaluated_key if last_evaluated_key && last_evaluated_key != :start params[:exclusive_start_key] = last_evaluated_key end meth = params[:key_condition_expression] ? :query : :scan log_debug(params) raw_warn_scan if meth == :scan response = client.send(meth, params) # scan or query records = response.items.map { |i| build_item(i, run_callback: false) } y.yield(response, records) # Track total_count across pages. If limit is set, then stop when we reach it. # Since limit can be greater than each API response paged size. total_count += response.items.size break if total_limit && total_count >= total_limit last_evaluated_key = response.last_evaluated_key end end.lazy end |
#raw_warn_scan ⇒ Object
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/dynomite/item/query/relation.rb', line 116 def raw_warn_scan warn_on_scan = @warn_on_scan.nil? ? Dynomite.config.warn_on_scan : @warn_on_scan return unless warn_on_scan warn_scan <<~EOL WARN: Scanning detected. It's recommended to not use scan. It can be slow. Scanning table: #{@source.table_name} Try creating a LSI or GSI index so dynomite can use query instead. Docs: https://v5.docs.rubyonjets.com/docs/database/dynamodb/indexing/ EOL end |