aws-record 2.11.0 → 2.13.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +84 -19
  3. data/VERSION +1 -1
  4. data/lib/aws-record/record/attribute.rb +4 -2
  5. data/lib/aws-record/record/batch_read.rb +8 -13
  6. data/lib/aws-record/record/batch_write.rb +2 -1
  7. data/lib/aws-record/record/buildable_search.rb +15 -20
  8. data/lib/aws-record/record/client_configuration.rb +7 -7
  9. data/lib/aws-record/record/dirty_tracking.rb +3 -11
  10. data/lib/aws-record/record/errors.rb +18 -1
  11. data/lib/aws-record/record/item_collection.rb +5 -5
  12. data/lib/aws-record/record/item_data.rb +10 -11
  13. data/lib/aws-record/record/item_operations.rb +128 -96
  14. data/lib/aws-record/record/marshalers/boolean_marshaler.rb +4 -4
  15. data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -3
  16. data/lib/aws-record/record/marshalers/date_time_marshaler.rb +1 -3
  17. data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +2 -6
  18. data/lib/aws-record/record/marshalers/float_marshaler.rb +4 -4
  19. data/lib/aws-record/record/marshalers/integer_marshaler.rb +4 -4
  20. data/lib/aws-record/record/marshalers/list_marshaler.rb +6 -6
  21. data/lib/aws-record/record/marshalers/map_marshaler.rb +6 -6
  22. data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +7 -7
  23. data/lib/aws-record/record/marshalers/string_marshaler.rb +3 -1
  24. data/lib/aws-record/record/marshalers/string_set_marshaler.rb +6 -6
  25. data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -3
  26. data/lib/aws-record/record/model_attributes.rb +14 -16
  27. data/lib/aws-record/record/query.rb +4 -4
  28. data/lib/aws-record/record/secondary_indexes.rb +22 -25
  29. data/lib/aws-record/record/table_config.rb +45 -56
  30. data/lib/aws-record/record/table_migration.rb +32 -36
  31. data/lib/aws-record/record/transactions.rb +15 -23
  32. data/lib/aws-record/record/version.rb +1 -1
  33. data/lib/aws-record/record.rb +8 -8
  34. metadata +4 -5
@@ -52,31 +52,29 @@ module Aws
52
52
  end
53
53
 
54
54
  def _validate_attr_name(name)
55
- unless name.is_a?(Symbol)
56
- raise ArgumentError, 'Must use symbolized :name attribute.'
57
- end
58
- if @attributes[name]
59
- raise Errors::NameCollision, "Cannot overwrite existing attribute #{name}"
60
- end
55
+ raise ArgumentError, 'Must use symbolized :name attribute.' unless name.is_a?(Symbol)
56
+ return unless @attributes[name]
57
+
58
+ raise Errors::NameCollision, "Cannot overwrite existing attribute #{name}"
61
59
  end
62
60
 
63
61
  def _check_if_reserved(name)
64
- if @model_class.instance_methods.include?(name)
65
- raise Errors::ReservedName, "Cannot name an attribute #{name}, that would collide with an"\
66
- ' existing instance method.'
67
- end
62
+ return unless @model_class.instance_methods.include?(name)
63
+
64
+ raise Errors::ReservedName, "Cannot name an attribute #{name}, that would collide with an " \
65
+ 'existing instance method.'
68
66
  end
69
67
 
70
68
  def _check_for_naming_collisions(name, storage_name)
71
69
  if @attributes[storage_name.to_sym]
72
- raise Errors::NameCollision, "Custom storage name #{storage_name} already exists as an"\
73
- " attribute name in #{@attributes}"
70
+ raise Errors::NameCollision, "Custom storage name #{storage_name} already exists as an " \
71
+ "attribute name in #{@attributes}"
74
72
  elsif @storage_attributes[name.to_s]
75
- raise Errors::NameCollision, "Attribute name #{name} already exists as a custom storage"\
76
- " name in #{@storage_attributes}"
73
+ raise Errors::NameCollision, "Attribute name #{name} already exists as a custom storage " \
74
+ "name in #{@storage_attributes}"
77
75
  elsif @storage_attributes[storage_name]
