dynamini 2.9.1 → 2.9.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +17 -20
- data/README.md +18 -9
- data/dynamini.gemspec +1 -1
- data/lib/dynamini/batch_operations.rb +12 -8
- data/lib/dynamini/test_client.rb +12 -13
- data/spec/dynamini/batch_operations_spec.rb +20 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4da5852711d8ecb8a226a9ae7c987f2ea0324927
|
4
|
+
data.tar.gz: eec0aaae89719060294b9ae055f8effabf79dd9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6eaf764f422c931ae8e5d669f2b26349cfaffedfcabb6c13654f06ac40b758ea371b0328149d1f3c0914de67972fa7971d7a01d89bef94b6ab825b3bd1527c3
|
7
|
+
data.tar.gz: d97dab7690b1c371052bff3c1c1a7b8d39107281b2ed71c90e6eb05b3dc18998d9f51c8ad81307ebb249de1d4924f56245ef8f4e85100d42d4fd71b870f5081c
|
data/Gemfile.lock
CHANGED
@@ -1,30 +1,29 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dynamini (2.9.
|
4
|
+
dynamini (2.9.2)
|
5
5
|
activemodel (>= 3, < 5.0)
|
6
6
|
aws-sdk (~> 2)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activemodel (4.2.
|
12
|
-
activesupport (= 4.2.
|
11
|
+
activemodel (4.2.5.1)
|
12
|
+
activesupport (= 4.2.5.1)
|
13
13
|
builder (~> 3.1)
|
14
|
-
activesupport (4.2.
|
14
|
+
activesupport (4.2.5.1)
|
15
15
|
i18n (~> 0.7)
|
16
|
+
json (~> 1.7, >= 1.7.7)
|
16
17
|
minitest (~> 5.1)
|
17
18
|
thread_safe (~> 0.3, >= 0.3.4)
|
18
19
|
tzinfo (~> 1.1)
|
19
|
-
aws-sdk (2.
|
20
|
-
aws-sdk-resources (= 2.
|
21
|
-
aws-sdk-core (2.
|
22
|
-
aws-sigv4 (~> 1.0)
|
20
|
+
aws-sdk (2.2.22)
|
21
|
+
aws-sdk-resources (= 2.2.22)
|
22
|
+
aws-sdk-core (2.2.22)
|
23
23
|
jmespath (~> 1.0)
|
24
|
-
aws-sdk-resources (2.
|
25
|
-
aws-sdk-core (= 2.
|
26
|
-
|
27
|
-
builder (3.2.3)
|
24
|
+
aws-sdk-resources (2.2.22)
|
25
|
+
aws-sdk-core (= 2.2.22)
|
26
|
+
builder (3.2.2)
|
28
27
|
coderay (1.1.0)
|
29
28
|
diff-lcs (1.2.5)
|
30
29
|
ffi (1.9.10)
|
@@ -49,14 +48,15 @@ GEM
|
|
49
48
|
guard-shell (0.7.1)
|
50
49
|
guard (>= 2.0.0)
|
51
50
|
guard-compat (~> 1.0)
|
52
|
-
i18n (0.
|
53
|
-
jmespath (1.3
|
51
|
+
i18n (0.7.0)
|
52
|
+
jmespath (1.1.3)
|
53
|
+
json (1.8.3)
|
54
54
|
listen (3.0.3)
|
55
55
|
rb-fsevent (>= 0.9.3)
|
56
56
|
rb-inotify (>= 0.9)
|
57
57
|
lumberjack (1.0.9)
|
58
58
|
method_source (0.8.2)
|
59
|
-
minitest (5.
|
59
|
+
minitest (5.8.4)
|
60
60
|
nenv (0.2.0)
|
61
61
|
notiffany (0.0.8)
|
62
62
|
nenv (~> 0.1)
|
@@ -85,8 +85,8 @@ GEM
|
|
85
85
|
shellany (0.0.1)
|
86
86
|
slop (3.6.0)
|
87
87
|
thor (0.19.1)
|
88
|
-
thread_safe (0.3.
|
89
|
-
tzinfo (1.2.
|
88
|
+
thread_safe (0.3.5)
|
89
|
+
tzinfo (1.2.2)
|
90
90
|
thread_safe (~> 0.1)
|
91
91
|
|
92
92
|
PLATFORMS
|
@@ -99,6 +99,3 @@ DEPENDENCIES
|
|
99
99
|
guard-shell
|
100
100
|
pry (~> 0)
|
101
101
|
rspec (~> 3)
|
102
|
-
|
103
|
-
BUNDLED WITH
|
104
|
-
1.16.0.pre.2
|
data/README.md
CHANGED
@@ -204,18 +204,27 @@ Table scanning is a very expensive operation, and should not be undertaken witho
|
|
204
204
|
|
205
205
|
The following options are supported:
|
206
206
|
|
207
|
-
* consistent_read (default: false)
|
208
|
-
* start_key (
|
209
|
-
* index_name (if scanning a secondary index - see below)
|
210
|
-
* limit
|
207
|
+
* :consistent_read (default: false)
|
208
|
+
* :start_key (key of first desired item, if unset will scan from beginning)
|
209
|
+
* :index_name (if scanning a secondary index - see below)
|
210
|
+
* :limit (default: no limit except for AWS chunk size)
|
211
|
+
* :segment (for multiprocess scanning)
|
212
|
+
* :total_segments (for multiprocess scanning)
|
213
|
+
|
214
|
+
Note that start_key can be either a hash { "AttributeName" => "Value" } or a value literal. If start_key is a literal then the attribute name will be inferred automatically, either being the main hash_key of your model or the key of the secondary index matching the provided index_name.
|
215
|
+
|
216
|
+
For more information about using segment and total_segments for parallelization, see: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
|
211
217
|
|
212
|
-
These two options are to support paralellization of table scanning, see: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html
|
213
|
-
* segment
|
214
|
-
* total_segments
|
215
218
|
|
216
219
|
```ruby
|
217
|
-
products_page_one = Product.scan(limit: 100)
|
218
|
-
|
220
|
+
products_page_one = Product.scan(limit: 100, start_key: 'abcd')
|
221
|
+
|
222
|
+
products_page_one.found
|
223
|
+
> [product, product...]
|
224
|
+
|
225
|
+
products_page_one.last_evaluated_key
|
226
|
+
> {'id' => 'wxyz'}
|
227
|
+
|
219
228
|
page_two = Product.scan(start_key: products_page_one.last_evaluated_key)
|
220
229
|
```
|
221
230
|
|
data/dynamini.gemspec
CHANGED
@@ -36,14 +36,9 @@ module Dynamini
|
|
36
36
|
def scan(options = {})
|
37
37
|
validate_scan_options(options)
|
38
38
|
response = dynamo_scan(options)
|
39
|
-
if options[:index_name]
|
40
|
-
last_evaluated_key = response.last_evaluated_key[secondary_index[options[:index_name]][:hash_key_name].to_s]
|
41
|
-
else
|
42
|
-
last_evaluated_key = response.last_evaluated_key[hash_key.to_s]
|
43
|
-
end
|
44
39
|
OpenStruct.new(
|
45
|
-
|
46
|
-
|
40
|
+
items: response.items.map { |i| new(i.symbolize_keys, false) },
|
41
|
+
last_evaluated_key: response.last_evaluated_key
|
47
42
|
)
|
48
43
|
end
|
49
44
|
|
@@ -72,9 +67,18 @@ module Dynamini
|
|
72
67
|
end
|
73
68
|
|
74
69
|
def dynamo_scan(options)
|
70
|
+
if options[:start_key] && !options[:start_key].is_a?(Hash)
|
71
|
+
if options[:index_name]
|
72
|
+
start_key = { options[:index_name].to_s => options[:start_key] }
|
73
|
+
else
|
74
|
+
start_key = { hash_key.to_s => options[:start_key] }
|
75
|
+
end
|
76
|
+
else
|
77
|
+
start_key = options[:start_key]
|
78
|
+
end
|
75
79
|
client.scan({
|
76
80
|
consistent_read: options[:consistent_read],
|
77
|
-
exclusive_start_key:
|
81
|
+
exclusive_start_key: start_key,
|
78
82
|
secondary_index_name: options[:index_name],
|
79
83
|
limit: options[:limit],
|
80
84
|
segment: options[:segment],
|
data/lib/dynamini/test_client.rb
CHANGED
@@ -90,8 +90,8 @@ module Dynamini
|
|
90
90
|
sort_scanned_records!(records, args[:secondary_index_name]) if args[:secondary_index_name]
|
91
91
|
start_index = index_of_start_key(args, records)
|
92
92
|
items = limit_scanned_records(args[:limit], records, start_index)
|
93
|
-
last_evaluated_key = get_last_evaluated_key(args[:secondary_index_name], items)
|
94
|
-
OpenStruct.new(items: items, last_evaluated_key: last_evaluated_key)
|
93
|
+
last_evaluated_key = get_last_evaluated_key(args[:secondary_index_name], items, records)
|
94
|
+
OpenStruct.new({items: items, last_evaluated_key: last_evaluated_key})
|
95
95
|
end
|
96
96
|
|
97
97
|
def sort_scanned_records!(records, secondary_index_name)
|
@@ -106,9 +106,9 @@ module Dynamini
|
|
106
106
|
sec_index = secondary_index[args[:secondary_index_name]]
|
107
107
|
start_index = records.index do |r|
|
108
108
|
if sec_index
|
109
|
-
r[get_secondary_hash_key(sec_index)] == args[:exclusive_start_key]
|
109
|
+
r[get_secondary_hash_key(sec_index)] == args[:exclusive_start_key].values[0]
|
110
110
|
else
|
111
|
-
r[hash_key_attr] == args[:exclusive_start_key]
|
111
|
+
r[hash_key_attr] == args[:exclusive_start_key].values[0]
|
112
112
|
end
|
113
113
|
end
|
114
114
|
start_index || -1
|
@@ -122,16 +122,15 @@ module Dynamini
|
|
122
122
|
records[start_index..end_index]
|
123
123
|
end
|
124
124
|
|
125
|
-
def get_last_evaluated_key(secondary_index_name, items)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
125
|
+
def get_last_evaluated_key(secondary_index_name, items, records)
|
126
|
+
if items.last != records.last
|
127
|
+
index = secondary_index[secondary_index_name]
|
128
|
+
if index
|
129
|
+
{ get_secondary_hash_key(index).to_s => items.last[get_secondary_hash_key(index)] }
|
130
|
+
else
|
131
|
+
{ hash_key_attr.to_s => items.last[hash_key_attr] }
|
132
|
+
end
|
133
133
|
end
|
134
|
-
# end
|
135
134
|
end
|
136
135
|
|
137
136
|
# TODO add range key support for delete, not currently implemented batch_operations.batch_delete
|
@@ -146,16 +146,24 @@ describe Dynamini::BatchOperations do
|
|
146
146
|
context 'with an exclusive_start_key' do
|
147
147
|
context 'with a limit' do
|
148
148
|
it 'retrieves the correct items' do
|
149
|
-
response = SecBase.scan(
|
149
|
+
response = SecBase.scan(start_key: '124', limit: 1)
|
150
150
|
expect(response.items.map { |i| i.id }).to eq(['124'])
|
151
|
-
expect(response.last_evaluated_key).to eq('124')
|
151
|
+
expect(response.last_evaluated_key).to eq('id' => '124')
|
152
152
|
end
|
153
153
|
end
|
154
154
|
context 'without a limit' do
|
155
155
|
it 'retrieves the correct items' do
|
156
|
-
response = SecBase.scan(
|
156
|
+
response = SecBase.scan(start_key: '124')
|
157
157
|
expect(response.items.map { |i| i.id }).to eq(%w(124 125 126))
|
158
|
-
expect(response.last_evaluated_key).to
|
158
|
+
expect(response.last_evaluated_key).to be_nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'the start key is in aws sdk style' do
|
163
|
+
it 'retrieves the correct items' do
|
164
|
+
response = SecBase.scan(start_key: {'id' => '124'}, limit: 2)
|
165
|
+
expect(response.items.map { |i| i.id }).to eq(['124', '125'])
|
166
|
+
expect(response.last_evaluated_key).to eq('id' => '125')
|
159
167
|
end
|
160
168
|
end
|
161
169
|
end
|
@@ -164,14 +172,14 @@ describe Dynamini::BatchOperations do
|
|
164
172
|
it 'retrieves the correct items' do
|
165
173
|
response = SecBase.scan(limit: 2)
|
166
174
|
expect(response.items.map { |i| i.id }).to eq(%w(123 124))
|
167
|
-
expect(response.last_evaluated_key).to eq('124')
|
175
|
+
expect(response.last_evaluated_key).to eq('id' => '124')
|
168
176
|
end
|
169
177
|
end
|
170
178
|
context 'without a limit' do
|
171
179
|
it 'retrieves the correct items' do
|
172
180
|
response = SecBase.scan
|
173
181
|
expect(response.items.map { |i| i.id }).to eq(%w(123 124 125 126))
|
174
|
-
expect(response.last_evaluated_key).to
|
182
|
+
expect(response.last_evaluated_key).to be_nil
|
175
183
|
end
|
176
184
|
end
|
177
185
|
end
|
@@ -180,16 +188,16 @@ describe Dynamini::BatchOperations do
|
|
180
188
|
context 'with an exclusive_start_key' do
|
181
189
|
context 'with a limit' do
|
182
190
|
it 'retrieves the correct items' do
|
183
|
-
response = SecBase.scan(index_name: 'sec',
|
191
|
+
response = SecBase.scan(index_name: 'sec', start_key: 'B', limit: 2)
|
184
192
|
expect(response.items.map { |i| i.sec }).to eq(%w(B C))
|
185
|
-
expect(response.last_evaluated_key).to eq('C')
|
193
|
+
expect(response.last_evaluated_key).to eq('sec' => 'C')
|
186
194
|
end
|
187
195
|
end
|
188
196
|
context 'without a limit' do
|
189
197
|
it 'retrieves the correct items' do
|
190
|
-
response = SecBase.scan(index_name: 'sec',
|
198
|
+
response = SecBase.scan(index_name: 'sec', start_key: 'B')
|
191
199
|
expect(response.items.map { |i| i.sec }).to eq(%w(B C D))
|
192
|
-
expect(response.last_evaluated_key).to
|
200
|
+
expect(response.last_evaluated_key).to be_nil
|
193
201
|
end
|
194
202
|
end
|
195
203
|
end
|
@@ -198,14 +206,14 @@ describe Dynamini::BatchOperations do
|
|
198
206
|
it 'retrieves the correct items' do
|
199
207
|
response = SecBase.scan(index_name: 'sec', limit: 3)
|
200
208
|
expect(response.items.map { |i| i.sec }).to eq(%w(A B C))
|
201
|
-
expect(response.last_evaluated_key).to eq('C')
|
209
|
+
expect(response.last_evaluated_key).to eq('sec' => 'C')
|
202
210
|
end
|
203
211
|
end
|
204
212
|
context 'without a limit' do
|
205
213
|
it 'retrieves the correct items' do
|
206
214
|
response = SecBase.scan(index_name: 'sec')
|
207
215
|
expect(response.items.map { |i| i.sec }).to eq(%w(A B C D))
|
208
|
-
expect(response.last_evaluated_key).to
|
216
|
+
expect(response.last_evaluated_key).to be_nil
|
209
217
|
end
|
210
218
|
end
|
211
219
|
end
|