dynamoid 3.3.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -1
  3. data/README.md +146 -52
  4. data/lib/dynamoid.rb +1 -0
  5. data/lib/dynamoid/adapter.rb +20 -7
  6. data/lib/dynamoid/adapter_plugin/aws_sdk_v3.rb +70 -37
  7. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/batch_get_item.rb +3 -0
  8. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/create_table.rb +20 -12
  9. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/item_updater.rb +5 -4
  10. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/backoff.rb +2 -2
  11. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/limit.rb +2 -3
  12. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/start_key.rb +2 -2
  13. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/query.rb +4 -2
  14. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/scan.rb +4 -2
  15. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/table.rb +1 -0
  16. data/lib/dynamoid/adapter_plugin/aws_sdk_v3/until_past_table_status.rb +2 -1
  17. data/lib/dynamoid/application_time_zone.rb +1 -0
  18. data/lib/dynamoid/associations.rb +182 -19
  19. data/lib/dynamoid/associations/association.rb +10 -2
  20. data/lib/dynamoid/associations/belongs_to.rb +2 -1
  21. data/lib/dynamoid/associations/has_and_belongs_to_many.rb +2 -1
  22. data/lib/dynamoid/associations/has_many.rb +2 -1
  23. data/lib/dynamoid/associations/has_one.rb +2 -1
  24. data/lib/dynamoid/associations/many_association.rb +68 -23
  25. data/lib/dynamoid/associations/single_association.rb +31 -4
  26. data/lib/dynamoid/components.rb +2 -0
  27. data/lib/dynamoid/config.rb +15 -3
  28. data/lib/dynamoid/config/backoff_strategies/constant_backoff.rb +1 -0
  29. data/lib/dynamoid/config/backoff_strategies/exponential_backoff.rb +1 -0
  30. data/lib/dynamoid/config/options.rb +1 -0
  31. data/lib/dynamoid/criteria.rb +9 -1
  32. data/lib/dynamoid/criteria/chain.rb +421 -46
  33. data/lib/dynamoid/criteria/ignored_conditions_detector.rb +3 -3
  34. data/lib/dynamoid/criteria/key_fields_detector.rb +31 -10
  35. data/lib/dynamoid/criteria/nonexistent_fields_detector.rb +3 -2
  36. data/lib/dynamoid/criteria/overwritten_conditions_detector.rb +1 -1
  37. data/lib/dynamoid/dirty.rb +119 -64
  38. data/lib/dynamoid/document.rb +133 -46
  39. data/lib/dynamoid/dumping.rb +9 -0
  40. data/lib/dynamoid/dynamodb_time_zone.rb +1 -0
  41. data/lib/dynamoid/errors.rb +2 -0
  42. data/lib/dynamoid/fields.rb +251 -39
  43. data/lib/dynamoid/fields/declare.rb +86 -0
  44. data/lib/dynamoid/finders.rb +69 -32
  45. data/lib/dynamoid/identity_map.rb +6 -0
  46. data/lib/dynamoid/indexes.rb +86 -17
  47. data/lib/dynamoid/loadable.rb +2 -2
  48. data/lib/dynamoid/log/formatter.rb +26 -0
  49. data/lib/dynamoid/middleware/identity_map.rb +1 -0
  50. data/lib/dynamoid/persistence.rb +502 -104
  51. data/lib/dynamoid/persistence/import.rb +2 -1
  52. data/lib/dynamoid/persistence/save.rb +1 -0
  53. data/lib/dynamoid/persistence/update_fields.rb +5 -2
  54. data/lib/dynamoid/persistence/update_validations.rb +18 -0
  55. data/lib/dynamoid/persistence/upsert.rb +5 -3
  56. data/lib/dynamoid/primary_key_type_mapping.rb +1 -0
  57. data/lib/dynamoid/railtie.rb +1 -0
  58. data/lib/dynamoid/tasks.rb +3 -1
  59. data/lib/dynamoid/tasks/database.rb +1 -0
  60. data/lib/dynamoid/type_casting.rb +12 -2
  61. data/lib/dynamoid/undumping.rb +8 -0
  62. data/lib/dynamoid/validations.rb +6 -1
  63. data/lib/dynamoid/version.rb +1 -1
  64. metadata +48 -75
  65. data/.coveralls.yml +0 -1
  66. data/.document +0 -5
  67. data/.gitignore +0 -74
  68. data/.rspec +0 -2
  69. data/.rubocop.yml +0 -71
  70. data/.rubocop_todo.yml +0 -55
  71. data/.travis.yml +0 -44
  72. data/Appraisals +0 -22
  73. data/Gemfile +0 -8
  74. data/Rakefile +0 -46
  75. data/Vagrantfile +0 -29
  76. data/docker-compose.yml +0 -7
  77. data/dynamoid.gemspec +0 -57
  78. data/gemfiles/rails_4_2.gemfile +0 -9
  79. data/gemfiles/rails_5_0.gemfile +0 -8
  80. data/gemfiles/rails_5_1.gemfile +0 -8
  81. data/gemfiles/rails_5_2.gemfile +0 -8
  82. data/gemfiles/rails_6_0.gemfile +0 -8
data/lib/dynamoid.rb CHANGED
@@ -57,6 +57,7 @@ module Dynamoid
57
57
  @included_models ||= []
58
58
  end
59
59
 
60
+ # @private
60
61
  def adapter
61
62
  @adapter ||= Adapter.new
62
63
  end
@@ -3,7 +3,7 @@
3
3
  # require only 'concurrent/atom' once this issue is resolved:
4
4
  # https://github.com/ruby-concurrency/concurrent-ruby/pull/377
5
5
  require 'concurrent'
6
- require "dynamoid/adapter_plugin/aws_sdk_v3"
6
+ require 'dynamoid/adapter_plugin/aws_sdk_v3'
7
7
 
8
8
  # encoding: utf-8
9
9
  module Dynamoid
@@ -11,6 +11,7 @@ module Dynamoid
11
11
  # 1) For the rest of Dynamoid, the gateway to DynamoDB.
12
12
  # 2) Allows switching `config.adapter` to ease development of a new adapter.
13
13
  # 3) Caches the list of tables Dynamoid knows about.
14
+ # @private
14
15
  class Adapter
15
16
  def initialize
16
17
  @adapter_ = Concurrent::Atom.new(nil)
@@ -78,8 +79,8 @@ module Dynamoid
78
79
  #
79
80
  # @param [String] table the name of the table to write the object to
80
81
  # @param [Array] ids to fetch, can also be a string of just one id
81
- # @param [Hash] options: Passed to the underlying query. The :range_key option is required whenever the table has a range key,
82
- # unless multiple ids are passed in.
82
+ # @param [Hash] options Passed to the underlying query. The :range_key option is required whenever the table has a range key,
83
+ # unless multiple ids are passed in.
83
84
  #
84
85
  # @since 0.2.0
85
86
  def read(table, ids, options = {}, &blk)
@@ -94,7 +95,9 @@ module Dynamoid
94
95
  #
95
96
  # @param [String] table the name of the table to write the object to
96
97
  # @param [Array] ids to delete, can also be a string of just one id
97
- # @param [Array] range_key of the record to delete, can also be a string of just one range_key
98
+ # @param [Hash] options allowed only +range_key+ - range key or array of
99
+ # range keys of the record to delete, can also be
100
+ # a string of just one range_key, and +conditions+
98
101
  #
99
102
  def delete(table, ids, options = {})
100
103
  range_key = options[:range_key] # array of range keys that matches the ids passed in
@@ -115,7 +118,7 @@ module Dynamoid
115
118
  # Scans a table. Generally quite slow; try to avoid using scan if at all possible.
116
119
  #
117
120
  # @param [String] table the name of the table to write the object to
118
- # @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
121
+ # @param [Hash] query a hash of attributes: matching records will be returned by the scan
119
122
  #
120
123
  # @since 0.2.0
121
124
  def scan(table, query = {}, opts = {})
@@ -124,8 +127,12 @@ module Dynamoid
124
127
 
125
128
  def create_table(table_name, key, options = {})
126
129
  unless tables.include?(table_name)
127
- benchmark('Create Table') { adapter.create_table(table_name, key, options) }
130
+ result = nil
131
+ benchmark('Create Table') { result = adapter.create_table(table_name, key, options) }
128
132
  tables << table_name
133
+ result
134
+ else
135
+ false
129
136
  end
130
137
  end
131
138
 
@@ -151,8 +158,14 @@ module Dynamoid
151
158
  #
152
159
  # @since 0.2.0
153
160
  def method_missing(method, *args, &block)
154
- return benchmark(method, *args) { adapter.send(method, *args, &block) } if adapter.respond_to?(method)
161
+ # Don't use keywork arguments delegating (with **kw). It works in
162
+ # different way in different Ruby versions: <= 2.6, 2.7, 3.0 and in some
163
+ # future 3.x versions. Providing that there are no downstream methods
164
+ # with keyword arguments in adapter.
165
+ #
166
+ # https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
155
167
 
168
+ return benchmark(method, *args) { adapter.send(method, *args, &block) } if adapter.respond_to?(method)
156
169
  super
157
170
  end
158
171
 
@@ -9,8 +9,18 @@ require_relative 'aws_sdk_v3/table'
9
9
  require_relative 'aws_sdk_v3/until_past_table_status'
10
10
 
11
11
  module Dynamoid
12
+ # @private
12
13
  module AdapterPlugin
13
14
  # The AwsSdkV3 adapter provides support for the aws-sdk version 2 for ruby.
15
+
16
+ # Note: Don't use keyword arguments in public methods as far as method
17
+ # calls on adapter are delegated to the plugin.
18
+ #
19
+ # There are breaking changes in Ruby related to delegating keyword
20
+ # arguments so we have decided just to avoid them when use delegation.
21
+ #
22
+ # https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
23
+
14
24
  class AwsSdkV3
15
25
  EQ = 'EQ'
16
26
  RANGE_MAP = {
@@ -61,6 +71,25 @@ module Dynamoid
61
71
 
62
72
  attr_reader :table_cache
63
73
 
74
+ # Build an array of values for Condition
75
+ # Is used in ScanFilter and QueryFilter
76
+ # https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html
77
+ # @param [String] operator value of RANGE_MAP or FIELD_MAP hash, e.g. "EQ", "LT" etc
78
+ # @param [Object] value scalar value or array/set
79
+ def self.attribute_value_list(operator, value)
80
+ # For BETWEEN and IN operators we should keep value as is (it should be already an array)
81
+ # NULL and NOT_NULL require absence of attribute list
82
+ # For all the other operators we wrap the value with array
83
+ # https://docs.aws.amazon.com/en_us/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Conditions.html
84
+ if %w[BETWEEN IN].include?(operator)
85
+ [value].flatten
86
+ elsif %w[NULL NOT_NULL].include?(operator)
87
+ nil
88
+ else
89
+ [value]
90
+ end
91
+ end
92
+
64
93
  # Establish the connection to DynamoDB.
65
94
  #
66
95
  # @return [Aws::DynamoDB::Client] the DynamoDB connection
@@ -75,19 +104,28 @@ module Dynamoid
75
104
  (Dynamoid::Config.settings.compact.keys & CONNECTION_CONFIG_OPTIONS).each do |option|
76
105
  @connection_hash[option] = Dynamoid::Config.send(option)
77
106
  end
78
- if Dynamoid::Config.access_key?
79
- @connection_hash[:access_key_id] = Dynamoid::Config.access_key
80
- end
81
- if Dynamoid::Config.secret_key?
82
- @connection_hash[:secret_access_key] = Dynamoid::Config.secret_key
107
+
108
+ # if credentials are passed, they already contain access key & secret key
109
+ if Dynamoid::Config.credentials?
110
+ @connection_hash[:credentials] = Dynamoid::Config.credentials
111
+ else
112
+ # otherwise, pass access key & secret key for credentials creation
113
+ if Dynamoid::Config.access_key?
114
+ @connection_hash[:access_key_id] = Dynamoid::Config.access_key
115
+ end
116
+ if Dynamoid::Config.secret_key?
117
+ @connection_hash[:secret_access_key] = Dynamoid::Config.secret_key
118
+ end
83
119
  end
84
120
 
85
- # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
86
- # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
87
- formatter = Aws::Log::Formatter.new(':operation | Request :http_request_body | Response :http_response_body')
88
121
  @connection_hash[:logger] = Dynamoid::Config.logger
89
122
  @connection_hash[:log_level] = :debug
90
- @connection_hash[:log_formatter] = formatter
123
+
124
+ # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
125
+ # https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
126
+ if Dynamoid::Config.log_formatter
127
+ @connection_hash[:log_formatter] = Dynamoid::Config.log_formatter
128
+ end
91
129
 
92
130
  @connection_hash
93
131
  end
@@ -115,9 +153,9 @@ module Dynamoid
115
153
  # end
116
154
  #
117
155
  # @param [String] table_name the name of the table
118
- # @param [Array] items to be processed
119
- # @param [Hash] additional options
120
- # @param [Proc] optional block
156
+ # @param [Array] objects to be processed
157
+ # @param [Hash] options additional options
158
+ # @yield [true|false] invokes an optional block with argument - whether there are unprocessed items
121
159
  #
122
160
  # See:
123
161
  # * http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html
@@ -172,9 +210,9 @@ module Dynamoid
172
210
  # end
173
211
  # end
174
212
  #
175
- # @param [Hash] table_ids the hash of tables and IDs to retrieve
213
+ # @param [Hash] table_names_with_ids the hash of tables and IDs to retrieve
176
214
  # @param [Hash] options to be passed to underlying BatchGet call
177
- # @param [Proc] optional block can be passed to handle each batch of items
215
+ # @param [Proc] block optional block can be passed to handle each batch of items
178
216
  #
179
217
  # @return [Hash] a hash where keys are the table names and the values are the retrieved items
180
218
  #
@@ -246,8 +284,22 @@ module Dynamoid
246
284
  def create_table(table_name, key = :id, options = {})
247
285
  Dynamoid.logger.info "Creating #{table_name} table. This could take a while."
248
286
  CreateTable.new(client, table_name, key, options).call
287
+ true
249
288
  rescue Aws::DynamoDB::Errors::ResourceInUseException => e
250
289
  Dynamoid.logger.error "Table #{table_name} cannot be created as it already exists"
290
+ false
291
+ end
292
+
293
+ def update_time_to_live(table_name, attribute)
294
+ request = {
295
+ table_name: table_name,
296
+ time_to_live_specification: {
297
+ attribute_name: attribute,
298
+ enabled: true,
299
+ }
300
+ }
301
+
302
+ client.update_time_to_live(request)
251
303
  end
252
304
 
253
305
  # Create a table on DynamoDB *synchronously*.
@@ -504,11 +556,11 @@ module Dynamoid
504
556
  hk = table.hash_key
505
557
  rk = table.range_key
506
558
 
507
- scan(table_name, {}, {}).flat_map{ |i| i }.each do |attributes|
508
- opts = {}
509
- opts[:range_key] = attributes[rk.to_sym] if rk
510
- delete_item(table_name, attributes[hk], opts)
559
+ ids = scan(table_name, {}, {}).flat_map { |i| i }.map do |attributes|
560
+ rk ? [attributes[hk], attributes[rk.to_sym]] : attributes[hk]
511
561
  end
562
+
563
+ batch_delete_item(table_name => ids)
512
564
  end
513
565
 
514
566
  def count(table_name)
@@ -566,25 +618,6 @@ module Dynamoid
566
618
  end
567
619
  end
568
620
 
569
- # Build an array of values for Condition
570
- # Is used in ScanFilter and QueryFilter
571
- # https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html
572
- # @params [String] operator: value of RANGE_MAP or FIELD_MAP hash, e.g. "EQ", "LT" etc
573
- # @params [Object] value: scalar value or array/set
574
- def self.attribute_value_list(operator, value)
575
- # For BETWEEN and IN operators we should keep value as is (it should be already an array)
576
- # NULL and NOT_NULL require absence of attribute list
577
- # For all the other operators we wrap the value with array
578
- # https://docs.aws.amazon.com/en_us/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Conditions.html
579
- if %w[BETWEEN IN].include?(operator)
580
- [value].flatten
581
- elsif %w[NULL NOT_NULL].include?(operator)
582
- nil
583
- else
584
- [value]
585
- end
586
- end
587
-
588
621
  def sanitize_item(attributes)
589
622
  config_value = Dynamoid.config.store_attribute_with_nil_value
590
623
  store_attribute_with_nil_value = config_value.nil? ? false : !!config_value
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dynamoid
4
+ # @private
2
5
  module AdapterPlugin
3
6
  class AwsSdkV3
4
7
  # Documentation
@@ -3,6 +3,7 @@
3
3
  require_relative 'until_past_table_status'
4
4
 
5
5
  module Dynamoid
6
+ # @private
6
7
  module AdapterPlugin
7
8
  class AwsSdkV3
8
9
  class CreateTable
@@ -16,6 +17,7 @@ module Dynamoid
16
17
  end
17
18
 
18
19
  def call
20
+ billing_mode = options[:billing_mode]
19
21
  read_capacity = options[:read_capacity] || Dynamoid::Config.read_capacity
20
22
  write_capacity = options[:write_capacity] || Dynamoid::Config.write_capacity
21
23
 
@@ -41,14 +43,20 @@ module Dynamoid
41
43
 
42
44
  client_opts = {
43
45
  table_name: table_name,
44
- provisioned_throughput: {
45
- read_capacity_units: read_capacity,
46
- write_capacity_units: write_capacity
47
- },
48
46
  key_schema: key_schema,
49
47
  attribute_definitions: attribute_definitions
50
48
  }
51
49
 
50
+ if billing_mode == :on_demand
51
+ client_opts[:billing_mode] = 'PAY_PER_REQUEST'
52
+ else
53
+ client_opts[:billing_mode] = 'PROVISIONED'
54
+ client_opts[:provisioned_throughput] = {
55
+ read_capacity_units: read_capacity,
56
+ write_capacity_units: write_capacity
57
+ }
58
+ end
59
+
52
60
  if ls_indexes.present?
53
61
  client_opts[:local_secondary_indexes] = ls_indexes.map do |index|
54
62
  index_to_aws_hash(index)
@@ -80,9 +88,9 @@ module Dynamoid
80
88
  # Builds aws attributes definitions based off of primary hash/range and
81
89
  # secondary indexes
82
90
  #
83
- # @param key_data
84
- # @option key_data [Hash] hash_key_schema - eg: {:id => :string}
85
- # @option key_data [Hash] range_key_schema - eg: {:created_at => :number}
91
+ # @param key_schema
92
+ # @option key_schema [Hash] hash_key_schema - eg: {:id => :string}
93
+ # @option key_schema [Hash] range_key_schema - eg: {:created_at => :number}
86
94
  # @param [Hash] secondary_indexes
87
95
  # @option secondary_indexes [Array<Dynamoid::Indexes::Index>] :local_secondary_indexes
88
96
  # @option secondary_indexes [Array<Dynamoid::Indexes::Index>] :global_secondary_indexes
@@ -123,8 +131,8 @@ module Dynamoid
123
131
  end
124
132
 
125
133
  # Builds an attribute definitions based on hash key and range key
126
- # @params [Hash] hash_key_schema - eg: {:id => :string}
127
- # @params [Hash] range_key_schema - eg: {:created_at => :datetime}
134
+ # @param [Hash] hash_key_schema - eg: {:id => :string}
135
+ # @param [Hash] range_key_schema - eg: {:created_at => :datetime}
128
136
  # @return [Array]
129
137
  def build_attribute_definitions(hash_key_schema, range_key_schema = nil)
130
138
  attrs = []
@@ -145,8 +153,8 @@ module Dynamoid
145
153
  end
146
154
 
147
155
  # Builds an aws attribute definition based on name and dynamoid type
148
- # @params [Symbol] name - eg: :id
149
- # @params [Symbol] dynamoid_type - eg: :string
156
+ # @param [Symbol] name - eg: :id
157
+ # @param [Symbol] dynamoid_type - eg: :string
150
158
  # @return [Hash]
151
159
  def attribute_definition_element(name, dynamoid_type)
152
160
  aws_type = api_type(dynamoid_type)
@@ -206,7 +214,7 @@ module Dynamoid
206
214
  end
207
215
 
208
216
  # Only global secondary indexes have a separate throughput.
209
- if index.type == :global_secondary
217
+ if index.type == :global_secondary && options[:billing_mode] != :on_demand
210
218
  hash[:provisioned_throughput] = {
211
219
  read_capacity_units: index.read_capacity,
212
220
  write_capacity_units: index.write_capacity
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dynamoid
4
+ # @private
4
5
  module AdapterPlugin
5
6
  class AwsSdkV3
6
7
  # Mimics behavior of the yielded object on DynamoDB's update_item API (high level).
@@ -20,8 +21,8 @@ module Dynamoid
20
21
  # Adds the given values to the values already stored in the corresponding columns.
21
22
  # The column must contain a Set or a number.
22
23
  #
23
- # @param [Hash] vals keys of the hash are the columns to update, vals are the values to
24
- # add. values must be a Set, Array, or Numeric
24
+ # @param [Hash] values keys of the hash are the columns to update, values
25
+ # are the values to add. values must be a Set, Array, or Numeric
25
26
  #
26
27
  def add(values)
27
28
  @additions.merge!(sanitize_attributes(values))
@@ -58,9 +59,9 @@ module Dynamoid
58
59
  end
59
60
  @deletions.each do |k, v|
60
61
  ret[k.to_s] = {
61
- action: DELETE,
62
- value: v
62
+ action: DELETE
63
63
  }
64
+ ret[k.to_s][:value] = v unless v.nil?
64
65
  end
65
66
  @updates.each do |k, v|
66
67
  ret[k.to_s] = {
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dynamoid
4
+ # @private
4
5
  module AdapterPlugin
5
6
  class AwsSdkV3
6
7
  module Middleware
@@ -14,11 +15,10 @@ module Dynamoid
14
15
  response = @next_chain.call(request)
15
16
  @backoff.call if @backoff
16
17
 
17
- return response
18
+ response
18
19
  end
19
20
  end
20
21
  end
21
22
  end
22
23
  end
23
24
  end
24
-
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dynamoid
4
+ # @private
4
5
  module AdapterPlugin
5
6
  class AwsSdkV3
6
7
  module Middleware
@@ -46,12 +47,10 @@ module Dynamoid
46
47
  @scan_count += response.scanned_count
47
48
  throw :stop_pagination if @scan_limit && @scan_count >= @scan_limit
48
49
 
49
- return response
50
+ response
50
51
  end
51
52
  end
52
-
53
53
  end
54
54
  end
55
55
  end
56
56
  end
57
-
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dynamoid
4
+ # @private
4
5
  module AdapterPlugin
5
6
  class AwsSdkV3
6
7
  module Middleware
@@ -18,11 +19,10 @@ module Dynamoid
18
19
  throw :stop_pagination
19
20
  end
20
21
 
21
- return response
22
+ response
22
23
  end
23
24
  end
24
25
  end
25
26
  end
26
27
  end
27
28
  end
28
-
@@ -5,6 +5,7 @@ require_relative 'middleware/limit'
5
5
  require_relative 'middleware/start_key'
6
6
 
7
7
  module Dynamoid
8
+ # @private
8
9
  module AdapterPlugin
9
10
  class AwsSdkV3
10
11
  class Query
@@ -29,8 +30,8 @@ module Dynamoid
29
30
  request = build_request
30
31
 
31
32
  Enumerator.new do |yielder|
32
- api_call = -> (request) do
33
- client.query(request).tap do |response|
33
+ api_call = lambda do |req|
34
+ client.query(req).tap do |response|
34
35
  yielder << response
35
36
  end
36
37
  end
@@ -122,6 +123,7 @@ module Dynamoid
122
123
 
123
124
  def attributes_to_get
124
125
  return if options[:project].nil?
126
+
125
127
  options[:project].map(&:to_s)
126
128
  end
127
129
  end