78
- raise Errors::NameCollision, "Custom storage name #{storage_name} already in use in"\
79
- " #{@storage_attributes}"
76
+ raise Errors::NameCollision, "Custom storage name #{storage_name} already in use in " \
77
+ "#{@storage_attributes}"
80
78
 
81
79
  end
82
80
  end
@@ -10,7 +10,7 @@ module Aws
10
10
 
11
11
  module QueryClassMethods
12
12
  # This method calls
13
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#query-instance_method
13
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#query-instance_method
14
14
  # Aws::DynamoDB::Client#query}, populating the +:table_name+ parameter from the model
15
15
  # class, and combining this with the other parameters you provide.
16
16
  #
@@ -44,7 +44,7 @@ module Aws
44
44
  # end
45
45
  #
46
46
  # @param [Hash] opts options to pass on to the client call to +#query+.
47
- # See the documentation above in the AWS SDK for Ruby V2.
47
+ # See the documentation above in the AWS SDK for Ruby V3.
48
48
  # @return [Aws::Record::ItemCollection] an enumerable collection of the
49
49
  # query result.
50
50
  def query(opts)
@@ -53,7 +53,7 @@ module Aws
53
53
  end
54
54
 
55
55
  # This method calls
56
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#scan-instance_method
56
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#scan-instance_method
57
57
  # Aws::DynamoDB::Client#scan}, populating the +:table_name+ parameter from the model
58
58
  # class, and combining this with the other parameters you provide.
59
59
  #
@@ -82,7 +82,7 @@ module Aws
82
82
  # end
83
83
  #
84
84
  # @param [Hash] opts options to pass on to the client call to +#scan+.
85
- # See the documentation above in the AWS SDK for Ruby V2.
85
+ # See the documentation above in the AWS SDK for Ruby V3.
86
86
  # @return [Aws::Record::ItemCollection] an enumerable collection of the
87
87
  # scan result.
88
88
  def scan(opts = {})
@@ -30,11 +30,11 @@ module Aws
30
30
  # @param [Symbol] name index name for this local secondary index
31
31
  # @param [Hash] opts
32
32
  # @option opts [Symbol] :range_key the range key used by this local
33
- # secondary index. Note that the hash key MUST be the table's hash
34
- # key, and so that value will be filled in for you.
33
+ # secondary index. Note that the hash key MUST be the table's hash
34
+ # key, and so that value will be filled in for you.
35
35
  # @option opts [Hash] :projection a hash which defines which attributes
36
- # are copied from the table to the index. See shape details in the
37
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V2 docs}.
36
+ # are copied from the table to the index. See shape details in the
37
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V3 docs}.
38
38
  def local_secondary_index(name, opts)
39
39
  opts[:hash_key] = hash_key
40
40
  _validate_required_lsi_keys(opts)
@@ -50,12 +50,12 @@ module Aws
50
50
  # @param [Symbol] name index name for this global secondary index
51
51
  # @param [Hash] opts
52
52
  # @option opts [Symbol] :hash_key the hash key used by this global
53
- # secondary index.
53
+ # secondary index.
54
54
  # @option opts [Symbol] :range_key the range key used by this global
55
- # secondary index.
55
+ # secondary index.
56
56
  # @option opts [Hash] :projection a hash which defines which attributes
57
- # are copied from the table to the index. See shape details in the
58
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V2 docs}.
57
+ # are copied from the table to the index. See shape details in the
58
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Types/Projection.html AWS SDK for Ruby V3 docs}.
59
59
  def global_secondary_index(name, opts)
60
60
  _validate_required_gsi_keys(opts)
61
61
  global_secondary_indexes[name] = opts
@@ -99,7 +99,8 @@ module Aws
99
99
 
100
100
  def _migration_format_indexes(indexes)
101
101
  return nil if indexes.empty?
102
- mfi = indexes.collect do |name, opts|
102
+
103
+ indexes.collect do |name, opts|
103
104
  h = { index_name: name }
104
105
  h[:key_schema] = _si_key_schema(opts)
105
106
  hk = opts.delete(:hash_key)
@@ -109,7 +110,6 @@ module Aws
109
110
  opts[:range_key] = rk if rk
