dynamoid_advanced_where 1.2.0 → 1.4.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: 0acc4dd6fd2beb8c36ce5ee16ac0a1e2a612e9f1f835ebab56d0d445bf026bbb
4
- data.tar.gz: 0dbe226b9e1ef5037069b6af0133f72c20a64fd2fb9049648d015a58963cc43f
3
+ metadata.gz: 77c5c86c6aeccd5d5cd9db4a6e030a3527d17c87776fb05de5a06966699a1167
4
+ data.tar.gz: 02426eb629574d8bcd1ec7507c1f6795d0e3f22577ef54c21bf203351ccd81d3
5
5
  SHA512:
6
- metadata.gz: bc34e3547aa649fed56dd816aea6998a70c8ca2d45a43eed56912f3215c41f7326b6e340bee29ca12b93e059cd135770d136383dd9e7e1f2be30a52a71ab1500
7
- data.tar.gz: f58df477e8073f0792d5cc362c37dd4c3a78486aa4e4f3c3fe50ae72b62eb5f642b645308389d048dee03ed2279d29467034b938796a359dfcafea6577a08f99
6
+ metadata.gz: dcb79577e6f5e90cccb482e77d26614f7be1fe16bf265970441176fd794c0760107a994f444eabe9290151f5dfea9d8c263f359b663e7d5c87536a85540c38ac
7
+ data.tar.gz: 5e736cf0adaa648c1b088ddb938ce8a41080df77e243fe8cb0cb70fb561ae985582e3002c9078eed4d2ebd3284cccee30c657d9f24806082520f0055c5b22849
data/Appraisals CHANGED
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
 
2
- appraise "dynamoid-3.4" do
3
- gem "dynamoid", "~> 3.4.0"
3
+ appraise 'dynamoid-3.4' do
4
+ gem 'dynamoid', '~> 3.4.0'
4
5
  end
5
6
 
6
- appraise "dynamoid-latest" do
7
- gem "dynamoid", "~> 3.0"
7
+ appraise 'dynamoid-latest' do
8
+ gem 'dynamoid', '~> 3.0'
8
9
  end
data/Gemfile CHANGED
@@ -1,9 +1,10 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in dynamoid-advanced-where.gemspec
6
8
  gemspec
7
9
 
8
10
  gem 'pry'
9
-
data/Gemfile.lock CHANGED
@@ -1,103 +1,104 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamoid_advanced_where (1.2.0)
4
+ dynamoid_advanced_where (1.4.0)
5
5
  dynamoid (>= 3.2, < 4)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activemodel (6.1.0)
11
- activesupport (= 6.1.0)
12
- activesupport (6.1.0)
10
+ activemodel (6.1.4)
11
+ activesupport (= 6.1.4)
12
+ activesupport (6.1.4)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 1.6, < 2)
15
15
  minitest (>= 5.1)
16
16
  tzinfo (~> 2.0)
17
17
  zeitwerk (~> 2.3)
18
- appraisal (2.3.0)
18
+ appraisal (2.4.1)
19
19
  bundler
20
20
  rake
21
21
  thor (>= 0.14.0)
22
- ast (2.4.1)
23
- aws-eventstream (1.1.0)
24
- aws-partitions (1.408.0)
25
- aws-sdk-core (3.110.0)
22
+ ast (2.4.2)
23
+ aws-eventstream (1.1.1)
24
+ aws-partitions (1.482.0)
25
+ aws-sdk-core (3.119.0)
26
26
  aws-eventstream (~> 1, >= 1.0.2)
27
27
  aws-partitions (~> 1, >= 1.239.0)
28
28
  aws-sigv4 (~> 1.1)
29
29
  jmespath (~> 1.0)
30
- aws-sdk-dynamodb (1.58.0)
31
- aws-sdk-core (~> 3, >= 3.109.0)
30
+ aws-sdk-dynamodb (1.62.0)
31
+ aws-sdk-core (~> 3, >= 3.119.0)
32
32
  aws-sigv4 (~> 1.1)
33
- aws-sigv4 (1.2.2)
33
+ aws-sigv4 (1.2.4)
34
34
  aws-eventstream (~> 1, >= 1.0.2)
35
- bundler-audit (0.7.0.1)
35
+ bundler-audit (0.8.0)
36
36
  bundler (>= 1.2.0, < 3)
37
- thor (>= 0.18, < 2)
38
- childprocess (4.0.0)
37
+ thor (~> 1.0)
38
+ childprocess (4.1.0)
39
39
  coderay (1.1.3)
40
40
  colorize (0.8.1)
41
- concurrent-ruby (1.1.7)
41
+ concurrent-ruby (1.1.9)
42
42
  diff-lcs (1.4.4)
43
- dynamoid (3.6.0)
43
+ dynamoid (3.7.1)
44
44
  activemodel (>= 4)
45
45
  aws-sdk-dynamodb (~> 1.0)
46
46
  concurrent-ruby (>= 1.0)
47
- fasterer (0.8.3)
47
+ fasterer (0.9.0)
48
48
  colorize (~> 0.7)
49
49
  ruby_parser (>= 3.14.1)
50
- i18n (1.8.5)
50
+ i18n (1.8.10)
51
51
  concurrent-ruby (~> 1.0)
52
52
  iniparse (1.5.0)
53
53
  jmespath (1.4.0)
54
54
  method_source (1.0.0)
55
- minitest (5.14.2)
56
- overcommit (0.57.0)
55
+ minitest (5.14.4)
56
+ overcommit (0.58.0)
57
57
  childprocess (>= 0.6.3, < 5)
58
58
  iniparse (~> 1.4)
59
+ rexml (~> 3.2)
59
60
  parallel (1.20.1)
60
- parser (2.7.2.0)
61
+ parser (3.0.2.0)
61
62
  ast (~> 2.4.1)
62
- pry (0.13.1)
63
+ pry (0.14.1)
63
64
  coderay (~> 1.1)
64
65
  method_source (~> 1.0)
65
66
  rainbow (3.0.0)
66
67
  rake (10.5.0)
67
- regexp_parser (2.0.0)
68
- rexml (3.2.4)
68
+ regexp_parser (2.1.1)
69
+ rexml (3.2.5)
69
70
  rspec (3.10.0)
70
71
  rspec-core (~> 3.10.0)
71
72
  rspec-expectations (~> 3.10.0)
72
73
  rspec-mocks (~> 3.10.0)
73
- rspec-core (3.10.0)
74
+ rspec-core (3.10.1)
74
75
  rspec-support (~> 3.10.0)
75
- rspec-expectations (3.10.0)
76
+ rspec-expectations (3.10.1)
76
77
  diff-lcs (>= 1.2.0, < 2.0)
77
78
  rspec-support (~> 3.10.0)
78
- rspec-mocks (3.10.0)
79
+ rspec-mocks (3.10.2)
79
80
  diff-lcs (>= 1.2.0, < 2.0)
80
81
  rspec-support (~> 3.10.0)
81
- rspec-support (3.10.0)
82
- rubocop (1.6.1)
82
+ rspec-support (3.10.2)
83
+ rubocop (1.18.4)
83
84
  parallel (~> 1.10)
84
- parser (>= 2.7.1.5)
85
+ parser (>= 3.0.0.0)
85
86
  rainbow (>= 2.2.2, < 4.0)
86
87
  regexp_parser (>= 1.8, < 3.0)
87
88
  rexml
88
- rubocop-ast (>= 1.2.0, < 2.0)
89
+ rubocop-ast (>= 1.8.0, < 2.0)
89
90
  ruby-progressbar (~> 1.7)
90
- unicode-display_width (>= 1.4.0, < 2.0)
91
- rubocop-ast (1.3.0)
92
- parser (>= 2.7.1.5)
93
- ruby-progressbar (1.10.1)
94
- ruby_parser (3.15.0)
95
- sexp_processor (~> 4.9)
96
- sexp_processor (4.15.1)
97
- thor (1.0.1)
91
+ unicode-display_width (>= 1.4.0, < 3.0)
92
+ rubocop-ast (1.8.0)
93
+ parser (>= 3.0.1.1)
94
+ ruby-progressbar (1.11.0)
95
+ ruby_parser (3.16.0)
96
+ sexp_processor (~> 4.15, >= 4.15.1)
97
+ sexp_processor (4.15.3)
98
+ thor (1.1.0)
98
99
  tzinfo (2.0.4)
