aws-record 2.10.1 → 2.12.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/CHANGELOG.md +83 -19
- data/VERSION +1 -1
- data/lib/aws-record/record/attribute.rb +8 -8
- data/lib/aws-record/record/attributes.rb +36 -49
- data/lib/aws-record/record/batch.rb +13 -12
- data/lib/aws-record/record/batch_read.rb +10 -12
- data/lib/aws-record/record/batch_write.rb +2 -1
- data/lib/aws-record/record/buildable_search.rb +37 -39
- data/lib/aws-record/record/client_configuration.rb +14 -14
- data/lib/aws-record/record/dirty_tracking.rb +29 -40
- data/lib/aws-record/record/errors.rb +11 -2
- data/lib/aws-record/record/item_collection.rb +7 -7
- data/lib/aws-record/record/item_data.rb +13 -17
- data/lib/aws-record/record/item_operations.rb +150 -138
- data/lib/aws-record/record/key_attributes.rb +0 -2
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +2 -5
- data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -6
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +2 -5
- data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +2 -8
- data/lib/aws-record/record/marshalers/float_marshaler.rb +3 -8
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +3 -8
- data/lib/aws-record/record/marshalers/list_marshaler.rb +4 -7
- data/lib/aws-record/record/marshalers/map_marshaler.rb +4 -7
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +7 -9
- data/lib/aws-record/record/marshalers/string_marshaler.rb +1 -2
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +5 -7
- data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -5
- data/lib/aws-record/record/model_attributes.rb +17 -29
- data/lib/aws-record/record/query.rb +8 -11
- data/lib/aws-record/record/secondary_indexes.rb +40 -51
- data/lib/aws-record/record/table_config.rb +93 -115
- data/lib/aws-record/record/table_migration.rb +56 -72
- data/lib/aws-record/record/transactions.rb +40 -43
- data/lib/aws-record/record/version.rb +1 -1
- data/lib/aws-record/record.rb +36 -44
- metadata +13 -8
@@ -3,7 +3,6 @@
|
|
3
3
|
module Aws
|
4
4
|
module Record
|
5
5
|
module ItemOperations
|
6
|
-
|
7
6
|
# @api private
|
8
7
|
def self.included(sub_class)
|
9
8
|
sub_class.extend(ItemOperationsClassMethods)
|
@@ -12,20 +11,27 @@ module Aws
|
|
12
11
|
# Saves this instance of an item to Amazon DynamoDB. If this item is "new"
|
13
12
|
# as defined by having new or altered key attributes, will attempt a
|
14
13
|
# conditional
|
15
|
-
# {http://docs.aws.amazon.com/
|
16
|
-
# call, which will not overwrite an existing
|
17
|
-
# altered non-key attributes, will perform an
|
18
|
-
# {http://docs.aws.amazon.com/
|
19
|
-
# call. Uses this item instance's attributes
|
20
|
-
# request on your behalf.
|
14
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
15
|
+
# Aws::DynamoDB::Client#put_item} call, which will not overwrite an existing
|
16
|
+
# item. If the item only has altered non-key attributes, will perform an
|
17
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
18
|
+
# Aws::DynamoDB::Client#update_item} call. Uses this item instance's attributes
|
19
|
+
# in order to build the request on your behalf.
|
21
20
|
#
|
22
21
|
# You can use the +:force+ option to perform a simple put/overwrite
|
23
22
|
# without conditional validation or update logic.
|
24
23
|
#
|
25
|
-
# @param [Hash] opts
|
24
|
+
# @param [Hash] opts Options to pass through to the
|
25
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
26
|
+
# Aws::DynamoDB::Client#put_item} call or the
|
27
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
28
|
+
# Aws::DynamoDB::Client#update_item} call. +:put_item+ is used when
|
29
|
+
# +:force+ is true or when the item is new. +:update_item+ is used when
|
30
|
+
# the item is not new.
|
26
31
|
# @option opts [Boolean] :force if true, will save as a put operation and
|
27
32
|
# overwrite any existing item on the remote end. Otherwise, and by
|
28
33
|
# default, will either perform a conditional put or an update call.
|
34
|
+
#
|
29
35
|
# @raise [Aws::Record::Errors::KeyMissing] if a required key attribute
|
30
36
|
# does not have a value within this item instance.
|
31
37
|
# @raise [Aws::Record::Errors::ConditionalWriteFailed] if a conditional
|
@@ -35,30 +41,35 @@ module Aws
|
|
35
41
|
# cause is dependent on the validation library you are using.
|
36
42
|
def save!(opts = {})
|
37
43
|
ret = save(opts)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
raise Errors::ValidationError.new("Validation hook returned false!")
|
42
|
-
end
|
44
|
+
raise Errors::ValidationError, 'Validation hook returned false!' unless ret
|
45
|
+
|
46
|
+
ret
|
43
47
|
end
|
44
48
|
|
45
49
|
# Saves this instance of an item to Amazon DynamoDB. If this item is "new"
|
46
50
|
# as defined by having new or altered key attributes, will attempt a
|
47
51
|
# conditional
|
48
|
-
# {http://docs.aws.amazon.com/
|
49
|
-
# call, which will not overwrite an
|
50
|
-
# altered non-key attributes, will perform an
|
51
|
-
# {http://docs.aws.amazon.com/
|
52
|
-
# call. Uses this item instance's attributes
|
53
|
-
# request on your behalf.
|
52
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
53
|
+
# Aws::DynamoDB::Client#put_item} call, which will not overwrite an
|
54
|
+
# existing item. If the item only has altered non-key attributes, will perform an
|
55
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
56
|
+
# Aws::DynamoDB::Client#update_item} call. Uses this item instance's attributes
|
57
|
+
# in order to build the request on your behalf.
|
54
58
|
#
|
55
59
|
# You can use the +:force+ option to perform a simple put/overwrite
|
56
60
|
# without conditional validation or update logic.
|
57
61
|
#
|
58
|
-
# @param [Hash] opts
|
62
|
+
# @param [Hash] opts Options to pass through to the
|
63
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
64
|
+
# Aws::DynamoDB::Client#put_item} call or the
|
65
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
66
|
+
# Aws::DynamoDB::Client#update_item} call. +:put_item+ is used when
|
67
|
+
# +:force+ is true or when the item is new. +:update_item+ is used when
|
68
|
+
# the item is not new.
|
59
69
|
# @option opts [Boolean] :force if true, will save as a put operation and
|
60
70
|
# overwrite any existing item on the remote end. Otherwise, and by
|
61
71
|
# default, will either perform a conditional put or an update call.
|
72
|
+
#
|
62
73
|
# @return false if the record is invalid as defined by an attempt to call
|
63
74
|
# +valid?+ on this item, if that method exists. Otherwise, returns client
|
64
75
|
# call return value.
|
@@ -70,7 +81,6 @@ module Aws
|
|
70
81
|
end
|
71
82
|
end
|
72
83
|
|
73
|
-
|
74
84
|
# Assigns the attributes provided onto the model.
|
75
85
|
#
|
76
86
|
# @example Usage Example
|
@@ -99,7 +109,8 @@ module Aws
|
|
99
109
|
opts.each do |field, new_value|
|
100
110
|
field = field.to_sym
|
101
111
|
setter = "#{field}="
|
102
|
-
raise ArgumentError
|
112
|
+
raise ArgumentError, "Invalid field: #{field} for model" unless respond_to?(setter)
|
113
|
+
|
103
114
|
public_send(setter, new_value)
|
104
115
|
end
|
105
116
|
end
|
@@ -134,12 +145,19 @@ module Aws
|
|
134
145
|
# model.dirty? # => false
|
135
146
|
#
|
136
147
|
#
|
137
|
-
# @param [Hash]
|
148
|
+
# @param [Hash] new_params Contains the new parameters for the model.
|
138
149
|
#
|
139
|
-
# @param [Hash] opts
|
150
|
+
# @param [Hash] opts Options to pass through to the
|
151
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
152
|
+
# Aws::DynamoDB::Client#put_item} call or the
|
153
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
154
|
+
# Aws::DynamoDB::Client#update_item} call. +:put_item+ is used when
|
155
|
+
# +:force+ is true or when the item is new. +:update_item+ is used when
|
156
|
+
# the item is not new.
|
140
157
|
# @option opts [Boolean] :force if true, will save as a put operation and
|
141
158
|
# overwrite any existing item on the remote end. Otherwise, and by
|
142
159
|
# default, will either perform a conditional put or an update call.
|
160
|
+
#
|
143
161
|
# @return false if the record is invalid as defined by an attempt to call
|
144
162
|
# +valid?+ on this item, if that method exists. Otherwise, returns client
|
145
163
|
# call return value.
|
@@ -157,12 +175,18 @@ module Aws
|
|
157
175
|
# but this will be interpreted as persisting a new item to your DynamoDB
|
158
176
|
# table
|
159
177
|
#
|
160
|
-
# @param [Hash]
|
161
|
-
#
|
162
|
-
#
|
178
|
+
# @param [Hash] new_params Contains the new parameters for the model.
|
179
|
+
# @param [Hash] opts Options to pass through to the
|
180
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#put_item-instance_method
|
181
|
+
# Aws::DynamoDB::Client#put_item} call or the
|
182
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
183
|
+
# Aws::DynamoDB::Client#update_item} call. +:put_item+ is used when
|
184
|
+
# +:force+ is true or when the item is new. +:update_item+ is used when
|
185
|
+
# the item is not new.
|
163
186
|
# @option opts [Boolean] :force if true, will save as a put operation and
|
164
187
|
# overwrite any existing item on the remote end. Otherwise, and by
|
165
188
|
# default, will either perform a conditional put or an update call.
|
189
|
+
#
|
166
190
|
# @return The update mode if the update is successful
|
167
191
|
#
|
168
192
|
# @raise [Aws::Record::Errors::ValidationError] if any new values
|
@@ -174,71 +198,74 @@ module Aws
|
|
174
198
|
|
175
199
|
# Deletes the item instance that matches the key values of this item
|
176
200
|
# instance in Amazon DynamoDB. Uses the
|
177
|
-
# {http://docs.aws.amazon.com/
|
178
|
-
# API.
|
179
|
-
|
180
|
-
|
201
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#delete_item-instance_method
|
202
|
+
# Aws::DynamoDB::Client#delete_item} API.
|
203
|
+
#
|
204
|
+
# @param [Hash] opts Options to pass through to the
|
205
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#delete_item-instance_method
|
206
|
+
# Aws::DynamoDB::Client#delete_item} call.
|
207
|
+
def delete!(opts = {})
|
208
|
+
delete_opts = {
|
181
209
|
table_name: self.class.table_name,
|
182
210
|
key: key_values
|
183
|
-
|
184
|
-
|
211
|
+
}
|
212
|
+
dynamodb_client.delete_item(opts.merge(delete_opts))
|
213
|
+
instance_variable_get('@data').destroyed = true
|
185
214
|
end
|
186
215
|
|
187
216
|
# Validates and generates the key values necessary for API operations such as the
|
188
|
-
# {http://docs.aws.amazon.com/
|
189
|
-
# operation.
|
217
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#delete_item-instance_method
|
218
|
+
# Aws::DynamoDB::Client#delete_item} operation.
|
190
219
|
def key_values
|
191
220
|
validate_key_values
|
192
221
|
attributes = self.class.attributes
|
193
222
|
self.class.keys.values.each_with_object({}) do |attr_name, hash|
|
194
223
|
db_name = attributes.storage_name_for(attr_name)
|
195
|
-
hash[db_name] = attributes
|
196
|
-
|
197
|
-
.serialize(@data.raw_value(attr_name))
|
224
|
+
hash[db_name] = attributes.attribute_for(attr_name)
|
225
|
+
.serialize(@data.raw_value(attr_name))
|
198
226
|
end
|
199
227
|
end
|
200
228
|
|
201
229
|
# Validates key values and returns a hash consisting of the parameters
|
202
230
|
# to save the record using the
|
203
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#batch_write_item-instance_method
|
204
|
-
# operation.
|
231
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#batch_write_item-instance_method
|
232
|
+
# Aws::DynamoDB::Client#batch_write_item} operation.
|
205
233
|
def save_values
|
206
234
|
_build_item_for_save
|
207
235
|
end
|
208
236
|
|
209
237
|
private
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
else
|
215
|
-
false
|
216
|
-
end
|
238
|
+
|
239
|
+
def _invalid_record?(_opts)
|
240
|
+
if respond_to?(:valid?)
|
241
|
+
!valid?
|
217
242
|
else
|
218
243
|
false
|
219
244
|
end
|
220
245
|
end
|
221
246
|
|
222
247
|
def _perform_save(opts)
|
223
|
-
force = opts
|
248
|
+
force = opts.delete(:force)
|
224
249
|
expect_new = expect_new_item?
|
225
250
|
if force
|
226
|
-
|
251
|
+
put_opts = {
|
227
252
|
table_name: self.class.table_name,
|
228
253
|
item: _build_item_for_save
|
229
|
-
|
254
|
+
}
|
255
|
+
dynamodb_client.put_item(opts.merge(put_opts))
|
230
256
|
elsif expect_new
|
231
257
|
put_opts = {
|
232
258
|
table_name: self.class.table_name,
|
233
259
|
item: _build_item_for_save
|
234
260
|
}.merge(prevent_overwrite_expression)
|
235
261
|
begin
|
236
|
-
dynamodb_client.put_item(put_opts)
|
262
|
+
dynamodb_client.put_item(opts.merge(put_opts))
|
237
263
|
rescue Aws::DynamoDB::Errors::ConditionalCheckFailedException => e
|
238
264
|
raise Errors::ConditionalWriteFailed.new(
|
239
|
-
|
240
|
-
|
241
|
-
|
265
|
+
'Conditional #put_item call failed! Check that conditional write ' \
|
266
|
+
'conditions are met, or include the :force option to clobber ' \
|
267
|
+
'the remote item.',
|
268
|
+
e
|
242
269
|
)
|
243
270
|
end
|
244
271
|
else
|
@@ -249,22 +276,22 @@ module Aws
|
|
249
276
|
)
|
250
277
|
if update_tuple
|
251
278
|
uex, exp_attr_names, exp_attr_values = update_tuple
|
252
|
-
|
279
|
+
update_opts = {
|
253
280
|
table_name: self.class.table_name,
|
254
281
|
key: key_values,
|
255
282
|
update_expression: uex,
|
256
|
-
expression_attribute_names: exp_attr_names
|
283
|
+
expression_attribute_names: exp_attr_names
|
257
284
|
}
|
258
|
-
|
259
|
-
dynamodb_client.update_item(request_opts)
|
285
|
+
update_opts[:expression_attribute_values] = exp_attr_values unless exp_attr_values.empty?
|
260
286
|
else
|
261
|
-
|
287
|
+
update_opts = {
|
262
288
|
table_name: self.class.table_name,
|
263
289
|
key: key_values
|
264
|
-
|
290
|
+
}
|
265
291
|
end
|
292
|
+
dynamodb_client.update_item(opts.merge(update_opts))
|
266
293
|
end
|
267
|
-
data =
|
294
|
+
data = instance_variable_get('@data')
|
268
295
|
data.destroyed = false
|
269
296
|
data.new_record = false
|
270
297
|
true
|
@@ -278,15 +305,11 @@ module Aws
|
|
278
305
|
|
279
306
|
def validate_key_values
|
280
307
|
missing = missing_key_values
|
281
|
-
unless missing.empty?
|
282
|
-
raise Errors::KeyMissing.new(
|
283
|
-
"Missing required keys: #{missing.join(', ')}"
|
284
|
-
)
|
285
|
-
end
|
308
|
+
raise Errors::KeyMissing, "Missing required keys: #{missing.join(', ')}" unless missing.empty?
|
286
309
|
end
|
287
310
|
|
288
311
|
def missing_key_values
|
289
|
-
self.class.keys.
|
312
|
+
self.class.keys.each_with_object([]) do |key, acc|
|
290
313
|
acc << key.last if @data.raw_value(key.last).nil?
|
291
314
|
acc
|
292
315
|
end
|
@@ -302,32 +325,29 @@ module Aws
|
|
302
325
|
def prevent_overwrite_expression
|
303
326
|
conditions = []
|
304
327
|
expression_attribute_names = {}
|
305
|
-
keys = self.class.instance_variable_get(
|
328
|
+
keys = self.class.instance_variable_get('@keys')
|
306
329
|
# Hash Key
|
307
|
-
conditions <<
|
308
|
-
expression_attribute_names[
|
330
|
+
conditions << 'attribute_not_exists(#H)'
|
331
|
+
expression_attribute_names['#H'] = keys.hash_key_attribute.database_name
|
309
332
|
# Range Key
|
310
333
|
if self.class.range_key
|
311
|
-
conditions <<
|
312
|
-
expression_attribute_names[
|
334
|
+
conditions << 'attribute_not_exists(#R)'
|
335
|
+
expression_attribute_names['#R'] = keys.range_key_attribute.database_name
|
313
336
|
end
|
314
337
|
{
|
315
|
-
condition_expression: conditions.join(
|
338
|
+
condition_expression: conditions.join(' and '),
|
316
339
|
expression_attribute_names: expression_attribute_names
|
317
340
|
}
|
318
341
|
end
|
319
342
|
|
320
343
|
def _dirty_changes_for_update
|
321
|
-
|
322
|
-
ret = dirty.inject({}) do |acc, attr_name|
|
344
|
+
dirty.each_with_object({}) do |attr_name, acc|
|
323
345
|
acc[attr_name] = @data.raw_value(attr_name)
|
324
346
|
acc
|
325
347
|
end
|
326
|
-
ret
|
327
348
|
end
|
328
349
|
|
329
350
|
module ItemOperationsClassMethods
|
330
|
-
|
331
351
|
# @example Usage Example
|
332
352
|
# check_exp = Model.transact_check_expression(
|
333
353
|
# key: { uuid: "foo" },
|
@@ -347,9 +367,10 @@ module Aws
|
|
347
367
|
#
|
348
368
|
# @param [Hash] opts Options matching the :condition_check contents in
|
349
369
|
# the
|
350
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_write_items-instance_method
|
351
|
-
# API, with the exception that
|
352
|
-
#
|
370
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_write_items-instance_method
|
371
|
+
# Aws::DynamoDB::Client#transact_write_items} API, with the exception that
|
372
|
+
# keys will be marshalled for you, and the table name will be provided
|
373
|
+
# for you by the operation.
|
353
374
|
# @return [Hash] Options suitable to be used as a check expression when
|
354
375
|
# calling the +#transact_write+ operation.
|
355
376
|
def transact_check_expression(opts)
|
@@ -358,14 +379,11 @@ module Aws
|
|
358
379
|
key = opts.delete(:key)
|
359
380
|
check_key = {}
|
360
381
|
@keys.keys.each_value do |attr_sym|
|
361
|
-
unless key[attr_sym]
|
362
|
-
|
363
|
-
"Missing required key #{attr_sym} in #{key}"
|
364
|
-
)
|
365
|
-
end
|
382
|
+
raise Errors::KeyMissing, "Missing required key #{attr_sym} in #{key}" unless key[attr_sym]
|
383
|
+
|
366
384
|
attr_name = attributes.storage_name_for(attr_sym)
|
367
|
-
check_key[attr_name] = attributes.attribute_for(attr_sym)
|
368
|
-
|
385
|
+
check_key[attr_name] = attributes.attribute_for(attr_sym)
|
386
|
+
.serialize(key[attr_sym])
|
369
387
|
end
|
370
388
|
opts[:key] = check_key
|
371
389
|
opts[:table_name] = table_name
|
@@ -384,14 +402,11 @@ module Aws
|
|
384
402
|
key = opts.delete(:key)
|
385
403
|
request_key = {}
|
386
404
|
@keys.keys.each_value do |attr_sym|
|
387
|
-
unless key[attr_sym]
|
388
|
-
|
389
|
-
"Missing required key #{attr_sym} in #{key}"
|
390
|
-
)
|
391
|
-
end
|
405
|
+
raise Errors::KeyMissing, "Missing required key #{attr_sym} in #{key}" unless key[attr_sym]
|
406
|
+
|
392
407
|
attr_name = attributes.storage_name_for(attr_sym)
|
393
|
-
request_key[attr_name] = attributes.attribute_for(attr_sym)
|
394
|
-
|
408
|
+
request_key[attr_name] = attributes.attribute_for(attr_sym)
|
409
|
+
.serialize(key[attr_sym])
|
395
410
|
end
|
396
411
|
# this is a :get item used by #transact_get_items, with the exception
|
397
412
|
# of :model_class which needs to be removed before passing along
|
@@ -422,10 +437,11 @@ module Aws
|
|
422
437
|
# or virtual tables.
|
423
438
|
#
|
424
439
|
# @param [Hash] opts Options to pass through to
|
425
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_get_items-instance_method
|
426
|
-
# with the exception of the
|
427
|
-
# +#tfind_opts+ operation on
|
428
|
-
# metadata used to marshal your
|
440
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_get_items-instance_method
|
441
|
+
# Aws::DynamoDB::Client#transact_get_items}, with the exception of the
|
442
|
+
# :transact_items array, which uses the +#tfind_opts+ operation on
|
443
|
+
# your model class to provide extra metadata used to marshal your
|
444
|
+
# items after retrieval.
|
429
445
|
# @option opts [Array] :transact_items A set of options describing
|
430
446
|
# instances of the model class to return.
|
431
447
|
# @return [OpenStruct] Structured like the client API response from
|
@@ -479,32 +495,33 @@ module Aws
|
|
479
495
|
# supports the options you are including, and avoid adding options not
|
480
496
|
# recognized by the underlying client to avoid runtime exceptions.
|
481
497
|
#
|
482
|
-
# @param [Hash] opts Options to pass through to the
|
483
|
-
#
|
484
|
-
#
|
498
|
+
# @param [Hash] opts Options to pass through to the
|
499
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#get_item-instance_method
|
500
|
+
# Aws::DynamoDB::Client#get_item} request. The +:key+ option is a
|
501
|
+
# special case where attributes are serialized and translated for you
|
502
|
+
# similar to the #find method.
|
485
503
|
# @option opts [Hash] :key attribute-value pairs for the key you wish to
|
486
504
|
# search for.
|
505
|
+
#
|
487
506
|
# @return [Aws::Record] builds and returns an instance of your model.
|
507
|
+
#
|
488
508
|
# @raise [Aws::Record::Errors::KeyMissing] if your option parameters do
|
489
509
|
# not include all table keys.
|
490
510
|
def find_with_opts(opts)
|
491
511
|
key = opts.delete(:key)
|
492
512
|
request_key = {}
|
493
513
|
@keys.keys.each_value do |attr_sym|
|
494
|
-
unless key[attr_sym]
|
495
|
-
|
496
|
-
"Missing required key #{attr_sym} in #{key}"
|
497
|
-
)
|
498
|
-
end
|
514
|
+
raise Errors::KeyMissing, "Missing required key #{attr_sym} in #{key}" unless key[attr_sym]
|
515
|
+
|
499
516
|
attr_name = attributes.storage_name_for(attr_sym)
|
500
|
-
request_key[attr_name] = attributes.attribute_for(attr_sym)
|
501
|
-
|
517
|
+
request_key[attr_name] = attributes.attribute_for(attr_sym)
|
518
|
+
.serialize(key[attr_sym])
|
502
519
|
end
|
503
|
-
|
520
|
+
get_opts = {
|
504
521
|
table_name: table_name,
|
505
522
|
key: request_key
|
506
523
|
}.merge(opts)
|
507
|
-
resp = dynamodb_client.get_item(
|
524
|
+
resp = dynamodb_client.get_item(get_opts)
|
508
525
|
if resp.item.nil?
|
509
526
|
nil
|
510
527
|
else
|
@@ -512,7 +529,6 @@ module Aws
|
|
512
529
|
end
|
513
530
|
end
|
514
531
|
|
515
|
-
|
516
532
|
# @example Usage Example
|
517
533
|
# class MyModel
|
518
534
|
# include Aws::Record
|
@@ -561,53 +577,54 @@ module Aws
|
|
561
577
|
# MyModel.update(id: 1, name: "First", body: "Hello!")
|
562
578
|
#
|
563
579
|
# Performs an
|
564
|
-
# {http://docs.aws.amazon.com/
|
565
|
-
# call immediately on the table,
|
566
|
-
# provided.
|
580
|
+
# {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_item-instance_method
|
581
|
+
# Aws::DynamoDB::Client#update_item} call immediately on the table,
|
582
|
+
# using the attribute key/value pairs provided.
|
567
583
|
#
|
568
584
|
# @param [Hash] opts attribute-value pairs for the update operation you
|
569
585
|
# wish to perform. You must include all key attributes for a valid
|
570
586
|
# call, then you may optionally include any other attributes that you
|
571
587
|
# wish to update.
|
588
|
+
#
|
572
589
|
# @raise [Aws::Record::Errors::KeyMissing] if your option parameters do
|
573
590
|
# not include all table keys.
|
574
591
|
def update(opts)
|
575
592
|
key = {}
|
576
|
-
updates = {}
|
577
593
|
@keys.keys.each_value do |attr_sym|
|
578
|
-
unless value = opts.delete(attr_sym)
|
579
|
-
raise Errors::KeyMissing
|
580
|
-
|
581
|
-
)
|
594
|
+
unless (value = opts.delete(attr_sym))
|
595
|
+
raise Errors::KeyMissing, "Missing required key #{attr_sym} in #{opts}"
|
596
|
+
|
582
597
|
end
|
598
|
+
|
583
599
|
attr_name = attributes.storage_name_for(attr_sym)
|
584
600
|
key[attr_name] = attributes.attribute_for(attr_sym).serialize(value)
|
585
601
|
end
|
586
|
-
|
602
|
+
update_opts = {
|
587
603
|
table_name: table_name,
|
588
604
|
key: key
|
589
605
|
}
|
590
606
|
update_tuple = _build_update_expression(opts)
|
591
607
|
unless update_tuple.nil?
|
592
608
|
uex, exp_attr_names, exp_attr_values = update_tuple
|
593
|
-
|
594
|
-
|
595
|
-
|
609
|
+
update_opts[:update_expression] = uex
|
610
|
+
update_opts[:expression_attribute_names] = exp_attr_names
|
611
|
+
update_opts[:expression_attribute_values] = exp_attr_values unless exp_attr_values.empty?
|
596
612
|
end
|
597
|
-
dynamodb_client.update_item(
|
613
|
+
dynamodb_client.update_item(update_opts)
|
598
614
|
end
|
599
615
|
|
600
616
|
private
|
617
|
+
|
601
618
|
def _build_update_expression(attr_value_pairs)
|
602
619
|
set_expressions = []
|
603
620
|
remove_expressions = []
|
604
621
|
exp_attr_names = {}
|
605
622
|
exp_attr_values = {}
|
606
|
-
name_sub_token =
|
607
|
-
value_sub_token =
|
623
|
+
name_sub_token = 'UE_A'
|
624
|
+
value_sub_token = 'ue_a'
|
608
625
|
attr_value_pairs.each do |attr_sym, value|
|
609
|
-
name_sub = "
|
610
|
-
value_sub = "
|
626
|
+
name_sub = "##{name_sub_token}"
|
627
|
+
value_sub = ":#{value_sub_token}"
|
611
628
|
name_sub_token = name_sub_token.succ
|
612
629
|
value_sub_token = value_sub_token.succ
|
613
630
|
|
@@ -615,29 +632,25 @@ module Aws
|
|
615
632
|
attr_name = attributes.storage_name_for(attr_sym)
|
616
633
|
exp_attr_names[name_sub] = attr_name
|
617
634
|
if _update_type_remove?(attribute, value)
|
618
|
-
remove_expressions <<
|
635
|
+
remove_expressions << name_sub.to_s
|
619
636
|
else
|
620
637
|
set_expressions << "#{name_sub} = #{value_sub}"
|
621
638
|
exp_attr_values[value_sub] = attribute.serialize(value)
|
622
639
|
end
|
623
640
|
end
|
624
641
|
update_expressions = []
|
625
|
-
unless set_expressions.empty?
|
626
|
-
|
627
|
-
end
|
628
|
-
unless remove_expressions.empty?
|
629
|
-
update_expressions << "REMOVE " + remove_expressions.join(", ")
|
630
|
-
end
|
642
|
+
update_expressions << ("SET #{set_expressions.join(', ')}") unless set_expressions.empty?
|
643
|
+
update_expressions << ("REMOVE #{remove_expressions.join(', ')}") unless remove_expressions.empty?
|
631
644
|
if update_expressions.empty?
|
632
645
|
nil
|
633
646
|
else
|
634
|
-
[update_expressions.join(
|
647
|
+
[update_expressions.join(' '), exp_attr_names, exp_attr_values]
|
635
648
|
end
|
636
649
|
end
|
637
650
|
|
638
651
|
def build_item_from_resp(resp)
|
639
652
|
record = new
|
640
|
-
data = record.instance_variable_get(
|
653
|
+
data = record.instance_variable_get('@data')
|
641
654
|
attributes.attributes.each do |name, attr|
|
642
655
|
data.set_attribute(name, attr.extract(resp.item))
|
643
656
|
data.new_record = false
|
@@ -649,7 +662,6 @@ module Aws
|
|
649
662
|
value.nil? && !attribute.persist_nil?
|
650
663
|
end
|
651
664
|
end
|
652
|
-
|
653
665
|
end
|
654
666
|
end
|
655
667
|
end
|
@@ -3,16 +3,14 @@
|
|
3
3
|
module Aws
|
4
4
|
module Record
|
5
5
|
module Marshalers
|
6
|
-
|
7
6
|
class BooleanMarshaler
|
8
7
|
def initialize(opts = {})
|
8
|
+
# pass
|
9
9
|
end
|
10
10
|
|
11
11
|
def type_cast(raw_value)
|
12
12
|
case raw_value
|
13
|
-
when nil
|
14
|
-
nil
|
15
|
-
when ''
|
13
|
+
when nil, ''
|
16
14
|
nil
|
17
15
|
when false, 'false', '0', 0
|
18
16
|
false
|
@@ -36,7 +34,6 @@ module Aws
|
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
39
|
-
|
40
37
|
end
|
41
38
|
end
|
42
39
|
end
|
@@ -5,7 +5,6 @@ require 'date'
|
|
5
5
|
module Aws
|
6
6
|
module Record
|
7
7
|
module Marshalers
|
8
|
-
|
9
8
|
class DateMarshaler
|
10
9
|
def initialize(opts = {})
|
11
10
|
@formatter = opts[:formatter] || Iso8601Formatter
|
@@ -13,9 +12,7 @@ module Aws
|
|
13
12
|
|
14
13
|
def type_cast(raw_value)
|
15
14
|
case raw_value
|
16
|
-
when nil
|
17
|
-
nil
|
18
|
-
when ''
|
15
|
+
when nil, ''
|
19
16
|
nil
|
20
17
|
when Date
|
21
18
|
raw_value
|
@@ -36,7 +33,6 @@ module Aws
|
|
36
33
|
raise ArgumentError, "expected a Date value or nil, got #{date.class}"
|
37
34
|
end
|
38
35
|
end
|
39
|
-
|
40
36
|
end
|
41
37
|
|
42
38
|
module Iso8601Formatter
|
@@ -44,7 +40,6 @@ module Aws
|
|
44
40
|
date.iso8601
|
45
41
|
end
|
46
42
|
end
|
47
|
-
|
48
43
|
end
|
49
44
|
end
|
50
45
|
end
|