aws-record 2.10.1 → 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 +5 -0
- data/VERSION +1 -1
- data/lib/aws-record/record/attribute.rb +4 -6
- data/lib/aws-record/record/attributes.rb +36 -49
- data/lib/aws-record/record/batch.rb +13 -12
- data/lib/aws-record/record/batch_read.rb +5 -2
- data/lib/aws-record/record/buildable_search.rb +29 -26
- data/lib/aws-record/record/client_configuration.rb +9 -9
- data/lib/aws-record/record/dirty_tracking.rb +29 -32
- data/lib/aws-record/record/errors.rb +0 -1
- data/lib/aws-record/record/item_collection.rb +4 -4
- data/lib/aws-record/record/item_data.rb +3 -6
- data/lib/aws-record/record/item_operations.rb +77 -93
- data/lib/aws-record/record/key_attributes.rb +0 -2
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +1 -4
- data/lib/aws-record/record/marshalers/date_marshaler.rb +0 -3
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +1 -2
- data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +0 -2
- data/lib/aws-record/record/marshalers/float_marshaler.rb +2 -7
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +2 -7
- data/lib/aws-record/record/marshalers/list_marshaler.rb +1 -4
- data/lib/aws-record/record/marshalers/map_marshaler.rb +1 -4
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +2 -4
- data/lib/aws-record/record/marshalers/string_marshaler.rb +1 -4
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +2 -4
- data/lib/aws-record/record/marshalers/time_marshaler.rb +0 -2
- data/lib/aws-record/record/model_attributes.rb +13 -23
- data/lib/aws-record/record/query.rb +6 -9
- data/lib/aws-record/record/secondary_indexes.rb +22 -30
- data/lib/aws-record/record/table_config.rb +51 -62
- data/lib/aws-record/record/table_migration.rb +42 -54
- data/lib/aws-record/record/transactions.rb +32 -35
- data/lib/aws-record/record.rb +29 -37
- metadata +11 -5
@@ -6,7 +6,6 @@ module Aws
|
|
6
6
|
extend ClientConfiguration
|
7
7
|
|
8
8
|
class << self
|
9
|
-
|
10
9
|
# @example Usage Example
|
11
10
|
# class TableOne
|
12
11
|
# include Aws::Record
|
@@ -43,11 +42,11 @@ module Aws
|
|
43
42
|
# * The aggregate size of the items in the transaction cannot exceed 4 MB.
|
44
43
|
#
|
45
44
|
# @param [Hash] opts Options to pass through to
|
46
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_get_items-instance_method
|
47
|
-
# with the exception of the
|
48
|
-
# {ItemOperations.ItemOperationsClassMethods.tfind_opts #tfind_opts}
|
49
|
-
# on your model class to provide extra metadata
|
50
|
-
# after retrieval.
|
45
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_get_items-instance_method
|
46
|
+
# Aws::DynamoDB::Client#transact_get_items}, with the exception of the
|
47
|
+
# +:transact_items+ array, which uses the {ItemOperations.ItemOperationsClassMethods.tfind_opts #tfind_opts}
|
48
|
+
# operation on your model class to provide extra metadata
|
49
|
+
# used to marshal your items after retrieval.
|
51
50
|
# @option opts [Array] :transact_items A set of +#tfind_opts+ results,
|
52
51
|
# such as those created by the usage example.
|
53
52
|
# @option opts [Aws::DynamoDB::Client] :client Optionally, you can pass
|
@@ -71,7 +70,6 @@ module Aws
|
|
71
70
|
client_resp = client.transact_get_items(
|
72
71
|
request_opts
|
73
72
|
)
|
74
|
-
responses = client_resp.responses
|
75
73
|
index = -1
|
76
74
|
ret = OpenStruct.new
|
77
75
|
ret.consumed_capacity = client_resp.consumed_capacity
|
@@ -187,11 +185,11 @@ module Aws
|
|
187
185
|
# * There is a user error, such as an invalid data format.
|
188
186
|
#
|
189
187
|
# @param [Hash] opts Options to pass through to
|
190
|
-
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_write_items-instance_method
|
191
|
-
# with the exception of
|
192
|
-
# to use your item to populate
|
193
|
-
# :
|
194
|
-
# for a comprehensive set of combinations.
|
188
|
+
# {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#transact_write_items-instance_method
|
189
|
+
# Aws::DynamoDB::Client#transact_write_items} with the exception of
|
190
|
+
# :transact_items array, which is transformed to use your item to populate
|
191
|
+
# the :key, :table_name, :item, and/or :update_expression parameters
|
192
|
+
# as appropriate. See the usage example for a comprehensive set of combinations.
|
195
193
|
# @option opts [Array] :transact_items An array of hashes, accepting
|
196
194
|
# +:save+, +:put+, +:delete+, +:update+, and +:check+ as specified.
|
197
195
|
# @option opts [Aws::DynamoDB::Client] :client Optionally, you can
|
@@ -212,35 +210,35 @@ module Aws
|
|
212
210
|
opts[:transact_items] = transact_items
|
213
211
|
resp = client.transact_write_items(opts)
|
214
212
|
# mark all items clean/destroyed as needed if we didn't raise an exception
|
215
|
-
dirty_items.each
|
216
|
-
delete_items.each { |i| i.instance_variable_get(
|
213
|
+
dirty_items.each(&:clean!)
|
214
|
+
delete_items.each { |i| i.instance_variable_get('@data').destroyed = true }
|
217
215
|
resp
|
218
216
|
end
|
219
217
|
|
220
218
|
private
|
219
|
+
|
221
220
|
def _transform_transact_write_items(transact_items, dirty_items, delete_items)
|
222
221
|
transact_items.map do |item|
|
223
222
|
# this code will assume users only provided one operation, and
|
224
223
|
# will fail down the line if that assumption is wrong
|
225
|
-
if save_record = item.delete(:save)
|
224
|
+
if (save_record = item.delete(:save))
|
226
225
|
dirty_items << save_record
|
227
226
|
_transform_save_record(save_record, item)
|
228
|
-
elsif put_record = item.delete(:put)
|
227
|
+
elsif (put_record = item.delete(:put))
|
229
228
|
dirty_items << put_record
|
230
229
|
_transform_put_record(put_record, item)
|
231
|
-
elsif delete_record = item.delete(:delete)
|
230
|
+
elsif (delete_record = item.delete(:delete))
|
232
231
|
delete_items << delete_record
|
233
232
|
_transform_delete_record(delete_record, item)
|
234
|
-
elsif update_record = item.delete(:update)
|
233
|
+
elsif (update_record = item.delete(:update))
|
235
234
|
dirty_items << update_record
|
236
235
|
_transform_update_record(update_record, item)
|
237
|
-
elsif check_record = item.delete(:check)
|
236
|
+
elsif (check_record = item.delete(:check))
|
238
237
|
_transform_check_record(check_record, item)
|
239
238
|
else
|
240
|
-
raise ArgumentError
|
241
|
-
|
242
|
-
|
243
|
-
)
|
239
|
+
raise ArgumentError, 'Invalid transact write item, must include an operation of '\
|
240
|
+
"type :save, :update, :delete, :update, or :check - #{item}"
|
241
|
+
|
244
242
|
end
|
245
243
|
end
|
246
244
|
end
|
@@ -251,16 +249,15 @@ module Aws
|
|
251
249
|
if save_record.send(:expect_new_item?)
|
252
250
|
safety_expression = save_record.send(:prevent_overwrite_expression)
|
253
251
|
if opts.include?(:condition_expression)
|
254
|
-
raise Errors::TransactionalSaveConditionCollision
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
)
|
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"\
|
260
|
+
"\tExtra Options: #{JSON.pretty_unparse(opts)}"
|
264
261
|
else
|
265
262
|
opts = opts.merge(safety_expression)
|
266
263
|
_transform_put_record(save_record, opts)
|
@@ -296,12 +293,12 @@ module Aws
|
|
296
293
|
opts[:key] = update_record.send(:key_values)
|
297
294
|
opts[:update_expression] = uex
|
298
295
|
# need to combine expression attribute names and values
|
299
|
-
if names = opts[:expression_attribute_names]
|
296
|
+
if (names = opts[:expression_attribute_names])
|
300
297
|
opts[:expression_attribute_names] = exp_attr_names.merge(names)
|
301
298
|
else
|
302
299
|
opts[:expression_attribute_names] = exp_attr_names
|
303
300
|
end
|
304
|
-
if values = opts[:expression_attribute_values]
|
301
|
+
if (values = opts[:expression_attribute_values])
|
305
302
|
opts[:expression_attribute_values] = exp_attr_values.merge(values)
|
306
303
|
else
|
307
304
|
opts[:expression_attribute_values] = exp_attr_values
|
data/lib/aws-record/record.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Aws
|
4
|
-
|
5
4
|
# +Aws::Record+ is the module you include in your model classes in order to
|
6
5
|
# decorate them with the Amazon DynamoDB integration methods provided by this
|
7
6
|
# library. Methods you can use are shown below, in sub-modules organized by
|
@@ -73,9 +72,7 @@ module Aws
|
|
73
72
|
sub_class.send(:include, DirtyTracking)
|
74
73
|
sub_class.send(:include, Query)
|
75
74
|
sub_class.send(:include, SecondaryIndexes)
|
76
|
-
if Aws::Record.extends_record?(sub_class)
|
77
|
-
inherit_track_mutations(sub_class)
|
78
|
-
end
|
75
|
+
inherit_track_mutations(sub_class) if Aws::Record.extends_record?(sub_class)
|
79
76
|
end
|
80
77
|
|
81
78
|
# @api private
|
@@ -83,18 +80,21 @@ module Aws
|
|
83
80
|
klass.superclass.include?(Aws::Record)
|
84
81
|
end
|
85
82
|
|
83
|
+
# @api private
|
84
|
+
def self.inherit_track_mutations(klass)
|
85
|
+
superclass_track_mutations = klass.superclass.instance_variable_get('@track_mutations')
|
86
|
+
klass.instance_variable_set('@track_mutations', superclass_track_mutations)
|
87
|
+
end
|
88
|
+
|
89
|
+
private_class_method :inherit_track_mutations
|
90
|
+
|
86
91
|
private
|
92
|
+
|
87
93
|
def dynamodb_client
|
88
94
|
self.class.dynamodb_client
|
89
95
|
end
|
90
96
|
|
91
|
-
def self.inherit_track_mutations(klass)
|
92
|
-
superclass_track_mutations = klass.superclass.instance_variable_get("@track_mutations")
|
93
|
-
klass.instance_variable_set("@track_mutations", superclass_track_mutations)
|
94
|
-
end
|
95
|
-
|
96
97
|
module RecordClassMethods
|
97
|
-
|
98
98
|
# Returns the Amazon DynamoDB table name for this model class.
|
99
99
|
#
|
100
100
|
# By default, this will simply be the name of the class. However, you can
|
@@ -116,14 +116,16 @@ module Aws
|
|
116
116
|
# MyTable.table_name # => "MyTable"
|
117
117
|
# MyOtherTable.table_name # => "test_MyTable"
|
118
118
|
def table_name
|
119
|
+
# rubocop:disable Style/RedundantSelf
|
119
120
|
@table_name ||= begin
|
120
121
|
if Aws::Record.extends_record?(self) &&
|
121
|
-
|
122
|
+
default_table_name(self.superclass) != self.superclass.table_name
|
122
123
|
self.superclass.instance_variable_get('@table_name')
|
123
124
|
else
|
124
125
|
default_table_name(self)
|
125
126
|
end
|
126
127
|
end
|
128
|
+
# rubocop:enable Style/RedundantSelf
|
127
129
|
end
|
128
130
|
|
129
131
|
# Allows you to set a custom Amazon DynamoDB table name for this model
|
@@ -175,7 +177,7 @@ module Aws
|
|
175
177
|
# end
|
176
178
|
#
|
177
179
|
# Dog.table_name # => "DogTable"
|
178
|
-
def set_table_name(name)
|
180
|
+
def set_table_name(name) # rubocop:disable Naming/AccessorMethodName
|
179
181
|
@table_name = name
|
180
182
|
end
|
181
183
|
|
@@ -187,32 +189,24 @@ module Aws
|
|
187
189
|
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table name does
|
188
190
|
# not exist in DynamoDB.
|
189
191
|
def provisioned_throughput
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
raise Record::Errors::TableDoesNotExist
|
199
|
-
end
|
192
|
+
resp = dynamodb_client.describe_table(table_name: table_name)
|
193
|
+
throughput = resp.table.provisioned_throughput
|
194
|
+
{
|
195
|
+
read_capacity_units: throughput.read_capacity_units,
|
196
|
+
write_capacity_units: throughput.write_capacity_units
|
197
|
+
}
|
198
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
199
|
+
raise Record::Errors::TableDoesNotExist
|
200
200
|
end
|
201
201
|
|
202
202
|
# Checks if the model's table name exists in Amazon DynamoDB.
|
203
203
|
#
|
204
204
|
# @return [Boolean] true if the table does exist, false if it does not.
|
205
205
|
def table_exists?
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
else
|
211
|
-
false
|
212
|
-
end
|
213
|
-
rescue DynamoDB::Errors::ResourceNotFoundException
|
214
|
-
false
|
215
|
-
end
|
206
|
+
resp = dynamodb_client.describe_table(table_name: table_name)
|
207
|
+
resp.table.table_status == 'ACTIVE'
|
208
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
209
|
+
false
|
216
210
|
end
|
217
211
|
|
218
212
|
# Turns off mutation tracking for all attributes in the model.
|
@@ -246,17 +240,15 @@ module Aws
|
|
246
240
|
end
|
247
241
|
|
248
242
|
def model_valid?
|
249
|
-
if @keys.hash_key.nil?
|
250
|
-
raise Errors::InvalidModel.new("Table models must include a hash key")
|
251
|
-
end
|
243
|
+
raise Errors::InvalidModel, 'Table models must include a hash key' if @keys.hash_key.nil?
|
252
244
|
end
|
253
245
|
|
254
246
|
private
|
247
|
+
|
255
248
|
def default_table_name(klass)
|
256
249
|
return unless klass.name
|
257
|
-
klass.name.split(
|
250
|
+
klass.name.split('::').join('_')
|
258
251
|
end
|
259
|
-
|
260
252
|
end
|
261
253
|
end
|
262
254
|
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.
|
4
|
+
version: 2.11.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-
|
11
|
+
date: 2023-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-dynamodb
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1
|
19
|
+
version: '1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.85.0
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1
|
29
|
+
version: '1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.85.0
|
27
33
|
description: Provides an object mapping abstraction for Amazon DynamoDB.
|
28
34
|
email:
|
29
35
|
- mamuller@amazon.com
|
@@ -88,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
94
|
- !ruby/object:Gem::Version
|
89
95
|
version: '0'
|
90
96
|
requirements: []
|
91
|
-
rubygems_version: 3.
|
97
|
+
rubygems_version: 3.4.10
|
92
98
|
signing_key:
|
93
99
|
specification_version: 4
|
94
100
|
summary: AWS Record library for Amazon DynamoDB
|