Class: Aws::Record::BuildableSearch

Inherits:
Object
  • Object
show all
Defined in:
lib/aws-record/record/buildable_search.rb

Constant Summary collapse

SUPPORTED_OPERATIONS =
%i[query scan].freeze

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ BuildableSearch

This should never be called directly, rather it is called by the #build_query or #build_scan methods of your aws-record model class.

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/aws-record/record/buildable_search.rb', line 10

def initialize(opts)
  operation = opts[:operation]
  model = opts[:model]
  raise ArgumentError, "Unsupported operation: #{operation}" unless SUPPORTED_OPERATIONS.include?(operation)

  @operation = operation

  @model = model
  @params = {}
  @next_name = 'BUILDERA'
  @next_value = 'buildera'
end

Instance Method Details

#complete!Aws::Record::ItemCollection

You must call this method at the end of any query or scan you build.

Returns:



227
228
229
# File 'lib/aws-record/record/buildable_search.rb', line 227

def complete!
  @model.send(@operation, @params)
end

#consistent_read(b) ⇒ Object

If true, will perform your query or scan as a consistent read. If false, the query or scan is eventually consistent.



33
34
35
36
# File 'lib/aws-record/record/buildable_search.rb', line 33

def consistent_read(b)
  @params[:consistent_read] = b
  self
end

#exclusive_start_key(key) ⇒ Object

If you have an exclusive start key for your query or scan, you can provide it with this builder method. You should not use this if you are querying or scanning without a set starting point, as the ItemCollection class handles pagination automatically for you.



68
69
70
71
# File 'lib/aws-record/record/buildable_search.rb', line 68

def exclusive_start_key(key)
  @params[:exclusive_start_key] = key
  self
end

#filter_expr(statement_str, *subs) ⇒ Object

Provide a filter expression for your query or scan using a substitution expression.

Examples:

Building a simple scan:

# Example model class
class ExampleTable
  include Aws::Record
  string_attr  :uuid, hash_key: true
  integer_attr :id,   range_key: true
  string_attr  :body
end

scan = ExampleTable.build_scan.filter_expr(
  "contains(:body, ?)",
  "bacon"
).complete!


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/aws-record/record/buildable_search.rb', line 125

def filter_expr(statement_str, *subs)
  names = @params[:expression_attribute_names]
  if names.nil?
    @params[:expression_attribute_names] = {}
    names = @params[:expression_attribute_names]
  end
  values = @params[:expression_attribute_values]
  if values.nil?
    @params[:expression_attribute_values] = {}
    values = @params[:expression_attribute_values]
  end
  prepared = _key_pass(statement_str, names)
  statement = _apply_values(prepared, subs, values)
  @params[:filter_expression] = statement
  self
end

#key_expr(statement_str, *subs) ⇒ Object

Provide a key condition expression for your query using a substitution expression.

Examples:

Building a simple query with a key expression:

# Example model class
class ExampleTable
  include Aws::Record
  string_attr  :uuid, hash_key: true
  integer_attr :id,   range_key: true
  string_attr  :body
end

q = ExampleTable.build_query.key_expr(
      ":uuid = ? AND :id > ?", "smpl-uuid", 100
    ).complete!
q.to_a # You can use this like any other query result in aws-record

Raises:

  • (ArgumentError)


89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/aws-record/record/buildable_search.rb', line 89

def key_expr(statement_str, *subs)
  raise ArgumentError, 'key_expr is only supported for queries.' unless @operation == :query

  names = @params[:expression_attribute_names]
  if names.nil?
    @params[:expression_attribute_names] = {}
    names = @params[:expression_attribute_names]
  end
  values = @params[:expression_attribute_values]
  if values.nil?
    @params[:expression_attribute_values] = {}
    values = @params[:expression_attribute_values]
  end
  prepared = _key_pass(statement_str, names)
  statement = _apply_values(prepared, subs, values)
  @params[:key_condition_expression] = statement
  self
end

#limit(size) ⇒ Object

