aws-record 2.4.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d017802e3f3023427a79e39fe59468a66f1fe138ef3a6bd173bdcc4d4a15c05c
4
- data.tar.gz: c9efe98e3226977a5c381d16cf0dd9ffcd77e6c99d7d4407d58c2e20908c5be2
3
+ metadata.gz: 67f48531ca8b917f680a1d9a5d21afd1611aba0eb96916a5783addaf7939cda8
4
+ data.tar.gz: 7f6cbb16271455ada17a61f32106800b65d3b4103a5254e7686e06d5cf715cca
5
5
  SHA512:
6
- metadata.gz: 0fd56a56605143708ee9f70074317452105860f86835f59653e484c0b1f700b9a7e587383fb9a9278c1eb3c0585cb6fde1024d07bf3d6bcefc1497fcd9ab5984
7
- data.tar.gz: ba3f5889ca0954c294ca77b752ab45cb7151067c81369b3b303c86f72e32bc2f0eb7496ca6ccdfbfbf515ef6d04c1809cf32f839cc3574d35ff1f965646505a9
6
+ metadata.gz: 5bb474f4d13e469b9af991e061b10a54279f37d7390b9cb1bffafd40d039c649c12ca5423140d4a232a08536ec715df89db2e07f6670ef0242732cbe78d1d890
7
+ data.tar.gz: 9b61d0d93ce9b657989fefde1201aab35253e656035ffb87ccbebfbafe4ea423883146dd4dec510dfdf5deec74b274784f6490d86804cf76b09aeee58f41cdfb
@@ -53,9 +53,7 @@ module Aws
53
53
  @marshaler = options[:marshaler] || DefaultMarshaler
54
54
  @persist_nil = options[:persist_nil]
55
55
  dv = options[:default_value]
56
- unless dv.nil?
57
- @default_value_or_lambda = _is_lambda?(dv) ? dv : type_cast(dv)
58
- end
56
+ @default_value_or_lambda = _is_lambda?(dv) ? dv : type_cast(dv)
59
57
  end
60
58
 
61
59
  # Attempts to type cast a raw value into the attribute's type. This call
