dynamini 2.9.1 → 2.9.2

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
  SHA1:
3
- metadata.gz: d5e2c24bc6e120e7bb25eebcc819ec7081aef462
4
- data.tar.gz: e484085550e7692f05431a5b79b38a6f4f002cda
3
+ metadata.gz: 4da5852711d8ecb8a226a9ae7c987f2ea0324927
4
+ data.tar.gz: eec0aaae89719060294b9ae055f8effabf79dd9b
5
5
  SHA512:
6
- metadata.gz: 5e82d4a69eb80db5534cd3a70e4c1f795ba13651202ca6b228945a7fb58fd5c7289c173f7cbf12a8ca9b3a255f986b14c7b6410e63d8e8e44168c82f417dbf18
7
- data.tar.gz: 387de4884bedfed45b9a475a617d2666382271221288eb45ae2d9d32fb3bcdf51f8f05e5fe5d7e511533526e7c4b7166a11977984a923abf61e9453eb71aae03
6
+ metadata.gz: f6eaf764f422c931ae8e5d669f2b26349cfaffedfcabb6c13654f06ac40b758ea371b0328149d1f3c0914de67972fa7971d7a01d89bef94b6ab825b3bd1527c3
7
+ data.tar.gz: d97dab7690b1c371052bff3c1c1a7b8d39107281b2ed71c90e6eb05b3dc18998d9f51c8ad81307ebb249de1d4924f56245ef8f4e85100d42d4fd71b870f5081c
@@ -1,30 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamini (2.9.1)
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.9)
12
- activesupport (= 4.2.9)
11
+ activemodel (4.2.5.1)
12
+ activesupport (= 4.2.5.1)
13
13
  builder (~> 3.1)
14
- activesupport (4.2.9)
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.10.44)
20
- aws-sdk-resources (= 2.10.44)
21
- aws-sdk-core (2.10.44)
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.10.44)
25
- aws-sdk-core (= 2.10.44)
26
- aws-sigv4 (1.0.2)
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.8.6)
53
- jmespath (1.3.1)
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.10.3)
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.6)
89
- tzinfo (1.2.3)
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 (hash key of first desired item, default will scan from beginning)
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
- products_page_one.found # [product, product...]
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
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dynamini'
3
- s.version = '2.9.1'
3
+ s.version = '2.9.2'
4
4
  s.summary = 'DynamoDB interface'
5
5
  s.description = 'Lightweight DynamoDB interface gem designed as
6
6
  a drop-in replacement for ActiveRecord.
@@ -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
- last_evaluated_key: last_evaluated_key,
46
- items: response.items.map { |i| new(i.symbolize_keys, false) }
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: options[: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],
@@ -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
- # TODO should last evaluated key be present if the args[:limit] was reached?
127
- # if items.length > records.length
128
- index = secondary_index[secondary_index_name]
129
- if index
130
- { get_secondary_hash_key(index).to_s => items.last[get_secondary_hash_key(index)] }
131
- else
132
- { hash_key_attr.to_s => items.last[hash_key_attr] }
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(exclusive_start_key: '124', limit: 1)
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(exclusive_start_key: '124')
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 eq('126')
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 eq('126')
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', exclusive_start_key: 'B', limit: 2)
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', exclusive_start_key: 'B')
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 eq('D')
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 eq('D')
216
+ expect(response.last_evaluated_key).to be_nil
209
217
  end
210
218
  end
211
219
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamini
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.1
4
+ version: 2.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Ward