dynamodb_framework 1.5.2 → 1.6.0
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/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:
|