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)
-
(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)
(**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