module Aws::Record::Transactions

def _transform_check_record(check_record, opts)

def _transform_check_record(check_record, opts)
  # check records are a pass-through
  { condition_check: opts.merge(check_record) }
end

def _transform_delete_record(delete_record, opts)

def _transform_delete_record(delete_record, opts)
  # extract the key from each record to perform a deletion
  opts[:table_name] = delete_record.class.table_name
  opts[:key] = delete_record.send(:key_values)
  { delete: opts }
end

def _transform_put_record(put_record, opts)

def _transform_put_record(put_record, opts)
  # convert to a straight put
  opts[:table_name] = put_record.class.table_name
  opts[:item] = put_record.send(:_build_item_for_save)
  { put: opts }
end

def _transform_save_record(save_record, opts)

def _transform_save_record(save_record, opts)
  # determine if record is considered a new item or not
  # then create a put with conditions, or an update
  if save_record.send(:expect_new_item?)
    safety_expression = save_record.send(:prevent_overwrite_expression)
    if opts.include?(:condition_expression)
      raise Errors::TransactionalSaveConditionCollision,
            'Transactional write includes a :save operation that would ' \
            "result in a 'safe put' for the given item, yet a " \
            'condition expression was also provided. This is not ' \
            'currently supported. You should rewrite this case to use ' \
            'a :put transaction, adding the existence check to your ' \
            "own condition expression if desired.\n" \
            "\tItem: #{JSON.pretty_unparse(save_record.to_h)}\n" \
            "\tExtra Options: #{JSON.pretty_unparse(opts)}"
    else
      opts = opts.merge(safety_expression)
      _transform_put_record(save_record, opts)
    end
  else
    _transform_update_record(save_record, opts)
  end
end

def _transform_transact_write_items(transact_items, dirty_items, delete_items)

def _transform_transact_write_items(transact_items, dirty_items, delete_items)
  transact_items.map do |item|
    # this code will assume users only provided one operation, and
    # will fail down the line if that assumption is wrong
    if (save_record = item.delete(:save))
      dirty_items << save_record
      _transform_save_record(save_record, item)
    elsif (put_record = item.delete(:put))
      dirty_items << put_record
      _transform_put_record(put_record, item)
    elsif (delete_record = item.delete(:delete))
      delete_items << delete_record
      _transform_delete_record(delete_record, item)
    elsif (update_record = item.delete(:update))
      dirty_items << update_record
      _transform_update_record(update_record, item)
    elsif (check_record = item.delete(:check))
      _transform_check_record(check_record, item)
    else
      raise ArgumentError, 'Invalid transact write item, must include an operation of ' \
                           "type :save, :update, :delete, :update, or :check - #{item}"
    end
  end
end

def _transform_update_record(update_record, opts)

def _transform_update_record(update_record, opts)
  # extract dirty attribute changes to perform an update
  opts[:table_name] = update_record.class.table_name
  opts[:key] = update_record.send(:key_values)
  dirty_changes = update_record.send(:_dirty_changes_for_update)
  update_expression_opts = update_record.class.send(
    :_build_update_expression,
    dirty_changes
  )
  opts = update_record.class.send(
    :_merge_update_expression_opts,
    update_expression_opts,
    opts
  )
  { update: opts }
end

def transact_find(opts)

Returns:
  • (OpenStruct) - Structured like the client API response from

Options Hash: (**opts)
  • :client (Aws::DynamoDB::Client) -- Optionally, you can pass
  • :transact_items (Array) -- A set of +#tfind_opts+ results,

Parameters:
  • opts (Hash) -- Options to pass through to

Other tags:
    Example: Usage Example -
def transact_find(opts)
  opts = opts.dup
  client = opts.delete(:client) || dynamodb_client
  transact_items = opts.delete(:transact_items) # add nil check?
  model_classes = []
  client_transact_items = transact_items.map do |tfind_opts|
    model_class = tfind_opts.delete(:model_class)
    model_classes << model_class
    tfind_opts
  end
  request_opts = opts
  request_opts[:transact_items] = client_transact_items
  client_resp = client.transact_get_items(
    request_opts
  )
  index = -1
  ret = OpenStruct.new
  ret.consumed_capacity = client_resp.consumed_capacity
  ret.missing_items = []
  ret.responses = client_resp.responses.map do |item|
    index += 1
    if item.nil? || item.item.nil?
      missing_data = {
        model_class: model_classes[index],
        key: transact_items[index][:get][:key]
      }
      ret.missing_items << missing_data
      nil
    else
      # need to translate the item keys
      raw_item = item.item
      model_class = model_classes[index]
      new_item_opts = {}
      raw_item.each do |db_name, value|
        name = model_class.attributes.db_to_attribute_name(db_name)
        new_item_opts[name] = value
      end
      item = model_class.new(new_item_opts)
      item.clean!
      item
    end
  end
  ret
end

def transact_write(opts)

Options Hash: (**opts)
  • :client (Aws::DynamoDB::Client) -- Optionally, you can
  • :transact_items (Array) -- An array of hashes, accepting

Parameters:
  • opts (Hash) -- Options to pass through to

Other tags:
    Example: Usage Example -
def transact_write(opts)
  opts = opts.dup
  client = opts.delete(:client) || dynamodb_client
  dirty_items = []
  delete_items = []
  # fetch abstraction records
  transact_items = _transform_transact_write_items(
    opts.delete(:transact_items),
    dirty_items,
    delete_items
  )
  opts[:transact_items] = transact_items
  resp = client.transact_write_items(opts)
  # mark all items clean/destroyed as needed if we didn't raise an exception
  dirty_items.each(&:clean!)
  delete_items.each { |i| i.instance_variable_get('@data').destroyed = true }
  resp
end