Allows you to set a page size limit on each query or scan request.



174
175
176
177
# File 'lib/aws-record/record/buildable_search.rb', line 174

def limit(size)
  @params[:limit] = size
  self
end

#multi_model_filter(proc = nil, &block) ⇒ Object

Allows you to define a callback that will determine the model class to be used for each item, allowing queries to return an ItemCollection with mixed models. The provided block must return the model class based on any logic on the raw item attributes or ‘nil` if no model applies and the item should be skipped. Note: The block only has access to raw item data so attributes must be accessed using their names as defined in the table, not as the symbols defined in the model class(s).

Examples:

Scan with heterogeneous results:

# Example model classes
class Model_A
  include Aws::Record
  set_table_name(TABLE_NAME)

  string_attr :uuid, hash_key: true
  string_attr :class_name, range_key: true

  string_attr :attr_a
end

class Model_B
  include Aws::Record
  set_table_name(TABLE_NAME)

  string_attr :uuid, hash_key: true
  string_attr :class_name, range_key: true

  string_attr :attr_b
end

# use multi_model_filter to create a query on TABLE_NAME
items = Model_A.build_scan.multi_model_filter do |raw_item_attributes|
  case raw_item_attributes['class_name']
  when "A" then Model_A
  when "B" then Model_B
  else
    nil
  end
end.complete!


218
219
220
221
# File 'lib/aws-record/record/buildable_search.rb', line 218

def multi_model_filter(proc = nil, &block)
  @params[:model_filter] = proc || block
  self
end

#on_index(index) ⇒ Object

If you are querying or scanning on an index, you can specify it with this builder method. Provide the symbol of your index as defined on your model class.



26
27
28
29
# File 'lib/aws-record/record/buildable_search.rb', line 26

def on_index(index)
  @params[:index_name] = index
  self
end

#parallel_scan(opts) ⇒ Object

For the scan operation, you can split your scan into multiple segments to be scanned in parallel. If you wish to do this, you can use this builder method to provide the :total_segments of your parallel scan and the :segment number of this scan.

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
51
# File 'lib/aws-record/record/buildable_search.rb', line 42

def parallel_scan(opts)
  raise ArgumentError, 'parallel_scan is only supported for scans' unless @operation == :scan
  unless opts[:total_segments] && opts[:segment]
    raise ArgumentError, 'Must specify :total_segments and :segment in a parallel scan.'
  end

  @params[:total_segments] = opts[:total_segments]
  @params[:segment] = opts[:segment]
  self
end

#projection_expr(statement_str) ⇒ Object

Allows you to define a projection expression for the values returned by a query or scan. See the Amazon DynamoDB Developer Guide for more details on projection expressions. You can use the symbols from your aws-record model class in a projection expression. Keys are always retrieved.

Examples:

Scan with a projection expression:

# Example model class
class ExampleTable
  include Aws::Record
  string_attr  :uuid, hash_key: true
  integer_attr :id,   range_key: true
  string_attr  :body
  map_attr     :metadata
end

scan = ExampleTable.build_scan.projection_expr(
  ":body"
).complete!


162
163
164
165
166
167
168
169
170
171
# File 'lib/aws-record/record/buildable_search.rb', line 162

def projection_expr(statement_str)
  names = @params[:expression_attribute_names]
  if names.nil?
    @params[:expression_attribute_names] = {}
    names = @params[:expression_attribute_names]
  end
  prepared = _key_pass(statement_str, names)
  @params[:projection_expression] = prepared
  self
end

#scan_ascending(b) ⇒ Object

For a query operation, you can use this to set if you query is in ascending or descending order on your range key. By default, a query is run in ascending order.

Raises:

  • (ArgumentError)


56
57
58
59
60
61
# File 'lib/aws-record/record/buildable_search.rb', line 56

def scan_ascending(b)
  raise ArgumentError, 'scan_ascending is only supported for queries.' unless @operation == :query

  @params[:scan_index_forward] = b
  self
end