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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +83 -19
  3. data/VERSION +1 -1
  4. data/lib/aws-record/record/attribute.rb +8 -8
  5. data/lib/aws-record/record/attributes.rb +36 -49
  6. data/lib/aws-record/record/batch.rb +13 -12
  7. data/lib/aws-record/record/batch_read.rb +10 -12
  8. data/lib/aws-record/record/batch_write.rb +2 -1
  9. data/lib/aws-record/record/buildable_search.rb +37 -39
  10. data/lib/aws-record/record/client_configuration.rb +14 -14
  11. data/lib/aws-record/record/dirty_tracking.rb +29 -40
  12. data/lib/aws-record/record/errors.rb +11 -2
  13. data/lib/aws-record/record/item_collection.rb +7 -7
  14. data/lib/aws-record/record/item_data.rb +13 -17
  15. data/lib/aws-record/record/item_operations.rb +150 -138
  16. data/lib/aws-record/record/key_attributes.rb +0 -2
  17. data/lib/aws-record/record/marshalers/boolean_marshaler.rb +2 -5
  18. data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -6
  19. data/lib/aws-record/record/marshalers/date_time_marshaler.rb +2 -5
  20. data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +2 -8
  21. data/lib/aws-record/record/marshalers/float_marshaler.rb +3 -8
  22. data/lib/aws-record/record/marshalers/integer_marshaler.rb +3 -8
  23. data/lib/aws-record/record/marshalers/list_marshaler.rb +4 -7
  24. data/lib/aws-record/record/marshalers/map_marshaler.rb +4 -7
  25. data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +7 -9
  26. data/lib/aws-record/record/marshalers/string_marshaler.rb +1 -2
  27. data/lib/aws-record/record/marshalers/string_set_marshaler.rb +5 -7
  28. data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -5
  29. data/lib/aws-record/record/model_attributes.rb +17 -29
  30. data/lib/aws-record/record/query.rb +8 -11
  31. data/lib/aws-record/record/secondary_indexes.rb +40 -51
  32. data/lib/aws-record/record/table_config.rb +93 -115
  33. data/lib/aws-record/record/table_migration.rb +56 -72
  34. data/lib/aws-record/record/transactions.rb +40 -43
  35. data/lib/aws-record/record/version.rb +1 -1
  36. data/lib/aws-record/record.rb +36 -44
  37. 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/sdkforruby/api/Aws/DynamoDB/Client.html#put_item-instance_method Aws::DynamoDB::Client#put_item}
16
- # call, which will not overwrite an existing item. If the item only has
17
- # altered non-key attributes, will perform an
18
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_item-instance_method Aws::DynamoDB::Client#update_item}
19
- # call. Uses this item instance's attributes in order to build the
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
- if ret
39
- ret
40
- else
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/sdkforruby/api/Aws/DynamoDB/Client.html#put_item-instance_method Aws::DynamoDB::Client#put_item}
49
- # call, which will not overwrite an existing item. If the item only has
50
- # altered non-key attributes, will perform an
51
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_item-instance_method Aws::DynamoDB::Client#update_item}
52
- # call. Uses this item instance's attributes in order to build the
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.new "Invalid field: #{field} for model" unless respond_to?(setter)
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] new_param, contains the new parameters for the model
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] new_param, contains the new parameters for the model
161
- #
162
- # @param [Hash] opts
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/sdkforruby/api/Aws/DynamoDB/Client.html#delete_item-instance_method Aws::DynamoDB::Client#delete_item}
178
- # API.
179
- def delete!
180
- dynamodb_client.delete_item(
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
- self.instance_variable_get("@data").destroyed = true
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/sdkforruby/api/Aws/DynamoDB/Client.html#delete_item-instance_method Aws::DynamoDB::Client#delete_item}
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
- .attribute_for(attr_name)
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 Aws::DynamoDB::Client#batch_write_item}
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
- def _invalid_record?(opts)
211
- if self.respond_to?(:valid?)
212
- if !self.valid?
213
- true
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[:force]
248
+ force = opts.delete(:force)
224
249
  expect_new = expect_new_item?
225
250
  if force
226
- dynamodb_client.put_item(
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
- "Conditional #put_item call failed! Check that conditional write"\
240
- " conditions are met, or include the :force option to clobber"\
241
- " the remote item."
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
- request_opts = {
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
- request_opts[:expression_attribute_values] = exp_attr_values unless exp_attr_values.empty?
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
- dynamodb_client.update_item(
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 = self.instance_variable_get("@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.inject([]) do |acc, key|
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("@keys")
328
+ keys = self.class.instance_variable_get('@keys')
306
329
  # Hash Key
307
- conditions << "attribute_not_exists(#H)"
308
- expression_attribute_names["#H"] = keys.hash_key_attribute.database_name
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 << "attribute_not_exists(#R)"
312
- expression_attribute_names["#R"] = keys.range_key_attribute.database_name
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(" and "),
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
- attributes = self.class.attributes
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 Aws::DynamoDB::Client#transact_write_items}
351
- # API, with the exception that keys will be marshalled for you, and
352
- # the table name will be provided for you by the operation.
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
- raise Errors::KeyMissing.new(
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
- serialize(key[attr_sym])
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
- raise Errors::KeyMissing.new(
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
- serialize(key[attr_sym])
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 Aws::DynamoDB::Client#transact_get_items},
426
- # with the exception of the :transact_items array, which uses the
427
- # +#tfind_opts+ operation on your model class to provide extra
428
- # metadata used to marshal your items after retrieval.
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 DynamoDB #get_item
483
- # request. The +:key+ option is a special case where attributes are
484
- # serialized and translated for you similar to the #find method.
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
- raise Errors::KeyMissing.new(
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
- serialize(key[attr_sym])
517
+ request_key[attr_name] = attributes.attribute_for(attr_sym)
518
+ .serialize(key[attr_sym])
502
519
  end
503
- request_opts = {
520
+ get_opts = {
504
521
  table_name: table_name,
505
522
  key: request_key
506
523
  }.merge(opts)
507
- resp = dynamodb_client.get_item(request_opts)
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/sdkforruby/api/Aws/DynamoDB/Client.html#update_item-instance_method Aws::DynamoDB::Client#update_item}
565
- # call immediately on the table, using the attribute key/value pairs
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.new(
580
- "Missing required key #{attr_sym} in #{opts}"
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
- request_opts = {
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
- request_opts[:update_expression] = uex
594
- request_opts[:expression_attribute_names] = exp_attr_names
595
- request_opts[:expression_attribute_values] = exp_attr_values unless exp_attr_values.empty?
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(request_opts)
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 = "UE_A"
607
- value_sub_token = "ue_a"
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 = "#" + name_sub_token
610
- value_sub = ":" + value_sub_token
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 << "#{name_sub}"
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
- update_expressions << "SET " + set_expressions.join(", ")
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(" "), exp_attr_names, exp_attr_values]
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("@data")
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
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  module Record
5
-
6
5
  # @api private
7
6
  class KeyAttributes
8
7
  attr_reader :keys
@@ -38,6 +37,5 @@ module Aws
38
37
  @range_key = value
39
38
  end
40
39
  end
41
-
42
40
  end
43
41
  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