dynamoid_advanced_where 1.0.1 → 1.1.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: f415151e23b5baba11532ebc26bf31020983502dd979a41a49e262933bf4ea50
4
- data.tar.gz: be4300fcbfe8db7056c2c0e0163f8573854434c3a40826476686243dc4cafd5b
3
+ metadata.gz: f806a04e8969341d1397e35cc86d7694dec55693ae90c5d34d85ccb4faa95805
4
+ data.tar.gz: f2f44f2f359c679cffa89f150eb20406a8712c2fb5d22cb857e78e7aa5ecee1f
5
5
  SHA512:
6
- metadata.gz: ce2f7f1722ffbfb98bc4302495679d5511ef59b88f0b676850e77c20600bb7f19b728bdb0fd6bee8f385abd42947a9afb0b12ffd469165bb5ffaaeffeb5586fa
7
- data.tar.gz: 69dd0f4ad676256f5e6b0d52decd79198f69aa7f03efec1602d87e8bebb5a133076b337a00d7c2ef91ac71b0d9bf48c599aef9f9d1cc097028762a07724e5e5e
6
+ metadata.gz: c5a692ab92a62c20d36b563f0e452aa897cc5b22eeaf527624a709fe01145566c13fa5a37789741d5dddf5c0b79eeb8c3c6e30412e139f93a40dc1a6b6f54989
7
+ data.tar.gz: 39ca15de11981b84b41484042f141927b8076f718bdf449cebf193c2845cf1d7773b9653cbaf3d1efe19f75c685e07b4a7c23edb04e111c976f19de5d72a12e7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamoid_advanced_where (1.0.1)
4
+ dynamoid_advanced_where (1.1.0)
5
5
  dynamoid (>= 3.2, < 4)
6
6
 
7
7
  GEM
@@ -21,13 +21,13 @@ GEM
21
21
  thor (>= 0.14.0)
22
22
  ast (2.4.0)
23
23
  aws-eventstream (1.0.3)
24
- aws-partitions (1.270.0)
25
- aws-sdk-core (3.89.1)
24
+ aws-partitions (1.275.0)
25
+ aws-sdk-core (3.90.1)
26
26
  aws-eventstream (~> 1.0, >= 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.41.0)
30
+ aws-sdk-dynamodb (1.42.0)
31
31
  aws-sdk-core (~> 3, >= 3.71.0)
32
32
  aws-sigv4 (~> 1.1)
33
33
  aws-sigv4 (1.1.0)
@@ -67,6 +67,7 @@ GEM
67
67
  method_source (~> 0.9.0)
68
68
  rainbow (3.0.0)
69
69
  rake (10.5.0)
70
+ rexml (3.2.4)
70
71
  rspec (3.9.0)
71
72
  rspec-core (~> 3.9.0)
72
73
  rspec-expectations (~> 3.9.0)
@@ -80,11 +81,12 @@ GEM
80
81
  diff-lcs (>= 1.2.0, < 2.0)
81
82
  rspec-support (~> 3.9.0)
82
83
  rspec-support (3.9.2)
83
- rubocop (0.79.0)
84
+ rubocop (0.80.0)
84
85
  jaro_winkler (~> 1.5.1)
85
86
  parallel (~> 1.10)
86
87
  parser (>= 2.7.0.1)
87
88
  rainbow (>= 2.2.2, < 4.0)
89
+ rexml
88
90
  ruby-progressbar (~> 1.7)
89
91
  unicode-display_width (>= 1.4.0, < 1.7)
90
92
  ruby-progressbar (1.10.1)
data/README.md CHANGED
@@ -174,6 +174,10 @@ Provided methods
174
174
  * `first`
175
175
  * `each` (and related enumerable methods)
176
176
 
177
+ ### Start
178
+
179
+ `.start({ some_hash_key: some_value })` takes a hash argument that must match the key structure of the table (range key must be specified where valid). If passed an empty hash, results will start from the beginning of the table. Records before the specified start key will not be scanned or returned. This is useful when doing manual pagination.
180
+
177
181
  ### Scan vs Query
178
182
  DAW will automatically preform a query when it determines it is possible,
179
183
  however if a query is determined to not be appropriate, a scan will be conduced
@@ -4,13 +4,16 @@ require_relative './batched_updater'
4
4
 
5
5
  module DynamoidAdvancedWhere
6
6
  class QueryBuilder
7
- attr_accessor :klass, :root_node
7
+ attr_accessor :klass, :root_node, :start_hash
8
8
 