110
111
  h
111
112
  end
112
- mfi
113
113
  end
114
114
 
115
115
  def _si_key_schema(opts)
@@ -127,22 +127,20 @@ module Aws
127
127
  end
128
128
 
129
129
  def _validate_required_lsi_keys(params)
130
- if params[:hash_key] && params[:range_key]
131
- _validate_attributes_exist(params[:hash_key], params[:range_key])
132
- else
130
+ unless params[:hash_key] && params[:range_key]
133
131
  raise ArgumentError, 'Local Secondary Indexes require a hash and range key!'
134
132
  end
133
+
134
+ _validate_attributes_exist(params[:hash_key], params[:range_key])
135
135
  end
136
136
 
137
137
  def _validate_required_gsi_keys(params)
138
- if params[:hash_key]
139
- if params[:range_key]
140
- _validate_attributes_exist(params[:hash_key], params[:range_key])
141
- else
142
- _validate_attributes_exist(params[:hash_key])
143
- end
138
+ raise ArgumentError, 'Global Secondary Indexes require at least a hash key!' unless params[:hash_key]
139
+
140
+ if params[:range_key]
141
+ _validate_attributes_exist(params[:hash_key], params[:range_key])
144
142
  else
145
- raise ArgumentError, 'Global Secondary Indexes require at least a hash key!'
143
+ _validate_attributes_exist(params[:hash_key])
146
144
  end
147
145
  end
148
146
 
@@ -150,12 +148,11 @@ module Aws
150
148
  missing = attr_names.reject do |attr_name|
151
149
  @attributes.present?(attr_name)
152
150
  end
153
- unless missing.empty?
154
- raise ArgumentError, "#{missing.join(', ')} not present in model attributes."\
155
- ' Please ensure that attributes are defined in the model'\
156
- ' class BEFORE defining an index on those attributes.'
151
+ return if missing.empty?
157
152
 
158
- end
153
+ raise ArgumentError, "#{missing.join(', ')} not present in model attributes. " \
154
+ 'Please ensure that attributes are defined in the model ' \
155
+ 'class BEFORE defining an index on those attributes.'
159
156
  end
160
157
  end
161
158
  end
@@ -194,11 +194,9 @@ module Aws
194
194
  # @api private
195
195
  def ttl_attribute(attribute_symbol)
196
196
  attribute = @model_class.attributes.attribute_for(attribute_symbol)
197
- if attribute
198
- @ttl_attribute = attribute.database_name
199
- else
200
- raise ArgumentError, "Invalid attribute #{attribute_symbol} for #{@model_class}"
201
- end
197
+ raise ArgumentError, "Invalid attribute #{attribute_symbol} for #{@model_class}" unless attribute
198
+
199
+ @ttl_attribute = attribute.database_name
202
200
  end
203
201
 
204
202
  # @api private
@@ -245,17 +243,18 @@ module Aws
245
243
  # First up is TTL attribute. Since this migration is not exact match,
246
244
  # we will only alter TTL status if we have a TTL attribute defined. We
247
245
  # may someday support explicit TTL deletion, but we do not yet do this.
248
- if @ttl_attribute
249
- unless _ttl_compatibility_check
250
- client.update_time_to_live(
251
- table_name: @model_class.table_name,
252
- time_to_live_specification: {
253
- enabled: true,
254
- attribute_name: @ttl_attribute
255
- }
256
- )
257
- end # Else TTL is compatible and we are done.
258
- end # Else our work is done.
246
+ return unless @ttl_attribute
247
+ return if _ttl_compatibility_check
248
+
249
+ client.update_time_to_live(
250
+ table_name: @model_class.table_name,
251
+ time_to_live_specification: {
252
+ enabled: true,
253
+ attribute_name: @ttl_attribute
254
+ }
255
+ )
256
+ # Else TTL is compatible and we are done.
257
+ # Else our work is done.
259
258
  end
260
259
 
261
260
  # Checks the remote table for compatibility. Similar to +#exact_match?+,
@@ -382,7 +381,7 @@ module Aws
382
381
  resp_gsis = resp.table.global_secondary_indexes
383
382
  _add_global_secondary_index_throughput(opts, resp_gsis)
384
383
  end
385
- end # else don't include billing mode
384
+ end
386
385
  opts
387
386
  elsif @billing_mode == 'PAY_PER_REQUEST'
388
387
  {
@@ -400,9 +399,7 @@ module Aws
400
399
  table_name: @model_class.table_name,
401
400
  global_secondary_index_updates: gsi_updates
402
401
  }
403
- unless attribute_definitions.empty?
404
- opts[:attribute_definitions] = attribute_definitions
405
- end
402
+ opts[:attribute_definitions] = attribute_definitions unless attribute_definitions.empty?
406
403
  opts
407
404
  end
408
405
 
@@ -474,12 +471,12 @@ module Aws
474
471
  exists = attribute_definitions.any? do |ad|
475
472
  ad[:attribute_name] == attribute.database_name
476
473
  end
477
- unless exists
478
- attribute_definitions << {
479
- attribute_name: attribute.database_name,
480
- attribute_type: attribute.dynamodb_type
481
- }
482
- end
474
+ next if exists
475
+
476
+ attribute_definitions << {
477
+ attribute_name: attribute.database_name,
478
+ attribute_type: attribute.dynamodb_type
479
+ }
483
480
  end
484
481
  end
485
482
  attribute_definitions
@@ -566,15 +563,15 @@ module Aws
566
563
  rpt[k] == v
567
564
  end
568
565
  elsif @billing_mode == 'PAY_PER_REQUEST'
569
- pt_match = lpt.nil? ? true : false
566
+ pt_match = lpt.nil?
570
567
  else
571
568
  raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
572
569
  end
573
570
 
574
571
  rp = rgsi.projection.to_h
575
572
  lp = lgsi[:projection]
576
- rp[:non_key_attributes].sort! if rp[:non_key_attributes]
577
- lp[:non_key_attributes].sort! if lp[:non_key_attributes]
573
+ rp[:non_key_attributes]&.sort!
574
+ lp[:non_key_attributes]&.sort!
578
575
  p_match = rp == lp
579
576
 
580
577
  ks_match && pt_match && p_match
@@ -584,15 +581,11 @@ module Aws
584
581
  def _gsi_index_names(remote, local)
585
582
  remote_index_names = Set.new
586
583
  local_index_names = Set.new
587
- if remote
588
- remote.each do |gsi|
589
- remote_index_names.add(gsi.index_name)
590
- end
584
+ remote&.each do |gsi|
585
+ remote_index_names.add(gsi.index_name)
591
586
  end
592
- if local
593
- local.each do |gsi|
594
- local_index_names.add(gsi[:index_name].to_s)
595
- end
587
+ local&.each do |gsi|
588
+ local_index_names.add(gsi[:index_name].to_s)
596
589
  end
597
590
  [remote_index_names, local_index_names]
598
591
  end
@@ -601,17 +594,15 @@ module Aws
601
594
  gsis = []
602
595
  model_gsis = @model_class.global_secondary_indexes_for_migration
603
596
  gsi_config = @global_secondary_indexes
604
- if model_gsis
605
- model_gsis.each do |mgsi|
606
- config = gsi_config[mgsi[:index_name]]
607
- if @billing_mode == 'PROVISIONED'
608
- gsis << mgsi.merge(
609
- provisioned_throughput: config.provisioned_throughput
610
- )
611
- else
612
- gsis << mgsi
613
- end
614
- end
597
+ model_gsis&.each do |mgsi|
598
+ config = gsi_config[mgsi[:index_name]]
599
+ gsis << if @billing_mode == 'PROVISIONED'
600
+ mgsi.merge(
601
+ provisioned_throughput: config.provisioned_throughput
602
+ )
603
+ else
604
+ mgsi
605
+ end
615
606
  end
616
607
  gsis
617
608
  end
@@ -626,15 +617,13 @@ module Aws
626
617
  if @billing_mode == 'PROVISIONED'
627
618
  missing_config << 'read_capacity_units' unless @read_capacity_units
628
619
  missing_config << 'write_capacity_units' unless @write_capacity_units
629
- else
630
- if @read_capacity_units || @write_capacity_units
631
- raise ArgumentError, "Cannot have billing mode #{@billing_mode} with provisioned capacity."
632
- end
633
- end
634
- unless missing_config.empty?
635
- msg = missing_config.join(', ')
636
- raise Errors::MissingRequiredConfiguration, 'Missing: ' + msg
620
+ elsif @read_capacity_units || @write_capacity_units
621
+ raise ArgumentError, "Cannot have billing mode #{@billing_mode} with provisioned capacity."
637
622
  end
623
+ return if missing_config.empty?
624
+
625
+ msg = missing_config.join(', ')
626
+ raise Errors::MissingRequiredConfiguration, "Missing: #{msg}"
638
627
  end
639
628
 
640
629
  # @api private
@@ -5,7 +5,7 @@ module Aws
5
5
  class TableMigration
6
6
  # @!attribute [rw] client
7
7
  # @return [Aws::DynamoDB::Client] the
8
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
8
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
9
9
  # class used by this table migration instance.
10
10
  attr_accessor :client
11
11
 
@@ -13,7 +13,7 @@ module Aws
13
13
  # @param [Hash] opts
14
14
  # @option opts [Aws::DynamoDB::Client] :client Allows you to inject your
15
15
  # own
16
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
16
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
17
17
  # class. If this option is not included, a client will be constructed for
18
18
  # you with default parameters.
19
19
  def initialize(model, opts = {})
@@ -24,7 +24,7 @@ module Aws
24
24
  end
25
25
 
26
26
  # This method calls
27
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#create_table-instance_method
27
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#create_table-instance_method
28
28
  # Aws::DynamoDB::Client#create_table}, populating the attribute definitions and
29
29
  # key schema based on your model class, as well as passing through other
30
30
  # parameters as provided by you.
@@ -75,9 +75,9 @@ module Aws
75
75
  end
76
76
  if (gsis = @model.global_secondary_indexes_for_migration)
77
77
  unless gsit || opts[:billing_mode] == 'PAY_PER_REQUEST'
78
- raise ArgumentError, 'If you define global secondary indexes, you must also define'\
79
- ' :global_secondary_index_throughput on table creation,'\
80
- " unless :billing_mode is set to 'PAY_PER_REQUEST'."
78
+ raise ArgumentError, 'If you define global secondary indexes, you must also define ' \
79
+ ':global_secondary_index_throughput on table creation, ' \
80
+ "unless :billing_mode is set to 'PAY_PER_REQUEST'."
81
81
  end
82
82
  gsis_opts = if opts[:billing_mode] == 'PAY_PER_REQUEST'
83
83
  gsis
@@ -91,7 +91,7 @@ module Aws
91
91
  end
92
92
 
93
93
  # This method calls
94
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_table-instance_method
94
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#update_table-instance_method
95
95
  # Aws::DynamoDB::Client#update_table} using the parameters that you provide.
96
96
  #
97
97
  # @param [Hash] opts options to pass on to the client call to
@@ -109,7 +109,7 @@ module Aws
109
109
  end
110
110
 
111
111
  # This method calls
112
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_table-instance_method
112
+ # {http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#delete_table-instance_method
113
113
  # Aws::DynamoDB::Client#delete_table} using the table name of your model.
114
114
  #
115
115
  # @raise [Aws::Record::Errors::TableDoesNotExist] if the table did not
@@ -136,29 +136,25 @@ module Aws
136
136
  end
137
137
 
138
138
  def _assert_required_include(model)
139
- unless model.include?(::Aws::Record)
140
- raise Errors::InvalidModel, 'Table models must include Aws::Record'
141
- end
139
+ return if model.include?(::Aws::Record)
140
+
141
+ raise Errors::InvalidModel, 'Table models must include Aws::Record'
142
142
  end
143
143
 
144
144
  def _validate_billing(opts)
145
145
  valid_modes = %w[PAY_PER_REQUEST PROVISIONED]
146
- if opts.key?(:billing_mode)
147
- unless valid_modes.include?(opts[:billing_mode])
148
- raise ArgumentError, ":billing_mode option must be one of #{valid_modes.join(', ')}"\
149
- " current value is: #{opts[:billing_mode]}"
150
- end
146
+ if opts.key?(:billing_mode) && !valid_modes.include?(opts[:billing_mode])
147
+ raise ArgumentError, ":billing_mode option must be one of #{valid_modes.join(', ')} " \
148
+ "current value is: #{opts[:billing_mode]}"
151
149
  end
152
150
  if opts.key?(:provisioned_throughput)
153
151
  if opts[:billing_mode] == 'PAY_PER_REQUEST'
154
- raise ArgumentError, 'when :provisioned_throughput option is specified, :billing_mode'\
155
- " must either be unspecified or have a value of 'PROVISIONED'"
156
- end
157
- else
158
- if opts[:billing_mode] != 'PAY_PER_REQUEST'
159
- raise ArgumentError, 'when :provisioned_throughput option is not specified,'\
160
- " :billing_mode must be set to 'PAY_PER_REQUEST'"
152
+ raise ArgumentError, 'when :provisioned_throughput option is specified, :billing_mode ' \
153
+ "must either be unspecified or have a value of 'PROVISIONED'"
161
154
  end
155
+ elsif opts[:billing_mode] != 'PAY_PER_REQUEST'
156
+ raise ArgumentError, 'when :provisioned_throughput option is not specified, ' \
157
+ ":billing_mode must be set to 'PAY_PER_REQUEST'"
162
158
  end
163
159
  end
164
160
 
@@ -179,15 +175,15 @@ module Aws
179
175
  exists = attr_def.find do |a|
180
176
  a[:attribute_name] == key_schema[:attribute_name]
181
177
  end
182
- unless exists
183
- attr = attributes.attribute_for(
184
- attributes.db_to_attribute_name(key_schema[:attribute_name])
185
- )
186
- attr_def << {
187
- attribute_name: attr.database_name,
188
- attribute_type: attr.dynamodb_type
189
- }
190
- end
178
+ next if exists
179
+
180
+ attr = attributes.attribute_for(
181
+ attributes.db_to_attribute_name(key_schema[:attribute_name])
182
+ )
183
+ attr_def << {
184
+ attribute_name: attr.database_name,
185
+ attribute_type: attr.dynamodb_type
186
+ }
191
187
  end
192
188
  end
193
189
  create_opts[:attribute_definitions] = attr_def
@@ -202,10 +198,10 @@ module Aws
202
198
  params.merge(provisioned_throughput: throughput)
203
199
  end
204
200
  unless missing_throughput.empty?
205
- raise ArgumentError, 'Missing provisioned throughput for the following global secondary'\
206
- " indexes: #{missing_throughput.join(', ')}. GSIs:"\
207
- " #{global_secondary_indexes} and defined throughput:"\
208
- " #{gsi_throughput}"
201
+ raise ArgumentError, 'Missing provisioned throughput for the following global secondary ' \
202
+ "indexes: #{missing_throughput.join(', ')}. GSIs: " \
203
+ "#{global_secondary_indexes} and defined throughput: " \
204
+ "#{gsi_throughput}"
209
205
  end
210
206
  ret
211
207
  end
@@ -236,7 +236,7 @@ module Aws
236
236
  elsif (check_record = item.delete(:check))
237
237
  _transform_check_record(check_record, item)
238
238
  else
239
- raise ArgumentError, 'Invalid transact write item, must include an operation of '\
239
+ raise ArgumentError, 'Invalid transact write item, must include an operation of ' \
240
240
  "type :save, :update, :delete, :update, or :check - #{item}"
241
241
 
242
242
  end
@@ -250,13 +250,13 @@ module Aws
250
250
  safety_expression = save_record.send(:prevent_overwrite_expression)
251
251
  if opts.include?(:condition_expression)
252
252
  raise Errors::TransactionalSaveConditionCollision,
253
- 'Transactional write includes a :save operation that would '\
254
- "result in a 'safe put' for the given item, yet a "\
255
- 'condition expression was also provided. This is not '\
256
- 'currently supported. You should rewrite this case to use '\
257
- 'a :put transaction, adding the existence check to your '\
258
- "own condition expression if desired.\n"\
259
- "\tItem: #{JSON.pretty_unparse(save_record.to_h)}\n"\
253
+ 'Transactional write includes a :save operation that would ' \
254
+ "result in a 'safe put' for the given item, yet a " \
255
+ 'condition expression was also provided. This is not ' \
256
+ 'currently supported. You should rewrite this case to use ' \
257
+ 'a :put transaction, adding the existence check to your ' \
258
+ "own condition expression if desired.\n" \
259
+ "\tItem: #{JSON.pretty_unparse(save_record.to_h)}\n" \
260
260
  "\tExtra Options: #{JSON.pretty_unparse(opts)}"
261
261
  else
262
262
  opts = opts.merge(safety_expression)
@@ -284,25 +284,17 @@ module Aws
284
284
  def _transform_update_record(update_record, opts)
285
285
  # extract dirty attribute changes to perform an update
286
286
  opts[:table_name] = update_record.class.table_name
287
+ opts[:key] = update_record.send(:key_values)
287
288
  dirty_changes = update_record.send(:_dirty_changes_for_update)
288
- update_tuple = update_record.class.send(
289
+ update_expression_opts = update_record.class.send(
289
290
  :_build_update_expression,
290
291
  dirty_changes
291
292
  )
292
- uex, exp_attr_names, exp_attr_values = update_tuple
293
- opts[:key] = update_record.send(:key_values)
294
- opts[:update_expression] = uex
295
- # need to combine expression attribute names and values
296
- if (names = opts[:expression_attribute_names])
297
- opts[:expression_attribute_names] = exp_attr_names.merge(names)
298
- else
299
- opts[:expression_attribute_names] = exp_attr_names
300
- end
301
- if (values = opts[:expression_attribute_values])
302
- opts[:expression_attribute_values] = exp_attr_values.merge(values)
303
- else
304
- opts[:expression_attribute_values] = exp_attr_values
305
- end
293
+ opts = update_record.class.send(
294
+ :_merge_update_expression_opts,
295
+ update_expression_opts,
296
+ opts
297
+ )
306
298
  { update: opts }
307
299
  end
308
300
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  module Record
5
- VERSION = File.read(File.expand_path('../../../../VERSION', __FILE__)).strip
5
+ VERSION = File.read(File.expand_path('../../../VERSION', __dir__)).strip
6
6
  end
7
7
  end
@@ -117,14 +117,13 @@ module Aws
117
117
  # MyOtherTable.table_name # => "test_MyTable"
118
118
  def table_name
119
119
  # rubocop:disable Style/RedundantSelf
120
- @table_name ||= begin
121
- if Aws::Record.extends_record?(self) &&
122
- default_table_name(self.superclass) != self.superclass.table_name
123
- self.superclass.instance_variable_get('@table_name')
124
- else
125
- default_table_name(self)
126
- end
127
- end
120
+ @table_name ||= if Aws::Record.extends_record?(self) &&
121
+ default_table_name(self.superclass) != self.superclass.table_name
122
+ self.superclass.instance_variable_get('@table_name')
123
+ else
124
+ default_table_name(self)
125
+ end
126
+
128
127
  # rubocop:enable Style/RedundantSelf
129
128
  end
130
129
 
@@ -247,6 +246,7 @@ module Aws
247
246
 
248
247
  def default_table_name(klass)
249
248
  return unless klass.name
249
+
250
250
  klass.name.split('::').join('_')
251
251
  end
252
252
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-record
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.0
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-02 00:00:00.000000000 Z
11
+ date: 2023-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb
@@ -32,8 +32,7 @@ dependencies:
32
32
  version: 1.85.0
33
33
  description: Provides an object mapping abstraction for Amazon DynamoDB.
34
34
  email:
35
- - mamuller@amazon.com
36
- - alexwoo@amazon.com
35
+ - aws-dr-rubygems@amazon.com
37
36
  executables: []
38
37
  extensions: []
39
38
  extra_rdoc_files: []
@@ -87,7 +86,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
86
  requirements:
88
87
  - - ">="
89
88
  - !ruby/object:Gem::Version
90
- version: '0'
89
+ version: '2.3'
91
90
  required_rubygems_version: !ruby/object:Gem::Requirement
92
91
  requirements:
93
92
  - - ">="