aws-record 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/aws-record.rb +1 -0
- data/lib/aws-record/record/errors.rb +8 -0
- data/lib/aws-record/record/item_operations.rb +106 -0
- data/lib/aws-record/record/transactions.rb +332 -0
- data/lib/aws-record/record/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ded98837103b96b4599121d600cc139054de43637168121bae6a35302ba24ac8
|
4
|
+
data.tar.gz: 14c7d413a0b108fffd9c118aa05234b7e6d33852121e8b6828e88db6cadd45d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 722b31cd37b441f33cc9993596b7fb92dc360bc280a00d9da9f03419a792669419bd9fa58006e59f09a027bde88444d795951902e3181aa697644a89baf09b17
|
7
|
+
data.tar.gz: bd7399265054c4483039e432fb4804713428151b3cef0f8e661132e9cf30d0c6876ed5611b09fcd6063c50b0f1baa31976cbfede27aba042457a9df3ac6cdffa
|
data/lib/aws-record.rb
CHANGED
@@ -27,6 +27,7 @@ require_relative 'aws-record/record/secondary_indexes'
|
|
27
27
|
require_relative 'aws-record/record/table_config'
|
28
28
|
require_relative 'aws-record/record/table_migration'
|
29
29
|
require_relative 'aws-record/record/version'
|
30
|
+
require_relative 'aws-record/record/transactions'
|
30
31
|
require_relative 'aws-record/record/marshalers/string_marshaler'
|
31
32
|
require_relative 'aws-record/record/marshalers/boolean_marshaler'
|
32
33
|
require_relative 'aws-record/record/marshalers/integer_marshaler'
|
@@ -54,6 +54,14 @@ module Aws
|
|
54
54
|
class TableDoesNotExist < RuntimeError; end
|
55
55
|
|
56
56
|
class MissingRequiredConfiguration < RuntimeError; end
|
57
|
+
|
58
|
+
# Raised when you attempt to combine your own condition expression with
|
59
|
+
# the auto-generated condition expression from a "safe put" from saving
|
60
|
+
# a new item in a transactional write operation. The path forward until
|
61
|
+
# this case is supported is to use a plain "put" call, and to include
|
62
|
+
# the key existance check yourself in your condition expression if you
|
63
|
+
# wish to do so.
|
64
|
+
class TransactionalSaveConditionCollision < RuntimeError; end
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
@@ -329,6 +329,112 @@ module Aws
|
|
329
329
|
|
330
330
|
module ItemOperationsClassMethods
|
331
331
|
|
332
|
+
# @example Usage Example
|
333
|
+
# check_exp = Model.transact_check_expression(
|
334
|
+
# key: { uuid: "foo" },
|
335
|
+
# condition_expression: "size(#T) <= :v",
|
336
|
+
# expression_attribute_names: {
|
337
|
+
# "#T" => "body"
|
338
|
+
# },
|
339
|
+
# expression_attribute_values: {
|
340
|
+
# ":v" => 1024
|
341
|
+
# }
|
342
|
+
# )
|
343
|
+
#
|
344
|
+
# Allows you to build a "check" expression for use in transactional
|
345
|
+
# write operations.
|
346
|
+
#
|
347
|
+
# @param [Hash] opts Options matching the :condition_check contents in
|
348
|
+
# the
|
349
|
+
# {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}
|
350
|
+
# API, with the exception that keys will be marshalled for you, and
|
351
|
+
# the table name will be provided for you by the operation.
|
352
|
+
# @return [Hash] Options suitable to be used as a check expression when
|
353
|
+
# calling the +#transact_write+ operation.
|
354
|
+
def transact_check_expression(opts)
|
355
|
+
# need to transform the key, and add the table name
|
356
|
+
opts = opts.dup
|
357
|
+
key = opts.delete(:key)
|
358
|
+
check_key = {}
|
359
|
+
@keys.keys.each_value do |attr_sym|
|
360
|
+
unless key[attr_sym]
|
361
|
+
raise Errors::KeyMissing.new(
|
362
|
+
"Missing required key #{attr_sym} in #{key}"
|
363
|
+
)
|
364
|
+
end
|
365
|
+
attr_name = attributes.storage_name_for(attr_sym)
|
366
|
+
check_key[attr_name] = attributes.attribute_for(attr_sym).
|
367
|
+
serialize(key[attr_sym])
|
368
|
+
end
|
369
|
+
opts[:key] = check_key
|
370
|
+
opts[:table_name] = table_name
|
371
|
+
opts
|
372
|
+
end
|
373
|
+
|
374
|
+
def tfind_opts(opts)
|
375
|
+
opts = opts.dup
|
376
|
+
key = opts.delete(:key)
|
377
|
+
request_key = {}
|
378
|
+
@keys.keys.each_value do |attr_sym|
|
379
|
+
unless key[attr_sym]
|
380
|
+
raise Errors::KeyMissing.new(
|
381
|
+
"Missing required key #{attr_sym} in #{key}"
|
382
|
+
)
|
383
|
+
end
|
384
|
+
attr_name = attributes.storage_name_for(attr_sym)
|
385
|
+
request_key[attr_name] = attributes.attribute_for(attr_sym).
|
386
|
+
serialize(key[attr_sym])
|
387
|
+
end
|
388
|
+
# this is a :get item used by #transact_get_items, with the exception
|
389
|
+
# of :model_class which needs to be removed before passing along
|
390
|
+
opts[:key] = request_key
|
391
|
+
opts[:table_name] = table_name
|
392
|
+
{
|
393
|
+
model_class: self,
|
394
|
+
get: opts
|
395
|
+
}
|
396
|
+
end
|
397
|
+
|
398
|
+
# @example Usage Example
|
399
|
+
# class Table
|
400
|
+
# include Aws::Record
|
401
|
+
# string_attr :hk, hash_key: true
|
402
|
+
# string_attr :rk, range_key: true
|
403
|
+
# end
|
404
|
+
#
|
405
|
+
# results = Table.transact_find(
|
406
|
+
# transact_items: [
|
407
|
+
# {key: { hk: "hk1", rk: "rk1"}},
|
408
|
+
# {key: { hk: "hk2", rk: "rk2"}}
|
409
|
+
# ]
|
410
|
+
# ) # => results.responses contains nil or instances of Table
|
411
|
+
#
|
412
|
+
# Provides a way to run a transactional find across multiple DynamoDB
|
413
|
+
# items, including transactions which get items across multiple actual
|
414
|
+
# or virtual tables.
|
415
|
+
#
|
416
|
+
# @param [Hash] opts Options to pass through to
|
417
|
+
# {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},
|
418
|
+
# with the exception of the :transact_items array, which uses the
|
419
|
+
# +#tfind_opts+ operation on your model class to provide extra
|
420
|
+
# metadata used to marshal your items after retrieval.
|
421
|
+
# @option opts [Array] :transact_items A set of options describing
|
422
|
+
# instances of the model class to return.
|
423
|
+
# @return [OpenStruct] Structured like the client API response from
|
424
|
+
# +#transact_get_items+, except that the +responses+ member contains
|
425
|
+
# +Aws::Record+ items marshaled into the model class used to call
|
426
|
+
# this method. See the usage example.
|
427
|
+
def transact_find(opts)
|
428
|
+
opts = opts.dup
|
429
|
+
transact_items = opts.delete(:transact_items)
|
430
|
+
global_transact_items = transact_items.map do |topts|
|
431
|
+
tfind_opts(topts)
|
432
|
+
end
|
433
|
+
opts[:transact_items] = global_transact_items
|
434
|
+
opts[:client] = dynamodb_client
|
435
|
+
Transactions.transact_find(opts)
|
436
|
+
end
|
437
|
+
|
332
438
|
# @example Usage Example
|
333
439
|
# class MyModel
|
334
440
|
# include Aws::Record
|
@@ -0,0 +1,332 @@
|
|
1
|
+
module Aws
|
2
|
+
module Record
|
3
|
+
module Transactions
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# @example Usage Example
|
7
|
+
# class TableOne
|
8
|
+
# include Aws::Record
|
9
|
+
# string_attr :uuid, hash_key: true
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# class TableTwo
|
13
|
+
# include Aws::Record
|
14
|
+
# string_attr :hk, hash_key: true
|
15
|
+
# string_attr :rk, range_key: true
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# results = Aws::Record::Transactions.transact_find(
|
19
|
+
# transact_items: [
|
20
|
+
# TableOne.tfind_opts(key: { uuid: "uuid1234" }),
|
21
|
+
# TableTwo.tfind_opts(key: { hk: "hk1", rk: "rk1"}),
|
22
|
+
# TableTwo.tfind_opts(key: { hk: "hk2", rk: "rk2"})
|
23
|
+
# ]
|
24
|
+
# ) # => results.responses contains nil or marshalled items
|
25
|
+
# results.responses.map { |r| r.class } # [TableOne, TableTwo, TableTwo]
|
26
|
+
#
|
27
|
+
# Provides a way to run a transactional find across multiple DynamoDB
|
28
|
+
# items, including transactions which get items across multiple actual
|
29
|
+
# or virtual tables.
|
30
|
+
#
|
31
|
+
# @param [Hash] opts Options to pass through to
|
32
|
+
# {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},
|
33
|
+
# with the exception of the :transact_items array, which uses the
|
34
|
+
# +#tfind_opts+ operation on your model class to provide extra
|
35
|
+
# metadata used to marshal your items after retrieval.
|
36
|
+
# @option opts [Array] :transact_items A set of +#tfind_opts+ results,
|
37
|
+
# such as those created by the usage example.
|
38
|
+
# @option opts [Aws::DynamoDB::Client] :client Optionally, you can pass
|
39
|
+
# in your own client to use for the transaction calls.
|
40
|
+
# @return [OpenStruct] Structured like the client API response from
|
41
|
+
# +#transact_get_items+, except that the +responses+ member contains
|
42
|
+
# +Aws::Record+ items marshaled into the classes used to call
|
43
|
+
# +#tfind_opts+ in each positional member. See the usage example.
|
44
|
+
def transact_find(opts)
|
45
|
+
opts = opts.dup
|
46
|
+
client = opts.delete(:client) || dynamodb_client
|
47
|
+
transact_items = opts.delete(:transact_items) # add nil check?
|
48
|
+
model_classes = []
|
49
|
+
client_transact_items = transact_items.map do |tfind_opts|
|
50
|
+
model_class = tfind_opts.delete(:model_class)
|
51
|
+
model_classes << model_class
|
52
|
+
tfind_opts
|
53
|
+
end
|
54
|
+
request_opts = opts
|
55
|
+
request_opts[:transact_items] = client_transact_items
|
56
|
+
client_resp = client.transact_get_items(
|
57
|
+
request_opts
|
58
|
+
)
|
59
|
+
responses = client_resp.responses
|
60
|
+
index = -1
|
61
|
+
ret = OpenStruct.new
|
62
|
+
ret.consumed_capacity = client_resp.consumed_capacity
|
63
|
+
ret.missing_items = []
|
64
|
+
ret.responses = client_resp.responses.map do |item|
|
65
|
+
index += 1
|
66
|
+
if item.nil? || item.item.nil?
|
67
|
+
missing_data = {
|
68
|
+
model_class: model_classes[index],
|
69
|
+
key: transact_items[index][:get][:key]
|
70
|
+
}
|
71
|
+
ret.missing_items << missing_data
|
72
|
+
nil
|
73
|
+
else
|
74
|
+
# need to translate the item keys
|
75
|
+
raw_item = item.item
|
76
|
+
model_class = model_classes[index]
|
77
|
+
new_item_opts = {}
|
78
|
+
raw_item.each do |db_name, value|
|
79
|
+
name = model_class.attributes.db_to_attribute_name(db_name)
|
80
|
+
new_item_opts[name] = value
|
81
|
+
end
|
82
|
+
item = model_class.new(new_item_opts)
|
83
|
+
item.clean!
|
84
|
+
item
|
85
|
+
end
|
86
|
+
end
|
87
|
+
ret
|
88
|
+
end
|
89
|
+
|
90
|
+
# @example Usage Example
|
91
|
+
# class TableOne
|
92
|
+
# include Aws::Record
|
93
|
+
# string_attr :uuid, hash_key: true
|
94
|
+
# string_attr :body
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# class TableTwo
|
98
|
+
# include Aws::Record
|
99
|
+
# string_attr :hk, hash_key: true
|
100
|
+
# string_attr :rk, range_key: true
|
101
|
+
# string_attr :body
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# check_exp = TableOne.transact_check_expression(
|
105
|
+
# key: { uuid: "foo" },
|
106
|
+
# condition_expression: "size(#T) <= :v",
|
107
|
+
# expression_attribute_names: {
|
108
|
+
# "#T" => "body"
|
109
|
+
# },
|
110
|
+
# expression_attribute_values: {
|
111
|
+
# ":v" => 1024
|
112
|
+
# }
|
113
|
+
# )
|
114
|
+
# new_item = TableTwo.new(hk: "hk1", rk: "rk1", body: "Hello!")
|
115
|
+
# update_item_1 = TableOne.find(uuid: "bar")
|
116
|
+
# update_item_1.body = "Updated the body!"
|
117
|
+
# put_item = TableOne.new(uuid: "foobar", body: "Content!")
|
118
|
+
# update_item_2 = TableTwo.find(hk: "hk2", rk: "rk2")
|
119
|
+
# update_item_2.body = "Update!"
|
120
|
+
# delete_item = TableOne.find(uuid: "to_be_deleted")
|
121
|
+
#
|
122
|
+
# Aws::Record::Transactions.transact_write(
|
123
|
+
# transact_items: [
|
124
|
+
# { check: check_exp },
|
125
|
+
# { save: new_item },
|
126
|
+
# { save: update_item_1 },
|
127
|
+
# {
|
128
|
+
# put: put_item,
|
129
|
+
# condition_expression: "attribute_not_exists(#H)",
|
130
|
+
# expression_attribute_names: { "#H" => "uuid" },
|
131
|
+
# return_values_on_condition_check_failure: "ALL_OLD"
|
132
|
+
# },
|
133
|
+
# { update: update_item_2 },
|
134
|
+
# { delete: delete_item }
|
135
|
+
# ]
|
136
|
+
# )
|
137
|
+
#
|
138
|
+
# Provides a way to pass in aws-record items into transactional writes,
|
139
|
+
# as well as adding the ability to run 'save' commands in a transaction
|
140
|
+
# while allowing aws-record to determine if a :put or :update operation
|
141
|
+
# is most appropriate. +#transact_write+ supports 5 different transact
|
142
|
+
# item modes:
|
143
|
+
# - save: Behaves much like the +#save+ operation on the item itself.
|
144
|
+
# If the keys are dirty, and thus it appears to be a new item, will
|
145
|
+
# create a :put operation with a conditional check on the item's
|
146
|
+
# existance. Note that you cannot bring your own conditional
|
147
|
+
# expression in this case. If you wish to force put or add your
|
148
|
+
# own conditional checks, use the :put operation.
|
149
|
+
# - put: Does a force put for the given item key and model.
|
150
|
+
# - update: Does an upsert for the given item.
|
151
|
+
# - delete: Deletes the given item.
|
152
|
+
# - check: Takes the result of +#transact_check_expression+,
|
153
|
+
# performing the specified check as a part of the transaction.
|
154
|
+
#
|
155
|
+
# @param [Hash] opts Options to pass through to
|
156
|
+
# {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}
|
157
|
+
# with the exception of :transact_items array, which is transformed
|
158
|
+
# to use your item to populate the :key, :table_name, :item, and/or
|
159
|
+
# :update_expression parameters as appropriate. See the usage example
|
160
|
+
# for a comprehensive set of combinations.
|
161
|
+
# @option opts [Array] :transact_items An array of hashes, accepting
|
162
|
+
# +:save+, +:put+, +:delete+, +:update+, and +:check+ as specified.
|
163
|
+
# @option opts [Aws::DynamoDB::Client] :client Optionally, you can
|
164
|
+
# specify a client to use for this transaction call. If not
|
165
|
+
# specified, the configured client for +Aws::Record::Transactions+
|
166
|
+
# is used.
|
167
|
+
def transact_write(opts)
|
168
|
+
opts = opts.dup
|
169
|
+
client = opts.delete(:client) || dynamodb_client
|
170
|
+
dirty_items = []
|
171
|
+
delete_items = []
|
172
|
+
# fetch abstraction records
|
173
|
+
transact_items = _transform_transact_write_items(
|
174
|
+
opts.delete(:transact_items),
|
175
|
+
dirty_items,
|
176
|
+
delete_items
|
177
|
+
)
|
178
|
+
opts[:transact_items] = transact_items
|
179
|
+
resp = client.transact_write_items(opts)
|
180
|
+
# mark all items clean/destroyed as needed if we didn't raise an exception
|
181
|
+
dirty_items.each { |i| i.clean! }
|
182
|
+
delete_items.each { |i| i.instance_variable_get("@data").destroyed = true }
|
183
|
+
resp
|
184
|
+
end
|
185
|
+
|
186
|
+
# Configures the Amazon DynamoDB client used by global transaction
|
187
|
+
# operations.
|
188
|
+
#
|
189
|
+
# Please note that this method is also called internally when you first
|
190
|
+
# attempt to perform an operation against the remote end, if you have
|
191
|
+
# not already configured a client. As such, please read and understand
|
192
|
+
# the documentation in the AWS SDK for Ruby V3 around
|
193
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/#Configuration configuration}
|
194
|
+
# to ensure you understand how default configuration behavior works.
|
195
|
+
# When in doubt, call this method to ensure your client is configured
|
196
|
+
# the way you want it to be configured.
|
197
|
+
#
|
198
|
+
# @param [Hash] opts the options you wish to use to create the client.
|
199
|
+
# Note that if you include the option +:client+, all other options
|
200
|
+
# will be ignored. See the documentation for other options in the
|
201
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby V3}.
|
202
|
+
# @option opts [Aws::DynamoDB::Client] :client allows you to pass in
|
203
|
+
# your own pre-configured client.
|
204
|
+
def configure_client(opts = {})
|
205
|
+
provided_client = opts.delete(:client)
|
206
|
+
opts[:user_agent_suffix] = _user_agent(
|
207
|
+
opts.delete(:user_agent_suffix)
|
208
|
+
)
|
209
|
+
client = provided_client || Aws::DynamoDB::Client.new(opts)
|
210
|
+
@@dynamodb_client = client
|
211
|
+
end
|
212
|
+
|
213
|
+
# Gets the
|
214
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html}
|
215
|
+
# instance that Transactions use. When called for the first time, if
|
216
|
+
# {#configure_client} has not yet been called, will configure a new
|
217
|
+
# client for you with default parameters.
|
218
|
+
#
|
219
|
+
# @return [Aws::DynamoDB::Client] the Amazon DynamoDB client instance.
|
220
|
+
def dynamodb_client
|
221
|
+
@@dynamodb_client ||= configure_client
|
222
|
+
end
|
223
|
+
|
224
|
+
private
|
225
|
+
def _transform_transact_write_items(transact_items, dirty_items, delete_items)
|
226
|
+
transact_items.map do |item|
|
227
|
+
# this code will assume users only provided one operation, and
|
228
|
+
# will fail down the line if that assumption is wrong
|
229
|
+
if save_record = item.delete(:save)
|
230
|
+
dirty_items << save_record
|
231
|
+
_transform_save_record(save_record, item)
|
232
|
+
elsif put_record = item.delete(:put)
|
233
|
+
dirty_items << put_record
|
234
|
+
_transform_put_record(put_record, item)
|
235
|
+
elsif delete_record = item.delete(:delete)
|
236
|
+
delete_items << delete_record
|
237
|
+
_transform_delete_record(delete_record, item)
|
238
|
+
elsif update_record = item.delete(:update)
|
239
|
+
dirty_items << update_record
|
240
|
+
_transform_update_record(update_record, item)
|
241
|
+
elsif check_record = item.delete(:check)
|
242
|
+
_transform_check_record(check_record, item)
|
243
|
+
else
|
244
|
+
raise ArgumentError.new(
|
245
|
+
"Invalid transact write item, must include an operation of "\
|
246
|
+
"type :save, :update, :delete, :update, or :check - #{item}"
|
247
|
+
)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def _transform_save_record(save_record, opts)
|
253
|
+
# determine if record is considered a new item or not
|
254
|
+
# then create a put with conditions, or an update
|
255
|
+
if save_record.send(:expect_new_item?)
|
256
|
+
safety_expression = save_record.send(:prevent_overwrite_expression)
|
257
|
+
if opts.include?(:condition_expression)
|
258
|
+
raise Errors::TransactionalSaveConditionCollision.new(
|
259
|
+
"Transactional write includes a :save operation that would "\
|
260
|
+
"result in a 'safe put' for the given item, yet a "\
|
261
|
+
"condition expression was also provided. This is not "\
|
262
|
+
"currently supported. You should rewrite this case to use "\
|
263
|
+
"a :put transaction, adding the existence check to your "\
|
264
|
+
"own condition expression if desired.\n"\
|
265
|
+
"\tItem: #{JSON.pretty_unparse(save_record.to_h)}\n"\
|
266
|
+
"\tExtra Options: #{JSON.pretty_unparse(opts)}"
|
267
|
+
)
|
268
|
+
else
|
269
|
+
opts = opts.merge(safety_expression)
|
270
|
+
_transform_put_record(save_record, opts)
|
271
|
+
end
|
272
|
+
else
|
273
|
+
_transform_update_record(save_record, opts)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def _transform_put_record(put_record, opts)
|
278
|
+
# convert to a straight put
|
279
|
+
opts[:table_name] = put_record.class.table_name
|
280
|
+
opts[:item] = put_record.send(:_build_item_for_save)
|
281
|
+
{ put: opts }
|
282
|
+
end
|
283
|
+
|
284
|
+
def _transform_delete_record(delete_record, opts)
|
285
|
+
# extract the key from each record to perform a deletion
|
286
|
+
opts[:table_name] = delete_record.class.table_name
|
287
|
+
opts[:key] = delete_record.send(:key_values)
|
288
|
+
{ delete: opts }
|
289
|
+
end
|
290
|
+
|
291
|
+
def _transform_update_record(update_record, opts)
|
292
|
+
# extract dirty attribute changes to perform an update
|
293
|
+
opts[:table_name] = update_record.class.table_name
|
294
|
+
dirty_changes = update_record.send(:_dirty_changes_for_update)
|
295
|
+
update_tuple = update_record.class.send(
|
296
|
+
:_build_update_expression,
|
297
|
+
dirty_changes
|
298
|
+
)
|
299
|
+
uex, exp_attr_names, exp_attr_values = update_tuple
|
300
|
+
opts[:key] = update_record.send(:key_values)
|
301
|
+
opts[:update_expression] = uex
|
302
|
+
# need to combine expression attribute names and values
|
303
|
+
if names = opts[:expression_attribute_names]
|
304
|
+
opts[:expression_attribute_names] = exp_attr_names.merge(names)
|
305
|
+
else
|
306
|
+
opts[:expression_attribute_names] = exp_attr_names
|
307
|
+
end
|
308
|
+
if values = opts[:expression_attribute_values]
|
309
|
+
opts[:expression_attribute_values] = exp_attr_values.merge(values)
|
310
|
+
else
|
311
|
+
opts[:expression_attribute_values] = exp_attr_values
|
312
|
+
end
|
313
|
+
{ update: opts }
|
314
|
+
end
|
315
|
+
|
316
|
+
def _transform_check_record(check_record, opts)
|
317
|
+
# check records are a pass-through
|
318
|
+
{ condition_check: opts.merge(check_record) }
|
319
|
+
end
|
320
|
+
|
321
|
+
def _user_agent(custom)
|
322
|
+
if custom
|
323
|
+
custom
|
324
|
+
else
|
325
|
+
" aws-record/#{VERSION}"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amazon Web Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/aws-record/record/secondary_indexes.rb
|
59
59
|
- lib/aws-record/record/table_config.rb
|
60
60
|
- lib/aws-record/record/table_migration.rb
|
61
|
+
- lib/aws-record/record/transactions.rb
|
61
62
|
- lib/aws-record/record/version.rb
|
62
63
|
homepage: http://github.com/aws/aws-sdk-ruby-record
|
63
64
|
licenses:
|