@@ -0,0 +1,82 @@
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.
13
+
14
+ module Aws
15
+ module Record
16
+ class Batch
17
+ extend ClientConfiguration
18
+
19
+ class << self
20
+ # @example Usage Example
21
+ # class Breakfast
22
+ # include Aws::Record
23
+ # integer_attr :id, hash_key: true
24
+ # string_attr :name, range_key: true
25
+ # string_attr :body
26
+ # end
27
+ #
28
+ # # setup
29
+ # eggs = Breakfast.new(id: 1, name: "eggs").save!
30
+ # waffles = Breakfast.new(id: 2, name: "waffles")
31
+ # pancakes = Breakfast.new(id: 3, name: "pancakes")
32
+ #
33
+ # # batch operations
34
+ # operation = Aws::Record::Batch.write(client: Breakfast.dynamodb_client) do |db|
35
+ # db.put(waffles)
36
+ # db.delete(eggs)
37
+ # db.put(pancakes)
38
+ # end
39
+ #
40
+ # # unprocessed items can be retried by calling Aws::Record::BatchWrite#execute!
41
+ # operation.execute! unless operation.complete?
42
+ #
43
+ # Provides a thin wrapper to the
44
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#batch_write_item-instance_method Aws::DynamoDB::Client#batch_write_item}
45
+ # method. Up to 25 +PutItem+ or +DeleteItem+ operations are supported.
46
+ # A single rquest may write up to 16 MB of data, with each item having a
47
+ # write limit of 400 KB.
48
+ #
49
+ # *Note*: this operation does not support dirty attribute handling,
50
+ # nor does it enforce safe write operations (i.e. update vs new record
51
+ # checks).
52
+ #
53
+ # This call may partially execute write operations. Failed operations
54
+ # are returned as +Aws::Record::BatchWrite#unprocessed_items+ (i.e. the
55
+ # table fails to meet requested write capacity). Any unprocessed
56
+ # items may be retried by calling +Aws::Record::BatchWrite#execute!+
57
+ # again. You can determine if the request needs to be retried by calling
58
+ # the +Aws::Record::BatchWrite#complete?+ method - which returns +true+
59
+ # when all operations have been completed.
60
+ #
61
+ # Please see
62
+ # {https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.Errors.html#Programming.Errors.BatchOperations Batch Operations and Error Handling}
63
+ # in the DynamoDB Developer Guide for more details.
64
+ #
65
+ # @param [Hash] opts the options you wish to use to create the client.
66
+ # Note that if you include the option +:client+, all other options
67
+ # will be ignored. See the documentation for other options in the
68
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby}.
69
+ # @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
70
+ # own pre-configured client.
71
+ #
72
+ # @return [Aws::Record::BatchWrite] An instance that contains any
73
+ # unprocessed items and allows for a retry strategy.
74
+ def write(opts = {}, &block)
75
+ batch = BatchWrite.new(client: _build_client(opts))
76
+ block.call(batch)
77
+ batch.execute!
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,81 @@
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.
13
+
14
+ module Aws
15
+ module Record
16
+ class BatchWrite
17
+ # @param [Aws::DynamoDB::Client] client the DynamoDB SDK client.
18
+ def initialize(client:)
19
+ @client = client
20
+ end
21
+
22
+ # Append a +PutItem+ operation to a batch write request.
23
+ #
24
+ # @param [Aws::Record] record a model class that includes {Aws::Record}.
25
+ def put(record)
26
+ table_name, params = record_put_params(record)
27
+ operations[table_name] ||= []
28
+ operations[table_name] << { put_request: params }
29
+ end
30
+
31
+ # Append a +DeleteItem+ operation to a batch write request.
32
+ #
33
+ # @param [Aws::Record] record a model class that includes {Aws::Record}.
34
+ def delete(record)
35
+ table_name, params = record_delete_params(record)
36
+ operations[table_name] ||= []
37
+ operations[table_name] << { delete_request: params }
38
+ end
39
+
40
+ # Perform a +batch_write_item+ request.
41
+ #
42
+ # @return [Aws::Record::BatchWrite] an instance that provides access to
43
+ # unprocessed items and allows for retries.
44
+ def execute!
45
+ result = @client.batch_write_item(request_items: operations)
46
+ @operations = result.unprocessed_items
47
+ self
48
+ end
49
+
50
+ # Indicates if all items have been processed.
51
+ #
52
+ # @return [Boolean] +true+ if +unprocessed_items+ is empty, +false+
53
+ # otherwise
54
+ def complete?
55
+ unprocessed_items.values.none?
56
+ end
57
+
58
+ # Returns all +DeleteItem+ and +PutItem+ operations that have not yet been
59
+ # processed successfully.
60
+ #
61
+ # @return [Hash] All operations that have not yet successfully completed.
62
+ def unprocessed_items
63
+ operations
64
+ end
65
+
66
+ private
67
+
68
+ def operations
69
+ @operations ||= {}
70
+ end
71
+
72
+ def record_delete_params(record)
73
+ [record.class.table_name, { key: record.key_values }]
74
+ end
75
+
76
+ def record_put_params(record)
77
+ [record.class.table_name, { item: record.save_values }]
78
+ end
79
+ end
80
+ end
81
+ end
@@ -101,9 +101,9 @@ module Aws
101
101
  @params[:expression_attribute_values] = {}
102
102
  values = @params[:expression_attribute_values]
103
103
  end
104
- _key_pass(statement_str, names)
105
- _apply_values(statement_str, subs, values)
106
- @params[:key_condition_expression] = statement_str
104
+ prepared = _key_pass(statement_str, names)
105
+ statement = _apply_values(prepared, subs, values)
106
+ @params[:key_condition_expression] = statement
107
107
  self
108
108
  end
109
109
 
@@ -123,7 +123,7 @@ module Aws
123
123
  # "contains(:body, ?)",
124
124
  # "bacon"
125
125
  # ).complete!
126
- #
126
+ #
127
127
  def filter_expr(statement_str, *subs)
128
128
  names = @params[:expression_attribute_names]
129
129
  if names.nil?
@@ -135,9 +135,9 @@ module Aws
135
135
  @params[:expression_attribute_values] = {}
136
136
  values = @params[:expression_attribute_values]
137
137
  end
138
- _key_pass(statement_str, names)
139
- _apply_values(statement_str, subs, values)
140
- @params[:filter_expression] = statement_str
138
+ prepared = _key_pass(statement_str, names)
139
+ statement = _apply_values(prepared, subs, values)
140
+ @params[:filter_expression] = statement
141
141
  self
142
142
  end
143
143
 
@@ -167,8 +167,8 @@ module Aws
167
167
  @params[:expression_attribute_names] = {}
168
168
  names = @params[:expression_attribute_names]
169
169
  end
170
- _key_pass(statement_str, names)
171
- @params[:projection_expression] = statement_str
170
+ prepared = _key_pass(statement_str, names)
171
+ @params[:projection_expression] = prepared
172
172
  self
173
173
  end
174
174
 
@@ -178,6 +178,50 @@ module Aws
178
178
  self
179
179
  end
180
180
 
181
+ # Allows you to define a callback that will determine the model class
182
+ # to be used for each item, allowing queries to return an ItemCollection
183
+ # with mixed models. The provided block must return the model class based on
184
+ # any logic on the raw item attributes or `nil` if no model applies and
185
+ # the item should be skipped. Note: The block only has access to raw item
186
+ # data so attributes must be accessed using their names as defined in the
187
+ # table, not as the symbols defined in the model class(s).
188
+ #
189
+ # @example Scan with heterogeneous results:
190
+ # # Example model classes
191
+ # class Model_A
192
+ # include Aws::Record
193
+ # set_table_name(TABLE_NAME)
194
+ #
195
+ # string_attr :uuid, hash_key: true
196
+ # string_attr :class_name, range_key: true
197
+ #
198
+ # string_attr :attr_a
199
+ # end
200
+ #
201
+ # class Model_B
202
+ # include Aws::Record
203
+ # set_table_name(TABLE_NAME)
204
+ #
205
+ # string_attr :uuid, hash_key: true
206
+ # string_attr :class_name, range_key: true
207
+ #
208
+ # string_attr :attr_b
209
+ # end
210
+ #
211
+ # # use multi_model_filter to create a query on TABLE_NAME
212
+ # items = Model_A.build_scan.multi_model_filter do |raw_item_attributes|
213
+ # case raw_item_attributes['class_name']
214
+ # when "A" then Model_A
215
+ # when "B" then Model_B
216
+ # else
217
+ # nil
218
+ # end
219
+ # end.complete!
220
+ def multi_model_filter(proc = nil, &block)
221
+ @params[:model_filter] = proc || block
222
+ self
223
+ end
224
+
181
225
  # You must call this method at the end of any query or scan you build.
182
226
  #
183
227
  # @return [Aws::Record::ItemCollection] The item collection lazy
@@ -188,8 +232,8 @@ module Aws
188
232
 
189
233
  private
190
234
  def _key_pass(statement, names)
191
- statement.gsub!(/:(\w+)/) do |match|
192
- key = match.gsub!(':','').to_sym
235
+ statement.gsub(/:(\w+)/) do |match|
236
+ key = match.gsub(':','').to_sym
193
237
  key_name = @model.attributes.storage_name_for(key)
194
238
  if key_name
195
239
  sub_name = _next_name
@@ -204,15 +248,16 @@ module Aws
204
248
 
205
249
  def _apply_values(statement, subs, values)
206
250
  count = 0
207
- statement.gsub!(/[?]/) do |match|
251
+ statement.gsub(/[?]/) do |match|
208
252
  sub_value = _next_value
209
253
  raise "Substitution collision!" if values[sub_value]
210
254
  values[sub_value] = subs[count]
211
255
  count += 1
212
256
  sub_value
213
- end
214
- unless count == subs.size
215
- raise "Expected #{count} values in the substitution set, but found #{subs.size}"
257
+ end.tap do
258
+ unless count == subs.size
259
+ raise "Expected #{count} values in the substitution set, but found #{subs.size}"
260
+ end
216
261
  end
217
262
  end
218
263
 
@@ -0,0 +1,63 @@
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.
13
+
14
+ module Aws
15
+ module Record
16
+ module ClientConfiguration
17
+ # Configures the Amazon DynamoDB client used by this class and all
18
+ # instances of this class.
19
+ #
20
+ # Please note that this method is also called internally when you first
21
+ # attempt to perform an operation against the remote end, if you have not
22
+ # already configured a client. As such, please read and understand the
23
+ # documentation in the AWS SDK for Ruby around
24
+ # {http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration configuration}
25
+ # to ensure you understand how default configuration behavior works. When
26
+ # in doubt, call this method to ensure your client is configured the way
27
+ # you want it to be configured.
28
+ #
29
+ # @param [Hash] opts the options you wish to use to create the client.
30
+ # Note that if you include the option +:client+, all other options
31
+ # will be ignored. See the documentation for other options in the
32
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby}.
33
+ # @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
34
+ # own pre-configured client.
35
+ def configure_client(opts = {})
36
+ @dynamodb_client = _build_client(opts)
37
+ end
38
+
39
+ # Gets the
40
+ # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html}
41
+ # instance that Transactions use. When called for the first time, if
42
+ # {#configure_client} has not yet been called, will configure a new
43
+ # client for you with default parameters.
44
+ #
45
+ # @return [Aws::DynamoDB::Client] the Amazon DynamoDB client instance.
46
+ def dynamodb_client
47
+ @dynamodb_client ||= configure_client
48
+ end
49
+
50
+ private
51
+
52
+ def _build_client(opts = {})
53
+ provided_client = opts.delete(:client)
54
+ opts[:user_agent_suffix] = _user_agent(opts.delete(:user_agent_suffix))
55
+ provided_client || Aws::DynamoDB::Client.new(opts)
56
+ end
57
+
58
+ def _user_agent(custom)
59
+ custom || " aws-record/#{VERSION}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -19,6 +19,7 @@ module Aws
19
19
  def initialize(search_method, search_params, model, client)
20
20
  @search_method = search_method
21
21
  @search_params = search_params
22
+ @model_filter = @search_params.delete(:model_filter)
22
23
  @model = model
23
24
  @client = client
24
25
  end
@@ -91,9 +92,11 @@ module Aws
91
92
  def _build_items_from_response(items, model)
92
93
  ret = []
93
94
  items.each do |item|
94
- record = model.new
95
+ model_class = @model_filter ? @model_filter.call(item) : model
96
+ next unless model_class
97
+ record = model_class.new
95
98
  data = record.instance_variable_get("@data")
96
- model.attributes.attributes.each do |name, attr|
99
+ model_class.attributes.attributes.each do |name, attr|
97
100
  data.set_attribute(name, attr.extract(item))
98
101
  end
99
102
  data.clean!
@@ -82,8 +82,7 @@ module Aws
82
82
  end
83
83
 
84
84
 
85
- # Deletes the item instance that matches the key values of this item
86
- # instance in Amazon DynamoDB.
85
+ # Assigns the attributes provided onto the model.
87
86
  #
88
87
  # @example Usage Example
89
88
  # class MyModel
@@ -98,13 +97,13 @@ module Aws
98
97
  # model.age # => 4
99
98
  # model.height # => 70.5
100
99
  # model.save
101
- # model.dirty? # => false
102
- #
100
+ # model.dirty? # => false
101
+ #
103
102
  # model.assign_attributes(age: 5, height: 150.75)
104
103
  # model.age # => 5
105
104
  # model.height # => 150.75
106
105
  # model.dirty? # => true
107
- #
106
+ #
108
107
  #
109
108
  # @param [Hash] opts
110
109
  def assign_attributes(opts)
@@ -138,14 +137,14 @@ module Aws
138
137
  # model.age # => 4
139
138
  # model.height # => 70.5
140
139
  # model.save
141
- # model.dirty? # => false
142
- #
140
+ # model.dirty? # => false
141
+ #
143
142
  # model.update(age: 5, height: 150.75)
144
143
  # model.age # => 5
145
144
  # model.height # => 150.75
146
145
  # model.dirty? # => false
147
146
  #
148
- #
147
+ #
149
148
  # @param [Hash] new_param, contains the new parameters for the model
150
149
  #
151
150
  # @param [Hash] opts
@@ -168,7 +167,7 @@ module Aws
168
167
  # Note that aws-record allows you to change your model's key values,
169
168
  # but this will be interpreted as persisting a new item to your DynamoDB
170
169
  # table
171
- #
170
+ #
172
171
  # @param [Hash] new_param, contains the new parameters for the model
173
172
  #
174
173
  # @param [Hash] opts
@@ -196,6 +195,28 @@ module Aws
196
195
  self.instance_variable_get("@data").destroyed = true
197
196
  end
198
197
 
198
+ # Validates and generates the key values necessary for API operations such as the
199
+ # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_item-instance_method Aws::DynamoDB::Client#delete_item}
200
+ # operation.
201
+ def key_values
202
+ validate_key_values
203
+ attributes = self.class.attributes
204
+ self.class.keys.values.each_with_object({}) do |attr_name, hash|
205
+ db_name = attributes.storage_name_for(attr_name)
206
+ hash[db_name] = attributes
207
+ .attribute_for(attr_name)
208
+ .serialize(@data.raw_value(attr_name))
209
+ end
210
+ end
211
+
212
+ # Validates key values and returns a hash consisting of the parameters
213
+ # to save the record using the
214
+ # {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}
215
+ # operation.
216
+ def save_values
217
+ _build_item_for_save
218
+ end
219
+
199
220
  private
200
221
  def _invalid_record?(opts)
201
222
  if self.respond_to?(:valid?)
@@ -266,17 +287,6 @@ module Aws
266
287
  @data.build_save_hash
267
288
  end
268
289
 
269
- def key_values
270
- validate_key_values
271
- attributes = self.class.attributes
272
- self.class.keys.inject({}) do |acc, (_, attr_name)|
273
- db_name = attributes.storage_name_for(attr_name)
274
- acc[db_name] = attributes.attribute_for(attr_name).
275
- serialize(@data.raw_value(attr_name))
276
- acc
277
- end
278
- end
279
-
280
290
  def validate_key_values
281
291
  missing = missing_key_values
282
292
  unless missing.empty?
@@ -340,7 +350,7 @@ module Aws
340
350
  # ":v" => 1024
341
351
  # }
342
352
  # )
343
- #
353
+ #
344
354
  # Allows you to build a "check" expression for use in transactional
345
355
  # write operations.
346
356
  #
@@ -401,7 +411,7 @@ module Aws
401
411
  # string_attr :hk, hash_key: true
402
412
  # string_attr :rk, range_key: true
403
413
  # end
404
- #
414
+ #
405
415
  # results = Table.transact_find(
406
416
  # transact_items: [
407
417
  # {key: { hk: "hk1", rk: "rk1"}},
@@ -56,15 +56,24 @@ module Aws
56
56
  # @param [Hash] opts options to pass on to the client call to
57
57
  # +#create_table+. See the documentation above in the AWS SDK for Ruby
58
58
  # V2.
59
- # @option opts [Hash] :provisioned_throughput This is a required argument,
60
- # in which you must specify the +:read_capacity_units+ and
59
+ # @option opts [Hash] :billing_mode Accepts values 'PAY_PER_REQUEST' or
60
+ # 'PROVISIONED'. If :provisioned_throughput option is specified, this
61
+ # option is not required, as 'PROVISIONED' is assumed. If
62
+ # :provisioned_throughput is not specified, this option is required
63
+ # and must be set to 'PAY_PER_REQUEST'.
64
+ # @option opts [Hash] :provisioned_throughput Unless :billing_mode is
65
+ # set to 'PAY_PER_REQUEST', this is a required argument, in which
66
+ # you must specify the +:read_capacity_units+ and
61
67
  # +:write_capacity_units+ of your new table.
62
68
  # @option opts [Hash] :global_secondary_index_throughput This argument is
63
- # required if you define any global secondary indexes. It should map your
69
+ # required if you define any global secondary indexes, unless
70
+ # :billing_mode is set to 'PAY_PER_REQUEST'. It should map your
64
71
  # global secondary index names to their provisioned throughput, similar
65
72
  # to how you define the provisioned throughput for the table in general.
66
73
  def create!(opts)
67
74
  gsit = opts.delete(:global_secondary_index_throughput)
75
+ _validate_billing(opts)
76
+
68
77
  create_opts = opts.merge({
69
78
  table_name: @model.table_name,
70
79
  attribute_definitions: _attribute_definitions,
@@ -75,14 +84,19 @@ module Aws
75
84
  _append_to_attribute_definitions(lsis, create_opts)
76
85
  end
77
86
  if gsis = @model.global_secondary_indexes_for_migration
78
- unless gsit
87
+ unless gsit || opts[:billing_mode] == 'PAY_PER_REQUEST'
79
88
  raise ArgumentError.new(
80
- "If you define global secondary indexes, you must also define"\
81
- " :global_secondary_index_throughput on table creation."
89
+ 'If you define global secondary indexes, you must also define'\
90
+ ' :global_secondary_index_throughput on table creation,'\
91
+ " unless :billing_mode is set to 'PAY_PER_REQUEST'."
82
92
  )
83
93
  end
84
- gsis_with_throughput = _add_throughout_to_gsis(gsis, gsit)
85
- create_opts[:global_secondary_indexes] = gsis_with_throughput
94
+ gsis_opts = if opts[:billing_mode] == 'PAY_PER_REQUEST'
95
+ gsis
96
+ else
97
+ _add_throughput_to_gsis(gsis, gsit)
98
+ end
99
+ create_opts[:global_secondary_indexes] = gsis_opts
86
100
  _append_to_attribute_definitions(gsis, create_opts)
87
101
  end
88
102
  @client.create_table(create_opts)
@@ -142,6 +156,33 @@ module Aws
142
156
  end
143
157
  end
144
158
 
159
+ def _validate_billing(opts)
160
+ valid_modes = %w[PAY_PER_REQUEST PROVISIONED]
161
+ if opts.key?(:billing_mode)
162
+ unless valid_modes.include?(opts[:billing_mode])
163
+ raise ArgumentError.new(
164
+ ":billing_mode option must be one of #{valid_modes.join(', ')}"\
165
+ " current value is: #{opts[:billing_mode]}"
166
+ )
167
+ end
168
+ end
169
+ if opts.key?(:provisioned_throughput)
170
+ if opts[:billing_mode] == 'PAY_PER_REQUEST'
171
+ raise ArgumentError.new(
172
+ 'when :provisioned_throughput option is specified, :billing_mode'\
173
+ " must either be unspecified or have a value of 'PROVISIONED'"
174
+ )
175
+ end
176
+ else
177
+ if opts[:billing_mode] != 'PAY_PER_REQUEST'
178
+ raise ArgumentError.new(
179
+ 'when :provisioned_throughput option is not specified,'\
180
+ " :billing_mode must be set to 'PAY_PER_REQUEST'"
181
+ )
182
+ end
183
+ end
184
+ end
185
+
145
186
  def _attribute_definitions
146
187
  _keys.map do |type, attr|
147
188
  {
@@ -173,7 +214,7 @@ module Aws
173
214
  create_opts[:attribute_definitions] = attr_def
174
215
  end
175
216
 
176
- def _add_throughout_to_gsis(global_secondary_indexes, gsi_throughput)
217
+ def _add_throughput_to_gsis(global_secondary_indexes, gsi_throughput)
177
218
  missing_throughput = []
178
219
  ret = global_secondary_indexes.map do |params|
179
220
  name = params[:index_name]
@@ -1,6 +1,8 @@
1
1
  module Aws
2
2
  module Record
3
3
  module Transactions
4
+ extend ClientConfiguration
5
+
4
6
  class << self
5
7
 
6
8
  # @example Usage Example
@@ -8,13 +10,13 @@ module Aws
8
10
  # include Aws::Record
9
11
  # string_attr :uuid, hash_key: true
10
12
  # end
11
- #
13
+ #
12
14
  # class TableTwo
13
15
  # include Aws::Record
14
16
  # string_attr :hk, hash_key: true
15
17
  # string_attr :rk, range_key: true
16
18
  # end
17
- #
19
+ #
18
20
  # results = Aws::Record::Transactions.transact_find(
19
21
  # transact_items: [
20
22
  # TableOne.tfind_opts(key: { uuid: "uuid1234" }),
@@ -93,14 +95,14 @@ module Aws
93
95
  # string_attr :uuid, hash_key: true
94
96
  # string_attr :body
95
97
  # end
96
- #
98
+ #
97
99
  # class TableTwo
98
100
  # include Aws::Record
99
101
  # string_attr :hk, hash_key: true
100
102
  # string_attr :rk, range_key: true
101
103
  # string_attr :body
102
104
  # end
103
- #
105
+ #
104
106
  # check_exp = TableOne.transact_check_expression(
105
107
  # key: { uuid: "foo" },
106
108
  # condition_expression: "size(#T) <= :v",
@@ -118,7 +120,7 @@ module Aws
118
120
  # update_item_2 = TableTwo.find(hk: "hk2", rk: "rk2")
119
121
  # update_item_2.body = "Update!"
120
122
  # delete_item = TableOne.find(uuid: "to_be_deleted")
121
- #
123
+ #
122
124
  # Aws::Record::Transactions.transact_write(
123
125
  # transact_items: [
124
126
  # { check: check_exp },
@@ -183,44 +185,6 @@ module Aws
183
185
  resp
184
186
  end
185
187
 
186
- # Configures the Amazon DynamoDB client used by global transaction
187
- # operations.
188
- #
189
- # Please note that this method is also called internally when you first
190
- # attempt to perform an operation against the remote end, if you have
191
- # not already configured a client. As such, please read and understand
192
- # the documentation in the AWS SDK for Ruby V3 around
193
- # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/#Configuration configuration}
194
- # to ensure you understand how default configuration behavior works.
195
- # When in doubt, call this method to ensure your client is configured
196
- # the way you want it to be configured.
197
- #
198
- # @param [Hash] opts the options you wish to use to create the client.
199
- # Note that if you include the option +:client+, all other options
200
- # will be ignored. See the documentation for other options in the
201
- # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby V3}.
202
- # @option opts [Aws::DynamoDB::Client] :client allows you to pass in
203
- # your own pre-configured client.
204
- def configure_client(opts = {})
205
- provided_client = opts.delete(:client)
206
- opts[:user_agent_suffix] = _user_agent(
207
- opts.delete(:user_agent_suffix)
208
- )
209
- client = provided_client || Aws::DynamoDB::Client.new(opts)
210
- @@dynamodb_client = client
211
- end
212
-
213
- # Gets the
214
- # {https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/DynamoDB/Client.html}
215
- # instance that Transactions use. When called for the first time, if
216
- # {#configure_client} has not yet been called, will configure a new
217
- # client for you with default parameters.
218
- #
219
- # @return [Aws::DynamoDB::Client] the Amazon DynamoDB client instance.
220
- def dynamodb_client
221
- @@dynamodb_client ||= configure_client
222
- end
223
-
224
188
  private
225
189
  def _transform_transact_write_items(transact_items, dirty_items, delete_items)
226
190
  transact_items.map do |item|
@@ -317,15 +281,6 @@ module Aws
317
281
  # check records are a pass-through
318
282
  { condition_check: opts.merge(check_record) }
319
283
  end
320
-
321
- def _user_agent(custom)
322
- if custom
323
- custom
324
- else
325
- " aws-record/#{VERSION}"
326
- end
327
- end
328
-
329
284
  end
330
285
  end
331
286
  end
@@ -13,6 +13,6 @@
13
13
 
14
14
  module Aws
15
15
  module Record
16
- VERSION = '2.4.0'
16
+ VERSION = '2.7.0'
17
17
  end
18
18
  end
@@ -50,7 +50,7 @@ module Aws
50
50
  # # Attribute definitions go here...
51
51
  # end
52
52
  def self.included(sub_class)
53
- @track_mutations = true
53
+ sub_class.send(:extend, ClientConfiguration)
54
54
  sub_class.send(:extend, RecordClassMethods)
55
55
  sub_class.send(:include, Attributes)
56
56
  sub_class.send(:include, ItemOperations)
@@ -76,12 +76,12 @@ module Aws
76
76
  # class MyTable
77
77
  # include Aws::Record
78
78
  # end
79
- #
79
+ #
80
80
  # class MyTableTest
81
81
  # include Aws::Record
82
82
  # set_table_name "test_MyTable"
83
83
  # end
84
- #
84
+ #
85
85
  # MyTable.table_name # => "MyTable"
86
86
  # MyOtherTable.table_name # => "test_MyTable"
87
87
  def table_name
@@ -100,12 +100,12 @@ module Aws
100
100
  # include Aws::Record
101
101
  # set_table_name "prod_MyTable"
102
102
  # end
103
- #
103
+ #
104
104
  # class MyTableTest
105
105
  # include Aws::Record
106
106
  # set_table_name "test_MyTable"
107
107
  # end
108
- #
108
+ #
109
109
  # MyTable.table_name # => "prod_MyTable"
110
110
  # MyOtherTable.table_name # => "test_MyTable"
111
111
  def set_table_name(name)
@@ -148,42 +148,6 @@ module Aws
148
148
  end
149
149
  end
150
150
 
151
- # Configures the Amazon DynamoDB client used by this class and all
152
- # instances of this class.
153
- #
154
- # Please note that this method is also called internally when you first
155
- # attempt to perform an operation against the remote end, if you have not
156
- # already configured a client. As such, please read and understand the
157
- # documentation in the AWS SDK for Ruby V2 around
158
- # {http://docs.aws.amazon.com/sdkforruby/api/index.html#Configuration configuration}
159
- # to ensure you understand how default configuration behavior works. When
160
- # in doubt, call this method to ensure your client is configured the way
161
- # you want it to be configured.
162
- #
163
- # @param [Hash] opts the options you wish to use to create the client.
164
- # Note that if you include the option +:client+, all other options
165
- # will be ignored. See the documentation for other options in the
166
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#initialize-instance_method AWS SDK for Ruby V2}.
167
- # @option opts [Aws::DynamoDB::Client] :client allows you to pass in your
168
- # own pre-configured client.
169
- def configure_client(opts = {})
170
- provided_client = opts.delete(:client)
171
- opts[:user_agent_suffix] = _user_agent(opts.delete(:user_agent_suffix))
172
- client = provided_client || Aws::DynamoDB::Client.new(opts)
173
- @dynamodb_client = client
174
- end
175
-
176
- # Gets the
177
- # {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
178
- # instance that this model uses. When called for the first time, if
179
- # {#configure_client} has not yet been called, will configure a new client
180
- # for you with default parameters.
181
- #
182
- # @return [Aws::DynamoDB::Client] the Amazon DynamoDB client instance.
183
- def dynamodb_client
184
- @dynamodb_client ||= configure_client
185
- end
186
-
187
151
  # Turns off mutation tracking for all attributes in the model.
188
152
  def disable_mutation_tracking
189
153
  @track_mutations = false
@@ -201,7 +165,11 @@ module Aws
201
165
  # @return [Boolean] true if mutation tracking is enabled at the model
202
166
  # level, false otherwise.
203
167
  def mutation_tracking_enabled?
204
- @track_mutations == false ? false : true
168
+ if defined?(@track_mutations)
169
+ @track_mutations
170
+ else
171
+ @track_mutations = true
172
+ end
205
173
  end
206
174
 
207
175
  def model_valid?
@@ -209,15 +177,6 @@ module Aws
209
177
  raise Errors::InvalidModel.new("Table models must include a hash key")
210
178
  end
211
179
  end
212
-
213
- private
214
- def _user_agent(custom)
215
- if custom
216
- custom
217
- else
218
- " aws-record/#{VERSION}"
219
- end
220
- end
221
180
  end
222
181
  end
223
182
  end
data/lib/aws-record.rb CHANGED
@@ -12,6 +12,7 @@
12
12
  # and limitations under the License.
13
13
 
14
14
  require 'aws-sdk-dynamodb'
15
+ require_relative 'aws-record/record/client_configuration'
15
16
  require_relative 'aws-record/record'
16
17
  require_relative 'aws-record/record/attribute'
17
18
  require_relative 'aws-record/record/attributes'
@@ -29,6 +30,8 @@ require_relative 'aws-record/record/table_migration'
29
30
  require_relative 'aws-record/record/version'
30
31
  require_relative 'aws-record/record/transactions'
31
32
  require_relative 'aws-record/record/buildable_search'
33
+ require_relative 'aws-record/record/batch_write'
34
+ require_relative 'aws-record/record/batch'
32
35
  require_relative 'aws-record/record/marshalers/string_marshaler'
33
36
  require_relative 'aws-record/record/marshalers/boolean_marshaler'
34
37
  require_relative 'aws-record/record/marshalers/integer_marshaler'
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.1
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amazon Web Services
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-29 00:00:00.000000000 Z
11
+ date: 2021-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb
@@ -26,7 +26,8 @@ dependencies:
26
26
  version: '1.18'
27
27
  description: Provides an object mapping abstraction for Amazon DynamoDB.
28
28
  email:
29
- - alexwood@amazon.com
29
+ - mamuller@amazon.com
30
+ - alexwoo@amazon.com
30
31
  executables: []
31
32
  extensions: []
32
33
  extra_rdoc_files: []
@@ -35,7 +36,10 @@ files:
35
36
  - lib/aws-record/record.rb
36
37
  - lib/aws-record/record/attribute.rb
37
38
  - lib/aws-record/record/attributes.rb
39
+ - lib/aws-record/record/batch.rb
40
+ - lib/aws-record/record/batch_write.rb
38
41
  - lib/aws-record/record/buildable_search.rb
42
+ - lib/aws-record/record/client_configuration.rb
39
43
  - lib/aws-record/record/dirty_tracking.rb
40
44
  - lib/aws-record/record/errors.rb
41
45
  - lib/aws-record/record/item_collection.rb
@@ -65,7 +69,7 @@ homepage: http://github.com/aws/aws-sdk-ruby-record
65
69
  licenses:
66
70
  - Apache 2.0
67
71
  metadata: {}
68
- post_install_message:
72
+ post_install_message:
69
73
  rdoc_options: []
70
74
  require_paths:
71
75
  - lib
@@ -80,8 +84,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
84
  - !ruby/object:Gem::Version
81
85
  version: '0'
82
86
  requirements: []
83
- rubygems_version: 3.0.3
84
- signing_key:
87
+ rubygems_version: 3.2.7
88
+ signing_key:
85
89
  specification_version: 4
86
90
  summary: AWS Record library for Amazon DynamoDB
87
91
  test_files: []