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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc49f68b676b1c89e2ca6dbb4c26d21e55b64e65
4
- data.tar.gz: 10048c3d4ca703ed3b5b08af98c6ce82f8e9bdfc
3
+ metadata.gz: 9f1a20436eb99c2fd68b4026a3cd3f089d071253
4
+ data.tar.gz: 40b8de349d71b2ec3b518be6ddbead9ad649fbd7
5
5
  SHA512:
6
- metadata.gz: 6f195b4b78087f0d6b6321224dab72978b7f2acc075c4856fea9c9aa681d4a68ce9267837b3e8bf432c66a2e7bccc6f2bb8f17a0041bee4f3c3e74eaa8791570
7
- data.tar.gz: ca6d31d38bebc5937bf70f092f261e5e6af13a96800606bf0206508f8dd85a36db0cca7f7f9698026072115c5c3a779676405a49ddb18251bef3a1c7a9c62708
6
+ metadata.gz: 2ca18eebc95c0f975c429c8950c89e962ffc512e2a6b6fdfce08dfdbbb066167a487a6bde7950097c28006f32d430861be537d65a0d7c793d503014acb64dec3
7
+ data.tar.gz: fa8166c654583540e2f2d4289899f618203097ca174f26fbe68eb7c68316ec4ff9c3cd3e100f735a9d7c552905f67ac7061080858d7d811f98529d34aa9f4d8a
@@ -60,5 +60,9 @@ module DynamoDbFramework
60
60
 
61
61
  end
62
62
 
63
+ def contains(name:)
64
+ @attributes.detect { |a| a[:name] == name } != nil
65
+ end
66
+
63
67
  end
64
68
  end
@@ -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
- table_manager.add_index(table_name, builder.attributes, index)
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
- DynamoDbFramework::TableManager.new(store).create_table({ name: full_table_name, attributes: builder.attributes, read_capacity: read_capacity, write_capacity: write_capacity })
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 = Time.now + 300
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 occured while waiting for table: #{table_name}, to become active."
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 = Time.now + 300
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 occured while waiting for table: #{table_name}, index: #{index_name}, to become active."
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 = Time.now + 300
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 occured while waiting for table: #{table_name}, index: #{index_name}, to be dropped."
234
+ raise "Timeout occurred while waiting for table: #{table_name}, index: #{index_name}, to be dropped."
208
235
 
209
236
  end
210
237
 
@@ -1,3 +1,3 @@
1
1
  module DynamoDbFramework
2
- VERSION = '1.5.2'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -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
@@ -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
 
@@ -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.5.2
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-08-18 00:00:00.000000000 Z
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: '0'
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: '0'
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: