ocean-dynamo 0.4.4 → 0.5.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: 3dc795167d56cef7e557c8f233b0e6e2fe3a205a
4
- data.tar.gz: 4979ca24a5937658f00a325981dec200a81f0263
3
+ metadata.gz: f06f0f651adf9199dd190cedd203390528548a1f
4
+ data.tar.gz: 1082719f92e830ef6e60658b77048719cfaed6b1
5
5
  SHA512:
6
- metadata.gz: 4796a5bb3c5b216a96b10c9955ec6815ce676e869c7ec6367bb4534bb8f8f349535f96c77308dcaa18a49a786bdcfff631321787a01079bc356aa9f106a6d911
7
- data.tar.gz: 132101d4bb782d609c75e912a658f19ba423f455e2be2b2bad4d4a720ddc7f45aee1c1ded129bb6713026af0ada9703b14f0539804d4a7dede8d9eb4d478ae99
6
+ metadata.gz: 67d5231c8cef81f6b566c4e9a1f630c32dc510289a5fe3d27a05cb2a83a4bf5f31db1df13b16a6369e7482351dbbf87470d4bb8fa859710eae6290d050701ec5
7
+ data.tar.gz: b529ee10710b85465e3b82668268ed5c78226b83a2a3619f54c213492ebf4d8aa334b0344fefb960548db84e536dd92e8f614da51592a7849405e0f758402ccc
@@ -94,28 +94,37 @@ value will return the empty string, <tt>""</tt>.
94
94
 
95
95
  ==== Example
96
96
 
97
- The following example shows how to set up a +has_many+ / +belongs_to+ relation:
98
-
99
- class Child < OceanDynamo::Table; end
97
+ The following example shows how to set up +has_many+ / +belongs_to+ relations:
100
98
 
101
- class Parent < OceanDynamo::Table
99
+ class Forum < OceanDynamo::Table
102
100
  dynamo_schema do
103
- attribute :this
104
- attribute :that
105
- attribute :the_other
101
+ attribute :name
102
+ attribute :description
106
103
  end
107
- has_many :children, dependent: :destroy
104
+ has_many :topics, dependent: :destroy
108
105
  end
109
106
 
110
107
 
111
- class Child < OceanDynamo::Table
108
+ class Topic < OceanDynamo::Table
112
109
  dynamo_schema(:uuid) do
113
- attribute :foo
114
- attribute :bar
115
- attribute :baz
110
+ attribute :title
116
111
  end
117
- belongs_to :parent
112
+ belongs_to :forum
113
+ has_many :posts, dependent: :destroy
118
114
  end
115
+
116
+
117
+ class Post < OceanDynamo::Table
118
+ dynamo_schema(:uuid) do
119
+ attribute :body
120
+ end
121
+ belongs_to :topic, composite_key: true
122
+ end
123
+
124
+ The only non-standard aspect of the above is <tt>composite_key: true</tt>, which
125
+ is required as the Topic class itself has a +belongs_to+ relation and thus has
126
+ a composite key. This must be declared in the child class as it needs to know
127
+ how to retrieve its parent.
119
128
 
120
129
  ==== Restrictions
121
130
 
@@ -126,7 +135,6 @@ Restrictions for +belongs_to+ tables:
126
135
  * +belongs_to+ must be placed after the +dynamo_schema+ attribute block.
127
136
 
128
137
  Restrictions for +has_many+ tables:
129
- * The +has_many+ table may not have a range key.
130
138
  * +has_many+ must be placed after the +dynamo_schema+ attribute block.
131
139
 
132
140
  These restrictions allow OceanDynamo to implement the +has_many+ / +belongs_to+
@@ -162,10 +170,8 @@ controllers. OceanDynamo implements much of the infrastructure of ActiveRecord;
162
170
  for instance, +read_attribute+, +write_attribute+, and much of the control logic and
163
171
  internal organisation.
164
172
 
165
- * The +dependent:+ keyword arg may now be +:destroy+, +:delete+ or +:nullify+
166
- with the same semantics as in ActiveRecord. With +:nullify+, however,
167
- the hash key is set to the string "NULL" rather than binary NULL, as
168
- DynamoDB doesn't permit storing empty fields.
173
+ * +has_many+ can now be nested in multiple layers through the use of +:composite_key+
174
+ in +belongs_to+. See the documentation for +belongs_to+.
169
175
 
170
176
  === Future milestones
171
177
 
@@ -52,6 +52,11 @@ module OceanDynamo
52
52
  super
53
53
  end
54
54
 
55
+
56
+ def define_class_if_not_defined(class_name)
57
+ Object.const_set(class_name, Class.new(OceanDynamo::Table)) unless const_defined?(class_name)
58
+ end
59
+
55
60
  end
56
61
 
57
62
 
@@ -15,12 +15,46 @@ module OceanDynamo
15
15
  module ClassMethods
16
16
 
17
17
  #
18
- # Class macro to define the +belongs_to+ relation.
18
+ # Class macro to define the +belongs_to+ relation. For example:
19
19
  #
20
- def belongs_to(target) # :master, "master", Master
20
+ # class Forum < OceanDynamo::Table
21
+ # dynamo_schema do
22
+ # attribute :name
23
+ # attribute :description
24
+ # end
25
+ # has_many :topics, dependent: :destroy
26
+ # end
27
+ #
28
+ # class Topic < OceanDynamo::Table
29
+ # dynamo_schema(:uuid) do
30
+ # attribute :title
31
+ # end
32
+ # belongs_to :forum
33
+ # has_many :posts, dependent: :destroy
34
+ # end
35
+ #
36
+ # class Post < OceanDynamo::Table
37
+ # dynamo_schema(:uuid) do
38
+ # attribute :body
39
+ # end
40
+ # belongs_to :topic, composite_key: true
41
+ # end
42
+ #
43
+ # The only non-standard aspect of the above is <tt>composite_key: true</tt>,
44
+ # which is required as the Topic class itself has a +belongs_to+ relation and
45
+ # thus has a composite key. This must be declared in the child class as it
46
+ # needs to know how to retrieve its parent. If you were to add a Comment class
47
+ # to the above with a <tt>has_many/belongs_to</tt> relation to Post, the Comment
48
+ # class would also have a <tt>belongs_to :post, composite_key: true</tt> statement,
49
+ # since Post already has a composite key due to its +belongs_to+ relation to
50
+ # the Topic class.
51
+ #
52
+ def belongs_to(target, composite_key: false) # :master, "master", Master
21
53
  target_attr = target.to_s.underscore # "master"
22
54
  target_attr_id = "#{target_attr}_id" # "master_id"
23
- target_class = target_attr.camelize.constantize # Master
55
+ class_name = target_attr.classify # "Master"
56
+ define_class_if_not_defined(class_name)
57
+ target_class = class_name.constantize # Master
24
58
 
25
59
  assert_only_one_belongs_to!
26
60
 
@@ -47,7 +81,7 @@ module OceanDynamo
47
81
 
48
82
  # Define accessors for instances
49
83
  self.class_eval "def #{target_attr}
50
- @#{target_attr} ||= load_target_from_id('#{target_attr_id}')
84
+ @#{target_attr} ||= load_target_from_id('#{target_attr_id}', #{composite_key})
51
85
  end"
52
86
 
53
87
  self.class_eval "def #{target_attr_id}
@@ -55,7 +89,7 @@ module OceanDynamo
55
89
  end"
56
90
 
57
91
  self.class_eval "def #{target_attr}=(value)
58
- target, target_id = type_check_target(#{target_class}, value)
92
+ target, target_id = type_check_target(#{target_class}, value, #{composite_key})
59
93
  write_attribute('#{target_attr_id}', target_id)
60
94
  @#{target_attr} = target
61
95
  value
@@ -118,11 +152,6 @@ module OceanDynamo
118
152
  # Instance variables and methods
119
153
  #
120
154
  # ---------------------------------------------------------
121
- # def initialize(attrs={})
122
- # super
123
- # end
124
-
125
-
126
155
 
127
156
  #
128
157
  # This is run by #initialize and by #assign_attributes to set the
@@ -138,10 +167,11 @@ module OceanDynamo
138
167
  end
139
168
 
140
169
 
141
- def load_target_from_id(name) # :nodoc:
170
+ def load_target_from_id(name, composite_key) # :nodoc:
142
171
  v = read_attribute(name)
143
172
  return nil unless v
144
- fields[name][:target_class].find(v, consistent: true)
173
+ h, r = composite_key ? v.split(':') : v
174
+ fields[name][:target_class].find(h, r, consistent: true)
145
175
  end
146
176
 
147
177
 
@@ -152,10 +182,15 @@ module OceanDynamo
152
182
  end
153
183
 
154
184
 
155
- def type_check_target(target_class, value)
185
+ def type_check_target(target_class, value, composite_key)
156
186
  return nil unless value
157
- return [value, value.hash_key] if value.kind_of?(target_class)
158
- raise AssociationTypeMismatch, "can't save a #{value.class} in a #{target_class} foreign key"
187
+ if value.kind_of?(target_class)
188
+ foreign_key = value.hash_key
189
+ foreign_key += ':' + value.range_key if composite_key
190
+ return [value, foreign_key]
191
+ else
192
+ raise AssociationTypeMismatch, "can't save a #{value.class} in a #{target_class} foreign key"
193
+ end
159
194
  end
160
195
 
161
196
  end
@@ -16,16 +16,18 @@ module OceanDynamo
16
16
 
17
17
 
18
18
  #
19
- # Defines a has_many relation to a belongs_to class.
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
22
  # and have the same semantics as in ActiveRecord. With +:nullify+, however,
23
23
  # the hash key is set to the string "NULL" rather than binary NULL, as
24
24
  # DynamoDB doesn't permit storing empty fields.
25
25
  #
26
- def has_many(children, dependent: :nullify) # :children
27
- children_attr = children.to_s.underscore # "children"
28
- child_class = children_attr.singularize.camelize.constantize # Child
26
+ def has_many(children, dependent: :nullify) # :children
27
+ children_attr = children.to_s.underscore # "children"
28
+ class_name = children_attr.classify # "Child"
29
+ define_class_if_not_defined(class_name)
30
+ child_class = class_name.constantize # Child
29
31
  register_relation(child_class, :has_many)
30
32
 
31
33
  # Handle children= after create and update
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "0.4.4"
2
+ VERSION = "0.5.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: 0.4.4
4
+ version: 0.5.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: 2013-09-30 00:00:00.000000000 Z
11
+ date: 2013-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk