ocean-dynamo 1.0.8 → 1.1.0

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: d978bad9958a6105af68a85d96d0d38b677f26b4
4
- data.tar.gz: de5eecbb27c422971d41e5a78b905b4ea183cde0
3
+ metadata.gz: 5a5d6a93318aea2c36029d1f40d3496ad5cc16a1
4
+ data.tar.gz: 17f2f4d1edf4885662aea89e61948924d7e2bfdb
5
5
  SHA512:
6
- metadata.gz: d8253aa7f354f8d3295be2482ab792aa5c00fd297473cbad21eba2b3e3dd3eb3e54cd1a10894a9229a4a22c4a114833809baed95b445f7e0b73bbf884732e74f
7
- data.tar.gz: 6385f3c5adab407a884bddfe592a453830792a7da8985851c14ab5e047377135676fc7b11cc1519c6cd5a88736d622990d22d6575e76ae2d726516df679acd77
6
+ metadata.gz: d3f9aff5b1b2f3402946acb6c5806b32582e3baeefa758ea4d35183386cde1bb937e88204a8feb8fddabc107b16c13540c334bd0ddf04ce91b39822e9a3c6284
7
+ data.tar.gz: 1cfb33f43e6888a7f7f7417900baf99b9d777ef2797a52d96f5af36e090bedd46f2543210f62237f7e4db547570a67094cb1bd3e094ec13e36671b11154fe1eb
@@ -18,16 +18,65 @@ closely and is of course based on ActiveModel.
18
18
 
19
19
  The attribute and persistence layer of OceanDynamo is modeled on that of ActiveRecord:
20
20
  there's +save+, +save!+, +create+, +update+, +update!+, +update_attributes+, +find_each+,
21
- +destroy_all+, +delete_all+ and all the other methods you're used to. The design goal
22
- is always to implement as much of the ActiveRecord interface as possible, without
23
- compromising scalability. This makes the task of switching from SQL to no-SQL much easier.
24
-
25
- Thanks to its structural similarity to ActiveRecord, OceanDynamo works with FactoryGirl.
21
+ +destroy_all+, +delete_all+, +read_attribute+, +write_attribute+ and all the other
22
+ methods you're used to. The design goal is always to implement as much of the ActiveRecord
23
+ interface as possible, without compromising scalability. This makes the task of switching
24
+ from SQL to no-SQL much easier.
26
25
 
27
26
  OceanDynamo uses only primary indices to retrieve related table items and collections,
28
27
  which means it will scale without limits.
29
28
 
30
- === Example
29
+ OceanDynamo is fully usable as an ActiveModel and can be used by Rails
30
+ controllers. Thanks to its structural similarity to ActiveRecord, OceanDynamo works
31
+ with FactoryGirl.
32
+
33
+
34
+ === Current State
35
+
36
+ * Local secondary indices are now supported! See below for more information.
37
+ * Version 2 of the AWS Ruby SDK is now used. This required an internal reorganisation,
38
+ but it also gives us access to local and global secondary indices.
39
+ * Work begun on association proxies, etc.
40
+
41
+
42
+ === Future milestones
43
+
44
+ * Association proxies, to implement ActiveRecord-style method chaining, e.g.:
45
+ <code>blog_entry.comments.build(body: "Cool!").save!</code>
46
+ * The +has_and_belongs_to_many+ assocation.
47
+ * A generator to install the <tt>config/aws.yml</tt> file.
48
+
49
+
50
+ === Current use
51
+
52
+ OceanDynamo is used as a central component in Ocean, a Rails framework and development
53
+ pipeline for creating highly scalable HATEOAS microservice SOAs in the cloud.
54
+ * http://wiki.oceanframework.net
55
+
56
+ Ocean uses OceanDynamo to implement highly scalable job queues and authentication.
57
+ It will be used increasingly as features are added to OceanDynamo and will eventually
58
+ replace all ActiveRecord tables in Ocean.
59
+
60
+ However, OceanDynamo can of course also be used stand-alone.
61
+
62
+
63
+ == Documentation
64
+
65
+ * Ocean-dynamo gem on Rubygems: https://rubygems.org/gems/ocean-dynamo
66
+ * Ocean-dynamo gem API: http://rubydoc.info/gems/ocean-dynamo/frames
67
+ * Ocean-dynamo source and wiki: https://github.org/OceanDev/ocean-dynamo
68
+ * AWS DynamoDB Ruby SDK v2: http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB.html
69
+
70
+
71
+ == Contributing
72
+
73
+ Contributions are welcome. Fork in the usual way. OceanDynamo is developed using
74
+ TDD: the specs are extensive and test coverage is very near to 100 percent. Pull requests
75
+ will not be considered unless all tests pass and coverage is equally high or higher.
76
+ All contributed code must therefore also be exhaustively tested.
77
+
78
+
79
+ === Examples
31
80
 
32
81
  ==== Basic syntax
33
82
 
@@ -45,7 +94,7 @@ The following example shows the basic syntax for declaring a DynamoDB-based sche
45
94
  attribute :started_at, :datetime
46
95
  attribute :last_completed_step, :integer
47
96
  attribute :finished_at, :datetime
48
- attribute :destroy_at, :datetime
97
+ attribute :destroy_at, :datetime, local_secondary_index: true
49
98
  attribute :created_by
50
99
  attribute :updated_by
51
100
  attribute :succeeded, :boolean, default: false
@@ -73,8 +122,8 @@ value will return the empty string, <tt>""</tt>.
73
122
  +dynamo_schema+ takes args and many options. Here's the full syntax:
74
123
 
75
124
  dynamo_schema(
76
- table_hash_key: = :id, # The name of the hash key attribute
77
- table_range_key: = nil, # The name of the range key attribute (or nil)
125
+ table_hash_key = :id, # The name of the hash key attribute
126
+ table_range_key = nil, # The name of the range key attribute (or nil)
78
127
  table_name: compute_table_name, # The basename of the DynamoDB table
79
128
  table_name_prefix: nil, # A basename prefix string or nil
80
129
  table_name_suffix: nil, # A basename suffix string or nil
@@ -166,32 +215,40 @@ Nevertheless, as we now have switched to v2 of the DynamoDB API, we will be addi
166
215
  the possibility to define both local and secondary indices for Tables.
167
216
 
168
217
 
169
- === Current State
170
-
171
- OceanDynamo is fully usable as an ActiveModel and can be used by Rails
172
- controllers. OceanDynamo implements much of the infrastructure of ActiveRecord;
173
- for instance, +read_attribute+, +write_attribute+, and much of the control logic and
174
- internal organisation.
175
-
176
- * Version 2 of the AWS Ruby SDK is now used. This required an internal reorganisation,
177
- but it also gives us access to local and global secondary indices.
178
- * Work begun on collection proxies, etc.
218
+ === Local Secondary Indices
179
219
 
180
- === Future milestones
220
+ We now have basic support for local secondary indices. Up to five attributes can
221
+ be declared as local secondary indices, in the following manner:
181
222
 
182
- * Association proxies, to implement ActiveRecord-style method chaining, e.g.:
183
- <code>blog_entry.comments.build(body: "Cool!").save!</code>
184
-
185
- * The +has_and_belongs_to_many+ assocation.
186
-
187
- * A generator to install the <tt>config/aws.yml</tt> file.
223
+ class Authentication < OceanDynamo::Table
224
+ dynamo_schema(:username, :expires_at,
225
+ timestamps: nil, locking: false
226
+ table_name_suffix: Api.basename_suffix) do
227
+ attribute :token, :string, local_secondary_index: true
228
+ attribute :max_age, :integer
229
+ attribute :created_at, :datetime
230
+ attribute :expires_at, :datetime
231
+ attribute :api_user_id, :string
232
+ end
233
+ end
188
234
 
235
+ The items of the above table can be accessed by using the hash key :username and
236
+ the range key :expires_at. The +local_secondary_index+ declaration makes it possible
237
+ to access items using the same hash key :username but with :token as an alternate
238
+ range key. Local secondary indices all use the same hash key as the primary index,
239
+ substituting another attribute instead as the range key.
189
240
 
190
- === Current use
241
+ NB: The primary index [:username, :expires_at] requires all items to have a unique
242
+ combination of keys. Secondary indices don't require the range key to be unique for
243
+ the same hash key. This means that secondary index searches always will return a
244
+ collection.
191
245
 
192
- OceanDynamo is currently used in the Ocean framework (http://wiki.oceanframework.net)
193
- e.g. to implement highly scalable job queues. It will be used increasingly as features are
194
- added to OceanDynamo and will eventually replace all ActiveRecord tables in Ocean.
246
+ We will add support for specifying that a secondary index is to be used in +find_each+
247
+ and its derivatives, but for now you will have to specify this explicitly in the
248
+ options passed to +in_batches+, +query+, and +scan+.
249
+ * +query+: http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Table.html#query-instance_method.
250
+ * +scan+: http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Table.html#scan-instance_method
251
+ * +in_batches+, +find_each+: lib/ocean-dynamo/queries.rb
195
252
 
196
253
 
197
254
  == Installation
@@ -219,27 +276,6 @@ Enter your AWS credentials in the latter file. Eventually, there
219
276
  will be a generator to copy these files for you, but for now you need to do it manually.
220
277
 
221
278
 
222
- == Documentation
223
-
224
- * Ocean-dynamo gem on Rubygems: https://rubygems.org/gems/ocean-dynamo
225
- * Ocean-dynamo gem API: http://rubydoc.info/gems/ocean-dynamo/frames
226
- * Ocean-dynamo source and wiki: https://github.org/OceanDev/ocean-dynamo
227
- * AWS DynamoDB Ruby SDK v2: http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB.html
228
-
229
- You might also want to take a look at Ocean, a Rails framework and development pipeline
230
- for creating highly scalable HATEOAS microservice SOAs in the cloud. Ocean uses
231
- OceanDynamo as a central component:
232
- * http://wiki.oceanframework.net
233
-
234
-
235
- == Contributing
236
-
237
- Contributions are welcome. Fork in the usual way. OceanDynamo is developed using
238
- TDD: the specs are extensive and test coverage is very near to 100 percent. Pull requests
239
- will not be considered unless all tests pass and coverage is equally high or higher.
240
- All contributed code must therefore also be exhaustively tested.
241
-
242
-
243
279
  == Running the specs
244
280
 
245
281
  To run the specs for the OceanDynamo gem, you must first install DynamoDB Local.
@@ -113,10 +113,7 @@ module OceanDynamo
113
113
  def condition_options(child_class)
114
114
  hash_key = child_class.table_hash_key
115
115
  range_key = child_class.table_range_key
116
- ean = {}
117
- ean["#H"] = hash_key.to_s
118
- ean["#R"] = range_key.to_s if range_key
119
- { expression_attribute_names: ean,
116
+ { expression_attribute_names: { "#H" => hash_key, "#R" => range_key },
120
117
  key_condition_expression: "#H = :hashval AND #R >= :rangeval",
121
118
  expression_attribute_values: { ":hashval" => id, ":rangeval" => "0" }
122
119
  }
@@ -50,8 +50,8 @@ module OceanDynamo
50
50
  #
51
51
  def delete_all
52
52
  _late_connect?
53
- ean = { "#H" => table_hash_key.to_s }
54
- ean["#R"] = table_range_key.to_s if table_range_key
53
+ ean = { "#H" => table_hash_key }
54
+ ean["#R"] = table_range_key if table_range_key
55
55
  options = {
56
56
  consistent_read: true,
57
57
  projection_expression: "#H" + (table_range_key ? ", #R" : ""),
@@ -44,7 +44,7 @@ module OceanDynamo
44
44
 
45
45
 
46
46
  def establish_db_connection
47
- setup_dynamo
47
+ setup_dynamo
48
48
  if table_exists?(dynamo_table)
49
49
  wait_until_table_is_active
50
50
  self.table_connected = true
@@ -95,17 +95,19 @@ module OceanDynamo
95
95
 
96
96
 
97
97
  def create_table
98
- attrs = table_attribute_definitions
98
+ attrs = table_attribute_definitions # This already includes secondary indices
99
99
  keys = table_key_schema
100
100
  options = {
101
101
  table_name: table_full_name,
102
+ attribute_definitions: attrs,
103
+ key_schema: keys,
102
104
  provisioned_throughput: {
103
105
  read_capacity_units: table_read_capacity_units,
104
106
  write_capacity_units: table_write_capacity_units
105
- },
106
- attribute_definitions: attrs,
107
- key_schema: keys
107
+ }
108
108
  }
109
+ lsi = local_secondary_indexes.collect { |n| local_secondary_index_declaration n }
110
+ options[:local_secondary_indexes] = lsi unless lsi.blank?
109
111
  dynamo_resource.create_table(options)
110
112
  sleep 1 until dynamo_table.table_status == "ACTIVE"
111
113
  setup_dynamo
@@ -126,10 +128,33 @@ module OceanDynamo
126
128
  end
127
129
 
128
130
 
131
+ def local_secondary_indexes
132
+ @local_secondary_indexes ||= begin
133
+ result = []
134
+ fields.each do |name, metadata|
135
+ (result << name) if metadata["local_secondary_index"]
136
+ end
137
+ result
138
+ end
139
+ end
140
+
141
+
142
+ def local_secondary_index_declaration(name)
143
+ { index_name: name,
144
+ key_schema: [{ attribute_name: table_hash_key.to_s, key_type: "HASH" },
145
+ { attribute_name: name.to_s, key_type: "RANGE" }],
146
+ projection: { projection_type: "KEYS_ONLY" }
147
+ }
148
+ end
149
+
150
+
129
151
  def table_attribute_definitions
130
152
  attrs = []
131
153
  attrs << { attribute_name: table_hash_key.to_s, attribute_type: attribute_type(table_hash_key) }
132
154
  attrs << { attribute_name: table_range_key.to_s, attribute_type: attribute_type(table_range_key) } if table_range_key
155
+ local_secondary_indexes.each do |name|
156
+ attrs << { attribute_name: name, attribute_type: attribute_type(name) }
157
+ end
133
158
  attrs
134
159
  end
135
160
 
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "1.0.8"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ocean-dynamo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Bengtson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-17 00:00:00.000000000 Z
11
+ date: 2015-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk