aws-record 2.9.0 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +330 -0
  3. data/LICENSE +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-record/record/attribute.rb +5 -15
  6. data/lib/aws-record/record/attributes.rb +32 -29
  7. data/lib/aws-record/record/batch.rb +99 -35
  8. data/lib/aws-record/record/batch_read.rb +186 -0
  9. data/lib/aws-record/record/batch_write.rb +9 -14
  10. data/lib/aws-record/record/buildable_search.rb +4 -2
  11. data/lib/aws-record/record/client_configuration.rb +1 -12
  12. data/lib/aws-record/record/dirty_tracking.rb +1 -12
  13. data/lib/aws-record/record/errors.rb +1 -12
  14. data/lib/aws-record/record/item_collection.rb +2 -13
  15. data/lib/aws-record/record/item_data.rb +1 -12
  16. data/lib/aws-record/record/item_operations.rb +47 -12
  17. data/lib/aws-record/record/key_attributes.rb +1 -12
  18. data/lib/aws-record/record/marshalers/boolean_marshaler.rb +1 -12
  19. data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -12
  20. data/lib/aws-record/record/marshalers/date_time_marshaler.rb +1 -12
  21. data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +1 -12
  22. data/lib/aws-record/record/marshalers/float_marshaler.rb +1 -12
  23. data/lib/aws-record/record/marshalers/integer_marshaler.rb +1 -12
  24. data/lib/aws-record/record/marshalers/list_marshaler.rb +1 -12
  25. data/lib/aws-record/record/marshalers/map_marshaler.rb +1 -12
  26. data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +1 -12
  27. data/lib/aws-record/record/marshalers/string_marshaler.rb +1 -12
  28. data/lib/aws-record/record/marshalers/string_set_marshaler.rb +1 -12
  29. data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -12
  30. data/lib/aws-record/record/model_attributes.rb +1 -12
  31. data/lib/aws-record/record/query.rb +1 -12
  32. data/lib/aws-record/record/secondary_indexes.rb +1 -12
  33. data/lib/aws-record/record/table_config.rb +1 -12
  34. data/lib/aws-record/record/table_migration.rb +1 -12
  35. data/lib/aws-record/record/transactions.rb +39 -7
  36. data/lib/aws-record/record/version.rb +2 -13
  37. data/lib/aws-record/record.rb +1 -12
  38. data/lib/aws-record.rb +2 -12
  39. metadata +7 -3
@@ -1,15 +1,4 @@
1
- # Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record
@@ -32,6 +21,7 @@ module Aws
32
21
  # === Inheritance Support
33
22
  # Child models will inherit the attributes and keys defined in the parent
34
23
  # model. Child models can override attribute keys if defined in their own model.
24
+ #
35
25
  # See examples below to see the feature in action.
36
26
  # @example Usage Example
37
27
  # class MyModel
@@ -137,7 +127,8 @@ module Aws
137
127
  # nil values will be ignored and not persisted. By default, is false.
138
128
  # @option opts [Object] :default_value Optional attribute used to
139
129
  # define a "default value" to be used if the attribute's value on an
140
- # item is nil or not set at persistence time.
130
+ # item is nil or not set at persistence time. Additionally, lambda
131
+ # can be used as a default value.
141
132
  # @option opts [Boolean] :hash_key Set to true if this attribute is
142
133
  # the hash key for the table.
143
134
  # @option opts [Boolean] :range_key Set to true if this attribute is
@@ -163,7 +154,8 @@ module Aws
163
154
  # nil values will be ignored and not persisted. By default, is false.
164
155
  # @option opts [Object] :default_value Optional attribute used to
165
156
  # define a "default value" to be used if the attribute's value on an
166
- # item is nil or not set at persistence time.
157
+ # item is nil or not set at persistence time. Additionally, lambda
158
+ # can be used as a default value.
167
159
  def string_attr(name, opts = {})
168
160
  opts[:dynamodb_type] = "S"
169
161
  attr(name, Marshalers::StringMarshaler.new(opts), opts)
@@ -184,7 +176,8 @@ module Aws
184
176
  # nil values will be ignored and not persisted. By default, is false.
185
177
  # @option opts [Object] :default_value Optional attribute used to
186
178
  # define a "default value" to be used if the attribute's value on an
187
- # item is nil or not set at persistence time.
179
+ # item is nil or not set at persistence time. Additionally, lambda
180
+ # can be used as a default value.
188
181
  def boolean_attr(name, opts = {})
189
182
  opts[:dynamodb_type] = "BOOL"
190
183
  attr(name, Marshalers::BooleanMarshaler.new(opts), opts)
@@ -205,7 +198,8 @@ module Aws
205
198
  # nil values will be ignored and not persisted. By default, is false.
206
199
  # @option opts [Object] :default_value Optional attribute used to
207
200
  # define a "default value" to be used if the attribute's value on an
208
- # item is nil or not set at persistence time.
201
+ # item is nil or not set at persistence time. Additionally, lambda
202
+ # can be used as a default value.
209
203
  def integer_attr(name, opts = {})
210
204
  opts[:dynamodb_type] = "N"
211
205
  attr(name, Marshalers::IntegerMarshaler.new(opts), opts)
@@ -226,7 +220,8 @@ module Aws
226
220
  # nil values will be ignored and not persisted. By default, is false.
227
221
  # @option opts [Object] :default_value Optional attribute used to
228
222
  # define a "default value" to be used if the attribute's value on an
229
- # item is nil or not set at persistence time.
223
+ # item is nil or not set at persistence time. Additionally, lambda
224
+ # can be used as a default value.
230
225
  def float_attr(name, opts = {})
231
226
  opts[:dynamodb_type] = "N"
232
227
  attr(name, Marshalers::FloatMarshaler.new(opts), opts)
@@ -247,7 +242,8 @@ module Aws
247
242
  # nil values will be ignored and not persisted. By default, is false.
248
243
  # @option options [Object] :default_value Optional attribute used to
249
244
  # define a "default value" to be used if the attribute's value on an
250
- # item is nil or not set at persistence time.
245
+ # item is nil or not set at persistence time. Additionally, lambda
246
+ # can be used as a default value.
251
247
  def date_attr(name, opts = {})
252
248
  opts[:dynamodb_type] = "S"
253
249
  attr(name, Marshalers::DateMarshaler.new(opts), opts)
@@ -268,7 +264,8 @@ module Aws
268
264
  # nil values will be ignored and not persisted. By default, is false.
269
265
  # @option opts [Object] :default_value Optional attribute used to
270
266
  # define a "default value" to be used if the attribute's value on an
271
- # item is nil or not set at persistence time.
267
+ # item is nil or not set at persistence time. Additionally, lambda
268
+ # can be used as a default value.
272
269
  def datetime_attr(name, opts = {})
273
270
  opts[:dynamodb_type] = "S"
274
271
  attr(name, Marshalers::DateTimeMarshaler.new(opts), opts)
@@ -289,14 +286,15 @@ module Aws
289
286
  # nil values will be ignored and not persisted. By default, is false.
290
287
  # @option opts [Object] :default_value Optional attribute used to
291
288
  # define a "default value" to be used if the attribute's value on an
292
- # item is nil or not set at persistence time.
289
+ # item is nil or not set at persistence time. Additionally, lambda
290
+ # can be used as a default value.
293
291
  def time_attr(name, opts = {})
294
292
  opts[:dynamodb_type] = "S"
295
293
  attr(name, Marshalers::TimeMarshaler.new(opts), opts)
296
294
  end
297
295
 
298
296
  # Define a time-type attribute for your model which persists as
299
- # epoch-seconds.
297
+ # epoch-seconds.
300
298
  #
301
299
  # @param [Symbol] name Name of this attribute. It should be a name
302
300
  # that is safe to use as a method.
@@ -311,7 +309,8 @@ module Aws
311
309
  # nil values will be ignored and not persisted. By default, is false.
312
310
  # @option opts [Object] :default_value Optional attribute used to
313
311
  # define a "default value" to be used if the attribute's value on an
314
- # item is nil or not set at persistence time.
312
+ # item is nil or not set at persistence time. Additionally, lambda
313
+ # can be used as a default value.
315
314
  def epoch_time_attr(name, opts = {})
316
315
  opts[:dynamodb_type] = "N"
317
316
  attr(name, Marshalers::EpochTimeMarshaler.new(opts), opts)
@@ -320,7 +319,7 @@ module Aws
320
319
  # Define a list-type attribute for your model.
321
320
  #
322
321
  # Lists do not have to be homogeneous, but they do have to be types that
323
- # the AWS SDK for Ruby V2's DynamoDB client knows how to marshal and
322
+ # the AWS SDK for Ruby V3's DynamoDB client knows how to marshal and
324
323
  # unmarshal. Those types are:
325
324
  #
326
325
  # * Hash
@@ -346,7 +345,8 @@ module Aws
346
345
  # the range key for the table.
347
346
  # @option opts [Object] :default_value Optional attribute used to
348
347
  # define a "default value" to be used if the attribute's value on an
349
- # item is nil or not set at persistence time.
348
+ # item is nil or not set at persistence time. Additionally, lambda
349
+ # can be used as a default value.
350
350
  def list_attr(name, opts = {})
351
351
  opts[:dynamodb_type] = "L"
352
352
  attr(name, Marshalers::ListMarshaler.new(opts), opts)
@@ -355,7 +355,7 @@ module Aws
355
355
  # Define a map-type attribute for your model.
356
356
  #
357
357
  # Maps do not have to be homogeneous, but they do have to use types that
358
- # the AWS SDK for Ruby V2's DynamoDB client knows how to marshal and
358
+ # the AWS SDK for Ruby V3's DynamoDB client knows how to marshal and
359
359
  # unmarshal. Those types are:
360
360
  #
361
361
  # * Hash
@@ -381,7 +381,8 @@ module Aws
381
381
  # the range key for the table.
382
382
  # @option opts [Object] :default_value Optional attribute used to
383
383
  # define a "default value" to be used if the attribute's value on an
384
- # item is nil or not set at persistence time.
384
+ # item is nil or not set at persistence time. Additionally, lambda
385
+ # can be used as a default value.
385
386
  def map_attr(name, opts = {})
386
387
  opts[:dynamodb_type] = "M"
387
388
  attr(name, Marshalers::MapMarshaler.new(opts), opts)
@@ -406,7 +407,8 @@ module Aws
406
407
  # the range key for the table.
407
408
  # @option opts [Object] :default_value Optional attribute used to
408
409
  # define a "default value" to be used if the attribute's value on an
409
- # item is nil or not set at persistence time.
410
+ # item is nil or not set at persistence time. Additionally, lambda
411
+ # can be used as a default value.
410
412
  def string_set_attr(name, opts = {})
411
413
  opts[:dynamodb_type] = "SS"
412
414
  attr(name, Marshalers::StringSetMarshaler.new(opts), opts)
@@ -431,7 +433,8 @@ module Aws
431
433
  # the range key for the table.
432
434
  # @option opts [Object] :default_value Optional attribute used to
433
435
  # define a "default value" to be used if the attribute's value on an
434
- # item is nil or not set at persistence time.
436
+ # item is nil or not set at persistence time. Additionally, lambda
437
+ # can be used as a default value.
435
438
  def numeric_set_attr(name, opts = {})
436
439
  opts[:dynamodb_type] = "NS"
437
440
  attr(name, Marshalers::NumericSetMarshaler.new(opts), opts)
@@ -513,7 +516,7 @@ module Aws
513
516
  @keys.hash_key
514
517
  end
515
518
 
516
- # @return [Symbol,nil] The symbloc name of the table's range key, or nil if there is no range key.
519
+ # @return [Symbol,nil] The symbolic name of the table's range key, or nil if there is no range key.
517
520
  def range_key
518
521
  @keys.range_key
519
522
  end
@@ -1,15 +1,4 @@
1
- # Copyright 2015-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record
@@ -17,6 +6,28 @@ module Aws
17
6
  extend ClientConfiguration
18
7
 
19
8
  class << self
9
+ # Provides a thin wrapper to the
10
+ # {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}
11
+ # method. Up to 25 +PutItem+ or +DeleteItem+ operations are supported.
12
+ # A single request may write up to 16 MB of data, with each item having a
13
+ # write limit of 400 KB.
14
+ #
15
+ # *Note*: this operation does not support dirty attribute handling,
16
+ # nor does it enforce safe write operations (i.e. update vs new record
17
+ # checks).
18
+ #
19
+ # This call may partially execute write operations. Failed operations
20
+ # are returned as {BatchWrite.unprocessed_items unprocessed_items} (i.e. the
21
+ # table fails to meet requested write capacity). Any unprocessed
22
+ # items may be retried by calling {BatchWrite.execute! .execute!}
23
+ # again. You can determine if the request needs to be retried by calling
24
+ # the {BatchWrite.complete? .complete?} method - which returns +true+
25
+ # when all operations have been completed.
26
+ #
27
+ # Please see
28
+ # {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.BatchOperations Batch Operations and Error Handling}
29
+ # in the DynamoDB Developer Guide for more details.
30
+ #
20
31
  # @example Usage Example
21
32
  # class Breakfast
22
33
  # include Aws::Record
@@ -38,29 +49,7 @@ module Aws
38
49
  # end
39
50
  #
40
51
  # # unprocessed items can be retried by calling Aws::Record::BatchWrite#execute!
41
- # operation.execute! unless operation.complete?
42
- #
43
- # Provides a thin wrapper to the
44
- # {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}
45
- # method. Up to 25 +PutItem+ or +DeleteItem+ operations are supported.
46
- # A single rquest may write up to 16 MB of data, with each item having a
47
- # write limit of 400 KB.
48
- #
49
- # *Note*: this operation does not support dirty attribute handling,
50
- # nor does it enforce safe write operations (i.e. update vs new record
51
- # checks).
52
- #
53
- # This call may partially execute write operations. Failed operations
54
- # are returned as +Aws::Record::BatchWrite#unprocessed_items+ (i.e. the
55
- # table fails to meet requested write capacity). Any unprocessed
56
- # items may be retried by calling +Aws::Record::BatchWrite#execute!+
57
- # again. You can determine if the request needs to be retried by calling
58
- # the +Aws::Record::BatchWrite#complete?+ method - which returns +true+
59
- # when all operations have been completed.
60
- #
61
- # Please see
62
- # {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.BatchOperations Batch Operations and Error Handling}
63
- # in the DynamoDB Developer Guide for more details.
52
+ # operation.execute! until operation.complete?
64
53
  #
65
54
  # @param [Hash] opts the options you wish to use to create the client.
66
55
  # Note that if you include the option +:client+, all other options
@@ -76,6 +65,81 @@ module Aws
76
65
  block.call(batch)
77
66
  batch.execute!
78
67
  end
68
+
69
+ # Provides support for the
70
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#batch_get_item-instance_method
71
+ # Aws::DynamoDB::Client#batch_get_item} for aws-record models.
72
+ #
73
+ # +Aws::Record::Batch+ is Enumerable and using Enumerable methods will handle
74
+ # paging through all requested keys automatically. Alternatively, a lower level
75
+ # interface is available. You can determine if there are any unprocessed keys by calling
76
+ # {BatchRead.complete? .complete?} and any unprocessed keys can be processed by
77
+ # calling {BatchRead.execute! .execute!}. You can access all processed items
78
+ # through {BatchRead.items .items}.
79
+ #
80
+ # The +batch_get_item+ supports up to 100 operations in a single call and a single
81
+ # operation can retrieve up to 16 MB of data.
82
+ #
83
+ # +Aws::Record::BatchRead+ can take more than 100 item keys. The first 100 requests
84
+ # will be processed and the remaining requests will be stored.
85
+ # When using Enumerable methods, any pending item keys will be automatically
86
+ # processed and the new items will be added to +items+.
87
+ # Alternately, use {BatchRead.execute! .execute!} to process any pending item keys.
88
+ #
89
+ # All processed operations can be accessed by {BatchRead.items items} - which is an
90
+ # array of modeled items from the response. The items will be unordered since
91
+ # DynamoDB does not return items in any particular order.
92
+ #
93
+ # If a requested item does not exist in the database, it is not returned in the response.
94
+ #
95
+ # If there is a returned item from the call and there's no reference model class
96
+ # to be found, the item will not show up under +items+.
97
+ #
98
+ # @example Usage Example
99
+ # class Lunch
100
+ # include Aws::Record
101
+ # integer_attr :id, hash_key: true
102
+ # string_attr :name, range_key: true
103
+ # end
104
+ #
105
+ # class Dessert
106
+ # include Aws::Record
107
+ # integer_attr :id, hash_key: true
108
+ # string_attr :name, range_key: true
109
+ # end
110
+ #
111
+ # # batch operations
112
+ # operation = Aws::Record::Batch.read do |db|
113
+ # db.find(Lunch, id: 1, name: 'Papaya Salad')
114
+ # db.find(Lunch, id: 2, name: 'BLT Sandwich')
115
+ # db.find(Dessert, id: 1, name: 'Apple Pie')
116
+ # end
117
+ #
118
+ # # BatchRead is enumerable and handles pagination
119
+ # operation.each { |item| item.id }
120
+ #
121
+ # # Alternatively, BatchRead provides a lower level
122
+ # # interface through: execute!, complete? and items.
123
+ # # Unprocessed items can be processed by calling:
124
+ # operation.execute! until operation.complete?
125
+ #
126
+ # @param [Hash] opts the options you wish to use to create the client.
127
+ # Note that if you include the option +:client+, all other options
128
+ # will be ignored. See the documentation for other options in the
129
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method
130
+ # AWS SDK for Ruby}.
131
+ # @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
132
+ # own pre-configured client.
133
+ # @return [Aws::Record::BatchRead] An instance that contains modeled items
134
+ # from the +BatchGetItem+ result and stores unprocessed keys to be
135
+ # manually processed later.
136
+ def read(opts = {}, &block)
137
+ batch = BatchRead.new(client: _build_client(opts))
138
+ block.call(batch)
139
+ batch.execute!
140
+ batch
141
+ end
142
+
79
143
  end
80
144
  end
81
145
  end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Record
5
+ class BatchRead
6
+ include Enumerable
7
+
8
+ # @api private
9
+ BATCH_GET_ITEM_LIMIT = 100
10
+
11
+ # @param [Aws::DynamoDB::Client] client the DynamoDB SDK client.
12
+ def initialize(opts = {})
13
+ @client = opts[:client]
14
+ end
15
+
16
+ # Append the item keys to a batch read request.
17
+ #
18
+ # See {Batch.read} for example usage.
19
+ # @param [Aws::Record] klass a model class that includes {Aws::Record}
20
+ # @param [Hash] key attribute-value pairs for the key you wish to search for.
21
+ # @raise [Aws::Record::Errors::KeyMissing] if your option parameters
22
+ # do not include all item keys defined in the model.
23
+ # @raise [ArgumentError] if the provided item keys is a duplicate request
24
+ # in the same instance.
25
+ def find(klass, key = {})
26
+ unprocessed_key = format_unprocessed_key(klass, key)
27
+ store_unprocessed_key(klass, unprocessed_key)
28
+ store_item_class(klass, unprocessed_key)
29
+ end
30
+
31
+ # Perform a +batch_get_item+ request.
32
+ #
33
+ # This method processes the first 100 item keys and
34
+ # returns an array of new modeled items.
35
+ #
36
+ # See {Batch.read} for example usage.
37
+ # @return [Array] an array of unordered new items
38
+ def execute!
39
+ operation_keys = unprocessed_keys[0..BATCH_GET_ITEM_LIMIT - 1]
40
+ @unprocessed_keys = unprocessed_keys[BATCH_GET_ITEM_LIMIT..-1] || []
41
+
42
+ operations = build_operations(operation_keys)
43
+ result = @client.batch_get_item(request_items: operations)
44
+ new_items = build_items(result.responses)
45
+ items.concat(new_items)
46
+
47
+ unless result.unprocessed_keys.nil?
48
+ update_unprocessed_keys(result.unprocessed_keys)
49
+ end
50
+
51
+ new_items
52
+ end
53
+
54
+ # Provides an enumeration of the results from the +batch_get_item+ request
55
+ # and handles pagination.
56
+ #
57
+ # Any pending item keys will be automatically processed and be
58
+ # added to the {#items}.
59
+ #
60
+ # See {Batch.read} for example usage.
61
+ # @yieldparam [Aws::Record] item a modeled item
62
+ # @return [Enumerable<BatchRead>] an enumeration over the results of
63
+ # +batch_get_item+ request.
64
+ def each
65
+ return enum_for(:each) unless block_given?
66
+
67
+ @items.each { |item| yield item }
68
+ until complete?
69
+ new_items = execute!
70
+ new_items.each { |new_item| yield new_item }
71
+ end
72
+ end
73
+
74
+ # Indicates if all item keys have been processed.
75
+ #
76
+ # See {Batch.read} for example usage.
77
+ # @return [Boolean] +true+ if all item keys has been processed, +false+ otherwise.
78
+ def complete?
79
+ unprocessed_keys.none?
80
+ end
81
+
82
+ # Returns an array of modeled items. The items are marshaled into classes used in {#find} method.
83
+ # These items will be unordered since DynamoDB does not return items in any particular order.
84
+ #
85
+ # See {Batch.read} for example usage.
86
+ # @return [Array] an array of modeled items from the +batch_get_item+ call.
87
+ def items
88
+ @items ||= []
89
+ end
90
+
91
+ private
92
+
93
+ def unprocessed_keys
94
+ @unprocessed_keys ||= []
95
+ end
96
+
97
+ def item_classes
98
+ @item_classes ||= Hash.new { |h, k| h[k] = [] }
99
+ end
100
+
101
+ def format_unprocessed_key(klass, key)
102
+ item_key = {}
103
+ attributes = klass.attributes
104
+ klass.keys.each_value do |attr_sym|
105
+ unless key[attr_sym]
106
+ raise Errors::KeyMissing, "Missing required key #{attr_sym} in #{key}"
107
+ end
108
+
109
+ attr_name = attributes.storage_name_for(attr_sym)
110
+ item_key[attr_name] = attributes.attribute_for(attr_sym)
111
+ .serialize(key[attr_sym])
112
+ end
113
+ item_key
114
+ end
115
+
116
+ def store_unprocessed_key(klass, unprocessed_key)
117
+ unprocessed_keys << { keys: unprocessed_key, table_name: klass.table_name }
118
+ end
119
+
120
+ def store_item_class(klass, key)
121
+ if item_classes.include?(klass.table_name)
122
+ item_classes[klass.table_name].each do |item|
123
+ if item[:keys] == key && item[:class] != klass
124
+ raise ArgumentError, 'Provided item keys is a duplicate request'
125
+ end
126
+ end
127
+ end
128
+ item_classes[klass.table_name] << { keys: key, class: klass }
129
+ end
130
+
131
+ def build_operations(keys)
132
+ operations = Hash.new { |h, k| h[k] = { keys: [] } }
133
+ keys.each do |key|
134
+ operations[key[:table_name]][:keys] << key[:keys]
135
+ end
136
+ operations
137
+ end
138
+
139
+ def build_items(item_responses)
140
+ new_items = []
141
+ item_responses.each do |table, unprocessed_items|
142
+ unprocessed_items.each do |item|
143
+ item_class = find_item_class(table, item)
144
+ if item_class.nil? && @client.config.logger
145
+ @client.config.logger.warn(
146
+ 'Unexpected response from service.'\
147
+ "Received: #{item}. Skipping above item and continuing"
148
+ )
149
+ else
150
+ new_items << build_item(item, item_class)
151
+ end
152
+ end
153
+ end
154
+ new_items
155
+ end
156
+
157
+ def update_unprocessed_keys(keys)
158
+ keys.each do |table_name, table_values|
159
+ table_values.keys.each do |key|
160
+ unprocessed_keys << { keys: key, table_name: table_name }
161
+ end
162
+ end
163
+ end
164
+
165
+ def find_item_class(table, item)
166
+ selected_item = item_classes[table].find { |item_info| contains_keys?(item, item_info[:keys]) }
167
+ selected_item[:class] if selected_item
168
+ end
169
+
170
+ def contains_keys?(item, keys)
171
+ item.merge(keys) == item
172
+ end
173
+
174
+ def build_item(item, item_class)
175
+ new_item_opts = {}
176
+ item.each do |db_name, value|
177
+ name = item_class.attributes.db_to_attribute_name(db_name)
178
+ new_item_opts[name] = value
179
+ end
180
+ item = item_class.new(new_item_opts)
181
+ item.clean!
182
+ item
183
+ end
184
+ end
185
+ end
186
+ end
@@ -1,26 +1,17 @@
1
- # Copyright 2015-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record
16
5
  class BatchWrite
