aws-record 2.1.2 → 2.2.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: 7b1ff4831b48174ce4404f6f24108ee85b11a104da96aa5176a218fdfeb8dcb8
4
- data.tar.gz: 0610b848e4705bbbb013e8833b8b54f701f100a617714ae9f5bc7891f2d63a99
3
+ metadata.gz: 76f3f70bc226f5e34e377328a8829db296bffa304238da8d7542a947ba0b7a9e
4
+ data.tar.gz: f22f14e087edf96717fbaffd03bc7b3917001fb5238597994143b50bc5e16894
5
5
  SHA512:
6
- metadata.gz: fa1408a44611715ae071ce35b937f40d2c8eae43d1dff2c4d4848a000b34e6944591f56478175ca5b5c3fb0e08e0711cb23ef171def537983d250854ff52a31d
7
- data.tar.gz: 73a5ae3dc603b55e2827cd8126219bddc066a61674ff328a6beed41fca855b3c2e3c8161be3fe57fdec6c7d095b0c482495200b87e5a9f5f10672b7e0b0e4a6e
6
+ metadata.gz: 745aff26cc027c53552b456066b56900f1489c1aa4433b8e539d1ac6f093d0cbaa62dec5054b433d2f8f2f42220471cca55dcdb6fa0d6ae1d23f542318ccd296
7
+ data.tar.gz: 2e20c004f7ca252dfdff66eb4005137c74da60a964ce4862bb2390fceaf6ce2fe0f1c63bcdc00a1671f13c69dc6165b0488afc1ba4779b524ba1740c1d7f2591
@@ -33,6 +33,17 @@ module Aws
33
33
  # t.write_capacity_units 5
34
34
  # end
35
35
  #
36
+ # @example A basic model with pay per request billing.
37
+ # class Model
38
+ # include Aws::Record
39
+ # string_attr :uuid, hash_key: true
40
+ # end
41
+ #
42
+ # table_config = Aws::Record::TableConfig.define do |t|
43
+ # t.model_class Model
44
+ # t.billing_mode "PAY_PER_REQUEST"
45
+ # end
46
+ #
36
47
  # @example Running a conditional migration on a basic model.
37
48
  # table_config = Aws::Record::TableConfig.define do |t|
38
49
  # t.model_class Model
@@ -59,7 +70,9 @@ module Aws
59
70
  # :title,
60
71
  # hash_key: :forum_uuid,
61
72
  # range_key: :post_title,
62
- # projection_type: "ALL"
73
+ # projection: {
74
+ # projection_type: "ALL"
75
+ # }
63
76
  # )
64
77
  # end
65
78
  #
@@ -106,7 +119,12 @@ module Aws
106
119
  # * +#write_capacity_units+ Sets the write capacity units for the
107
120
  # index.
108
121
  # * +#ttl_attribute+ Sets the attribute ID to be used as the TTL
109
- # attribute, and if present, TTL will be enabled for the table.
122
+ # attribute, and if present, TTL will be enabled for the table.
123
+ # * +#billing_mode+ Sets the billing mode, with the current supported
124
+ # options being "PROVISIONED" and "PAY_PER_REQUEST". If using
125
+ # "PAY_PER_REQUEST" you must not set provisioned throughput values,
126
+ # and if using "PROVISIONED" you must set provisioned throughput
127
+ # values. Default assumption is "PROVISIONED".
110
128
  #
111
129
  # @example Defining a migration with a GSI.
112
130
  # class Forum
@@ -151,6 +169,7 @@ module Aws
151
169
  def initialize
152
170
  @client_options = {}
153
171
  @global_secondary_indexes = {}
172
+ @billing_mode = "PROVISIONED" # default
154
173
  end
155
174
 
156
175
  # @api private
@@ -195,6 +214,11 @@ module Aws
195
214
  end
196
215
  end
197
216
 
217
+ # @api private
218
+ def billing_mode(mode)
219
+ @billing_mode = mode
220
+ end
221
+
198
222
  # Performs a migration, if needed, against the remote table. If
199
223
  # +#compatible?+ would return true, the remote table already has the same
200
224
  # throughput, key schema, attribute definitions, and global secondary
@@ -209,13 +233,7 @@ module Aws
209
233
  else
210
234
  # Gotcha: You need separate migrations for indexes and throughput
211
235
  unless _throughput_equal(resp)