99
100
  concurrent-ruby (~> 1.0)
100
- unicode-display_width (1.7.0)
101
+ unicode-display_width (2.0.0)
101
102
  zeitwerk (2.4.2)
102
103
 
103
104
  PLATFORMS
data/README.md CHANGED
@@ -249,6 +249,23 @@ if it successfully updates. If it fails to update, it will return nil.
249
249
  If the specified hash key, or hash/range key combination is not already present
250
250
  it will be inserted with the desired mutations (if possible).
251
251
 
252
+ ### Referencing a field
253
+ To identify the field to be updated, either through set, increment, decrement, or append you may just use the field name
254
+ for top level keys. When you use the top level single symbol key DAW will use the built in Dynamoid dumper.
255
+
256
+ If you need to reference the sub-key of a map, or custom serialized object you may pass an array of keys. Since DAW
257
+ looses context to the "type" it is up to you to ensure you are writing out the correct values. The only exception to
258
+ this is if you are set the field to a class which implements `dynamoid_dump`.
259
+
260
+ #### Example
261
+ ```ruby
262
+ Model.where{ conditions }.batch_update
263
+ .set_values([:map_or_custom_type, :sub_field, :foo] => 'value', [:map_or_custom_type2, :foo] => MyDumpableClass.new(test))
264
+ .increment([:some_map, :attempts], by: 1)
265
+ .decrement([:some_map, :attempts_remaining], by: 1)
266
+ .apply(hash_key, range_key)
267
+ ```
268
+
252
269
  ### Setting a single field
253
270
  The batch updated method `set_values(attr_name: new_attr_value, other_atter: val)`
254
271
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'dynamoid_advanced_where/version'
@@ -30,12 +32,12 @@ Gem::Specification.new do |spec|
30
32
 
31
33
  spec.add_dependency 'dynamoid', '>= 3.2', '< 4'
32
34
 
33
- spec.add_development_dependency 'bundler-audit'
35
+ spec.add_development_dependency 'appraisal'
34
36
  spec.add_development_dependency 'bundler', '>= 1.16'
37
+ spec.add_development_dependency 'bundler-audit'
35
38
  spec.add_development_dependency 'fasterer'
36
39
  spec.add_development_dependency 'overcommit'
37
40
  spec.add_development_dependency 'rake', '~> 10.0'
38
41
  spec.add_development_dependency 'rspec', '~> 3.0'
39
42
  spec.add_development_dependency 'rubocop'
40
- spec.add_development_dependency 'appraisal'
41
43
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "https://rubygems.org"
5
+ source 'https://rubygems.org'
4
6
 
5
- gem "pry"
6
- gem "dynamoid", "~> 3.4.0"
7
+ gem 'dynamoid', '~> 3.4.0'
8
+ gem 'pry'
7
9
 
8
- gemspec path: "../"
10
+ gemspec path: '../'
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "https://rubygems.org"
5
+ source 'https://rubygems.org'
4
6
 
5
- gem "pry"
6
- gem "dynamoid", "~> 3.5.0"
7
+ gem 'dynamoid', '~> 3.5.0'
8
+ gem 'pry'
7
9
 
8
- gemspec path: "../"
10
+ gemspec path: '../'
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "https://rubygems.org"
5
+ source 'https://rubygems.org'
4
6
 
5
- gem "pry"
6
- gem "dynamoid", "~> 3.6.0"
7
+ gem 'dynamoid', '~> 3.6.0'
8
+ gem 'pry'
7
9
 
8
- gemspec path: "../"
10
+ gemspec path: '../'
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "https://rubygems.org"
5
+ source 'https://rubygems.org'
4
6
 
5
- gem "pry"
6
- gem "dynamoid", "~> 3.0"
7
+ gem 'dynamoid', '~> 3.0'
8
+ gem 'pry'
7
9
 
8
- gemspec path: "../"
10
+ gemspec path: '../'
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "https://rubygems.org"
5
+ source 'https://rubygems.org'
4
6
 
5
- gem "pry"
6
- gem "dynamoid", git: "https://github.com/Dynamoid/dynamoid.git"
7
+ gem 'dynamoid', git: 'https://github.com/Dynamoid/dynamoid.git'
8
+ gem 'pry'
7
9
 
8
- gemspec path: "../"
10
+ gemspec path: '../'
@@ -5,6 +5,7 @@ module DynamoidAdvancedWhere
5
5
  DEEP_MERGE_ATTRIBUTES = %i[expression_attribute_names expression_attribute_values].freeze
6
6
 
7
7
  attr_accessor :query_builder, :_set_values, :_array_appends, :_set_appends, :_increments
8
+
8
9
  delegate :klass, to: :query_builder
9
10
 
10
11
  def initialize(query_builder:)
@@ -86,7 +87,7 @@ module DynamoidAdvancedWhere
86
87
  filter = merge_multiple_sets(
87
88
  [
88
89
  field_update_arguments,
89
- add_update_args,
90
+ add_update_args
90
91
  ],
91
92
  result_base: filter_builder.to_scan_filter,
92
93
  )
@@ -129,11 +130,10 @@ module DynamoidAdvancedWhere
129
130
 
130
131
  _set_values.each_with_object(builder_hash) do |(k, v), h|
131
132
  prefix = merge_in_attr_placeholders(h, k, v)
132
- h[:collected_update_expression] << "##{prefix} = :#{prefix}"
133
+ h[:collected_update_expression] << "#{prefix[0]} = :#{prefix[1]}"
133
134
  end
134
135
  end
135
136
 
136
-
137
137
  def increment_field_updates
138
138
  return {} if _increments.empty?
139
139
 
@@ -148,7 +148,7 @@ module DynamoidAdvancedWhere
148
148
 
149
149
  _increments.each_with_object(builder_hash) do |(field, change), h|
150
150
  prefix = merge_in_attr_placeholders(h, field, change)
151
- builder_hash[:collected_update_expression] << "##{prefix} = if_not_exists(##{prefix}, :#{zero_prefix}) + :#{prefix}"
151
+ builder_hash[:collected_update_expression] << "#{prefix[0]} = if_not_exists(#{prefix[0]}, :#{zero_prefix}) + :#{prefix[1]}"
152
152
  end
153
153
  end
154
154
 
@@ -158,7 +158,7 @@ module DynamoidAdvancedWhere
158
158
  _set_appends.each_with_object(builder_hash) do |to_append, h|
159
159
  to_append.each do |k, v|
160
160
  prefix = merge_in_attr_placeholders(h, k, v)
161
- builder_hash[:collected_update_expression] << "##{prefix} :#{prefix}"
161
+ builder_hash[:collected_update_expression] << "#{prefix[0]} :#{prefix[1]}"
162
162
  end
163
163
  end
164
164
  end
@@ -176,7 +176,7 @@ module DynamoidAdvancedWhere
176
176
  update_args = _array_appends.each_with_object(builder_hash) do |to_append, h|
177
177
  to_append.each do |k, v|
178
178
  prefix = merge_in_attr_placeholders(h, k, v)
179
- builder_hash[:collected_update_expression] << "##{prefix} = list_append(if_not_exists(##{prefix}, :#{empty_list_prefix}), :#{prefix})"
179
+ builder_hash[:collected_update_expression] << "#{prefix[0]} = list_append(if_not_exists(#{prefix[0]}, :#{empty_list_prefix}), :#{prefix[1]})"
180
180
  end
181
181
  end
182
182
 
@@ -184,7 +184,7 @@ module DynamoidAdvancedWhere
184
184
  end
185
185
 
186
186
  def merge_in_attr_placeholders(hsh, field_name, value)
187
- prefix, new_data = prefixerize(field_name, value)
187
+ *prefix, new_data = prefixerize(field_name, value)
188
188
 
189
189
  hsh.merge!(new_data, &method(:hash_extendeer))
190
190
 
@@ -192,14 +192,20 @@ module DynamoidAdvancedWhere
192
192
  end
193
193
 
194
194
  def prefixerize(field_name, value)
195
+ field_names = field_name.is_a?(Array) ? field_name : [field_name]
195
196
  prefix = SecureRandom.hex
