aws-record 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +335 -0
- data/LICENSE +202 -0
- data/VERSION +1 -0
- data/lib/aws-record/record/attribute.rb +9 -21
- data/lib/aws-record/record/attributes.rb +68 -78
- data/lib/aws-record/record/batch.rb +13 -12
- data/lib/aws-record/record/batch_read.rb +5 -2
- data/lib/aws-record/record/batch_write.rb +1 -12
- data/lib/aws-record/record/buildable_search.rb +33 -28
- data/lib/aws-record/record/client_configuration.rb +10 -21
- data/lib/aws-record/record/dirty_tracking.rb +30 -44
- data/lib/aws-record/record/errors.rb +1 -13
- data/lib/aws-record/record/item_collection.rb +5 -16
- data/lib/aws-record/record/item_data.rb +4 -18
- data/lib/aws-record/record/item_operations.rb +86 -93
- data/lib/aws-record/record/key_attributes.rb +1 -14
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -15
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +2 -14
- data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +1 -14
- data/lib/aws-record/record/marshalers/float_marshaler.rb +3 -19
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +3 -19
- data/lib/aws-record/record/marshalers/list_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/map_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +3 -16
- data/lib/aws-record/record/marshalers/string_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +3 -16
- data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -14
- data/lib/aws-record/record/model_attributes.rb +14 -35
- data/lib/aws-record/record/query.rb +7 -21
- data/lib/aws-record/record/secondary_indexes.rb +23 -42
- data/lib/aws-record/record/table_config.rb +52 -74
- data/lib/aws-record/record/table_migration.rb +43 -66
- data/lib/aws-record/record/transactions.rb +67 -38
- data/lib/aws-record/record/version.rb +2 -13
- data/lib/aws-record/record.rb +30 -49
- metadata +14 -5
@@ -1,28 +1,14 @@
|
|
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
|
module Attributes
|
17
|
-
|
18
6
|
def self.included(sub_class)
|
19
7
|
sub_class.extend(ClassMethods)
|
20
8
|
model_attributes = ModelAttributes.new(self)
|
21
|
-
sub_class.instance_variable_set(
|
22
|
-
sub_class.instance_variable_set(
|
23
|
-
if Aws::Record.extends_record?(sub_class)
|
24
|
-
inherit_attributes(sub_class)
|
25
|
-
end
|
9
|
+
sub_class.instance_variable_set('@attributes', model_attributes)
|
10
|
+
sub_class.instance_variable_set('@keys', KeyAttributes.new(model_attributes))
|
11
|
+
inherit_attributes(sub_class) if Aws::Record.extends_record?(sub_class)
|
26
12
|
end
|
27
13
|
|
28
14
|
# Base initialization method for a new item. Optionally, allows you to
|
@@ -32,6 +18,7 @@ module Aws
|
|
32
18
|
# === Inheritance Support
|
33
19
|
# Child models will inherit the attributes and keys defined in the parent
|
34
20
|
# model. Child models can override attribute keys if defined in their own model.
|
21
|
+
#
|
35
22
|
# See examples below to see the feature in action.
|
36
23
|
# @example Usage Example
|
37
24
|
# class MyModel
|
@@ -90,29 +77,24 @@ module Aws
|
|
90
77
|
@data.hash_copy
|
91
78
|
end
|
92
79
|
|
93
|
-
private
|
94
80
|
def self.inherit_attributes(klass)
|
95
|
-
superclass_attributes = klass.superclass.instance_variable_get(
|
81
|
+
superclass_attributes = klass.superclass.instance_variable_get('@attributes')
|
96
82
|
|
97
83
|
superclass_attributes.attributes.each do |name, attribute|
|
98
|
-
subclass_attributes = klass.instance_variable_get(
|
84
|
+
subclass_attributes = klass.instance_variable_get('@attributes')
|
99
85
|
subclass_attributes.register_superclass_attribute(name, attribute)
|
100
86
|
end
|
101
87
|
|
102
|
-
superclass_keys = klass.superclass.instance_variable_get(
|
103
|
-
subclass_keys = klass.instance_variable_get(
|
104
|
-
|
105
|
-
if superclass_keys.hash_key
|
106
|
-
subclass_keys.hash_key = superclass_keys.hash_key
|
107
|
-
end
|
88
|
+
superclass_keys = klass.superclass.instance_variable_get('@keys')
|
89
|
+
subclass_keys = klass.instance_variable_get('@keys')
|
108
90
|
|
109
|
-
if superclass_keys.
|
110
|
-
|
111
|
-
end
|
91
|
+
subclass_keys.hash_key = superclass_keys.hash_key if superclass_keys.hash_key
|
92
|
+
subclass_keys.range_key = superclass_keys.range_key if superclass_keys.range_key
|
112
93
|
end
|
113
94
|
|
114
|
-
|
95
|
+
private_class_method :inherit_attributes
|
115
96
|
|
97
|
+
module ClassMethods
|
116
98
|
# Define an attribute for your model, providing your own attribute type.
|
117
99
|
#
|
118
100
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
@@ -137,7 +119,8 @@ module Aws
|
|
137
119
|
# nil values will be ignored and not persisted. By default, is false.
|
138
120
|
# @option opts [Object] :default_value Optional attribute used to
|
139
121
|
# define a "default value" to be used if the attribute's value on an
|
140
|
-
# item is nil or not set at persistence time.
|
122
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
123
|
+
# can be used as a default value.
|
141
124
|
# @option opts [Boolean] :hash_key Set to true if this attribute is
|
142
125
|
# the hash key for the table.
|
143
126
|
# @option opts [Boolean] :range_key Set to true if this attribute is
|
@@ -163,9 +146,10 @@ module Aws
|
|
163
146
|
# nil values will be ignored and not persisted. By default, is false.
|
164
147
|
# @option opts [Object] :default_value Optional attribute used to
|
165
148
|
# define a "default value" to be used if the attribute's value on an
|
166
|
-
# item is nil or not set at persistence time.
|
149
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
150
|
+
# can be used as a default value.
|
167
151
|
def string_attr(name, opts = {})
|
168
|
-
opts[:dynamodb_type] =
|
152
|
+
opts[:dynamodb_type] = 'S'
|
169
153
|
attr(name, Marshalers::StringMarshaler.new(opts), opts)
|
170
154
|
end
|
171
155
|
|
@@ -184,9 +168,10 @@ module Aws
|
|
184
168
|
# nil values will be ignored and not persisted. By default, is false.
|
185
169
|
# @option opts [Object] :default_value Optional attribute used to
|
186
170
|
# define a "default value" to be used if the attribute's value on an
|
187
|
-
# item is nil or not set at persistence time.
|
171
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
172
|
+
# can be used as a default value.
|
188
173
|
def boolean_attr(name, opts = {})
|
189
|
-
opts[:dynamodb_type] =
|
174
|
+
opts[:dynamodb_type] = 'BOOL'
|
190
175
|
attr(name, Marshalers::BooleanMarshaler.new(opts), opts)
|
191
176
|
end
|
192
177
|
|
@@ -205,9 +190,10 @@ module Aws
|
|
205
190
|
# nil values will be ignored and not persisted. By default, is false.
|
206
191
|
# @option opts [Object] :default_value Optional attribute used to
|
207
192
|
# define a "default value" to be used if the attribute's value on an
|
208
|
-
# item is nil or not set at persistence time.
|
193
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
194
|
+
# can be used as a default value.
|
209
195
|
def integer_attr(name, opts = {})
|
210
|
-
opts[:dynamodb_type] =
|
196
|
+
opts[:dynamodb_type] = 'N'
|
211
197
|
attr(name, Marshalers::IntegerMarshaler.new(opts), opts)
|
212
198
|
end
|
213
199
|
|
@@ -226,9 +212,10 @@ module Aws
|
|
226
212
|
# nil values will be ignored and not persisted. By default, is false.
|
227
213
|
# @option opts [Object] :default_value Optional attribute used to
|
228
214
|
# define a "default value" to be used if the attribute's value on an
|
229
|
-
# item is nil or not set at persistence time.
|
215
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
216
|
+
# can be used as a default value.
|
230
217
|
def float_attr(name, opts = {})
|
231
|
-
opts[:dynamodb_type] =
|
218
|
+
opts[:dynamodb_type] = 'N'
|
232
219
|
attr(name, Marshalers::FloatMarshaler.new(opts), opts)
|
233
220
|
end
|
234
221
|
|
@@ -247,9 +234,10 @@ module Aws
|
|
247
234
|
# nil values will be ignored and not persisted. By default, is false.
|
248
235
|
# @option options [Object] :default_value Optional attribute used to
|
249
236
|
# define a "default value" to be used if the attribute's value on an
|
250
|
-
# item is nil or not set at persistence time.
|
237
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
238
|
+
# can be used as a default value.
|
251
239
|
def date_attr(name, opts = {})
|
252
|
-
opts[:dynamodb_type] =
|
240
|
+
opts[:dynamodb_type] = 'S'
|
253
241
|
attr(name, Marshalers::DateMarshaler.new(opts), opts)
|
254
242
|
end
|
255
243
|
|
@@ -268,9 +256,10 @@ module Aws
|
|
268
256
|
# nil values will be ignored and not persisted. By default, is false.
|
269
257
|
# @option opts [Object] :default_value Optional attribute used to
|
270
258
|
# define a "default value" to be used if the attribute's value on an
|
271
|
-
# item is nil or not set at persistence time.
|
259
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
260
|
+
# can be used as a default value.
|
272
261
|
def datetime_attr(name, opts = {})
|
273
|
-
opts[:dynamodb_type] =
|
262
|
+
opts[:dynamodb_type] = 'S'
|
274
263
|
attr(name, Marshalers::DateTimeMarshaler.new(opts), opts)
|
275
264
|
end
|
276
265
|
|
@@ -289,14 +278,15 @@ module Aws
|
|
289
278
|
# nil values will be ignored and not persisted. By default, is false.
|
290
279
|
# @option opts [Object] :default_value Optional attribute used to
|
291
280
|
# define a "default value" to be used if the attribute's value on an
|
292
|
-
# item is nil or not set at persistence time.
|
281
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
282
|
+
# can be used as a default value.
|
293
283
|
def time_attr(name, opts = {})
|
294
|
-
opts[:dynamodb_type] =
|
284
|
+
opts[:dynamodb_type] = 'S'
|
295
285
|
attr(name, Marshalers::TimeMarshaler.new(opts), opts)
|
296
286
|
end
|
297
287
|
|
298
288
|
# Define a time-type attribute for your model which persists as
|
299
|
-
#
|
289
|
+
# epoch-seconds.
|
300
290
|
#
|
301
291
|
# @param [Symbol] name Name of this attribute. It should be a name
|
302
292
|
# that is safe to use as a method.
|
@@ -311,16 +301,17 @@ module Aws
|
|
311
301
|
# nil values will be ignored and not persisted. By default, is false.
|
312
302
|
# @option opts [Object] :default_value Optional attribute used to
|
313
303
|
# define a "default value" to be used if the attribute's value on an
|
314
|
-
# item is nil or not set at persistence time.
|
304
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
305
|
+
# can be used as a default value.
|
315
306
|
def epoch_time_attr(name, opts = {})
|
316
|
-
opts[:dynamodb_type] =
|
307
|
+
opts[:dynamodb_type] = 'N'
|
317
308
|
attr(name, Marshalers::EpochTimeMarshaler.new(opts), opts)
|
318
309
|
end
|
319
310
|
|
320
311
|
# Define a list-type attribute for your model.
|
321
312
|
#
|
322
313
|
# Lists do not have to be homogeneous, but they do have to be types that
|
323
|
-
# the AWS SDK for Ruby
|
314
|
+
# the AWS SDK for Ruby V3's DynamoDB client knows how to marshal and
|
324
315
|
# unmarshal. Those types are:
|
325
316
|
#
|
326
317
|
# * Hash
|
@@ -346,16 +337,17 @@ module Aws
|
|
346
337
|
# the range key for the table.
|
347
338
|
# @option opts [Object] :default_value Optional attribute used to
|
348
339
|
# define a "default value" to be used if the attribute's value on an
|
349
|
-
# item is nil or not set at persistence time.
|
340
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
341
|
+
# can be used as a default value.
|
350
342
|
def list_attr(name, opts = {})
|
351
|
-
opts[:dynamodb_type] =
|
343
|
+
opts[:dynamodb_type] = 'L'
|
352
344
|
attr(name, Marshalers::ListMarshaler.new(opts), opts)
|
353
345
|
end
|
354
346
|
|
355
347
|
# Define a map-type attribute for your model.
|
356
348
|
#
|
357
349
|
# Maps do not have to be homogeneous, but they do have to use types that
|
358
|
-
# the AWS SDK for Ruby
|
350
|
+
# the AWS SDK for Ruby V3's DynamoDB client knows how to marshal and
|
359
351
|
# unmarshal. Those types are:
|
360
352
|
#
|
361
353
|
# * Hash
|
@@ -381,9 +373,10 @@ module Aws
|
|
381
373
|
# the range key for the table.
|
382
374
|
# @option opts [Object] :default_value Optional attribute used to
|
383
375
|
# define a "default value" to be used if the attribute's value on an
|
384
|
-
# item is nil or not set at persistence time.
|
376
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
377
|
+
# can be used as a default value.
|
385
378
|
def map_attr(name, opts = {})
|
386
|
-
opts[:dynamodb_type] =
|
379
|
+
opts[:dynamodb_type] = 'M'
|
387
380
|
attr(name, Marshalers::MapMarshaler.new(opts), opts)
|
388
381
|
end
|
389
382
|
|
@@ -406,9 +399,10 @@ module Aws
|
|
406
399
|
# the range key for the table.
|
407
400
|
# @option opts [Object] :default_value Optional attribute used to
|
408
401
|
# define a "default value" to be used if the attribute's value on an
|
409
|
-
# item is nil or not set at persistence time.
|
402
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
403
|
+
# can be used as a default value.
|
410
404
|
def string_set_attr(name, opts = {})
|
411
|
-
opts[:dynamodb_type] =
|
405
|
+
opts[:dynamodb_type] = 'SS'
|
412
406
|
attr(name, Marshalers::StringSetMarshaler.new(opts), opts)
|
413
407
|
end
|
414
408
|
|
@@ -431,9 +425,10 @@ module Aws
|
|
431
425
|
# the range key for the table.
|
432
426
|
# @option opts [Object] :default_value Optional attribute used to
|
433
427
|
# define a "default value" to be used if the attribute's value on an
|
434
|
-
# item is nil or not set at persistence time.
|
428
|
+
# item is nil or not set at persistence time. Additionally, lambda
|
429
|
+
# can be used as a default value.
|
435
430
|
def numeric_set_attr(name, opts = {})
|
436
|
-
opts[:dynamodb_type] =
|
431
|
+
opts[:dynamodb_type] = 'NS'
|
437
432
|
attr(name, Marshalers::NumericSetMarshaler.new(opts), opts)
|
438
433
|
end
|
439
434
|
|
@@ -449,8 +444,8 @@ module Aws
|
|
449
444
|
# * None of the attributes have dirty changes.
|
450
445
|
# * If there is a value passed in, it must be an integer.
|
451
446
|
# For more information, see
|
452
|
-
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.AtomicCounters
|
453
|
-
# in the Amazon DynamoDB Developer Guide.
|
447
|
+
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.AtomicCounters
|
448
|
+
# Atomic counter} in the Amazon DynamoDB Developer Guide.
|
454
449
|
#
|
455
450
|
# @param [Symbol] name Name of this attribute. It should be a name that
|
456
451
|
# is safe to use as a method.
|
@@ -473,14 +468,13 @@ module Aws
|
|
473
468
|
# record.increment_counter!(2) #=> 3
|
474
469
|
# @see #attr #attr method for additional hash options.
|
475
470
|
def atomic_counter(name, opts = {})
|
476
|
-
opts[:dynamodb_type] =
|
471
|
+
opts[:dynamodb_type] = 'N'
|
477
472
|
opts[:default_value] ||= 0
|
478
473
|
attr(name, Marshalers::IntegerMarshaler.new(opts), opts)
|
479
474
|
|
480
|
-
define_method("increment_#{name}!") do |increment=1|
|
481
|
-
|
475
|
+
define_method("increment_#{name}!") do |increment = 1|
|
482
476
|
if dirty?
|
483
|
-
msg =
|
477
|
+
msg = 'Attributes need to be saved before atomic counter can be incremented'
|
484
478
|
raise Errors::RecordError, msg
|
485
479
|
end
|
486
480
|
|
@@ -489,23 +483,22 @@ module Aws
|
|
489
483
|
raise ArgumentError, msg
|
490
484
|
end
|
491
485
|
|
492
|
-
resp = dynamodb_client.update_item(
|
486
|
+
resp = dynamodb_client.update_item(
|
493
487
|
table_name: self.class.table_name,
|
494
488
|
key: key_values,
|
495
489
|
expression_attribute_values: {
|
496
|
-
|
490
|
+
':i' => increment
|
497
491
|
},
|
498
492
|
expression_attribute_names: {
|
499
|
-
|
493
|
+
'#n' => name
|
500
494
|
},
|
501
|
-
update_expression:
|
502
|
-
return_values:
|
503
|
-
|
495
|
+
update_expression: 'SET #n = #n + :i',
|
496
|
+
return_values: 'UPDATED_NEW'
|
497
|
+
)
|
504
498
|
assign_attributes(resp[:attributes])
|
505
499
|
@data.clean!
|
506
500
|
@data.get_attribute(name)
|
507
501
|
end
|
508
|
-
|
509
502
|
end
|
510
503
|
|
511
504
|
# @return [Symbol,nil] The symbolic name of the table's hash key.
|
@@ -513,7 +506,7 @@ module Aws
|
|
513
506
|
@keys.hash_key
|
514
507
|
end
|
515
508
|
|
516
|
-
# @return [Symbol,nil] The
|
509
|
+
# @return [Symbol,nil] The symbolic name of the table's range key, or nil if there is no range key.
|
517
510
|
def range_key
|
518
511
|
@keys.range_key
|
519
512
|
end
|
@@ -529,6 +522,7 @@ module Aws
|
|
529
522
|
end
|
530
523
|
|
531
524
|
private
|
525
|
+
|
532
526
|
def _define_attr_methods(name)
|
533
527
|
define_method(name) do
|
534
528
|
@data.get_attribute(name)
|
@@ -541,18 +535,14 @@ module Aws
|
|
541
535
|
|
542
536
|
def _key_attributes(id, opts)
|
543
537
|
if opts[:hash_key] == true && opts[:range_key] == true
|
544
|
-
raise ArgumentError.
|
545
|
-
"Cannot have the same attribute be a hash and range key."
|
546
|
-
)
|
538
|
+
raise ArgumentError, 'Cannot have the same attribute be a hash and range key.'
|
547
539
|
elsif opts[:hash_key] == true
|
548
540
|
@keys.hash_key = id
|
549
541
|
elsif opts[:range_key] == true
|
550
542
|
@keys.range_key = id
|
551
543
|
end
|
552
544
|
end
|
553
|
-
|
554
545
|
end
|
555
|
-
|
556
546
|
end
|
557
547
|
end
|
558
548
|
end
|
@@ -7,10 +7,10 @@ module Aws
|
|
7
7
|
|
8
8
|
class << self
|
9
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
|
11
|
-
# method. Up to 25 +PutItem+ or +DeleteItem+
|
12
|
-
# A single request may write up to 16 MB of data, with each
|
13
|
-
# write limit of 400 KB.
|
10
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#batch_write_item-instance_method
|
11
|
+
# Aws::DynamoDB::Client#batch_write_item} method. Up to 25 +PutItem+ or +DeleteItem+
|
12
|
+
# operations are supported. A single request may write up to 16 MB of data, with each
|
13
|
+
# item having a write limit of 400 KB.
|
14
14
|
#
|
15
15
|
# *Note*: this operation does not support dirty attribute handling,
|
16
16
|
# nor does it enforce safe write operations (i.e. update vs new record
|
@@ -25,8 +25,9 @@ module Aws
|
|
25
25
|
# when all operations have been completed.
|
26
26
|
#
|
27
27
|
# Please see
|
28
|
-
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.BatchOperations
|
29
|
-
# in the DynamoDB Developer Guide for
|
28
|
+
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.BatchOperations
|
29
|
+
# Batch Operations and Error Handling} in the DynamoDB Developer Guide for
|
30
|
+
# more details.
|
30
31
|
#
|
31
32
|
# @example Usage Example
|
32
33
|
# class Breakfast
|
@@ -54,15 +55,16 @@ module Aws
|
|
54
55
|
# @param [Hash] opts the options you wish to use to create the client.
|
55
56
|
# Note that if you include the option +:client+, all other options
|
56
57
|
# will be ignored. See the documentation for other options in the
|
57
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method
|
58
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method
|
59
|
+
# AWS SDK for Ruby}.
|
58
60
|
# @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
|
59
61
|
# own pre-configured client.
|
60
62
|
#
|
61
63
|
# @return [Aws::Record::BatchWrite] An instance that contains any
|
62
64
|
# unprocessed items and allows for a retry strategy.
|
63
|
-
def write(opts = {}
|
65
|
+
def write(opts = {})
|
64
66
|
batch = BatchWrite.new(client: _build_client(opts))
|
65
|
-
|
67
|
+
yield(batch)
|
66
68
|
batch.execute!
|
67
69
|
end
|
68
70
|
|
@@ -133,13 +135,12 @@ module Aws
|
|
133
135
|
# @return [Aws::Record::BatchRead] An instance that contains modeled items
|
134
136
|
# from the +BatchGetItem+ result and stores unprocessed keys to be
|
135
137
|
# manually processed later.
|
136
|
-
def read(opts = {}
|
138
|
+
def read(opts = {})
|
137
139
|
batch = BatchRead.new(client: _build_client(opts))
|
138
|
-
|
140
|
+
yield(batch)
|
139
141
|
batch.execute!
|
140
142
|
batch
|
141
143
|
end
|
142
|
-
|
143
144
|
end
|
144
145
|
end
|
145
146
|
end
|
@@ -64,7 +64,10 @@ module Aws
|
|
64
64
|
def each
|
65
65
|
return enum_for(:each) unless block_given?
|
66
66
|
|
67
|
-
@items.each
|
67
|
+
@items.each do |item|
|
68
|
+
yield(item)
|
69
|
+
end
|
70
|
+
|
68
71
|
until complete?
|
69
72
|
new_items = execute!
|
70
73
|
new_items.each { |new_item| yield new_item }
|
@@ -156,7 +159,7 @@ module Aws
|
|
156
159
|
|
157
160
|
def update_unprocessed_keys(keys)
|
158
161
|
keys.each do |table_name, table_values|
|
159
|
-
table_values.keys.each do |key|
|
162
|
+
table_values.keys.each do |key| # rubocop:disable Style/HashEachMethods
|
160
163
|
unprocessed_keys << { keys: key, table_name: table_name }
|
161
164
|
end
|
162
165
|
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,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Aws
|
2
4
|
module Record
|
3
5
|
class BuildableSearch
|
4
|
-
SUPPORTED_OPERATIONS = [
|
6
|
+
SUPPORTED_OPERATIONS = %i[query scan].freeze
|
5
7
|
|
6
8
|
# This should never be called directly, rather it is called by the
|
7
9
|
# #build_query or #build_scan methods of your aws-record model class.
|
@@ -11,12 +13,12 @@ module Aws
|
|
11
13
|
if SUPPORTED_OPERATIONS.include?(operation)
|
12
14
|
@operation = operation
|
13
15
|
else
|
14
|
-
raise ArgumentError
|
16
|
+
raise ArgumentError, "Unsupported operation: #{operation}"
|
15
17
|
end
|
16
18
|
@model = model
|
17
19
|
@params = {}
|
18
|
-
@next_name =
|
19
|
-
@next_value =
|
20
|
+
@next_name = 'BUILDERA'
|
21
|
+
@next_value = 'buildera'
|
20
22
|
end
|
21
23
|
|
22
24
|
# If you are querying or scanning on an index, you can specify it with
|
@@ -40,10 +42,10 @@ module Aws
|
|
40
42
|
# the :segment number of this scan.
|
41
43
|
def parallel_scan(opts)
|
42
44
|
unless @operation == :scan
|
43
|
-
raise ArgumentError
|
45
|
+
raise ArgumentError, 'parallel_scan is only supported for scans'
|
44
46
|
end
|
45
47
|
unless opts[:total_segments] && opts[:segment]
|
46
|
-
raise ArgumentError
|
48
|
+
raise ArgumentError, 'Must specify :total_segments and :segment in a parallel scan.'
|
47
49
|
end
|
48
50
|
@params[:total_segments] = opts[:total_segments]
|
49
51
|
@params[:segment] = opts[:segment]
|
@@ -55,7 +57,7 @@ module Aws
|
|
55
57
|
# run in ascending order.
|
56
58
|
def scan_ascending(b)
|
57
59
|
unless @operation == :query
|
58
|
-
raise ArgumentError
|
60
|
+
raise ArgumentError, 'scan_ascending is only supported for queries.'
|
59
61
|
end
|
60
62
|
@params[:scan_index_forward] = b
|
61
63
|
self
|
@@ -89,7 +91,7 @@ module Aws
|
|
89
91
|
# q.to_a # You can use this like any other query result in aws-record
|
90
92
|
def key_expr(statement_str, *subs)
|
91
93
|
unless @operation == :query
|
92
|
-
raise ArgumentError
|
94
|
+
raise ArgumentError, 'key_expr is only supported for queries.'
|
93
95
|
end
|
94
96
|
names = @params[:expression_attribute_names]
|
95
97
|
if names.nil?
|
@@ -143,10 +145,10 @@ module Aws
|
|
143
145
|
|
144
146
|
# Allows you to define a projection expression for the values returned by
|
145
147
|
# a query or scan. See
|
146
|
-
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html
|
147
|
-
# for more details on projection expressions.
|
148
|
-
# your aws-record model class in a projection expression.
|
149
|
-
# retrieved.
|
148
|
+
# {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html
|
149
|
+
# the Amazon DynamoDB Developer Guide} for more details on projection expressions.
|
150
|
+
# You can use the symbols from your aws-record model class in a projection expression.
|
151
|
+
# Keys are always retrieved.
|
150
152
|
#
|
151
153
|
# @example Scan with a projection expression:
|
152
154
|
# # Example model class
|
@@ -231,30 +233,33 @@ module Aws
|
|
231
233
|
end
|
232
234
|
|
233
235
|
private
|
236
|
+
|
234
237
|
def _key_pass(statement, names)
|
235
238
|
statement.gsub(/:(\w+)/) do |match|
|
236
|
-
key = match.gsub(':','').to_sym
|
239
|
+
key = match.gsub(':', '').to_sym
|
237
240
|
key_name = @model.attributes.storage_name_for(key)
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
241
|
+
|
242
|
+
raise "No such key #{key}" unless key_name
|
243
|
+
|
244
|
+
sub_name = _next_name
|
245
|
+
|
246
|
+
raise 'Substitution collision!' if names[sub_name]
|
247
|
+
|
248
|
+
names[sub_name] = key_name
|
249
|
+
sub_name
|
246
250
|
end
|
247
251
|
end
|
248
252
|
|
249
253
|
def _apply_values(statement, subs, values)
|
250
254
|
count = 0
|
251
|
-
statement.gsub(/[?]/) do
|
255
|
+
result = statement.gsub(/[?]/) do ||
|
252
256
|
sub_value = _next_value
|
253
|
-
raise
|
257
|
+
raise 'Substitution collision!' if values[sub_value]
|
254
258
|
values[sub_value] = subs[count]
|
255
259
|
count += 1
|
256
260
|
sub_value
|
257
|
-
end
|
261
|
+
end
|
262
|
+
result.tap do
|
258
263
|
unless count == subs.size
|
259
264
|
raise "Expected #{count} values in the substitution set, but found #{subs.size}"
|
260
265
|
end
|
@@ -262,14 +267,14 @@ module Aws
|
|
262
267
|
end
|
263
268
|
|
264
269
|
def _next_name
|
265
|
-
ret =
|
266
|
-
@next_name.next
|
270
|
+
ret = '#' + @next_name
|
271
|
+
@next_name = @next_name.next
|
267
272
|
ret
|
268
273
|
end
|
269
274
|
|
270
275
|
def _next_value
|
271
|
-
ret =
|
272
|
-
@next_value.next
|
276
|
+
ret = ':' + @next_value
|
277
|
+
@next_value = @next_value.next
|
273
278
|
ret
|
274
279
|
end
|
275
280
|
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
|
@@ -31,16 +20,19 @@ module Aws
|
|
31
20
|
# @param [Hash] opts the options you wish to use to create the client.
|
32
21
|
# Note that if you include the option +:client+, all other options
|
33
22
|
# will be ignored. See the documentation for other options in the
|
34
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method
|
23
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method
|
24
|
+
# AWS SDK for Ruby}.
|
35
25
|
# @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
|
36
26
|
# own pre-configured client.
|
37
27
|
def configure_client(opts = {})
|
28
|
+
# rubocop:disable Style/RedundantSelf
|
38
29
|
if self.class != Module && Aws::Record.extends_record?(self) && opts.empty? &&
|
39
|
-
|
40
|
-
|
30
|
+
self.superclass.instance_variable_get('@dynamodb_client')
|
31
|
+
@dynamodb_client = self.superclass.instance_variable_get('@dynamodb_client')
|
41
32
|
else
|
42
33
|
@dynamodb_client = _build_client(opts)
|
43
34
|
end
|
35
|
+
# rubocop:enable Style/RedundantSelf
|
44
36
|
end
|
45
37
|
|
46
38
|
# Gets the
|
@@ -61,12 +53,9 @@ module Aws
|
|
61
53
|
|
62
54
|
def _build_client(opts = {})
|
63
55
|
provided_client = opts.delete(:client)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def _user_agent(custom)
|
69
|
-
custom || " aws-record/#{VERSION}"
|
56
|
+
client = provided_client || Aws::DynamoDB::Client.new(opts)
|
57
|
+
client.config.user_agent_frameworks << 'aws-record'
|
58
|
+
client
|
70
59
|
end
|
71
60
|
end
|
72
61
|
end
|