17
6
  # @param [Aws::DynamoDB::Client] client the DynamoDB SDK client.
18
- def initialize(client:)
19
- @client = client
7
+ def initialize(opts = {})
8
+ @client = opts[:client]
20
9
  end
21
10
 
22
11
  # Append a +PutItem+ operation to a batch write request.
23
12
  #
13
+ # See {Batch.write} for example usage.
14
+ #
24
15
  # @param [Aws::Record] record a model class that includes {Aws::Record}.
25
16
  def put(record)
26
17
  table_name, params = record_put_params(record)
@@ -30,6 +21,7 @@ module Aws
30
21
 
31
22
  # Append a +DeleteItem+ operation to a batch write request.
32
23
  #
24
+ # See {Batch.write} for example usage.
33
25
  # @param [Aws::Record] record a model class that includes {Aws::Record}.
34
26
  def delete(record)
35
27
  table_name, params = record_delete_params(record)
@@ -39,6 +31,7 @@ module Aws
39
31
 
40
32
  # Perform a +batch_write_item+ request.
41
33
  #
34
+ # See {Batch.write} for example usage.
42
35
  # @return [Aws::Record::BatchWrite] an instance that provides access to
43
36
  # unprocessed items and allows for retries.
44
37
  def execute!
@@ -49,6 +42,7 @@ module Aws
49
42
 
50
43
  # Indicates if all items have been processed.
51
44
  #
45
+ # See {Batch.write} for example usage.
52
46
  # @return [Boolean] +true+ if +unprocessed_items+ is empty, +false+
53
47
  # otherwise
54
48
  def complete?
@@ -58,6 +52,7 @@ module Aws
58
52
  # Returns all +DeleteItem+ and +PutItem+ operations that have not yet been
59
53
  # processed successfully.
60
54
  #
55
+ # See {Batch.write} for example usage.
61
56
  # @return [Hash] All operations that have not yet successfully completed.
62
57
  def unprocessed_items
63
58
  operations
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Record
3
5
  class BuildableSearch
@@ -263,13 +265,13 @@ module Aws
263
265
 
264
266
  def _next_name
265
267
  ret = "#" + @next_name
266
- @next_name.next!
268
+ @next_name = @next_name.next
267
269
  ret
268
270
  end
269
271
 
270
272
  def _next_value
271
273
  ret = ":" + @next_value
272
- @next_value.next!
274
+ @next_value = @next_value.next
273
275
  ret
274
276
  end
275
277
  end
@@ -1,15 +1,4 @@
1
- # Copyright 2015-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record
@@ -1,15 +1,4 @@
1
- # Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record
@@ -1,15 +1,4 @@
1
- # Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
- # use this file except in compliance with the License. A copy of the License is
5
- # located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is distributed on
10
- # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
- # or implied. See the License for the specific language governing permissions
12
- # and limitations under the License.
1
+ # frozen_string_literal: true
13
2
 
14
3
  module Aws
15
4
  module Record