aws-record 2.10.0 → 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 +335 -0
- data/LICENSE +202 -0
- data/VERSION +1 -0
- data/lib/aws-record/record/attribute.rb +9 -21
- data/lib/aws-record/record/attributes.rb +68 -78
- data/lib/aws-record/record/batch.rb +13 -12
- data/lib/aws-record/record/batch_read.rb +5 -2
- data/lib/aws-record/record/batch_write.rb +1 -12
- data/lib/aws-record/record/buildable_search.rb +33 -28
- data/lib/aws-record/record/client_configuration.rb +10 -21
- data/lib/aws-record/record/dirty_tracking.rb +30 -44
- data/lib/aws-record/record/errors.rb +1 -13
- data/lib/aws-record/record/item_collection.rb +5 -16
- data/lib/aws-record/record/item_data.rb +4 -18
- data/lib/aws-record/record/item_operations.rb +86 -93
- data/lib/aws-record/record/key_attributes.rb +1 -14
- data/lib/aws-record/record/marshalers/boolean_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/date_marshaler.rb +1 -15
- data/lib/aws-record/record/marshalers/date_time_marshaler.rb +2 -14
- data/lib/aws-record/record/marshalers/epoch_time_marshaler.rb +1 -14
- data/lib/aws-record/record/marshalers/float_marshaler.rb +3 -19
- data/lib/aws-record/record/marshalers/integer_marshaler.rb +3 -19
- data/lib/aws-record/record/marshalers/list_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/map_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/numeric_set_marshaler.rb +3 -16
- data/lib/aws-record/record/marshalers/string_marshaler.rb +2 -16
- data/lib/aws-record/record/marshalers/string_set_marshaler.rb +3 -16
- data/lib/aws-record/record/marshalers/time_marshaler.rb +1 -14
- data/lib/aws-record/record/model_attributes.rb +14 -35
- data/lib/aws-record/record/query.rb +7 -21
- data/lib/aws-record/record/secondary_indexes.rb +23 -42
- data/lib/aws-record/record/table_config.rb +52 -74
- data/lib/aws-record/record/table_migration.rb +43 -66
- data/lib/aws-record/record/transactions.rb +67 -38
- data/lib/aws-record/record/version.rb +2 -13
- data/lib/aws-record/record.rb +30 -49
- metadata +14 -5
@@ -1,19 +1,7 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
4
|
-
# use this file except in compliance with the License. A copy of the License is
|
5
|
-
# located at
|
6
|
-
#
|
7
|
-
# http://aws.amazon.com/apache2.0/
|
8
|
-
#
|
9
|
-
# or in the "license" file accompanying this file. This file is distributed on
|
10
|
-
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
-
# or implied. See the License for the specific language governing permissions
|
12
|
-
# and limitations under the License.
|
1
|
+
# frozen_string_literal: true
|
13
2
|
|
14
3
|
module Aws
|
15
4
|
module Record
|
16
|
-
|
17
5
|
# +Aws::Record::TableConfig+ provides a DSL for describing and modifying
|
18
6
|
# the remote configuration of your DynamoDB tables. A table configuration
|
19
7
|
# object can perform intelligent comparisons and incremental migrations
|
@@ -101,11 +89,9 @@ module Aws
|
|
101
89
|
# end
|
102
90
|
#
|
103
91
|
class TableConfig
|
104
|
-
|
105
92
|
attr_accessor :client
|
106
93
|
|
107
94
|
class << self
|
108
|
-
|
109
95
|
# Creates a new table configuration, using a DSL in the provided block.
|
110
96
|
# The DSL has the following methods:
|
111
97
|
# * +#model_class+ A class name reference to the +Aws::Record+ model
|
@@ -169,7 +155,7 @@ module Aws
|
|
169
155
|
def initialize
|
170
156
|
@client_options = {}
|
171
157
|
@global_secondary_indexes = {}
|
172
|
-
@billing_mode =
|
158
|
+
@billing_mode = 'PROVISIONED' # default
|
173
159
|
end
|
174
160
|
|
175
161
|
# @api private
|
@@ -202,6 +188,7 @@ module Aws
|
|
202
188
|
# @api private
|
203
189
|
def configure_client
|
204
190
|
@client = Aws::DynamoDB::Client.new(@client_options)
|
191
|
+
@client.config.user_agent_frameworks << 'aws-record'
|
205
192
|
end
|
206
193
|
|
207
194
|
# @api private
|
@@ -242,9 +229,9 @@ module Aws
|
|
242
229
|
unless _gsi_superset(resp)
|
243
230
|
@client.update_table(_update_index_opts(resp))
|
244
231
|
@client.wait_until(
|
245
|
-
|
246
|
-
|
247
|
-
|
232
|
+
:table_exists,
|
233
|
+
table_name: @model_class.table_name
|
234
|
+
)
|
248
235
|
end
|
249
236
|
end
|
250
237
|
rescue DynamoDB::Errors::ResourceNotFoundException
|
@@ -259,7 +246,7 @@ module Aws
|
|
259
246
|
# we will only alter TTL status if we have a TTL attribute defined. We
|
260
247
|
# may someday support explicit TTL deletion, but we do not yet do this.
|
261
248
|
if @ttl_attribute
|
262
|
-
|
249
|
+
unless _ttl_compatibility_check
|
263
250
|
client.update_time_to_live(
|
264
251
|
table_name: @model_class.table_name,
|
265
252
|
time_to_live_specification: {
|
@@ -281,12 +268,10 @@ module Aws
|
|
281
268
|
#
|
282
269
|
# @return [Boolean] true if remote is compatible, false otherwise.
|
283
270
|
def compatible?
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
false
|
289
|
-
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
|
290
275
|
end
|
291
276
|
|
292
277
|
# Checks against the remote table's configuration. If the remote table
|
@@ -296,26 +281,25 @@ module Aws
|
|
296
281
|
#
|
297
282
|
# @return [Boolean] true if remote is an exact match, false otherwise.
|
298
283
|
def exact_match?
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
false
|
308
|
-
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
|
309
292
|
end
|
310
293
|
|
311
294
|
private
|
295
|
+
|
312
296
|
def _ttl_compatibility_check
|
313
297
|
if @ttl_attribute
|
314
298
|
ttl_status = @client.describe_time_to_live(
|
315
299
|
table_name: @model_class.table_name
|
316
300
|
)
|
317
301
|
desc = ttl_status.time_to_live_description
|
318
|
-
[
|
302
|
+
%w[ENABLED ENABLING].include?(desc.time_to_live_status) &&
|
319
303
|
desc.attribute_name == @ttl_attribute
|
320
304
|
else
|
321
305
|
true
|
@@ -328,11 +312,11 @@ module Aws
|
|
328
312
|
)
|
329
313
|
desc = ttl_status.time_to_live_description
|
330
314
|
if @ttl_attribute
|
331
|
-
[
|
315
|
+
%w[ENABLED ENABLING].include?(desc.time_to_live_status) &&
|
332
316
|
desc.attribute_name == @ttl_attribute
|
333
317
|
else
|
334
|
-
|
335
|
-
desc.attribute_name
|
318
|
+
!%w[ENABLED ENABLING].include?(desc.time_to_live_status) ||
|
319
|
+
desc.attribute_name.nil?
|
336
320
|
end
|
337
321
|
end
|
338
322
|
|
@@ -347,30 +331,25 @@ module Aws
|
|
347
331
|
opts = {
|
348
332
|
table_name: @model_class.table_name
|
349
333
|
}
|
350
|
-
if @billing_mode ==
|
334
|
+
if @billing_mode == 'PROVISIONED'
|
351
335
|
opts[:provisioned_throughput] = {
|
352
336
|
read_capacity_units: @read_capacity_units,
|
353
337
|
write_capacity_units: @write_capacity_units
|
354
338
|
}
|
355
|
-
elsif @billing_mode ==
|
339
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
356
340
|
opts[:billing_mode] = @billing_mode
|
357
341
|
else
|
358
342
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
359
343
|
end
|
360
|
-
|
361
344
|
opts[:key_schema] = _key_schema
|
362
345
|
opts[:attribute_definitions] = _attribute_definitions
|
363
346
|
gsi = _global_secondary_indexes
|
364
|
-
unless gsi.empty?
|
365
|
-
opts[:global_secondary_indexes] = gsi
|
366
|
-
end
|
347
|
+
opts[:global_secondary_indexes] = gsi unless gsi.empty?
|
367
348
|
opts
|
368
349
|
end
|
369
350
|
|
370
351
|
def _add_global_secondary_index_throughput(opts, resp_gsis)
|
371
|
-
gsis = resp_gsis.map
|
372
|
-
g.index_name
|
373
|
-
end
|
352
|
+
gsis = resp_gsis.map(&:index_name)
|
374
353
|
gsi_updates = []
|
375
354
|
gsis.each do |index_name|
|
376
355
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
@@ -386,7 +365,7 @@ module Aws
|
|
386
365
|
end
|
387
366
|
|
388
367
|
def _update_throughput_opts(resp)
|
389
|
-
if @billing_mode ==
|
368
|
+
if @billing_mode == 'PROVISIONED'
|
390
369
|
opts = {
|
391
370
|
table_name: @model_class.table_name,
|
392
371
|
provisioned_throughput: {
|
@@ -397,7 +376,7 @@ module Aws
|
|
397
376
|
# special case: we have global secondary indexes existing, and they
|
398
377
|
# need provisioned capacity to be set within this call
|
399
378
|
if !resp.table.billing_mode_summary.nil? &&
|
400
|
-
|
379
|
+
resp.table.billing_mode_summary.billing_mode == 'PAY_PER_REQUEST'
|
401
380
|
opts[:billing_mode] = @billing_mode
|
402
381
|
if resp.table.global_secondary_indexes
|
403
382
|
resp_gsis = resp.table.global_secondary_indexes
|
@@ -405,10 +384,10 @@ module Aws
|
|
405
384
|
end
|
406
385
|
end # else don't include billing mode
|
407
386
|
opts
|
408
|
-
elsif @billing_mode ==
|
387
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
409
388
|
{
|
410
389
|
table_name: @model_class.table_name,
|
411
|
-
billing_mode:
|
390
|
+
billing_mode: 'PAY_PER_REQUEST'
|
412
391
|
}
|
413
392
|
else
|
414
393
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
@@ -442,7 +421,7 @@ module Aws
|
|
442
421
|
gsi[:key_schema].each do |k|
|
443
422
|
attributes_referenced.add(k[:attribute_name])
|
444
423
|
end
|
445
|
-
if @billing_mode ==
|
424
|
+
if @billing_mode == 'PROVISIONED'
|
446
425
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
447
426
|
gsi[:provisioned_throughput] = lgsi.provisioned_throughput
|
448
427
|
end
|
@@ -451,7 +430,7 @@ module Aws
|
|
451
430
|
}
|
452
431
|
end
|
453
432
|
# we don't currently update anything other than throughput
|
454
|
-
if @billing_mode ==
|
433
|
+
if @billing_mode == 'PROVISIONED'
|
455
434
|
update_candidates.each do |index_name|
|
456
435
|
lgsi = @global_secondary_indexes[index_name.to_sym]
|
457
436
|
gsi_updates << {
|
@@ -475,19 +454,19 @@ module Aws
|
|
475
454
|
_keys.map do |type, attr|
|
476
455
|
{
|
477
456
|
attribute_name: attr.database_name,
|
478
|
-
key_type: type == :hash ?
|
457
|
+
key_type: type == :hash ? 'HASH' : 'RANGE'
|
479
458
|
}
|
480
459
|
end
|
481
460
|
end
|
482
461
|
|
483
462
|
def _attribute_definitions
|
484
|
-
attribute_definitions = _keys.map do |
|
463
|
+
attribute_definitions = _keys.map do |_type, attr|
|
485
464
|
{
|
486
465
|
attribute_name: attr.database_name,
|
487
466
|
attribute_type: attr.dynamodb_type
|
488
467
|
}
|
489
468
|
end
|
490
|
-
@model_class.global_secondary_indexes.
|
469
|
+
@model_class.global_secondary_indexes.each_value do |attributes|
|
491
470
|
gsi_keys = [attributes[:hash_key]]
|
492
471
|
gsi_keys << attributes[:range_key] if attributes[:range_key]
|
493
472
|
gsi_keys.each do |name|
|
@@ -507,40 +486,40 @@ module Aws
|
|
507
486
|
end
|
508
487
|
|
509
488
|
def _keys
|
510
|
-
@model_class.keys.
|
489
|
+
@model_class.keys.each_with_object({}) do |(type, name), acc|
|
511
490
|
acc[type] = @model_class.attributes.attribute_for(name)
|
512
491
|
acc
|
513
492
|
end
|
514
493
|
end
|
515
494
|
|
516
495
|
def _throughput_equal(resp)
|
517
|
-
if @billing_mode ==
|
496
|
+
if @billing_mode == 'PAY_PER_REQUEST'
|
518
497
|
!resp.table.billing_mode_summary.nil? &&
|
519
|
-
resp.table.billing_mode_summary.billing_mode ==
|
498
|
+
resp.table.billing_mode_summary.billing_mode == 'PAY_PER_REQUEST'
|
520
499
|
else
|
521
500
|
expected = resp.table.provisioned_throughput.to_h
|
522
501
|
actual = {
|
523
502
|
read_capacity_units: @read_capacity_units,
|
524
503
|
write_capacity_units: @write_capacity_units
|
525
504
|
}
|
526
|
-
actual.all? do |k,v|
|
505
|
+
actual.all? do |k, v|
|
527
506
|
expected[k] == v
|
528
507
|
end
|
529
508
|
end
|
530
509
|
end
|
531
510
|
|
532
511
|
def _keys_equal(resp)
|
533
|
-
remote_key_schema = resp.table.key_schema.map
|
512
|
+
remote_key_schema = resp.table.key_schema.map(&:to_h)
|
534
513
|
_array_unsorted_eql(remote_key_schema, _key_schema)
|
535
514
|
end
|
536
515
|
|
537
516
|
def _ad_equal(resp)
|
538
|
-
remote_ad = resp.table.attribute_definitions.map
|
517
|
+
remote_ad = resp.table.attribute_definitions.map(&:to_h)
|
539
518
|
_array_unsorted_eql(remote_ad, _attribute_definitions)
|
540
519
|
end
|
541
520
|
|
542
521
|
def _ad_superset(resp)
|
543
|
-
remote_ad = resp.table.attribute_definitions.map
|
522
|
+
remote_ad = resp.table.attribute_definitions.map(&:to_h)
|
544
523
|
_attribute_definitions.all? do |attribute_definition|
|
545
524
|
remote_ad.include?(attribute_definition)
|
546
525
|
end
|
@@ -551,7 +530,7 @@ module Aws
|
|
551
530
|
local_gsis = _global_secondary_indexes
|
552
531
|
remote_idx, local_idx = _gsi_index_names(remote_gsis, local_gsis)
|
553
532
|
if local_idx.subset?(remote_idx)
|
554
|
-
|
533
|
+
_gsi_set_compare(remote_gsis, local_gsis)
|
555
534
|
else
|
556
535
|
# If we have any local indexes not on the remote table,
|
557
536
|
# guaranteed false.
|
@@ -576,17 +555,17 @@ module Aws
|
|
576
555
|
r.index_name == lgsi[:index_name].to_s
|
577
556
|
end
|
578
557
|
|
579
|
-
remote_key_schema = rgsi.key_schema.map
|
558
|
+
remote_key_schema = rgsi.key_schema.map(&:to_h)
|
580
559
|
ks_match = _array_unsorted_eql(remote_key_schema, lgsi[:key_schema])
|
581
560
|
|
582
561
|
# Throughput Check: Dependent on Billing Mode
|
583
562
|
rpt = rgsi.provisioned_throughput.to_h
|
584
563
|
lpt = lgsi[:provisioned_throughput]
|
585
|
-
if @billing_mode ==
|
586
|
-
pt_match = lpt.all? do |k,v|
|
564
|
+
if @billing_mode == 'PROVISIONED'
|
565
|
+
pt_match = lpt.all? do |k, v|
|
587
566
|
rpt[k] == v
|
588
567
|
end
|
589
|
-
elsif @billing_mode ==
|
568
|
+
elsif @billing_mode == 'PAY_PER_REQUEST'
|
590
569
|
pt_match = lpt.nil? ? true : false
|
591
570
|
else
|
592
571
|
raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
|
@@ -625,7 +604,7 @@ module Aws
|
|
625
604
|
if model_gsis
|
626
605
|
model_gsis.each do |mgsi|
|
627
606
|
config = gsi_config[mgsi[:index_name]]
|
628
|
-
if @billing_mode ==
|
607
|
+
if @billing_mode == 'PROVISIONED'
|
629
608
|
gsis << mgsi.merge(
|
630
609
|
provisioned_throughput: config.provisioned_throughput
|
631
610
|
)
|
@@ -644,12 +623,12 @@ module Aws
|
|
644
623
|
def _validate_required_configuration
|
645
624
|
missing_config = []
|
646
625
|
missing_config << 'model_class' unless @model_class
|
647
|
-
if @billing_mode ==
|
626
|
+
if @billing_mode == 'PROVISIONED'
|
648
627
|
missing_config << 'read_capacity_units' unless @read_capacity_units
|
649
628
|
missing_config << 'write_capacity_units' unless @write_capacity_units
|
650
629
|
else
|
651
630
|
if @read_capacity_units || @write_capacity_units
|
652
|
-
raise ArgumentError
|
631
|
+
raise ArgumentError, "Cannot have billing mode #{@billing_mode} with provisioned capacity."
|
653
632
|
end
|
654
633
|
end
|
655
634
|
unless missing_config.empty?
|
@@ -674,7 +653,6 @@ module Aws
|
|
674
653
|
@provisioned_throughput[:write_capacity_units] = units
|
675
654
|
end
|
676
655
|
end
|
677
|
-
|
678
656
|
end
|
679
657
|
end
|
680
658
|
end
|
@@ -1,20 +1,8 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
|
4
|
-
# use this file except in compliance with the License. A copy of the License is
|
5
|
-
# located at
|
6
|
-
#
|
7
|
-
# http://aws.amazon.com/apache2.0/
|
8
|
-
#
|
9
|
-
# or in the "license" file accompanying this file. This file is distributed on
|
10
|
-
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
-
# or implied. See the License for the specific language governing permissions
|
12
|
-
# and limitations under the License.
|
1
|
+
# frozen_string_literal: true
|
13
2
|
|
14
3
|
module Aws
|
15
4
|
module Record
|
16
5
|
class TableMigration
|
17
|
-
|
18
6
|
# @!attribute [rw] client
|
19
7
|
# @return [Aws::DynamoDB::Client] the
|
20
8
|
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html Aws::DynamoDB::Client}
|
@@ -32,12 +20,14 @@ module Aws
|
|
32
20
|
_assert_model_valid(model)
|
33
21
|
@model = model
|
34
22
|
@client = opts[:client] || model.dynamodb_client || Aws::DynamoDB::Client.new
|
23
|
+
@client.config.user_agent_frameworks << 'aws-record'
|
35
24
|
end
|
36
25
|
|
37
26
|
# This method calls
|
38
|
-
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#create_table-instance_method
|
39
|
-
# populating the attribute definitions and
|
40
|
-
# 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.
|
41
31
|
#
|
42
32
|
# @example Creating a table with a global secondary index named +:gsi+
|
43
33
|
# migration.create!(
|
@@ -74,22 +64,20 @@ module Aws
|
|
74
64
|
gsit = opts.delete(:global_secondary_index_throughput)
|
75
65
|
_validate_billing(opts)
|
76
66
|
|
77
|
-
create_opts = opts.merge(
|
67
|
+
create_opts = opts.merge(
|
78
68
|
table_name: @model.table_name,
|
79
69
|
attribute_definitions: _attribute_definitions,
|
80
70
|
key_schema: _key_schema
|
81
|
-
|
82
|
-
if lsis = @model.local_secondary_indexes_for_migration
|
71
|
+
)
|
72
|
+
if (lsis = @model.local_secondary_indexes_for_migration)
|
83
73
|
create_opts[:local_secondary_indexes] = lsis
|
84
74
|
_append_to_attribute_definitions(lsis, create_opts)
|
85
75
|
end
|
86
|
-
if gsis = @model.global_secondary_indexes_for_migration
|
76
|
+
if (gsis = @model.global_secondary_indexes_for_migration)
|
87
77
|
unless gsit || opts[:billing_mode] == 'PAY_PER_REQUEST'
|
88
|
-
raise ArgumentError
|
89
|
-
|
90
|
-
|
91
|
-
" unless :billing_mode is set to 'PAY_PER_REQUEST'."
|
92
|
-
)
|
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'."
|
93
81
|
end
|
94
82
|
gsis_opts = if opts[:billing_mode] == 'PAY_PER_REQUEST'
|
95
83
|
gsis
|
@@ -103,8 +91,8 @@ module Aws
|
|
103
91
|
end
|
104
92
|
|
105
93
|
# This method calls
|
106
|
-
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#update_table-instance_method
|
107
|
-
# 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.
|
108
96
|
#
|
109
97
|
# @param [Hash] opts options to pass on to the client call to
|
110
98
|
# +#update_table+. See the documentation above in the AWS SDK for Ruby
|
@@ -112,28 +100,24 @@ module Aws
|
|
112
100
|
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table does not
|
113
101
|
# currently exist in Amazon DynamoDB.
|
114
102
|
def update!(opts)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
raise Errors::TableDoesNotExist.new(e)
|
122
|
-
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
|
123
109
|
end
|
124
110
|
|
125
111
|
# This method calls
|
126
|
-
# {http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#delete_table-instance_method
|
127
|
-
# 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.
|
128
114
|
#
|
129
115
|
# @raise [Aws::Record::Errors::TableDoesNotExist] if the table did not
|
130
116
|
# exist in Amazon DynamoDB at the time of calling.
|
131
117
|
def delete!
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
raise Errors::TableDoesNotExist.new(e)
|
136
|
-
end
|
118
|
+
@client.delete_table(table_name: @model.table_name)
|
119
|
+
rescue DynamoDB::Errors::ResourceNotFoundException
|
120
|
+
raise Errors::TableDoesNotExist
|
137
121
|
end
|
138
122
|
|
139
123
|
# This method waits on the table specified in the model to exist and be
|
@@ -145,6 +129,7 @@ module Aws
|
|
145
129
|
end
|
146
130
|
|
147
131
|
private
|
132
|
+
|
148
133
|
def _assert_model_valid(model)
|
149
134
|
_assert_required_include(model)
|
150
135
|
model.model_valid?
|
@@ -152,7 +137,7 @@ module Aws
|
|
152
137
|
|
153
138
|
def _assert_required_include(model)
|
154
139
|
unless model.include?(::Aws::Record)
|
155
|
-
raise Errors::InvalidModel
|
140
|
+
raise Errors::InvalidModel, 'Table models must include Aws::Record'
|
156
141
|
end
|
157
142
|
end
|
158
143
|
|
@@ -160,31 +145,25 @@ module Aws
|
|
160
145
|
valid_modes = %w[PAY_PER_REQUEST PROVISIONED]
|
161
146
|
if opts.key?(:billing_mode)
|
162
147
|
unless valid_modes.include?(opts[:billing_mode])
|
163
|
-
raise ArgumentError.
|
164
|
-
|
165
|
-
" current value is: #{opts[:billing_mode]}"
|
166
|
-
)
|
148
|
+
raise ArgumentError, ":billing_mode option must be one of #{valid_modes.join(', ')}"\
|
149
|
+
" current value is: #{opts[:billing_mode]}"
|
167
150
|
end
|
168
151
|
end
|
169
152
|
if opts.key?(:provisioned_throughput)
|
170
153
|
if opts[:billing_mode] == 'PAY_PER_REQUEST'
|
171
|
-
raise ArgumentError
|
172
|
-
|
173
|
-
" must either be unspecified or have a value of 'PROVISIONED'"
|
174
|
-
)
|
154
|
+
raise ArgumentError, 'when :provisioned_throughput option is specified, :billing_mode'\
|
155
|
+
" must either be unspecified or have a value of 'PROVISIONED'"
|
175
156
|
end
|
176
157
|
else
|
177
158
|
if opts[:billing_mode] != 'PAY_PER_REQUEST'
|
178
|
-
raise ArgumentError
|
179
|
-
|
180
|
-
" :billing_mode must be set to 'PAY_PER_REQUEST'"
|
181
|
-
)
|
159
|
+
raise ArgumentError, 'when :provisioned_throughput option is not specified,'\
|
160
|
+
" :billing_mode must be set to 'PAY_PER_REQUEST'"
|
182
161
|
end
|
183
162
|
end
|
184
163
|
end
|
185
164
|
|
186
165
|
def _attribute_definitions
|
187
|
-
_keys.map do |
|
166
|
+
_keys.map do |_type, attr|
|
188
167
|
{
|
189
168
|
attribute_name: attr.database_name,
|
190
169
|
attribute_type: attr.dynamodb_type
|
@@ -197,9 +176,9 @@ module Aws
|
|
197
176
|
attr_def = create_opts[:attribute_definitions]
|
198
177
|
secondary_indexes.each do |si|
|
199
178
|
si[:key_schema].each do |key_schema|
|
200
|
-
exists = attr_def.find
|
179
|
+
exists = attr_def.find do |a|
|
201
180
|
a[:attribute_name] == key_schema[:attribute_name]
|
202
|
-
|
181
|
+
end
|
203
182
|
unless exists
|
204
183
|
attr = attributes.attribute_for(
|
205
184
|
attributes.db_to_attribute_name(key_schema[:attribute_name])
|
@@ -223,12 +202,10 @@ module Aws
|
|
223
202
|
params.merge(provisioned_throughput: throughput)
|
224
203
|
end
|
225
204
|
unless missing_throughput.empty?
|
226
|
-
raise ArgumentError
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
" #{gsi_throughput}"
|
231
|
-
)
|
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}"
|
232
209
|
end
|
233
210
|
ret
|
234
211
|
end
|
@@ -237,13 +214,13 @@ module Aws
|
|
237
214
|
_keys.map do |type, attr|
|
238
215
|
{
|
239
216
|
attribute_name: attr.database_name,
|
240
|
-
key_type: type == :hash ?
|
217
|
+
key_type: type == :hash ? 'HASH' : 'RANGE'
|
241
218
|
}
|
242
219
|
end
|
243
220
|
end
|
244
221
|
|
245
222
|
def _keys
|
246
|
-
@model.keys.
|
223
|
+
@model.keys.each_with_object({}) do |(type, name), acc|
|
247
224
|
acc[type] = @model.attributes.attribute_for(name)
|
248
225
|
acc
|
249
226
|
end
|