aws-record 2.10.1 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module Aws
|
4
4
|
module Record
|
5
|
-
|
6
5
|
# +Aws::Record::TableConfig+ provides a DSL for describing and modifying
|
7
6
|
# the remote configuration of your DynamoDB tables. A table configuration
|
8
7
|
# object can perform intelligent comparisons and incremental migrations
|
@@ -90,11 +89,9 @@ module Aws
|
|
90
89
|
# end
|
91
90
|
#
|
92
91
|
class TableConfig
|
93
|
-
|
94
92
|
attr_accessor :client
|
95
93
|
|
96
94
|
class << self
|
97
|
-
|
98
95
|
# Creates a new table configuration, using a DSL in the provided block.
|
99
96
|
# The DSL has the following methods:
|
100
97
|
# * +#model_class+ A class name reference to the +Aws::Record+ model
|
@@ -158,7 +155,7 @@ module Aws
|
|
158
155
|
def initialize
|
159
156
|
@client_options = {}
|
160
157
|
@global_secondary_indexes = {}
|
161
|
-
@billing_mode =
|
158
|
+
@billing_mode = 'PROVISIONED' # default
|
162
159
|
end
|
163
160
|
|
164
161
|
# @api private
|
@@ -191,6 +188,7 @@ module Aws
|
|
191
188
|
# @api private
|
192
189
|
def configure_client
|
193
190
|
@client = Aws::DynamoDB::Client.new(@client_options)
|
191
|
+
@client.config.user_agent_frameworks << 'aws-record'
|
194
192
|
end
|
195
193
|
|
196
194
|
# @api private
|
@@ -231,9 +229,9 @@ module Aws
|
|
231
229
|
unless _gsi_superset(resp)
|
232
230
|
@client.update_table(_update_index_opts(resp))
|
233
231
|
@client.wait_until(
|
234
|
-
|
235
|
-
|
236
|
-
|
232
|
+
:table_exists,
|
233
|
+
table_name: @model_class.table_name
|
234
|
+
)
|
237
235
|
end
|
238
236
|
end
|
239
237
|
rescue DynamoDB::Errors::ResourceNotFoundException
|
@@ -248,7 +246,7 @@ module Aws
|
|
248
246
|
# we will only alter TTL status if we have a TTL attribute defined. We
|
249
247
|
# may someday support explicit TTL deletion, but we do not yet do this.
|
250
248
|
if @ttl_attribute
|
251
|
-
|
249
|
+
unless _ttl_compatibility_check
|
252
250
|
client.update_time_to_live(
|
253
251
|
table_name: @model_class.table_name,
|
254
252
|
time_to_live_specification: {
|
@@ -270,12 +268,10 @@ module Aws
|
|
270
268
|
#
|
271
269
|
# @return [Boolean] true if remote is compatible, false otherwise.
|
272
270
|
def compatible?
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
false
|
278
|
-
end
|
271
|
+
resp = @client.describe_table(table_name: @model_class.table_name)
|
272
|
+
_compatible_check(resp) && _ttl_compatibility_check
|
273
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
274
|
+
false
|
279
275
|
end
|
280
276
|
|
281
277
|
# Checks against the remote table's configuration. If the remote table
|
@@ -285,26 +281,25 @@ module Aws
|
|
285
281
|
#
|
286
282
|
# @return [Boolean] true if remote is an exact match, false otherwise.
|
287
283
|
def exact_match?
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
false
|
297
|
-
end
|
284
|
+
resp = @client.describe_table(table_name: @model_class.table_name)
|
285
|
+
_throughput_equal(resp) &&
|
286
|
+
_keys_equal(resp) &&
|
287
|
+
_ad_equal(resp) &&
|
288
|
+
_gsi_equal(resp) &&
|
289
|
+
_ttl_match_check
|
290
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
291
|
+
false
|
298
292
|
end
|
299
293
|
|
300
294
|
private
|
295
|
+
|
301
296
|
def _ttl_compatibility_check
|
302
297
|
if @ttl_attribute
|
303
298
|
ttl_status = @client.describe_time_to_live(
|
304
299
|
table_name: @model_class.table_name
|
305
300
|
)
|
306
301
|
desc = ttl_status.time_to_live_description
|
307
|
-
[
|
302
|
+
%w[ENABLED ENABLING].include?(desc.time_to_live_status) &&
|
308
303
|
desc.attribute_name == @ttl_attribute
|
309
304
|
else
|
310
305
|
true
|
@@ -317,11 +312,11 @@ module Aws
|
|
317
312
|
)
|
318
313
|
desc = ttl_status.time_to_live_description
|
319
314
|
if @ttl_attribute
|
320
|
-
[
|
315
|
+
%w[ENABLED ENABLING].include?(desc.time_to_live_status) &&
|
321
316
|
desc.attribute_name == @ttl_attribute
|
322
317
|
else
|
323
|
-
|
324
|
-
desc.attribute_name
|
318
|
+
!%w[ENABLED ENABLING].include?(desc.time_to_live_status) ||
|
319
|
+
desc.attribute_name.nil?
|
325
320
|
end
|
326
321
|
end
|
327
322
|
|
@@ -336,30 +331,25 @@ module Aws
|
|
336
331
|
opts = {
|
337
332
|
table_name: @model_class.table_name
|
338
333
|
}
|
339
|
-
if @billing_mode ==
|
334
|
+
if @billing_mode == 'PROVISIONED'
|
340
335
|
opts[:provisioned_throughput] = {
|
341
336
|
read_capacity_units: @read_capacity_units,
|
342
337
|
write_capacity_units: @write_capacity_units
|
343
338
|
}
|
344
|
-
elsif @billing_mode ==
|
339
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
345
340
|
opts[:billing_mode] = @billing_mode
|
346
341
|
else
|
347
342
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
348
343
|
end
|
349
|
-
|
350
344
|
opts[:key_schema] = _key_schema
|
351
345
|
opts[:attribute_definitions] = _attribute_definitions
|
352
346
|
gsi = _global_secondary_indexes
|
353
|
-
unless gsi.empty?
|
354
|
-
opts[:global_secondary_indexes] = gsi
|
355
|
-
end
|
347
|
+
opts[:global_secondary_indexes] = gsi unless gsi.empty?
|
356
348
|
opts
|
357
349
|
end
|
358
350
|
|
359
351
|
def _add_global_secondary_index_throughput(opts, resp_gsis)
|
360
|
-
gsis = resp_gsis.map
|
361
|
-
g.index_name
|
362
|
-
end
|
352
|
+
gsis = resp_gsis.map(&:index_name)
|
363
353
|
gsi_updates = []
|
364
354
|
gsis.each do |index_name|
|
365
355
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
@@ -375,7 +365,7 @@ module Aws
|
|
375
365
|
end
|
376
366
|
|
377
367
|
def _update_throughput_opts(resp)
|
378
|
-
if @billing_mode ==
|
368
|
+
if @billing_mode == 'PROVISIONED'
|
379
369
|
opts = {
|
380
370
|
table_name: @model_class.table_name,
|
381
371
|
provisioned_throughput: {
|
@@ -386,7 +376,7 @@ module Aws
|
|
386
376
|
# special case: we have global secondary indexes existing, and they
|
387
377
|
# need provisioned capacity to be set within this call
|
388
378
|
if !resp.table.billing_mode_summary.nil? &&
|
389
|
-
|
379
|
+
resp.table.billing_mode_summary.billing_mode == 'PAY_PER_REQUEST'
|
390
380
|
opts[:billing_mode] = @billing_mode
|
391
381
|
if resp.table.global_secondary_indexes
|
392
382
|
resp_gsis = resp.table.global_secondary_indexes
|
@@ -394,10 +384,10 @@ module Aws
|
|
394
384
|
end
|
395
385
|
end # else don't include billing mode
|
396
386
|
opts
|
397
|
-
elsif @billing_mode ==
|
387
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
398
388
|
{
|
399
389
|
table_name: @model_class.table_name,
|
400
|
-
billing_mode:
|
390
|
+
billing_mode: 'PAY_PER_REQUEST'
|
401
391
|
}
|
402
392
|
else
|
403
393
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
@@ -431,7 +421,7 @@ module Aws
|
|
431
421
|
gsi[:key_schema].each do |k|
|
432
422
|
attributes_referenced.add(k[:attribute_name])
|
433
423
|
end
|
434
|
-
if @billing_mode ==
|
424
|
+
if @billing_mode == 'PROVISIONED'
|
435
425
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
436
426
|
gsi[:provisioned_throughput] = lgsi.provisioned_throughput
|
437
427
|
end
|
@@ -440,7 +430,7 @@ module Aws
|
|
440
430
|
}
|
441
431
|
end
|
442
432
|
# we don't currently update anything other than throughput
|
443
|
-
if @billing_mode ==
|
433
|
+
if @billing_mode == 'PROVISIONED'
|
444
434
|
update_candidates.each do |index_name|
|
445
435
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
446
436
|
gsi_updates << {
|
@@ -464,19 +454,19 @@ module Aws
|
|
464
454
|
_keys.map do |type, attr|
|
465
455
|
{
|
466
456
|
attribute_name: attr.database_name,
|
467
|
-
key_type: type == :hash ?
|
457
|
+
key_type: type == :hash ? 'HASH' : 'RANGE'
|
468
458
|
}
|
469
459
|
end
|
470
460
|
end
|
471
461
|
|
472
462
|
def _attribute_definitions
|
473
|
-
attribute_definitions = _keys.map do |
|
463
|
+
attribute_definitions = _keys.map do |_type, attr|
|
474
464
|
{
|
475
465
|
attribute_name: attr.database_name,
|
476
466
|
attribute_type: attr.dynamodb_type
|
477
467
|
}
|
478
468
|
end
|
479
|
-
@model_class.global_secondary_indexes.
|
469
|
+
@model_class.global_secondary_indexes.each_value do |attributes|
|
480
470
|
gsi_keys = [attributes[:hash_key]]
|
481
471
|
gsi_keys << attributes[:range_key] if attributes[:range_key]
|
482
472
|
gsi_keys.each do |name|
|
@@ -496,40 +486,40 @@ module Aws
|
|
496
486
|
end
|
497
487
|
|
498
488
|
def _keys
|
499
|
-
@model_class.keys.
|
489
|
+
@model_class.keys.each_with_object({}) do |(type, name), acc|
|
500
490
|
acc[type] = @model_class.attributes.attribute_for(name)
|
501
491
|
acc
|
502
492
|
end
|
503
493
|
end
|
504
494
|
|
505
495
|
def _throughput_equal(resp)
|
506
|
-
if @billing_mode ==
|
496
|
+
if @billing_mode == 'PAY_PER_REQUEST'
|
507
497
|
!resp.table.billing_mode_summary.nil? &&
|
508
|
-
resp.table.billing_mode_summary.billing_mode ==
|
498
|
+
resp.table.billing_mode_summary.billing_mode == 'PAY_PER_REQUEST'
|
509
499
|
else
|
510
500
|
expected = resp.table.provisioned_throughput.to_h
|
511
501
|
actual = {
|
512
502
|
read_capacity_units: @read_capacity_units,
|
513
503
|
write_capacity_units: @write_capacity_units
|
514
504
|
}
|
515
|
-
actual.all? do |k,v|
|
505
|
+
actual.all? do |k, v|
|
516
506
|
expected[k] == v
|
517
507
|
end
|
518
508
|
end
|
519
509
|
end
|
520
510
|
|
521
511
|
def _keys_equal(resp)
|
522
|
-
remote_key_schema = resp.table.key_schema.map
|
512
|
+
remote_key_schema = resp.table.key_schema.map(&:to_h)
|
523
513
|
_array_unsorted_eql(remote_key_schema, _key_schema)
|
524
514
|
end
|
525
515
|
|
526
516
|
def _ad_equal(resp)
|
527
|
-
remote_ad = resp.table.attribute_definitions.map
|
517
|
+
remote_ad = resp.table.attribute_definitions.map(&:to_h)
|
528
518
|
_array_unsorted_eql(remote_ad, _attribute_definitions)
|
529
519
|
end
|
530
520
|
|
531
521
|
def _ad_superset(resp)
|
532
|
-
remote_ad = resp.table.attribute_definitions.map
|
522
|
+
remote_ad = resp.table.attribute_definitions.map(&:to_h)
|
533
523
|
_attribute_definitions.all? do |attribute_definition|
|
534
524
|
remote_ad.include?(attribute_definition)
|
535
525
|
end
|
@@ -540,7 +530,7 @@ module Aws
|
|
540
530
|
local_gsis = _global_secondary_indexes
|
541
531
|
remote_idx, local_idx = _gsi_index_names(remote_gsis, local_gsis)
|
542
532
|
if local_idx.subset?(remote_idx)
|
543
|
-
|
533
|
+
_gsi_set_compare(remote_gsis, local_gsis)
|
544
534
|
else
|
545
535
|
# If we have any local indexes not on the remote table,
|
546
536
|
# guaranteed false.
|
@@ -565,17 +555,17 @@ module Aws
|
|
565
555
|
r.index_name == lgsi[:index_name].to_s
|
566
556
|
end
|
567
557
|
|
568
|
-
remote_key_schema = rgsi.key_schema.map
|
558
|
+
remote_key_schema = rgsi.key_schema.map(&:to_h)
|
569
559
|
ks_match = _array_unsorted_eql(remote_key_schema, lgsi[:key_schema])
|
570
560
|
|
571
561
|
# Throughput Check: Dependent on Billing Mode
|
572
562
|
rpt = rgsi.provisioned_throughput.to_h
|
573
563
|
lpt = lgsi[:provisioned_throughput]
|
574
|
-
if @billing_mode ==
|
575
|
-
pt_match = lpt.all? do |k,v|
|
564
|
+
if @billing_mode == 'PROVISIONED'
|
565
|
+
pt_match = lpt.all? do |k, v|
|
576
566
|
rpt[k] == v
|
577
567
|
end
|
578
|
-
elsif @billing_mode ==
|
568
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
579
569
|
pt_match = lpt.nil? ? true : false
|
580
570
|
else
|
581
571
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
@@ -614,7 +604,7 @@ module Aws
|
|
614
604
|
if model_gsis
|
615
605
|
model_gsis.each do |mgsi|
|
616
606
|
config = gsi_config[mgsi[:index_name]]
|
617
|
-
if @billing_mode ==
|
607
|
+
if @billing_mode == 'PROVISIONED'
|
618
608
|
gsis << mgsi.merge(
|
619
609
|
provisioned_throughput: config.provisioned_throughput
|
620
610
|
)
|
@@ -633,12 +623,12 @@ module Aws
|
|
633
623
|
def _validate_required_configuration
|
634
624
|
missing_config = []
|
635
625
|
missing_config << 'model_class' unless @model_class
|
636
|
-
if @billing_mode ==
|
626
|
+
if @billing_mode == 'PROVISIONED'
|
637
627
|
missing_config << 'read_capacity_units' unless @read_capacity_units
|
638
628
|
missing_config << 'write_capacity_units' unless @write_capacity_units
|
639
629
|
else
|
640
630
|
if @read_capacity_units || @write_capacity_units
|
641
|
-
raise ArgumentError
|
631
|
+
raise ArgumentError, "Cannot have billing mode #{@billing_mode} with provisioned capacity."
|
642
632
|
end
|
643
633
|
end
|
644
634
|
unless missing_config.empty?
|
@@ -663,7 +653,6 @@ module Aws
|
|
663
653
|
@provisioned_throughput[:write_capacity_units] = units
|
664
654
|
end
|
665
655
|
end
|
666
|
-
|
667
656
|
end
|
668
657
|
end
|
669
658
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module Aws
|
4
4
|
module Record
|
5
5
|
class TableMigration
|
6
|
-
|
7
6
|
# @!attribute [rw] client
|
8
7
|
# @return [Aws::DynamoDB::Client] the
|
9
8
|
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
|
@@ -21,12 +20,14 @@ module Aws
|
|
21
20
|
_assert_model_valid(model)
|
22
21
|
@model = model
|
23
22
|
@client = opts[:client] || model.dynamodb_client || Aws::DynamoDB::Client.new
|
23
|
+
@client.config.user_agent_frameworks << 'aws-record'
|
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
|
28
|
-
# populating the attribute definitions and
|
29
|
-
# class, as well as passing through other
|
27
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#create_table-instance_method
|
28
|
+
# Aws::DynamoDB::Client#create_table}, populating the attribute definitions and
|
29
|
+
# key schema based on your model class, as well as passing through other
|
30
|
+
# parameters as provided by you.
|
30
31
|
#
|
31
32
|
# @example Creating a table with a global secondary index named +:gsi+
|
32
33
|
# migration.create!(
|
@@ -63,22 +64,20 @@ module Aws
|
|
63
64
|
gsit = opts.delete(:global_secondary_index_throughput)
|
64
65
|
_validate_billing(opts)
|
65
66
|
|
66
|
-
create_opts = opts.merge(
|
67
|
+
create_opts = opts.merge(
|
67
68
|
table_name: @model.table_name,
|
68
69
|
attribute_definitions: _attribute_definitions,
|
69
70
|
key_schema: _key_schema
|
70
|
-
|
71
|
-
if lsis = @model.local_secondary_indexes_for_migration
|
71
|
+
)
|
72
|
+
if (lsis = @model.local_secondary_indexes_for_migration)
|
72
73
|
create_opts[:local_secondary_indexes] = lsis
|
73
74
|
_append_to_attribute_definitions(lsis, create_opts)
|
74
75
|
end
|
75
|
-
if gsis = @model.global_secondary_indexes_for_migration
|
76
|
+
if (gsis = @model.global_secondary_indexes_for_migration)
|
76
77
|
unless gsit || opts[:billing_mode] == 'PAY_PER_REQUEST'
|
77
|
-
raise ArgumentError
|
78
|
-
|
79
|
-
|
80
|
-
" unless :billing_mode is set to 'PAY_PER_REQUEST'."
|
81
|
-
)
|
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'."
|
82
81
|
end
|
83
82
|
gsis_opts = if opts[:billing_mode] == 'PAY_PER_REQUEST'
|
84
83
|
gsis
|
@@ -92,8 +91,8 @@ module Aws
|
|
92
91
|
end
|
93
92
|
|
94
93
|
# This method calls
|
95
|
-
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_table-instance_method
|
96
|
-
# using the parameters that you provide.
|
94
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_table-instance_method
|
95
|
+
# Aws::DynamoDB::Client#update_table} using the parameters that you provide.
|
97
96
|
#
|
98
97
|
# @param [Hash] opts options to pass on to the client call to
|
99
98
|
# +#update_table+. See the documentation above in the AWS SDK for Ruby
|
@@ -101,28 +100,24 @@ module Aws
|
|
101
100
|
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table does not
|
102
101
|
# currently exist in Amazon DynamoDB.
|
103
102
|
def update!(opts)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
raise Errors::TableDoesNotExist.new(e)
|
111
|
-
end
|
103
|
+
update_opts = opts.merge(
|
104
|
+
table_name: @model.table_name
|
105
|
+
)
|
106
|
+
@client.update_table(update_opts)
|
107
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
108
|
+
raise Errors::TableDoesNotExist
|
112
109
|
end
|
113
110
|
|
114
111
|
# This method calls
|
115
|
-
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_table-instance_method
|
116
|
-
# using the table name of your model.
|
112
|
+
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_table-instance_method
|
113
|
+
# Aws::DynamoDB::Client#delete_table} using the table name of your model.
|
117
114
|
#
|
118
115
|
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table did not
|
119
116
|
# exist in Amazon DynamoDB at the time of calling.
|
120
117
|
def delete!
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
raise Errors::TableDoesNotExist.new(e)
|
125
|
-
end
|
118
|
+
@client.delete_table(table_name: @model.table_name)
|
119
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
120
|
+
raise Errors::TableDoesNotExist
|
126
121
|
end
|
127
122
|
|
128
123
|
# This method waits on the table specified in the model to exist and be
|
@@ -134,6 +129,7 @@ module Aws
|
|
134
129
|
end
|
135
130
|
|
136
131
|
private
|
132
|
+
|
137
133
|
def _assert_model_valid(model)
|
138
134
|
_assert_required_include(model)
|
139
135
|
model.model_valid?
|
@@ -141,7 +137,7 @@ module Aws
|
|
141
137
|
|
142
138
|
def _assert_required_include(model)
|
143
139
|
unless model.include?(::Aws::Record)
|
144
|
-
raise Errors::InvalidModel
|
140
|
+
raise Errors::InvalidModel, 'Table models must include Aws::Record'
|
145
141
|
end
|
146
142
|
end
|
147
143
|
|
@@ -149,31 +145,25 @@ module Aws
|
|
149
145
|
valid_modes = %w[PAY_PER_REQUEST PROVISIONED]
|
150
146
|
if opts.key?(:billing_mode)
|
151
147
|
unless valid_modes.include?(opts[:billing_mode])
|
152
|
-
raise ArgumentError.
|
153
|
-
|
154
|
-
" current value is: #{opts[:billing_mode]}"
|
155
|
-
)
|
148
|
+
raise ArgumentError, ":billing_mode option must be one of #{valid_modes.join(', ')}"\
|
149
|
+
" current value is: #{opts[:billing_mode]}"
|
156
150
|
end
|
157
151
|
end
|
158
152
|
if opts.key?(:provisioned_throughput)
|
159
153
|
if opts[:billing_mode] == 'PAY_PER_REQUEST'
|
160
|
-
raise ArgumentError
|
161
|
-
|
162
|
-
" must either be unspecified or have a value of 'PROVISIONED'"
|
163
|
-
)
|
154
|
+
raise ArgumentError, 'when :provisioned_throughput option is specified, :billing_mode'\
|
155
|
+
" must either be unspecified or have a value of 'PROVISIONED'"
|
164
156
|
end
|
165
157
|
else
|
166
158
|
if opts[:billing_mode] != 'PAY_PER_REQUEST'
|
167
|
-
raise ArgumentError
|
168
|
-
|
169
|
-
" :billing_mode must be set to 'PAY_PER_REQUEST'"
|
170
|
-
)
|
159
|
+
raise ArgumentError, 'when :provisioned_throughput option is not specified,'\
|
160
|
+
" :billing_mode must be set to 'PAY_PER_REQUEST'"
|
171
161
|
end
|
172
162
|
end
|
173
163
|
end
|
174
164
|
|
175
165
|
def _attribute_definitions
|
176
|
-
_keys.map do |
|
166
|
+
_keys.map do |_type, attr|
|
177
167
|
{
|
178
168
|
attribute_name: attr.database_name,
|
179
169
|
attribute_type: attr.dynamodb_type
|
@@ -186,9 +176,9 @@ module Aws
|
|
186
176
|
attr_def = create_opts[:attribute_definitions]
|
187
177
|
secondary_indexes.each do |si|
|
188
178
|
si[:key_schema].each do |key_schema|
|
189
|
-
exists = attr_def.find
|
179
|
+
exists = attr_def.find do |a|
|
190
180
|
a[:attribute_name] == key_schema[:attribute_name]
|
191
|
-
|
181
|
+
end
|
192
182
|
unless exists
|
193
183
|
attr = attributes.attribute_for(
|
194
184
|
attributes.db_to_attribute_name(key_schema[:attribute_name])
|
@@ -212,12 +202,10 @@ module Aws
|
|
212
202
|
params.merge(provisioned_throughput: throughput)
|
213
203
|
end
|
214
204
|
unless missing_throughput.empty?
|
215
|
-
raise ArgumentError
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
" #{gsi_throughput}"
|
220
|
-
)
|
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}"
|
221
209
|
end
|
222
210
|
ret
|
223
211
|
end
|
@@ -226,13 +214,13 @@ module Aws
|
|
226
214
|
_keys.map do |type, attr|
|
227
215
|
{
|
228
216
|
attribute_name: attr.database_name,
|
229
|
-
key_type: type == :hash ?
|
217
|
+
key_type: type == :hash ? 'HASH' : 'RANGE'
|
230
218
|
}
|
231
219
|
end
|
232
220
|
end
|
233
221
|
|
234
222
|
def _keys
|
235
|
-
@model.keys.
|
223
|
+
@model.keys.each_with_object({}) do |(type, name), acc|
|
236
224
|
acc[type] = @model.attributes.attribute_for(name)
|
237
225
|
acc
|
238
226
|
end
|