9
9
  delegate :all, :each, to: :query_materializer
10
10
 
11
- def initialize(klass:, &blk)
11
+ def initialize(klass:, start_hash: nil, root_node: nil, &blk)
12
12
  self.klass = klass
13
- self.root_node = Nodes::RootNode.new(klass: klass, &blk)
13
+ self.root_node = root_node || Nodes::RootNode.new(klass: klass, &blk)
14
+ self.start_hash = start_hash
15
+
16
+ freeze
14
17
  end
15
18
 
16
19
  def query_materializer
@@ -43,5 +46,10 @@ module DynamoidAdvancedWhere
43
46
  end
44
47
  alias and where
45
48
 
49
+ def start(key_hash)
50
+ return self if key_hash.nil? || key_hash.empty?
51
+
52
+ self.class.new(klass: klass, start_hash: key_hash, root_node: root_node)
53
+ end
46
54
  end
47
55
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './filter_builder'
2
4
 
3
5
  module DynamoidAdvancedWhere
@@ -5,8 +7,7 @@ module DynamoidAdvancedWhere
5
7
  include Enumerable
6
8
  attr_accessor :query_builder
7
9
 
8
-
9
- delegate :klass, to: :query_builder
10
+ delegate :klass, :start_hash, to: :query_builder
10
11
  delegate :table_name, to: :klass
11
12
  delegate :to_a, :first, to: :each
12
13
 
@@ -23,39 +24,70 @@ module DynamoidAdvancedWhere
23
24
  def each(&blk)
24
25
  return enum_for(:each) unless blk
25
26
 
27
+ records.each(&blk)
28
+ end
29
+ alias find_each each
30
+
31
+ def each_page(&blk)
32
+ return enum_for(:each_page) unless blk
33
+
34
+ pages.each(&blk)
35
+ end
36
+
37
+ def records
38
+ pages.flat_map { |i, _| i }
39
+ end
40
+
41
+ def pages
26
42
  if must_scan?
27
- each_via_scan(&blk)
43
+ each_page_via_scan
28
44
  else
29
- each_via_query(&blk)
45
+ each_page_via_query
30
46
  end
31
47
  end
32
48
 
33
- def each_via_query
49
+ def each_page_via_query
34
50
  query = {
35
- table_name: table_name,
51
+ table_name: table_name
36
52
  }.merge(filter_builder.to_query_filter)
37
53
 
38
- results = client.query(query)
54
+ page_start = start_hash
39
55
 
40
- if results.items
41
- results.items.each do |item|
42
- yield klass.from_database(item.symbolize_keys)
56
+ Enumerator.new do |yielder|
57
+ loop do
58
+ results = client.query(query.merge(exclusive_start_key: page_start))
59
+
60
+ items = (results.items || []).each do |item|
61
+ klass.from_database(item.symbolize_keys)
62
+ end
63
+
64
+ yielder.yield(items, results)
65
+
66
+ (page_start = results.last_evaluated_key) || break
43
67
  end
44
- end
68
+ end.lazy
45
69
  end
46
70
 
47
- def each_via_scan
71
+ def each_page_via_scan
48
72
  query = {
49
73
  table_name: table_name
50
74
  }.merge(filter_builder.to_scan_filter)
51
75
 
52
- results = client.scan(query)
76
+ page_start = start_hash
77
+
78
+ Enumerator.new do |yielder|
79
+ loop do
80
+ results = client.scan(query.merge(exclusive_start_key: page_start))
53
81
 
54
- if results.items
55
- results.items.each do |item|
56
- yield klass.from_database(item.symbolize_keys)
82
+ items = (results.items || []).map do |item|
83
+ klass.from_database(item.symbolize_keys)
84
+ end
85
+
86
+ yielder.yield(items, results)
87
+
88
+ (page_start = results.last_evaluated_key) || break
57
89
  end
58
- end
90
+ end.lazy
59
91
  end
60
92
 
61
93
  def filter_builder
@@ -66,6 +98,7 @@ module DynamoidAdvancedWhere
66
98
  end
67
99
 
68
100
  private
101
+
69
102
  def client
70
103
  Dynamoid.adapter.client
71
104
  end
@@ -1,3 +1,3 @@
1
1
  module DynamoidAdvancedWhere
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  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.0.1
4
+ version: 1.1.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-02-07 00:00:00.000000000 Z
11
+ date: 2020-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynamoid