ocean-dynamo 1.2.4 → 1.3.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: eeab3b16bea7186a7a996113e1de39a7f9d21651
4
- data.tar.gz: 9bf14c5d5521673acb6637bd03885f02a7ec05e6
3
+ metadata.gz: 0e5d649565fd30bee32f1b8d80c7f6117009229e
4
+ data.tar.gz: e281cb72d49607d53e9ddd7053462f50c29b0604
5
5
  SHA512:
6
- metadata.gz: 71dd4bed657bb9fe67ec15f422f3007bbee26ed88bf5880bc2e569dafdf0a1726260b7d73eb0ec9598a3d7bc2565e9a9c0940aa875fbe268afa247d1a8df2de5
7
- data.tar.gz: 2558c9434f37ce7af79a34ced28eaf87f1257e6c0dbe7a0b8d2be6cab1d6966c8d345341b9ef0dbd2875b860d00cb85a3a55f47436882177fdb2177bb0f930a0
6
+ metadata.gz: cf608c59e414e273d9e13cf30070e3e2c3ba6ef79e343900b66d7fc1dbc08dd903332fe9297310fbebb5dbc1c9050957130178fe864dafc316ced76e397c629c
7
+ data.tar.gz: 708e7170927244786d84e20bc2b7ffc99206263d210f3fe4e73ee4306be3bb659b1383b01cb9631b91ef85c4d378a03947a28b3a4cb60f3f5dbbf896c99c34cf
@@ -40,16 +40,16 @@ with FactoryGirl.
40
40
 
41
41
  === Future milestones
42
42
 
43
- * Association proxies, to implement ActiveRecord-style method chaining, e.g.:
43
+ * Direct support for the DynamoDB JSON attribute types for arrays and hashes
44
+ * Collection proxies, to implement ActiveRecord-style method chaining, e.g.:
44
45
  <code>blog_entry.comments.build(body: "Cool!").save!</code>
45
46
  * The +has_and_belongs_to_many+ assocation.
46
- * A generator to install the <tt>config/aws.yml</tt> file.
47
47
 
48
48
 
49
49
  === Current use
50
50
 
51
51
  OceanDynamo is used as a central component in Ocean, a Rails framework and development
52
- pipeline for creating highly scalable HATEOAS microservice SOAs in the cloud.
52
+ pipeline for creating massively scalable HATEOAS microservice SOAs in the cloud.
53
53
  * http://wiki.oceanframework.net
54
54
 
55
55
  Ocean uses OceanDynamo to implement highly scalable job queues and authentication.
@@ -99,6 +99,8 @@ The following example shows the basic syntax for declaring a DynamoDB-based sche
99
99
  attribute :succeeded, :boolean, default: false
100
100
  attribute :failed, :boolean, default: false
101
101
  attribute :poison, :boolean, default: false
102
+
103
+ global_secondary_index :token, projection: :all
102
104
  end
103
105
 
104
106
  end
@@ -210,13 +212,9 @@ which means that secondary indices won't be necessary for the vast majority of
210
212
  DynamoDB tables. This ultimately means reduced operational costs, as well as
211
213
  reduced complexity.
212
214
 
213
- Nevertheless, as we now have switched to v2 of the DynamoDB API, we will be adding
214
- the possibility to define both local and secondary indices for Tables.
215
215
 
216
216
  == Secondary Indices
217
217
 
218
- We now have support for secondary indices.
219
-
220
218
  === Local Secondary Indices
221
219
 
222
220
  Up to five attributes can be declared as local secondary indices, in the following manner:
@@ -242,9 +240,9 @@ combination of keys. Secondary indices don't require the range key to be unique
242
240
  the same hash key. This means that secondary index searches always will return a
243
241
  collection.
244
242
 
245
- High-level support for local secondary indices is now available through
246
- +find_local_each+ and +find_local+. They take the same arguments; the former
247
- yields to a block for each item, the other returns all items in an array.
243
+ Local secondary indices are queried through +find_local_each+ and +find_local+.
244
+ They take the same arguments; the former yields to a block for each item,
245
+ the other returns all items in an array.
248
246
 
249
247
  The following finds all Authentications where +:username+ is "joe" and +:token+ is "quux":
250
248
 
@@ -259,9 +257,6 @@ The same thing but with the only the item with the highest token value:
259
257
  Authentication.find_local(:username, "joe", :token, ">=", "0",
260
258
  scan_index_forward: false, limit: 1)
261
259
 
262
- For more information, see the documentation for
263
- +find_local_each+ and +find_local+.
264
-
265
260
 
266
261
  === Global Secondary Indices
267
262
 
@@ -282,37 +277,34 @@ block:
282
277
  end
283
278
  end
284
279
 
285
- Each +global_secondary_index+ clause takes the following arguments:
280
+ Each +global_secondary_index+ clause (there can be a maximum of 5 per table) takes
281
+ the following arguments:
286
282
  * +hash_value+ (required),
287
283
  * +range_value+ (optional),
