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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +335 -0
  3. data/LICENSE +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-record/record/attribute.rb +9 -21
  6. data/lib/aws-record/record/attributes.rb +68 -78
  7. data/lib/aws-record/record/batch.rb +13 -12
  8. data/lib/aws-record/record/batch_read.rb +5 -2
  9. data/lib/aws-record/record/batch_write.rb +1 -12
  10. data/lib/aws-record/record/buildable_search.rb +33 -28
  11. data/lib/aws-record/record/client_configuration.rb +10 -21
  12. data/lib/aws-record/record/dirty_tracking.rb +30 -44
  13. data/lib/aws-record/record/errors.rb +1 -13
  14. data/lib/aws-record/record/item_collection.rb +5 -16
  15. data/lib/aws-record/record/item_data.rb +4 -18
  16. data/lib/aws-record/record/item_operations.rb +86 -93
  17. data/lib/aws-record/record/key_attributes.rb +1 -14
  18. data/lib/aws-record/record/marshalers/boolean_marshaler.rb +2 -16
  19. data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -15
  20. data/lib/aws-record/record/marshalers/date_time_marshaler.rb +2 -14
  21. data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +1 -14
  22. data/lib/aws-record/record/marshalers/float_marshaler.rb +3 -19
  23. data/lib/aws-record/record/marshalers/integer_marshaler.rb +3 -19
  24. data/lib/aws-record/record/marshalers/list_marshaler.rb +2 -16
  25. data/lib/aws-record/record/marshalers/map_marshaler.rb +2 -16
  26. data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +3 -16
  27. data/lib/aws-record/record/marshalers/string_marshaler.rb +2 -16
  28. data/lib/aws-record/record/marshalers/string_set_marshaler.rb +3 -16
  29. data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -14
  30. data/lib/aws-record/record/model_attributes.rb +14 -35
  31. data/lib/aws-record/record/query.rb +7 -21
  32. data/lib/aws-record/record/secondary_indexes.rb +23 -42
  33. data/lib/aws-record/record/table_config.rb +52 -74
  34. data/lib/aws-record/record/table_migration.rb +43 -66
  35. data/lib/aws-record/record/transactions.rb +67 -38
  36. data/lib/aws-record/record/version.rb +2 -13
  37. data/lib/aws-record/record.rb +30 -49
  38. metadata +14 -5
@@ -1,28 +1,14 @@
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
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("@attributes", model_attributes)
22
- sub_class.instance_variable_set("@keys", KeyAttributes.new(model_attributes))
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("@attributes")
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("@attributes")
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("@keys")
103
- subclass_keys = klass.instance_variable_get("@keys")
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.range_key
110
- subclass_keys.range_key = superclass_keys.range_key
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
- module ClassMethods
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] = "S"
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] = "BOOL"
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] = "N"
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] = "N"
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] = "S"
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] = "S"
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] = "S"
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
- # epoch-seconds.
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] = "N"
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 V2's DynamoDB client knows how to marshal and
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] = "L"
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 V2's DynamoDB client knows how to marshal and
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] = "M"
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] = "SS"
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] = "NS"
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 Atomic counter}
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] = "N"
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 = "Attributes need to be saved before atomic counter can be incremented"
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
- ":i" => increment
490
+ ':i' => increment
497
491
  },
498
492
  expression_attribute_names: {
499
- "#n" => name
493
+ '#n' => name
500
494
  },
501
- update_expression: "SET #n = #n + :i",
502
- return_values: "UPDATED_NEW"
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 symbloc name of the table's range key, or nil if there is no range key.
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.new(
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 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.
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 Batch Operations and Error Handling}
29
- # in the DynamoDB Developer Guide for more details.
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 AWS SDK for Ruby}.
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 = {}, &block)
65
+ def write(opts = {})
64
66
  batch = BatchWrite.new(client: _build_client(opts))
65
- block.call(batch)
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 = {}, &block)
138
+ def read(opts = {})
137
139
  batch = BatchRead.new(client: _build_client(opts))
138
- block.call(batch)
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 { |item| yield item }
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
- # 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,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Record
3
5
  class BuildableSearch
4
- SUPPORTED_OPERATIONS = [:query, :scan]
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.new("Unsupported operation: #{operation}")
16
+ raise ArgumentError, "Unsupported operation: #{operation}"
15
17
  end
16
18
  @model = model
17
19
  @params = {}
18
- @next_name = "BUILDERA"
19
- @next_value = "buildera"
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.new("parallel_scan is only supported for scans")
45
+ raise ArgumentError, 'parallel_scan is only supported for scans'
44
46
  end
45
47
  unless opts[:total_segments] && opts[:segment]
46
- raise ArgumentError.new("Must specify :total_segments and :segment in a parallel scan.")
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.new("scan_ascending is only supported for queries.")
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.new("key_expr is only supported for queries.")
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 the Amazon DynamoDB Developer Guide}
147
- # for more details on projection expressions. You can use the symbols from
148
- # your aws-record model class in a projection expression. Keys are always
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
- if key_name
239
- sub_name = _next_name
240
- raise "Substitution collision!" if names[sub_name]
241
- names[sub_name] = key_name
242
- sub_name
243
- else
244
- raise "No such key #{key}"
245
- end
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 |match|
255
+ result = statement.gsub(/[?]/) do ||
252
256
  sub_value = _next_value
253
- raise "Substitution collision!" if values[sub_value]
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.tap do
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 = "#" + @next_name
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 = ":" + @next_value
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
- # 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
@@ -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 AWS SDK for Ruby}.
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
- self.superclass.instance_variable_get('@dynamodb_client')
40
- @dynamodb_client = self.superclass.instance_variable_get('@dynamodb_client')
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
- opts[:user_agent_suffix] = _user_agent(opts.delete(:user_agent_suffix))
65
- provided_client || Aws::DynamoDB::Client.new(opts)
66
- end
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