module Aws::Record::ItemOperations::ItemOperationsClassMethods

Public Instance Methods

find(opts) click to toggle source

@example Usage Example

class MyModel
  include Aws::Record
  integer_attr :id,   hash_key: true
  string_attr  :name, range_key: true
end

MyModel.find(id: 1, name: "First")

@param [Hash] opts attribute-value pairs for the key you wish to

search for.

@return [Aws::Record] builds and returns an instance of your model. @raise [Aws::Record::Errors::KeyMissing] if your option parameters do

not include all table keys.
# File lib/aws-record/record/item_operations.rb, line 451
def find(opts)
  find_with_opts(key: opts)
end
find_with_opts(opts) click to toggle source

@example Usage Example

class MyModel
  include Aws::Record
  integer_attr :id,   hash_key: true
  string_attr  :name, range_key: true
end

MyModel.find_with_opts(
  key: { id: 1, name: "First" },
  consistent_read: true
)

Note that #find_with_opts will pass through all options other than :key unaltered to the underlying +Aws::DynamoDB::Client#get_item+ request. You should ensure that you have an aws-sdk gem version which supports the options you are including, and avoid adding options not recognized by the underlying client to avoid runtime exceptions.

@param [Hash] opts Options to pass through to the DynamoDB get_item

request. The +:key+ option is a special case where attributes are
serialized and translated for you similar to the #find method.

@option opts [Hash] :key attribute-value pairs for the key you wish to

search for.

@return [Aws::Record] builds and returns an instance of your model. @raise [Aws::Record::Errors::KeyMissing] if your option parameters do

not include all table keys.
# File lib/aws-record/record/item_operations.rb, line 481
def find_with_opts(opts)
  key = opts.delete(:key)
  request_key = {}
  @keys.keys.each_value do |attr_sym|
    unless key[attr_sym]
      raise Errors::KeyMissing.new(
        "Missing required key #{attr_sym} in #{key}"
      )
    end
    attr_name = attributes.storage_name_for(attr_sym)
    request_key[attr_name] = attributes.attribute_for(attr_sym).
      serialize(key[attr_sym])
  end
  request_opts = {
    table_name: table_name,
    key: request_key
  }.merge(opts)
  resp = dynamodb_client.get_item(request_opts)
  if resp.item.nil?
    nil
  else
    build_item_from_resp(resp)
  end
end
tfind_opts(opts) click to toggle source
# File lib/aws-record/record/item_operations.rb, line 373
def tfind_opts(opts)
  opts = opts.dup
  key = opts.delete(:key)
  request_key = {}
  @keys.keys.each_value do |attr_sym|
    unless key[attr_sym]
      raise Errors::KeyMissing.new(
        "Missing required key #{attr_sym} in #{key}"
      )
    end
    attr_name = attributes.storage_name_for(attr_sym)
    request_key[attr_name] = attributes.attribute_for(attr_sym).
      serialize(key[attr_sym])
  end
  # this is a :get item used by #transact_get_items, with the exception
  # of :model_class which needs to be removed before passing along
  opts[:key] = request_key
  opts[:table_name] = table_name
  {
    model_class: self,
    get: opts
  }
end
transact_check_expression(opts) click to toggle source

@example Usage Example

check_exp = Model.transact_check_expression(
  key: { uuid: "foo" },
  condition_expression: "size(#T) <= :v",
  expression_attribute_names: {
    "#T" => "body"
  },
  expression_attribute_values: {
    ":v" => 1024
  }
)

Allows you to build a “check” expression for use in transactional write operations.

@param [Hash] opts Options matching the :condition_check contents in

the
{https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_write_items-instance_method Aws::DynamoDB::Client#transact_write_items}
API, with the exception that keys will be marshalled for you, and
the table name will be provided for you by the operation.

@return [Hash] Options suitable to be used as a check expression when

calling the +#transact_write+ operation.
# File lib/aws-record/record/item_operations.rb, line 353
def transact_check_expression(opts)
  # need to transform the key, and add the table name
  opts = opts.dup
  key = opts.delete(:key)
  check_key = {}
  @keys.keys.each_value do |attr_sym|
    unless key[attr_sym]
      raise Errors::KeyMissing.new(
        "Missing required key #{attr_sym} in #{key}"
      )
    end
    attr_name = attributes.storage_name_for(attr_sym)
    check_key[attr_name] = attributes.attribute_for(attr_sym).
      serialize(key[attr_sym])
  end
  opts[:key] = check_key
  opts[:table_name] = table_name
  opts
end
transact_find(opts) click to toggle source

@example Usage Example

class Table
  include Aws::Record
  string_attr :hk, hash_key: true
  string_attr :rk, range_key: true
end

results = Table.transact_find(
  transact_items: [
    {key: { hk: "hk1", rk: "rk1"}},
    {key: { hk: "hk2", rk: "rk2"}}
  ]
) # => results.responses contains nil or instances of Table

Provides a way to run a transactional find across multiple DynamoDB items, including transactions which get items across multiple actual or virtual tables.

@param [Hash] opts Options to pass through to

{https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_get_items-instance_method Aws::DynamoDB::Client#transact_get_items},
with the exception of the :transact_items array, which uses the
+#tfind_opts+ operation on your model class to provide extra
metadata used to marshal your items after retrieval.

@option opts [Array] :transact_items A set of options describing

instances of the model class to return.

@return [OpenStruct] Structured like the client API response from

+#transact_get_items+, except that the +responses+ member contains
+Aws::Record+ items marshaled into the model class used to call
this method. See the usage example.
# File lib/aws-record/record/item_operations.rb, line 426
def transact_find(opts)
  opts = opts.dup
  transact_items = opts.delete(:transact_items)
  global_transact_items = transact_items.map do |topts|
    tfind_opts(topts)
  end
  opts[:transact_items] = global_transact_items
  opts[:client] = dynamodb_client
  Transactions.transact_find(opts)
end
update(opts) click to toggle source

@example Usage Example

class MyModel
  include Aws::Record
  integer_attr :id,   hash_key: true
  string_attr  :name, range_key: true
  string_attr  :body
  boolean_attr :sir_not_appearing_in_this_example
end

MyModel.update(id: 1, name: "First", body: "Hello!")

Performs an {docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_item-instance_method Aws::DynamoDB::Client#update_item} call immediately on the table, using the attribute key/value pairs provided.

@param [Hash] opts attribute-value pairs for the update operation you

wish to perform. You must include all key attributes for a valid
call, then you may optionally include any other attributes that you
wish to update.

@raise [Aws::Record::Errors::KeyMissing] if your option parameters do

not include all table keys.
# File lib/aws-record/record/item_operations.rb, line 528
def update(opts)
  key = {}
  updates = {}
  @keys.keys.each_value do |attr_sym|
    unless value = opts.delete(attr_sym)
      raise Errors::KeyMissing.new(
        "Missing required key #{attr_sym} in #{opts}"
      )
    end
    attr_name = attributes.storage_name_for(attr_sym)
    key[attr_name] = attributes.attribute_for(attr_sym).serialize(value)
  end
  request_opts = {
    table_name: table_name,
    key: key
  }
  update_tuple = _build_update_expression(opts)
  unless update_tuple.nil?
    uex, exp_attr_names, exp_attr_values = update_tuple
    request_opts[:update_expression] = uex
    request_opts[:expression_attribute_names] = exp_attr_names
    request_opts[:expression_attribute_values] = exp_attr_values unless exp_attr_values.empty?
  end
  dynamodb_client.update_item(request_opts)
end

Private Instance Methods

_build_update_expression(attr_value_pairs) click to toggle source
# File lib/aws-record/record/item_operations.rb, line 555
def _build_update_expression(attr_value_pairs)
  set_expressions = []
  remove_expressions = []
  exp_attr_names = {}
  exp_attr_values = {}
  name_sub_token = "UE_A"
  value_sub_token = "ue_a"
  attr_value_pairs.each do |attr_sym, value|
    name_sub = "#" + name_sub_token
    value_sub = ":" + value_sub_token
    name_sub_token = name_sub_token.succ
    value_sub_token = value_sub_token.succ

    attribute = attributes.attribute_for(attr_sym)
    attr_name = attributes.storage_name_for(attr_sym)
    exp_attr_names[name_sub] = attr_name
    if _update_type_remove?(attribute, value)
      remove_expressions << "#{name_sub}"
    else
      set_expressions << "#{name_sub} = #{value_sub}"
      exp_attr_values[value_sub] = attribute.serialize(value)
    end
  end
  update_expressions = []
  unless set_expressions.empty?
    update_expressions << "SET " + set_expressions.join(", ")
  end
  unless remove_expressions.empty?
    update_expressions << "REMOVE " + remove_expressions.join(", ")
  end
  if update_expressions.empty?
    nil
  else
    [update_expressions.join(" "), exp_attr_names, exp_attr_values]
  end
end
_update_type_remove?(attribute, value) click to toggle source
# File lib/aws-record/record/item_operations.rb, line 602
def _update_type_remove?(attribute, value)
  value.nil? && !attribute.persist_nil?
end
build_item_from_resp(resp) click to toggle source
# File lib/aws-record/record/item_operations.rb, line 592
def build_item_from_resp(resp)
  record = new
  data = record.instance_variable_get("@data")
  attributes.attributes.each do |name, attr|
    data.set_attribute(name, attr.extract(resp.item))
    data.new_record = false
  end
  record
end