288
- * +:projection+ (default :keys_only, :all for all attributes)
284
+ * +:projection+ (default +:keys_only+, +:all+ for all attributes)
289
285
  * +:read_capacity_units+ (defaults to the table's read capacity, normally 10)
290
286
  * +:write_capacity_units+ (default to the table's write capacity, normally 5)
291
287
 
292
- High-level support for global secondary indices is now available through
293
- +find_global_each+ and +find_global+. They take the same arguments; the former
294
- yields to a block for each item, the other returns all items in an array.
288
+ Global secondary indices are queried through +find_global_each+ and +find_global+.
289
+ They take the same arguments; the former yields to a block for each item,
290
+ the other returns all items in an array.
295
291
 
296
- The following finds all Authentications whose +:token+ is "quux"
292
+ The following finds all Authentications whose +:token+ is +"quux"+:
297
293
 
298
294
  Authentication.find_global(:token, "quux")
299
295
 
300
- This retrieves all Authentications belonging to the user with the ID "dfstw-ruyhdf-ewijf",
296
+ This retrieves all Authentications belonging to the user with the ID +"dfstw-ruyhdf-ewijf"+,
301
297
  sorted in ascending order of the +:expires_at+ attribute:
302
298
 
303
299
  Authentication.find_global(:api_user_id, "dfstw-ruyhdf-ewijf",
304
300
  :expires_at, ">=", 0)
305
301
 
306
- To get the highest +:expires_at+ record, execute the following:
302
+ To get the highest +:expires_at+ record:
307
303
 
308
304
  Authentication.find_global(:api_user_id, "dfstw-ruyhdf-ewijf",
309
305
  :expires_at, ">=", 0,
310
306
  scan_index_forward: false, limit: 1)
311
307
 
312
- The combination of hash and range key must have been explicitly declared using
313
- +global_secondary_index+. For more information, see the documentation for
314
- +find_global_each+ and +find_global+.
315
-
316
308
 
317
309
  == Installation
318
310
 
@@ -335,8 +327,7 @@ to both the following locations in your project:
335
327
  config/aws.yml.example
336
328
  config/aws.yml
337
329
 
338
- Enter your AWS credentials in the latter file. Eventually, there
339
- will be a generator to copy these files for you, but for now you need to do it manually.
330
+ Enter your AWS credentials in the latter file.
340
331
 
341
332
 
342
333
  == Running the specs
@@ -1,13 +1,15 @@
1
1
  module OceanDynamo
2
2
  module Associations
3
+
3
4
  #
4
5
  # This is the root class of all Associations.
5
6
  # The class structure is exactly like in ActiveRecord:
6
7
  #
7
- # Association
8
- # CollectionAssociation
9
- # HasAndBelongsToManyAssociation
10
- # HasManyAssociation
8
+ # Associations
9
+ # Association
10
+ # CollectionAssociation
11
+ # HasAndBelongsToManyAssociation
12
+ # HasManyAssociation
11
13
  #
12
14
  # It should be noted, however, that the ActiveRecord documentation
13
15
  # is misleading: belongs_to and has_one no longer are implemented using
@@ -1,3 +1,13 @@
1
+ #
2
+ # The class structure is exactly like in ActiveRecord:
3
+ #
4
+ # Associations
5
+ # Association
6
+ # CollectionAssociation
7
+ # HasAndBelongsToManyAssociation
8
+ # HasManyAssociation
9
+ #
10
+
1
11
  module OceanDynamo
2
12
  module Associations
3
13
 
@@ -151,7 +151,7 @@ module OceanDynamo
151
151
  #
152
152
  def assert_range_key_not_specified! # :nodoc:
153
153
  raise RangeKeyMustNotBeSpecified,
154
- "Tables with belongs_to relations may not specify the range key" if table_range_key
154
+ "Tables with belongs_to relations may not specify a range key" if table_range_key
155
155
  end
156
156
 
157
157
 
@@ -1,15 +1,17 @@
1
1
  module OceanDynamo
2
2
  module Associations
3
+
3
4
  #
4
5
  # CollectionAssociation is an abstract class that provides common stuff to
5
6
  # ease the implementation of association proxies that represent
6
7
  # collections. See the class hierarchy in AssociationProxy.
7
8
  #
8
- # Association
9
- # CollectionAssociation:
10
- # HasAndBelongsToManyAssociation => has_and_belongs_to_many
11
- # HasManyAssociation => has_many
12
- # HasManyThroughAssociation + ThroughAssociation => has_many :through
9
+ # Associations
10
+ # Association
11
+ # CollectionAssociation:
12
+ # HasAndBelongsToManyAssociation => has_and_belongs_to_many
13
+ # HasManyAssociation => has_many
14
+ # HasManyThroughAssociation + ThroughAssociation => has_many :through
13
15
  #
14
16
  # CollectionAssociation class provides common methods to the collections
15
17
  # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
@@ -19,9 +19,8 @@ module OceanDynamo
19
19
  # <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
20
20
  # the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
21
21
  #
22
- # This class delegates unknown methods to <tt>@target</tt> NOT via
23
- # <tt>method_missing</tt> (as the ActiveRecord documentation falsely states),
24
- # but through explicit proxy methods for each separate operation.
22
+ # This class delegates unknown methods to <tt>@target</tt> through explicit
23
+ # proxy methods for each separate operation.
25
24
  #
26
25
  # The <tt>@target</tt> object is not \loaded until needed. As it turns out,
27
26
  # the key to this lazy loading scheme is <tt>to_ary</tt>.
@@ -19,11 +19,13 @@ module OceanDynamo
19
19
  # Defines a +has_many+ relation to a +belongs_to+ class.
20
20
  #
21
21
  # The +dependent:+ keyword arg may be +:destroy+, +:delete+ or +:nullify+
22
- # and have the same semantics as in ActiveRecord. With +:nullify+, however,
23
- # the hash key is set to the string "NULL" rather than binary NULL, as
24
- # DynamoDB doesn't permit storing empty fields.
22
+ # and have the same semantics as in ActiveRecord.
25
23
  #
26
- def has_many(children, dependent: :nullify) # :children
24
+ # Using +:nullify+ is a Bad Idea on DynamoDB, as it has to first read,
25
+ # then delete, and finally recreate each record. You should redesign your
26
+ # application to user either +:delete+ (the default) or +:destroy+ instead.
27
+ #
28
+ def has_many(children, dependent: :delete) # :children
27
29
  children_attr = children.to_s.underscore # "children"
28
30
  class_name = children_attr.classify # "Child"
29
31
  define_class_if_not_defined(class_name)
@@ -176,6 +178,10 @@ module OceanDynamo
176
178
  # into orphans. Note that we're not setting the key to NULL as this isn't possible
177
179
  # in DynamoDB. Instead, we're using the literal string "NULL".
178
180
  #
181
+ # Using +:nullify+ is a Bad Idea on DynamoDB, as it has to first read, then delete, and
182
+ # then recreate each record. You should redesign your application to user either
183
+ # +:delete? (the default) or +:destroy+ instead.
184
+ #
179
185
  def nullify_children(child_class)
180
186
  return if new_record?
181
187
  opts = condition_options(child_class)
@@ -12,7 +12,6 @@ module OceanDynamo
12
12
  # CollectionProxy (@association)
13
13
  #
14
14
  #
15
-
16
15
  class Relation
17
16
 
18
17
  attr_reader :klass
@@ -184,6 +184,7 @@ module OceanDynamo
184
184
  return true if value == "true"
185
185
  false
186
186
  when :datetime
187
+ return value.to_time(:utc) if value.is_a?(String)
187
188
  return nil if value == nil || !value.kind_of?(Time)
188
189
  value
189
190
  when :serialized
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "1.2.4"
2
+ VERSION = "1.3.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.2.4
4
+ version: 1.3.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-19 00:00:00.000000000 Z
11
+ date: 2015-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -28,30 +28,30 @@ dependencies:
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '4'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rails
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '4.0'
117
+ version: '4'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '4.0'
124
+ version: '4'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: ocean-rails
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -140,18 +140,18 @@ description: "== OceanDynamo\n\nAs one important use case for OceanDynamo is to
140
140
  the conversion of SQL\ndatabases to no-SQL DynamoDB databases, it is important that
141
141
  the syntax and semantics\nof OceanDynamo are as close as possible to those of ActiveRecord.
142
142
  This includes\ncallbacks, exceptions and method chaining semantics. OceanDynamo
143
- follows this pattern \nclosely and is of course based on ActiveModel.\n\nThe attribute
143
+ follows this pattern \nclosely and is of course based on ActiveModel.\n\n\nThe attribute
144
144
  and persistence layer of OceanDynamo is modeled on that of ActiveRecord:\nthere's
145
145
  +save+, +save!+, +create+, +update+, +update!+, +update_attributes+, +find_each+,\n+destroy_all+,
146
146
  +delete_all+, +read_attribute+, +write_attribute+ and all the other \nmethods you're
147
147
  used to. The design goal is always to implement as much of the ActiveRecord\ninterface
148
148
  as possible, without compromising scalability. This makes the task of switching
149
- \nfrom SQL to no-SQL much easier.\n\nOceanDynamo uses only primary indices to retrieve
150
- related table items and collections, \nwhich means it will scale without limits.\n\nOceanDynamo
151
- is fully usable as an ActiveModel and can be used by Rails\ncontrollers. Thanks
152
- to its structural similarity to ActiveRecord, OceanDynamo works \nwith FactoryGirl.\n\nSee
149
+ \nfrom SQL to no-SQL much easier.\n\n\nOceanDynamo uses only primary indices to
150
+ retrieve related table items and collections, \nwhich means it will scale without
151
+ limits.\n\n\nOceanDynamo is fully usable as an ActiveModel and can be used by Rails\ncontrollers.
152
+ Thanks to its structural similarity to ActiveRecord, OceanDynamo works \nwith FactoryGirl.\n\n\nSee
153
153
  also Ocean, a Rails framework for creating highly scalable SOAs in the cloud, in
154
- which\nocean-dynamo is used as a central component: http://wiki.oceanframework.net"
154
+ which\nocean-dynamo is used as a central component: http://wiki.oceanframework.net\n"
155
155
  email:
156
156
  - peter@peterbengtson.com
157
157
  executables: []