dynamodb_framework 1.5.2 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dynamodb_framework/dynamodb_attributes_builder.rb +4 -0
- data/lib/dynamodb_framework/dynamodb_index.rb +25 -2
- data/lib/dynamodb_framework/dynamodb_table.rb +43 -2
- data/lib/dynamodb_framework/dynamodb_table_manager.rb +33 -6
- data/lib/dynamodb_framework/version.rb +1 -1
- data/spec/dynamodb_table_spec.rb +52 -0
- data/spec/example_index.rb +2 -2
- data/spec/example_table.rb +2 -2
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f1a20436eb99c2fd68b4026a3cd3f089d071253
|
4
|
+
data.tar.gz: 40b8de349d71b2ec3b518be6ddbead9ad649fbd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ca18eebc95c0f975c429c8950c89e962ffc512e2a6b6fdfce08dfdbbb066167a487a6bde7950097c28006f32d430861be537d65a0d7c793d503014acb64dec3
|
7
|
+
data.tar.gz: fa8166c654583540e2f2d4289899f618203097ca174f26fbe68eb7c68316ec4ff9c3cd3e100f735a9d7c552905f67ac7061080858d7d811f98529d34aa9f4d8a
|
@@ -46,13 +46,19 @@ module DynamoDbFramework
|
|
46
46
|
self.instance_variable_set(:@range_key, { field: field, type: type })
|
47
47
|
end
|
48
48
|
|
49
|
-
def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25)
|
49
|
+
def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25, submit: true)
|
50
50
|
unless self.instance_variable_defined?(:@table)
|
51
51
|
raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.')
|
52
52
|
end
|
53
53
|
table = self.instance_variable_get(:@table)
|
54
54
|
table_name = table.config[:table_name]
|
55
55
|
|
56
|
+
#make method idempotent
|
57
|
+
if exists?(store: store)
|
58
|
+
wait_until_active(store: store)
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
56
62
|
unless self.instance_variable_defined?(:@partition_key)
|
57
63
|
raise DynamoDbFramework::Index::InvalidConfigException.new('Partition key must be specified.')
|
58
64
|
end
|
@@ -80,7 +86,11 @@ module DynamoDbFramework
|
|
80
86
|
|
81
87
|
index =table_manager.create_global_index(full_index_name, partition_key[:field], range_key_field, read_capacity, write_capacity)
|
82
88
|
|
83
|
-
|
89
|
+
if submit
|
90
|
+
table_manager.add_index(table_name, builder.attributes, index)
|
91
|
+
end
|
92
|
+
|
93
|
+
index
|
84
94
|
end
|
85
95
|
|
86
96
|
def update(store: DynamoDbFramework.default_store, read_capacity:, write_capacity:)
|
@@ -99,6 +109,10 @@ module DynamoDbFramework
|
|
99
109
|
table = self.instance_variable_get(:@table)
|
100
110
|
table_name = table.config[:table_name]
|
101
111
|
|
112
|
+
unless exists?(store: store)
|
113
|
+
return
|
114
|
+
end
|
115
|
+
|
102
116
|
DynamoDbFramework::TableManager.new(store).drop_index(table_name, full_index_name)
|
103
117
|
end
|
104
118
|
|
@@ -111,6 +125,15 @@ module DynamoDbFramework
|
|
111
125
|
DynamoDbFramework::TableManager.new(store).has_index?(table_name, full_index_name)
|
112
126
|
end
|
113
127
|
|
128
|
+
def wait_until_active(store: DynamoDbFramework.default_store)
|
129
|
+
unless self.instance_variable_defined?(:@table)
|
130
|
+
raise DynamoDbFramework::Index::InvalidConfigException.new('Table must be specified.')
|
131
|
+
end
|
132
|
+
table = self.instance_variable_get(:@table)
|
133
|
+
table_name = table.config[:table_name]
|
134
|
+
DynamoDbFramework::TableManager.new(store).wait_until_index_active(table_name, full_index_name)
|
135
|
+
end
|
136
|
+
|
114
137
|
def query(partition:)
|
115
138
|
DynamoDbFramework::Query.new(index_name: config[:index_name], table_name: config[:table].config[:table_name], partition_key: config[:partition_key][:field], partition_value: partition)
|
116
139
|
end
|
@@ -41,7 +41,14 @@ module DynamoDbFramework
|
|
41
41
|
self.instance_variable_set(:@range_key, { field: field, type: type })
|
42
42
|
end
|
43
43
|
|
44
|
-
def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25)
|
44
|
+
def create(store: DynamoDbFramework.default_store, read_capacity: 25, write_capacity: 25, indexes: [])
|
45
|
+
|
46
|
+
#make method idempotent
|
47
|
+
if exists?(store: store)
|
48
|
+
wait_until_active(store: store)
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
45
52
|
unless self.instance_variable_defined?(:@partition_key)
|
46
53
|
raise DynamoDbFramework::Table::InvalidConfigException.new('Partition key must be specified.')
|
47
54
|
end
|
@@ -57,7 +64,26 @@ module DynamoDbFramework
|
|
57
64
|
builder.add({ name: range_key[:field], type: range_key[:type], key: :range })
|
58
65
|
end
|
59
66
|
|
60
|
-
|
67
|
+
global_indexes = nil
|
68
|
+
if indexes != nil && indexes.length > 0
|
69
|
+
global_indexes = []
|
70
|
+
indexes.each do |i|
|
71
|
+
global_indexes << i.create(store: store, submit: false)
|
72
|
+
index_partition_key = i.instance_variable_get(:@partition_key)
|
73
|
+
unless builder.contains(name: index_partition_key[:field])
|
74
|
+
builder.add({ name: index_partition_key[:field], type: index_partition_key[:type] })
|
75
|
+
end
|
76
|
+
if i.instance_variable_defined?(:@range_key)
|
77
|
+
index_range_key = i.instance_variable_get(:@range_key)
|
78
|
+
unless builder.contains(name: index_range_key[:field])
|
79
|
+
builder.add({ name: index_range_key[:field], type: index_range_key[:type] })
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
DynamoDbFramework::TableManager.new(store).create_table({ name: full_table_name, attributes: builder.attributes, read_capacity: read_capacity, write_capacity: write_capacity, global_indexes: global_indexes })
|
61
87
|
end
|
62
88
|
|
63
89
|
def update(store: DynamoDbFramework.default_store, read_capacity:, write_capacity:)
|
@@ -65,6 +91,9 @@ module DynamoDbFramework
|
|
65
91
|
end
|
66
92
|
|
67
93
|
def drop(store: DynamoDbFramework.default_store)
|
94
|
+
unless exists?(store: store)
|
95
|
+
return
|
96
|
+
end
|
68
97
|
DynamoDbFramework::TableManager.new(store).drop(full_table_name)
|
69
98
|
end
|
70
99
|
|
@@ -72,6 +101,18 @@ module DynamoDbFramework
|
|
72
101
|
DynamoDbFramework::TableManager.new(store).exists?(full_table_name)
|
73
102
|
end
|
74
103
|
|
104
|
+
def wait_until_active(store: DynamoDbFramework.default_store)
|
105
|
+
DynamoDbFramework::TableManager.new(store).wait_until_active(full_table_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_status(store: DynamoDbFramework.default_store)
|
109
|
+
DynamoDbFramework::TableManager.new(store).get_status(full_table_name)
|
110
|
+
end
|
111
|
+
|
112
|
+
def active?(store: DynamoDbFramework.default_store)
|
113
|
+
DynamoDbFramework::TableManager.new(store).get_status(full_table_name) == 'ACTIVE'
|
114
|
+
end
|
115
|
+
|
75
116
|
def query(partition:)
|
76
117
|
DynamoDbFramework::Query.new(table_name: config[:table_name], partition_key: config[:partition_key][:field], partition_value: partition)
|
77
118
|
end
|
@@ -116,6 +116,10 @@ module DynamoDbFramework
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def drop_index(table_name, index_name)
|
119
|
+
unless has_index?(table_name, index_name)
|
120
|
+
return
|
121
|
+
end
|
122
|
+
|
119
123
|
table = {
|
120
124
|
:table_name => table_name,
|
121
125
|
:global_secondary_index_updates => [
|
@@ -130,6 +134,7 @@ module DynamoDbFramework
|
|
130
134
|
# wait for table to be updated
|
131
135
|
DynamoDbFramework.logger.info "[#{self.class}] -Deleting global index: #{index_name}."
|
132
136
|
wait_until_index_dropped(table_name, index_name)
|
137
|
+
|
133
138
|
DynamoDbFramework.logger.info "[#{self.class}] -Index: [#{index_name}] dropped."
|
134
139
|
end
|
135
140
|
|
@@ -154,9 +159,13 @@ module DynamoDbFramework
|
|
154
159
|
return nil
|
155
160
|
end
|
156
161
|
|
162
|
+
def wait_timeout
|
163
|
+
Time.now + 900 #15 minutes
|
164
|
+
end
|
165
|
+
|
157
166
|
def wait_until_active(table_name)
|
158
167
|
|
159
|
-
end_time =
|
168
|
+
end_time = wait_timeout
|
160
169
|
while Time.now < end_time do
|
161
170
|
|
162
171
|
status = get_status(table_name)
|
@@ -168,13 +177,31 @@ module DynamoDbFramework
|
|
168
177
|
sleep(5)
|
169
178
|
end
|
170
179
|
|
171
|
-
raise "Timeout
|
180
|
+
raise "Timeout occurred while waiting for table: #{table_name}, to become active."
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
def wait_until_dropped(table_name)
|
185
|
+
|
186
|
+
end_time = wait_timeout
|
187
|
+
while Time.now < end_time do
|
188
|
+
|
189
|
+
status = get_status(table_name)
|
190
|
+
|
191
|
+
if status == nil
|
192
|
+
return
|
193
|
+
end
|
194
|
+
|
195
|
+
sleep(5)
|
196
|
+
end
|
197
|
+
|
198
|
+
raise "Timeout occurred while waiting for table: #{table_name}, to be dropped."
|
172
199
|
|
173
200
|
end
|
174
201
|
|
175
202
|
def wait_until_index_active(table_name, index_name)
|
176
203
|
|
177
|
-
end_time =
|
204
|
+
end_time = wait_timeout
|
178
205
|
while Time.now < end_time do
|
179
206
|
|
180
207
|
status = get_index_status(table_name, index_name)
|
@@ -186,13 +213,13 @@ module DynamoDbFramework
|
|
186
213
|
sleep(5)
|
187
214
|
end
|
188
215
|
|
189
|
-
raise "Timeout
|
216
|
+
raise "Timeout occurred while waiting for table: #{table_name}, index: #{index_name}, to become active."
|
190
217
|
|
191
218
|
end
|
192
219
|
|
193
220
|
def wait_until_index_dropped(table_name, index_name)
|
194
221
|
|
195
|
-
end_time =
|
222
|
+
end_time = wait_timeout
|
196
223
|
while Time.now < end_time do
|
197
224
|
|
198
225
|
status = get_index_status(table_name, index_name)
|
@@ -204,7 +231,7 @@ module DynamoDbFramework
|
|
204
231
|
sleep(5)
|
205
232
|
end
|
206
233
|
|
207
|
-
raise "Timeout
|
234
|
+
raise "Timeout occurred while waiting for table: #{table_name}, index: #{index_name}, to be dropped."
|
208
235
|
|
209
236
|
end
|
210
237
|
|
data/spec/dynamodb_table_spec.rb
CHANGED
@@ -22,6 +22,22 @@ RSpec.describe DynamoDbFramework::Table do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
context 'with an index specified' do
|
26
|
+
let(:table_name) { ExampleTable.config[:table_name] }
|
27
|
+
let(:index_name) { ExampleIndex.config[:index_name] }
|
28
|
+
before do
|
29
|
+
table_manager.drop(table_name)
|
30
|
+
table_manager.drop_index(table_name, index_name)
|
31
|
+
end
|
32
|
+
it 'should create the table and index' do
|
33
|
+
expect(table_manager.exists?(table_name)).to be false
|
34
|
+
expect(ExampleIndex.exists?(store: store)).to be false
|
35
|
+
ExampleTable.create(store: store, indexes: [ExampleIndex])
|
36
|
+
expect(table_manager.exists?(table_name)).to be true
|
37
|
+
expect(ExampleIndex.exists?(store: store)).to be true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
25
41
|
context 'without a range key' do
|
26
42
|
let(:table_name) { ExampleTableWithoutRangeKey.config[:table_name] }
|
27
43
|
before do
|
@@ -33,6 +49,19 @@ RSpec.describe DynamoDbFramework::Table do
|
|
33
49
|
expect(table_manager.exists?(table_name)).to be true
|
34
50
|
end
|
35
51
|
end
|
52
|
+
|
53
|
+
context 'when already exists' do
|
54
|
+
let(:table_name) { ExampleTableWithoutRangeKey.config[:table_name] }
|
55
|
+
before do
|
56
|
+
table_manager.drop(table_name)
|
57
|
+
ExampleTableWithoutRangeKey.create(store: store)
|
58
|
+
end
|
59
|
+
it 'should return without error' do
|
60
|
+
expect(table_manager.exists?(table_name)).to be true
|
61
|
+
expect { ExampleTableWithoutRangeKey.create(store: store) }.not_to raise_error
|
62
|
+
expect(table_manager.exists?(table_name)).to be true
|
63
|
+
end
|
64
|
+
end
|
36
65
|
end
|
37
66
|
context 'when an invalid table class calls the create method' do
|
38
67
|
context 'without a table_name specified' do
|
@@ -111,6 +140,29 @@ RSpec.describe DynamoDbFramework::Table do
|
|
111
140
|
end
|
112
141
|
end
|
113
142
|
|
143
|
+
describe '#wait_until_active' do
|
144
|
+
context 'when a table exists' do
|
145
|
+
let(:table_name) { ExampleTable.config[:table_name] }
|
146
|
+
before do
|
147
|
+
table_manager.drop(table_name)
|
148
|
+
ExampleTable.create(store: store)
|
149
|
+
end
|
150
|
+
it 'should not raise timeout error' do
|
151
|
+
expect { ExampleTable.wait_until_active(store: store) }.not_to raise_error
|
152
|
+
end
|
153
|
+
end
|
154
|
+
context 'when a table does NOT exist' do
|
155
|
+
let(:table_name) { ExampleTable.config[:table_name] }
|
156
|
+
before do
|
157
|
+
table_manager.drop(table_name)
|
158
|
+
allow_any_instance_of(DynamoDbFramework::TableManager).to receive(:wait_timeout).and_return(Time.now)
|
159
|
+
end
|
160
|
+
it 'should raise timeout error' do
|
161
|
+
expect { ExampleTable.wait_until_active(store: store) }.to raise_error
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
114
166
|
describe '#query' do
|
115
167
|
|
116
168
|
let(:repository) do
|
data/spec/example_index.rb
CHANGED
@@ -30,7 +30,7 @@ class ExampleIndexWithoutPartitionKey
|
|
30
30
|
extend DynamoDbFramework::Index
|
31
31
|
|
32
32
|
table ExampleTable
|
33
|
-
index_name 'example_index'
|
33
|
+
index_name 'example_index.without.partition'
|
34
34
|
range_key :id, :S
|
35
35
|
|
36
36
|
end
|
@@ -38,7 +38,7 @@ end
|
|
38
38
|
class ExampleIndexWithoutRangeKey
|
39
39
|
extend DynamoDbFramework::Index
|
40
40
|
|
41
|
-
index_name 'example_index'
|
41
|
+
index_name 'example_index.without.range'
|
42
42
|
table ExampleTable
|
43
43
|
partition_key :name, :S
|
44
44
|
|
data/spec/example_table.rb
CHANGED
@@ -27,7 +27,7 @@ end
|
|
27
27
|
class ExampleTableWithoutPartitionKey
|
28
28
|
extend DynamoDbFramework::Table
|
29
29
|
|
30
|
-
table_name 'example'
|
30
|
+
table_name 'example.without.partition'
|
31
31
|
range_key :timestamp, :N
|
32
32
|
|
33
33
|
end
|
@@ -35,7 +35,7 @@ end
|
|
35
35
|
class ExampleTableWithoutRangeKey
|
36
36
|
extend DynamoDbFramework::Table
|
37
37
|
|
38
|
-
table_name 'example'
|
38
|
+
table_name 'example.without.range'
|
39
39
|
partition_key :id, :S
|
40
40
|
|
41
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamodb_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vaughanbrittonsage
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,16 +98,16 @@ dependencies:
|
|
98
98
|
name: aws-sdk-core
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
103
|
+
version: '2.10'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
110
|
+
version: '2.10'
|
111
111
|
description: A lightweight framework to provide managers for working with aws dynamodb
|
112
112
|
(incuding local version).
|
113
113
|
email:
|