Class: Dynomite::Item::Query::Params

Inherits:
Object
  • Object
show all
Extended by:
Memoist
Includes:
Helpers, Types
Defined in:
lib/dynomite/item/query/params.rb,
lib/dynomite/item/query/params/base.rb,
lib/dynomite/item/query/params/filter.rb,
lib/dynomite/item/query/params/helpers.rb,
lib/dynomite/item/query/params/key_condition.rb,
lib/dynomite/item/query/params/expression_attribute.rb

Defined Under Namespace

Modules: Function, Helpers Classes: Base, ExpressionAttribute, Filter, KeyCondition

Constant Summary

Constants included from Types

Types::TYPE_MAP

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#all_where_field_names, #all_where_fields, #disable_index_for_any_or?, #disable_index_for_consistent_read?, #disable_index_for_not?, #normalize_expression_path, #normalize_project_expression, #query, #scan_required?, #with_where_groups

Methods included from Types

#type_map

Constructor Details

#initialize(relation, source) ⇒ Params

Returns a new instance of Params.



10
11
12
13
# File 'lib/dynomite/item/query/params.rb', line 10

def initialize(relation, source)
  @relation, @source = relation, source
  @query = relation.query
end

Instance Attribute Details

#sourceObject (readonly)

Returns the value of attribute source.



7
8
9
# File 'lib/dynomite/item/query/params.rb', line 7

def source
  @source
end

Instance Method Details

#build_attributesObject



91
92
93
94
95
# File 'lib/dynomite/item/query/params.rb', line 91

def build_attributes
  expression_attribute = ExpressionAttribute.new(@relation)
  @expression_attribute_names = expression_attribute.names
  @expression_attribute_values = expression_attribute.values
end

#build_filter_expressionObject



86
87
88
89
# File 'lib/dynomite/item/query/params.rb', line 86

def build_filter_expression
  filter = Filter.new(@relation, @index)
  @filter_expression = filter.expression
end

#build_key_condition_expressionObject

key_condition_expression is the most restrictive way to query. It requires the primary key and sort key. It also requires either the primary key or an index. Otherwise, we do not set it at all.

So we’ll build this first and then add the other expressions to it.

key condition

  1. primary key highest precedence

  2. index

  3. track fields used



81
82
83
84
# File 'lib/dynomite/item/query/params.rb', line 81

def build_key_condition_expression
  key_condition = KeyCondition.new(@relation, @index, partition_key_field, sort_key_field)
  @key_condition_expression = key_condition.expression
end

#index_finderObject



110
111
112
# File 'lib/dynomite/item/query/params.rb', line 110

def index_finder
  Dynomite::Item::Indexes::Finder.new(@source, @query)
end

#log_index_infoObject



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/dynomite/item/query/params.rb', line 97

def log_index_info
  return unless ENV['DYNOMITE_DEBUG']

  if @index
    Dynomite.logger.info "Index used #{@index.index_name}"
  elsif @params[:@expression_attribute_names]
    attributes_list = @params[:@expression_attribute_names].values.join(", ")
    Dynomite.logger.info "Not using index. None found for the attributes: #{attributes_list}"
  else
    Dynomite.logger.info "Not using index. @params #{@params.inspect}"
  end
end

#projection_expressionObject



62
63
64
65
66
67
68
# File 'lib/dynomite/item/query/params.rb', line 62

def projection_expression
  return if @query[:projection_expression].nil?
  projection_expression = normalize_project_expression(@query[:projection_expression])
  projection_expression.map do |field|
    '#'+field
  end.join(", ")
end

#to_hObject

key condition

  1. primary key highest precedence

  2. index

filter expression

  1. if field used in key condition

  2. then don’t use in filter expression

attributes

  1. all values will be mapped over

  2. will be in key condition or filter expression

index name

  1. if key condition set

  2. unless primary key



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dynomite/item/query/params.rb', line 27

def to_h
  # set @index first. used throughout class
  @index = index_finder.find(@query[:index_name])
  @index = nil if scan_required?(@index) # IE: NOT operator on where field

  # must build in this order
  build_key_condition_expression if @index # must build first
  build_filter_expression
  build_attributes                         # must build last

  @params = {
    expression_attribute_names: @expression_attribute_names,    # both scan and query
    expression_attribute_values: @expression_attribute_values,  # both scan and query
    table_name: table_name,
  }

  @params[:filter_expression] = @filter_expression # both scan and query
  @params[:key_condition_expression] = @key_condition_expression # query only. required

  # primary index does not have a name but they are added to the @key_condition_expression
  @params[:index_name] = @index.index_name if @index && !@index.primary? # both scan and query can use index

  @params.reject! { |k,v| v.blank? }

  # scan_index_forward after reject! so it's not removed
  @params[:scan_index_forward] = !!@query[:scan_index_forward] if @query.key?(:scan_index_forward)
  @params[:limit] = @query[:limit] if @query.key?(:limit)
  @params[:projection_expression] = projection_expression if projection_expression
  @params[:consistent_read] = @query[:consistent_read] if @query.key?(:consistent_read)
  @params[:exclusive_start_key] = @query[:exclusive_start_key] if @query.key?(:exclusive_start_key)

  log_index_info
  @params
end