Class: ROM::DynamoDB::Dataset

Inherits:
Object
  • Object
show all
Defined in:
lib/rom/dynamodb/dataset.rb,
lib/rom/dynamodb/dataset/where_clause.rb

Defined Under Namespace

Classes: WhereClause

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, operation: :query, config: {}, queries: []) ⇒ Dataset

Returns a new instance of Dataset.



40
41
42
43
44
45
# File 'lib/rom/dynamodb/dataset.rb', line 40

def initialize(name:, operation: :query, config: {}, queries: [])
  @name = name
  @operation = operation
  @config = config
  @queries = queries
end

Instance Attribute Details

#configObject (readonly)



28
29
30
# File 'lib/rom/dynamodb/dataset.rb', line 28

def config
  @config
end

#nameObject (readonly)



28
29
30
# File 'lib/rom/dynamodb/dataset.rb', line 28

def name
  @name
end

#operationObject (readonly)



28
29
30
# File 'lib/rom/dynamodb/dataset.rb', line 28

def operation
  @operation
end

#queriesObject

This array of hashes is built up by chaining the

relational methods together and when the query is finally executed,
all the hashes in this array are merged and send to the underlying
DynamoDB client.


38
39
40
# File 'lib/rom/dynamodb/dataset.rb', line 38

def queries
  @queries
end

Instance Method Details

#after(key, after, predicate = :ge) ⇒ self

Deprecated.

Use #where instead.

Retrieves all matching range keys within the composite key after the value provided.

Examples:

Given Table

users = relation.equal(:id, "mammal").after(:legs, 0).to_a
users #=> [{id: "mammal", legs: 2, name: "Human"}, ...]

Parameters:

  • key (Symbol)

    the key to match the provided value against.

  • after

    the value to match range values after

  • predicate (String) (defaults to: :ge)

    the query predicate to apply to DynamoDB.

Returns:



240
241
242
# File 'lib/rom/dynamodb/dataset.rb', line 240

def after(key, after, predicate = :ge)
  restrict_by(key, predicate, [after])
end

#ascendingself

Note:

This is the default behaviour.

Performs a traversal of the index in ascending order on the range key. DynamoDB will return the results in the order in which they have been stored.

Returns:



69
70
71
# File 'lib/rom/dynamodb/dataset.rb', line 69

def ascending
  restrict(scan_index_forward: true)
end

#batch_get(query = nil) ⇒ Object



256
257
258
# File 'lib/rom/dynamodb/dataset.rb', line 256

def batch_get(query = nil)
  append(:batch_get) { query }
end

#before(key, before, predicate = :le) ⇒ Object

Deprecated.

Use #where instead.

Retreives all matching range keys within the composite key before the value provided.



252
253
254
# File 'lib/rom/dynamodb/dataset.rb', line 252

def before(key, before, predicate = :le)
  restrict_by(key, predicate, [before])
end

#between(key, after, before, predicate = :between) ⇒ self

Deprecated.

Use #where instead.

Retrieves all matching range keys within the composite key for the index between two points.

Examples:

Given Table

users = relation.equal(:id, "mammal").between(:legs, 0, 4).to_a
users #=> [{id: "mammal", legs: 2, name: "Human"}, {id: "mammal", legs: 4, name: "Elephant"}, ...]

Parameters:

  • key (Symbol)

    the key to match the provided value against.

  • after

    the value to match range values after

  • before

    the value to match range values before

Returns:



216
217
218
# File 'lib/rom/dynamodb/dataset.rb', line 216

def between(key, after, before, predicate = :between)
  restrict_by(key, predicate, [after, before])
end

#build(parts = queries) ⇒ Object



272
273
274
# File 'lib/rom/dynamodb/dataset.rb', line 272

def build(parts = queries)
  parts.inject(:deep_merge).merge(table_name: name)
end

#connectionObject



302
303
304
# File 'lib/rom/dynamodb/dataset.rb', line 302

def connection
  @connection ||= Aws::DynamoDB::Client.new(config)
end

#create(hash) ⇒ Object



283
284
285
286
# File 'lib/rom/dynamodb/dataset.rb', line 283

def create(hash)
  payload = build([{ item: hash }])
  connection.put_item(payload).attributes
end

#delete(hash) ⇒ Object



288
289
290
291
# File 'lib/rom/dynamodb/dataset.rb', line 288

def delete(hash)
  payload = build([{ key: hash }])
  connection.delete_item(payload).data
end

#descendingself

Note:

This is the default behaviour.

Performs a traversal of the index in descending order on the range key. DynamoDB reads the results in reverse order by sort key value, and then returns the results to the client.

Returns:



83
84
85
# File 'lib/rom/dynamodb/dataset.rb', line 83

def descending
  restrict(scan_index_forward: false)
end

#each(&block) ⇒ Object



298
299
300
# File 'lib/rom/dynamodb/dataset.rb', line 298

def each(&block)
  each_item(build, &block)
end

#equal(key, val, predicate = :eq) ⇒ self

Deprecated.

Use #where instead.

Retrieves a key present within the composite key for this index by its exact value.

Examples:

Given Table

relation.equal(:id, 1).one! #=> { id: 1, ... }

Given Table

relation.equal(:id, 1).equal(:created_at, Time.now.to_f).one! #=> { id: 1, ... }

Parameters:

  • key (Symbol)

    the key to match the provided value against.

  • val

    the value to match against the key in the index.

  • predicate (Symbol) (defaults to: :eq)

    the query predicate to apply to DynamoDB.

Returns:



194
195
196
# File 'lib/rom/dynamodb/dataset.rb', line 194

def equal(key, val, predicate = :eq)
  restrict_by(key, predicate, [val])
end

#execute(query) ⇒ Object



306
307
308
309
310
311
312
313
# File 'lib/rom/dynamodb/dataset.rb', line 306

def execute(query)
  @response ||= case operation
  when :batch_get
    connection.send(operation, { request_items: { name => query } })
  else
    connection.send(operation, query).data
  end
end

#index(name) ⇒ self

The name of an index to query. This index can be any local secondary index or global secondary index on the table.

Parameters:

  • name (String)

    the name of the index to query.

Returns:



55
56
57
# File 'lib/rom/dynamodb/dataset.rb', line 55

def index(name)
  restrict(index_name: name)
end

#informationObject



293
294
295
296
# File 'lib/rom/dynamodb/dataset.rb', line 293

def information
  payload = build([{}])
  connection.describe_table(payload).table
end

#limit(num = nil) ⇒ self

Limits the number of results returned by the query or scan operation.

The maximum number of items to evaluate (not necessarily the number of matching items). If DynamoDB processes the number of items up to the limit while processing the results, it stops the operation and returns the matching values up to that point.

If there are more matches to be returned, the #last_evaluated_key

Returns:



99
100
101
# File 'lib/rom/dynamodb/dataset.rb', line 99

def limit(num = nil)
  append { { limit: num } unless num.nil? }
end

#offset(key) ⇒ self

Note:

When applying an offset, it must include the same composite key of which the index you are querying is composed from. Therefore, if your index has both a hash and range key, the key you provide must also have these.

The composite key of the first item that the resulting query will evaluate. Use this method if you have a populated #last_evaluated_key.

Parameters:

  • key (Hash)

    the composite offset key matching the queryable index.

Returns:



116
117
118
# File 'lib/rom/dynamodb/dataset.rb', line 116

def offset(key)
  append { { exclusive_start_key: key } unless key.nil? }
end

#restrict(query = nil) ⇒ Object



260
261
262
# File 'lib/rom/dynamodb/dataset.rb', line 260

def restrict(query = nil)
  append(:query) { query }
end

#retrieve(query = nil) ⇒ Object



264
265
266
# File 'lib/rom/dynamodb/dataset.rb', line 264

def retrieve(query = nil)
  append(:get_item) { query }
end

#scan(query = nil) ⇒ Object



268
269
270
# File 'lib/rom/dynamodb/dataset.rb', line 268

def scan(query = nil)
  append(:scan) { query }
end

#select(keys) ⇒ self

Selects one or more keys to retrieve from the table.

These keys can include scalars, sets, or elements of a JSON document.

Parameters:

  • keys (Array<String>)

    an array of string expressions to apply to the query

Returns:



131
132
133
# File 'lib/rom/dynamodb/dataset.rb', line 131

def select(keys)
  restrict(projection_expression: keys.collect(&:to_s).join(","))
end

#update(key, hash, action = 'PUT') ⇒ Object



276
277
278
279
280
281
# File 'lib/rom/dynamodb/dataset.rb', line 276

def update(key, hash, action = 'PUT')
  data = hash.delete_if { |k, _| key.keys.include?(k) }
  update = to_update_structure(data)
  payload = build([update, { key: key }])
  connection.update_item(payload).data
end

#where(maps = {}, &block) ⇒ Object

Note:

The following operands are supported, :>=, :>, :<, :<=, :== and :between

Restricts keys within a composite key, by values using a specific operand.

You can compose where clauses using compartive operators from inside a block, allowing a greater level of flexibility.

Multiple where clauses can be chained, or multiple predicates defined inside an array within a single clause. See the examples below.

Examples:

Given Table

animals = relation.where { [id == "mammal", legs > 0] }
animals #=> [{id: "mammal", legs: 2, name: "Human"}, ...]

Using a value mapping hash

keys = { type: "mammal", min_legs: 2 }
animals = relation.where(keys) { [id == type, legs > min_legs] }
animals #=> [{id: "mammal", legs: 2, name: "Elephant"}, ...]

Matching by exact value

keys = { type: "mammal" }
animals = relation.where(keys) { id == type }
animals #=> [{id: "mammal", legs: 2, name: "Elephant"}, ...]

Between two values

Matching with begins_with



165
166
167
168
169
170
171
172
173
174
# File 'lib/rom/dynamodb/dataset.rb', line 165

def where(maps = {}, &block)
  clauses = WhereClause.new(maps).execute(&block).clauses
  append(:query) do
    {
      expression_attribute_values: clauses.expression_attribute_values,
      expression_attribute_names: clauses.expression_attribute_names,
      key_condition_expression: clauses.key_condition_expression,
    }
  end
end