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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +330 -0
- data/LICENSE +202 -0
- data/VERSION +1 -0
- data/lib/aws-record/record/attribute.rb +5 -15
- data/lib/aws-record/record/attributes.rb +32 -29
- data/lib/aws-record/record/batch.rb +99 -35
- data/lib/aws-record/record/batch_read.rb +186 -0
- data/lib/aws-record/record/batch_write.rb +9 -14
- data/lib/aws-record/record/buildable_search.rb +4 -2
- data/lib/aws-record/record/client_configuration.rb +1 -12
- data/lib/aws-record/record/dirty_tracking.rb +1 -12
- data/lib/aws-record/record/errors.rb +1 -12
- data/lib/aws-record/record/item_collection.rb +2 -13
- data/lib/aws-record/record/item_data.rb +1 -12
- data/lib/aws-record/record/item_operations.rb +47 -12
- data/lib/aws-record/record/key_attributes.rb +1 -12
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/float_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/list_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/map_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/string_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +1 -12
- data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -12
- data/lib/aws-record/record/model_attributes.rb +1 -12
- data/lib/aws-record/record/query.rb +1 -12
- data/lib/aws-record/record/secondary_indexes.rb +1 -12
- data/lib/aws-record/record/table_config.rb +1 -12
- data/lib/aws-record/record/table_migration.rb +1 -12
- data/lib/aws-record/record/transactions.rb +39 -7
- data/lib/aws-record/record/version.rb +2 -13
- data/lib/aws-record/record.rb +1 -12
- data/lib/aws-record.rb +2 -12
- metadata +7 -3
@@ -1,15 +1,4 @@
|
|
1
|
-
#
|
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
|
-
#
|
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
|
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
|
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
|
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
|
-
#
|
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!
|
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
|
-
#
|
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(
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|