212
- @client.update_table(
213
- table_name: @model_class.table_name,
214
- provisioned_throughput: {
215
- read_capacity_units: @read_capacity_units,
216
- write_capacity_units: @write_capacity_units
217
- }
218
- )
236
+ @client.update_table(_update_throughput_opts(resp))
219
237
  @client.wait_until(
220
238
  :table_exists,
221
239
  table_name: @model_class.table_name
@@ -327,12 +345,19 @@ module Aws
327
345
 
328
346
  def _create_table_opts
329
347
  opts = {
330
- table_name: @model_class.table_name,
331
- provisioned_throughput: {
348
+ table_name: @model_class.table_name
349
+ }
350
+ if @billing_mode == "PROVISIONED"
351
+ opts[:provisioned_throughput] = {
332
352
  read_capacity_units: @read_capacity_units,
333
353
  write_capacity_units: @write_capacity_units
334
354
  }
335
- }
355
+ elsif @billing_mode == "PAY_PER_REQUEST"
356
+ opts[:billing_mode] = @billing_mode
357
+ else
358
+ raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
359
+ end
360
+
336
361
  opts[:key_schema] = _key_schema
337
362
  opts[:attribute_definitions] = _attribute_definitions
338
363
  gsi = _global_secondary_indexes
@@ -342,6 +367,54 @@ module Aws
342
367
  opts
343
368
  end
344
369
 
370
+ def _add_global_secondary_index_throughput(opts, resp_gsis)
371
+ gsis = resp_gsis.map do |g|
372
+ g.index_name
373
+ end
374
+ gsi_updates = []
375
+ gsis.each do |index_name|
376
+ lgsi = @global_secondary_indexes[index_name.to_sym]
377
+ gsi_updates << {
378
+ update: {
379
+ index_name: index_name,
380
+ provisioned_throughput: lgsi.provisioned_throughput
381
+ }
382
+ }
383
+ end
384
+ opts[:global_secondary_index_updates] = gsi_updates
385
+ true
386
+ end
387
+
388
+ def _update_throughput_opts(resp)
389
+ if @billing_mode == "PROVISIONED"
390
+ opts = {
391
+ table_name: @model_class.table_name,
392
+ provisioned_throughput: {
393
+ read_capacity_units: @read_capacity_units,
394
+ write_capacity_units: @write_capacity_units
395
+ }
396
+ }
397
+ # special case: we have global secondary indexes existing, and they
398
+ # need provisioned capacity to be set within this call
399
+ if !resp.table.billing_mode_summary.nil? &&
400
+ resp.table.billing_mode_summary.billing_mode == "PAY_PER_REQUEST"
401
+ opts[:billing_mode] = @billing_mode
402
+ if resp.table.global_secondary_indexes
403
+ resp_gsis = resp.table.global_secondary_indexes
404
+ _add_global_secondary_index_throughput(opts, resp_gsis)
405
+ end
406
+ end # else don't include billing mode
407
+ opts
408
+ elsif @billing_mode == "PAY_PER_REQUEST"
409
+ {
410
+ table_name: @model_class.table_name,
411
+ billing_mode: "PAY_PER_REQUEST"
412
+ }
413
+ else
414
+ raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
415
+ end
416
+ end
417
+
345
418
  def _update_index_opts(resp)
346
419
  gsi_updates, attribute_definitions = _gsi_updates(resp)
347
420
  opts = {
@@ -369,22 +442,25 @@ module Aws
369
442
  gsi[:key_schema].each do |k|
370
443
  attributes_referenced.add(k[:attribute_name])
371
444
  end
372
- # This may be a problem, check if I can maintain symbols.
373
- lgsi = @global_secondary_indexes[index_name.to_sym]
374
- gsi[:provisioned_throughput] = lgsi.provisioned_throughput
445
+ if @billing_mode == "PROVISIONED"
446
+ lgsi = @global_secondary_indexes[index_name.to_sym]
447
+ gsi[:provisioned_throughput] = lgsi.provisioned_throughput
448
+ end
375
449
  gsi_updates << {
376
450
  create: gsi
377
451
  }
378
452
  end
379
- update_candidates.each do |index_name|
380
- # This may be a problem, check if I can maintain symbols.
381
- lgsi = @global_secondary_indexes[index_name.to_sym]
382
- gsi_updates << {
383
- update: {
384
- index_name: index_name,
385
- provisioned_throughput: lgsi.provisioned_throughput
453
+ # we don't currently update anything other than throughput
454
+ if @billing_mode == "PROVISIONED"
455
+ update_candidates.each do |index_name|
456
+ lgsi = @global_secondary_indexes[index_name.to_sym]
457
+ gsi_updates << {
458
+ update: {
459
+ index_name: index_name,
460
+ provisioned_throughput: lgsi.provisioned_throughput
461
+ }
386
462
  }
387
- }
463
+ end
388
464
  end
389
465
  attribute_definitions = _attribute_definitions
390
466
  incremental_attributes = attributes_referenced.map do |attr_name|
@@ -438,13 +514,18 @@ module Aws
438
514
  end
439
515
 
440
516
  def _throughput_equal(resp)
441
- expected = resp.table.provisioned_throughput.to_h
442
- actual = {
443
- read_capacity_units: @read_capacity_units,
444
- write_capacity_units: @write_capacity_units
445
- }
446
- actual.all? do |k,v|
447
- expected[k] == v
517
+ if @billing_mode == "PAY_PER_REQUEST"
518
+ !resp.table.billing_mode_summary.nil? &&
519
+ resp.table.billing_mode_summary.billing_mode == "PAY_PER_REQUEST"
520
+ else
521
+ expected = resp.table.provisioned_throughput.to_h
522
+ actual = {
523
+ read_capacity_units: @read_capacity_units,
524
+ write_capacity_units: @write_capacity_units
525
+ }
526
+ actual.all? do |k,v|
527
+ expected[k] == v
528
+ end
448
529
  end
449
530
  end
450
531
 
@@ -498,10 +579,17 @@ module Aws
498
579
  remote_key_schema = rgsi.key_schema.map { |i| i.to_h }
499
580
  ks_match = _array_unsorted_eql(remote_key_schema, lgsi[:key_schema])
500
581
 
582
+ # Throughput Check: Dependent on Billing Mode
501
583
  rpt = rgsi.provisioned_throughput.to_h
502
584
  lpt = lgsi[:provisioned_throughput]
503
- pt_match = lpt.all? do |k,v|
504
- rpt[k] == v
585
+ if @billing_mode == "PROVISIONED"
586
+ pt_match = lpt.all? do |k,v|
587
+ rpt[k] == v
588
+ end
589
+ elsif @billing_mode == "PAY_PER_REQUEST"
590
+ pt_match = lpt.nil? ? true : false
591
+ else
592
+ raise ArgumentError, "Unsupported billing mode #{@billing_mode}"
505
593
  end
506
594
 
507
595
  rp = rgsi.projection.to_h
@@ -537,10 +625,13 @@ module Aws
537
625
  if model_gsis
538
626
  model_gsis.each do |mgsi|
539
627
  config = gsi_config[mgsi[:index_name]]
540
- # Validate throughput exists? Validate each throughput is in model?
541
- gsis << mgsi.merge(
542
- provisioned_throughput: config.provisioned_throughput
543
- )
628
+ if @billing_mode == "PROVISIONED"
629
+ gsis << mgsi.merge(
630
+ provisioned_throughput: config.provisioned_throughput
631
+ )
632
+ else
633
+ gsis << mgsi
634
+ end
544
635
  end
545
636
  end
546
637
  gsis
@@ -553,8 +644,14 @@ module Aws
553
644
  def _validate_required_configuration
554
645
  missing_config = []
555
646
  missing_config << 'model_class' unless @model_class
556
- missing_config << 'read_capacity_units' unless @read_capacity_units
557
- missing_config << 'write_capacity_units' unless @write_capacity_units
647
+ if @billing_mode == "PROVISIONED"
648
+ missing_config << 'read_capacity_units' unless @read_capacity_units
649
+ missing_config << 'write_capacity_units' unless @write_capacity_units
650
+ else
651
+ if @read_capacity_units || @write_capacity_units
652
+ raise ArgumentError.new("Cannot have billing mode #{@billing_mode} with provisioned capacity.")
653
+ end
654
+ end
558
655
  unless missing_config.empty?
559
656
  msg = missing_config.join(', ')
560
657
  raise Errors::MissingRequiredConfiguration, 'Missing: ' + msg
@@ -13,6 +13,6 @@
13
13
 
14
14
  module Aws
15
15
  module Record
16
- VERSION = '2.1.2'
16
+ VERSION = '2.2.0'
17
17
  end
18
18
  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.1.2
4
+ version: 2.2.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: 2018-11-15 00:00:00.000000000 Z
11
+ date: 2018-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.18'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.18'
27
27
  description: Provides an object mapping abstraction for Amazon DynamoDB.
28
28
  email:
29
29
  - alexwood@amazon.com