196
197
 
198
+ update_target = field_names.each_with_index.map do |name, idx|
199
+ ["##{prefix}#{idx}", name]
200
+ end
201
+
197
202
  [
203
+ update_target.map(&:first).join('.').to_s,
198
204
  prefix,
199
205
  {
200
- expression_attribute_names: { "##{prefix}" => field_name },
206
+ expression_attribute_names: Hash[update_target],
201
207
  expression_attribute_values: {
202
- ":#{prefix}" => dump(value, klass.attributes[field_name])
208
+ ":#{prefix}" => dump(value, field_name)
203
209
  }
204
210
  }
205
211
  ]
@@ -222,8 +228,15 @@ module DynamoidAdvancedWhere
222
228
  )
223
229
  end
224
230
 
225
- def dump(value, config)
226
- Dynamoid::Dumping.dump_field(value, config)
231
+ def dump(value, field_name)
232
+ if klass.attributes[field_name]
233
+ Dynamoid::Dumping.dump_field(value, klass.attributes[field_name])
234
+ elsif value.respond_to?(:dynamoid_dump)
235
+ value.dynamoid_dump
236
+ else
237
+ value
238
+
239
+ end
227
240
  end
228
241
  end
229
242
  end
@@ -31,4 +31,4 @@ module DynamoidAdvancedWhere
31
31
  end
32
32
  end
33
33
 
34
- Dynamoid::Document.send(:include, DynamoidAdvancedWhere::Integrations::Model)
34
+ Dynamoid::Document.include DynamoidAdvancedWhere::Integrations::Model
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
3
  module DynamoidAdvancedWhere
5
4
  module Nodes
6
5
  module Concerns
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'securerandom'
2
4
 
3
5
  module DynamoidAdvancedWhere
@@ -15,4 +17,3 @@ module DynamoidAdvancedWhere
15
17
  end
16
18
  end
17
19
  end
18
-
@@ -10,6 +10,7 @@ module DynamoidAdvancedWhere
10
10
  include Concerns::SupportsLogicalOr
11
11
 
12
12
  attr_accessor :field_node, :prefix
13
+
13
14
  def initialize(field_node:)
14
15
  self.field_node = field_node
15
16
  self.prefix = SecureRandom.hex
@@ -20,9 +20,7 @@ module DynamoidAdvancedWhere
20
20
  config.respond_to?(:call) ? config.call(attr_config) : config <= attr_config
21
21
  end&.last
22
22
 
23
- unless specific_klass
24
- raise ArgumentError, "unable to find field type for `#{attr_config}`"
25
- end
23
+ raise ArgumentError, "unable to find field type for `#{attr_config}`" unless specific_klass
26
24
 
27
25
  specific_klass.new(field_path: field_path)
28
26
  end
@@ -63,6 +61,7 @@ module DynamoidAdvancedWhere
63
61
  class StringAttributeNode < FieldNode
64
62
  include Concerns::SupportsIncludes
65
63
  end
64
+
66
65
  class NativeBooleanAttributeNode < FieldNode; end
67
66
 
68
67
  class StringBooleanAttributeNode < FieldNode
@@ -91,9 +90,10 @@ module DynamoidAdvancedWhere
91
90
  include Concerns::SupportsGreaterThan
92
91
 
93
92
  def parse_right_hand_side(val)
94
- if val.is_a?(Date)
93
+ case val
94
+ when Date
95
95
  val.to_time.to_i
96
- elsif val.is_a?(Time)
96
+ when Time
97
97
  val.to_f
98
98
  else
99
99
  raise ArgumentError, "unable to compare datetime to type #{val.class}"
@@ -105,9 +105,7 @@ module DynamoidAdvancedWhere
105
105
  include Concerns::SupportsGreaterThan
106
106
 
107
107
  def parse_right_hand_side(val)
108
- if !val.is_a?(Date) || val.is_a?(DateTime)
109
- raise ArgumentError, "unable to compare date to type #{val.class}"
110
- end
108
+ raise ArgumentError, "unable to compare date to type #{val.class}" if !val.is_a?(Date) || val.is_a?(DateTime)
111
109
 
112
110
  (val - Dynamoid::Persistence::UNIX_EPOCH_DATE).to_i
113
111
  end
@@ -117,9 +115,7 @@ module DynamoidAdvancedWhere
117
115
  include Concerns::SupportsIncludes
118
116
 
119
117
  def parse_right_hand_side(val)
120
- unless val.is_a?(String)
121
- raise ArgumentError, "unable to compare date to type #{val.class}"
122
- end
118
+ raise ArgumentError, "unable to compare date to type #{val.class}" unless val.is_a?(String)
123
119
 
124
120
  val
125
121
  end
@@ -129,9 +125,7 @@ module DynamoidAdvancedWhere
129
125
  include Concerns::SupportsIncludes
130
126
 
131
127
  def parse_right_hand_side(val)
132
- unless val.is_a?(Integer)
133
- raise ArgumentError, "unable to compare integer value to type #{val.class}"
134
- end
128
+ raise ArgumentError, "unable to compare integer value to type #{val.class}" unless val.is_a?(Integer)
135
129
 
136
130
  val
137
131
  end
@@ -141,9 +135,7 @@ module DynamoidAdvancedWhere
141
135
  include Concerns::SupportsIncludes
142
136
 
143
137
  def parse_right_hand_side(val)
144
- unless val.is_a?(String)
145
- raise ArgumentError, "unable to compare string to type #{val.class}"
146
- end
138
+ raise ArgumentError, "unable to compare string to type #{val.class}" unless val.is_a?(String)
147
139
 
148
140
  val
149
141
  end
@@ -153,9 +145,7 @@ module DynamoidAdvancedWhere
153
145
  include Concerns::SupportsIncludes
154
146
 
155
147
  def parse_right_hand_side(val)
156
- unless val.is_a?(Integer)
157
- raise ArgumentError, "unable to compare integer to type #{val.class}"
158
- end
148
+ raise ArgumentError, "unable to compare integer to type #{val.class}" unless val.is_a?(Integer)
159
149
 
160
150
  val
161
151
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DynamoidAdvancedWhere
2
4
  module Nodes
3
5
  class GreaterThanNode < OperationNode
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DynamoidAdvancedWhere
2
4
  module Nodes
3
5
  class IncludesNode < OperationNode
@@ -6,6 +6,7 @@ module DynamoidAdvancedWhere
6
6
  module Nodes
7
7
  class LiteralNode
8
8
  attr_accessor :value, :attr_prefix
9
+
9
10
  def initialize(value)
10
11
  self.value = value
11
12
  self.attr_prefix = SecureRandom.hex
@@ -37,6 +37,5 @@ module DynamoidAdvancedWhere
37
37
  "NOT(#{sub_node.to_expression})"
38
38
  end
39
39
  end
40
-
41
40
  end
42
41
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DynamoidAdvancedWhere
2
4
  module Nodes
3
5
  class OrNode < BaseNode
@@ -40,7 +40,7 @@ module DynamoidAdvancedWhere
40
40
  instance_eval(&blk)
41
41
  else
42
42
  blk.call(self)
43
- end
43
+ end
44
44
  end
45
45
  end
46
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './nodes/base_node'
2
4
  require_relative './nodes/field_node'
3
5
  require_relative './nodes/literal_node'
@@ -1,17 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './nodes'
2
4
  require_relative './query_materializer'
3
5
  require_relative './batched_updater'
4
6
 
5
7
  module DynamoidAdvancedWhere
6
8
  class QueryBuilder
7
- attr_accessor :klass, :root_node, :start_hash
9
+ attr_accessor :klass, :root_node, :start_hash, :record_limit
8
10
 
9
- delegate :all, :each, to: :query_materializer
11
+ delegate :all, :each_page, :each, to: :query_materializer
10
12
 
11
- def initialize(klass:, start_hash: nil, root_node: nil, &blk)
13
+ def initialize(klass:, record_limit: nil, start_hash: nil, root_node: nil, &blk)
12
14
  self.klass = klass
13
15
  self.root_node = root_node || Nodes::RootNode.new(klass: klass, &blk)
14
16
  self.start_hash = start_hash
17
+ self.record_limit = record_limit
15
18
 
16
19
  freeze
17
20
  end
@@ -46,10 +49,26 @@ module DynamoidAdvancedWhere
46
49
  end
47
50
  alias and where
48
51
 
52
+ def limit(value)
53
+ dup_with_changes(record_limit: value)
54
+ end
55
+
49
56
  def start(key_hash)
50
57
  return self if key_hash.nil? || key_hash.empty?
51
58
 
52
- self.class.new(klass: klass, start_hash: key_hash, root_node: root_node)
59
+ dup_with_changes(start_hash: key_hash)
60
+ end
61
+
62
+ alias to_a all
63
+
64
+ private
65
+
66
+ def dup_with_changes(**changes)
67
+ self.class.new(**{
68
+ klass: klass,
69
+ start_hash: start_hash,
70
+ root_node: root_node
71
+ }.merge(changes))
53
72
  end
54
73
  end
55
74
  end
@@ -51,6 +51,8 @@ module DynamoidAdvancedWhere
51
51
  table_name: table_name
52
52
  }.merge(filter_builder.to_query_filter)
53
53
 
54
+ query[:limit] = query_builder.record_limit if query_builder.record_limit
55
+
54
56
  page_start = start_hash
55
57
 
56
58
  Enumerator.new do |yielder|
@@ -63,7 +65,11 @@ module DynamoidAdvancedWhere
63
65
 
64
66
  yielder.yield(items, results)
65
67
 
66
- (page_start = results.last_evaluated_key) || break
68
+ query[:limit] = query[:limit] - results.items.length if query[:limit]
69
+
70
+ break if results.last_evaluated_key.nil? || query[:limit]&.zero?
71
+
72
+ (page_start = results.last_evaluated_key)
67
73
  end
68
74
  end.lazy
69
75
  end
@@ -73,6 +79,8 @@ module DynamoidAdvancedWhere
73
79
  table_name: table_name
74
80
  }.merge(filter_builder.to_scan_filter)
75
81
 
82
+ query[:limit] = query_builder.record_limit if query_builder.record_limit
83
+
76
84
  page_start = start_hash
77
85
 
78
86
  Enumerator.new do |yielder|
@@ -85,7 +93,11 @@ module DynamoidAdvancedWhere
85
93
 
86
94
  yielder.yield(items, results)
87
95
 
88
- (page_start = results.last_evaluated_key) || break
96
+ query[:limit] = query[:limit] - results.items.length if query[:limit]
97
+
98
+ break if results.last_evaluated_key.nil? || query[:limit]&.zero?
99
+
100
+ (page_start = results.last_evaluated_key)
89
101
  end
90
102
  end.lazy
91
103
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DynamoidAdvancedWhere
2
- VERSION = "1.2.0"
4
+ VERSION = '1.4.0'
3
5
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dynamoid'
2
4
 
3
- require "dynamoid_advanced_where/version"
4
- require "dynamoid_advanced_where/integrations/model"
5
+ require 'dynamoid_advanced_where/version'
6
+ require 'dynamoid_advanced_where/integrations/model'
5
7
 
6
8
  module DynamoidAdvancedWhere
7
- # Your code goes here...
9
+ # Your code goes here...
8
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamoid_advanced_where
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Malinconico
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-17 00:00:00.000000000 Z
11
+ date: 2022-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynamoid
@@ -31,7 +31,7 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: '4'
33
33
  - !ruby/object:Gem::Dependency
34
- name: bundler-audit
34
+ name: appraisal
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
@@ -58,6 +58,20 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '1.16'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler-audit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
61
75
  - !ruby/object:Gem::Dependency
62
76
  name: fasterer
63
77
  requirement: !ruby/object:Gem::Requirement
@@ -128,20 +142,6 @@ dependencies:
128
142
  - - ">="
129
143
  - !ruby/object:Gem::Version
130
144
  version: '0'
131
- - !ruby/object:Gem::Dependency
132
- name: appraisal
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - ">="
136
- - !ruby/object:Gem::Version
137
- version: '0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - ">="
143
- - !ruby/object:Gem::Version
144
- version: '0'
145
145
  description: things
146
146
  email:
147
147
  - bmalinconico@terminus.com