ocean-dynamo 0.3.3 → 0.3.4

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: 138288de7c56bfec0e6b855364e910db04068cb9
4
- data.tar.gz: 7d7777352fdd4fbd27b9bcc78cba18ce7e5f7343
3
+ metadata.gz: 8e2c646cd685be098d298f74ceab69c47f2902f9
4
+ data.tar.gz: 3739a76a1112bd433280cce959a2072c48ea33b6
5
5
  SHA512:
6
- metadata.gz: 6914457ba9a20640a814391b537d374b3654493c06fb455f054c200a0a4968a274c1acffc3d8e651ee6ba9ea7d74af45ca09287e997df10dc7190d7d1f68815f
7
- data.tar.gz: f8d8966879edc71173e31482a5cdbab7904b2eac1990549293c5ebc392501dedb4090a16f817cd7ab08034cd9cb3f2a6ead0ebe347384fef1e0e551d1e5c7237
6
+ metadata.gz: c60acec3262ac60b21834edbf0f83c2d6d4107e411e763eb870f2e1a40a711c950b98983f3913ada9a033f42aa6a7c703dd182b67668e041f169b1b216b893c9
7
+ data.tar.gz: 78b9983c8d189f1c9f755a301eeac0075c9252fc96590cd6f2d68f8407220113b943c2a871839f3801bff632ebb1724ceda5fa422838f62b6cf885a8671f36a2
data/README.rdoc CHANGED
@@ -30,7 +30,7 @@ from SQL to no-SQL much easier.
30
30
  Thanks to its structural similarity to ActiveRecord, OceanDynamo works with FactoryGirl.
31
31
  To facilitate testing, future versions will keep track of and delete instances after tests.
32
32
 
33
- OceanDynamo will use secondary indices to retrieve related table items,
33
+ OceanDynamo will use primary and secondary indices to retrieve related table items,
34
34
  which means it will scale without limits.
35
35
 
36
36
 
@@ -62,7 +62,7 @@ The following example shows the syntax.
62
62
 
63
63
  Each attribute has a name, a type (+:string+, +:integer+, +:float+, +:datetime+, +:boolean+,
64
64
  or +:serialized+) where +:string+ is the default. Each attribute also optionally has a default
65
- value, which can be a Proc. The hash key attribute is by default +:id+ (overridden as :uuid in
65
+ value, which can be a Proc. The hash key attribute is by default +:id+ (overridden as +:uuid+ in
66
66
  the example above) and is a +:string+. The keys can also be explicitly declared.
67
67
 
68
68
  The +:string+, +:integer+, +:float+ and +:datetime+ types can also store sets of their type.
@@ -96,9 +96,10 @@ controllers. Furthermore, OceanDynamo implements much of the infrastructure of A
96
96
  for instance, +read_attribute+, +write_attribute+, and much of the control logic and
97
97
  parameters.
98
98
 
99
- Relations are not yet implemented, but are underway. Relations will use secondary
99
+ Relations are not yet implemented, but are underway. Assocations will use secondary
100
100
  indices, up to the DynamoDB maximum of 5 secondary keys per table. At the moment,
101
- only find with a single uuid is implemented. Collections can not yet be obtained.
101
+ only find with a single id is implemented. Collections can not yet be obtained.
102
+ Work has begun on the +belongs_to+ association which requires only a primary index.
102
103
 
103
104
  OceanDynamo is currently used in the Ocean framework (http://wiki.oceanframework.net)
104
105
  e.g. to implement critical job queues. It will be used increasingly as features are
data/lib/ocean-dynamo.rb CHANGED
@@ -13,6 +13,7 @@ require "ocean-dynamo/callbacks"
13
13
  require "ocean-dynamo/attributes"
14
14
  require "ocean-dynamo/queries"
15
15
  require "ocean-dynamo/persistence"
16
+ require "ocean-dynamo/associations"
16
17
 
17
18
 
18
19
  module OceanDynamo
@@ -0,0 +1,51 @@
1
+ module OceanDynamo
2
+ class Base
3
+
4
+ def self.belongs_to(other_class)
5
+ klass = other_class.to_s.capitalize.constantize
6
+ other_class_attr = other_class.to_s.underscore
7
+ name = "#{other_class_attr}_id"
8
+ attribute name, :reference, default: nil, target_class: klass
9
+ attribute other_class_attr, :reference, default: nil, target_class: klass, no_save: true
10
+
11
+ self.class_eval "def #{other_class_attr}
12
+ read_and_maybe_load_pointer('#{name}')
13
+ end"
14
+
15
+ self.class_eval "def #{name}
16
+ read_pointer_id('#{name}')
17
+ end"
18
+
19
+ self.class_eval "def #{other_class_attr}=(value)
20
+ write_attribute('#{name}', value)
21
+ write_attribute('#{other_class_attr}', value)
22
+ end"
23
+
24
+ self.class_eval "def #{name}=(value)
25
+ write_attribute('#{name}', value)
26
+ write_attribute('#{other_class_attr}', value)
27
+ end"
28
+ # TODO: Additional "?" method for name
29
+ end
30
+
31
+
32
+ protected
33
+
34
+ def read_and_maybe_load_pointer(name) # :nodoc:
35
+ ptr = read_attribute(name)
36
+ return nil if ptr.blank?
37
+ if persisted? && ptr.is_a?(String)
38
+ write_attribute(name, fields[name][:target_class].find(ptr)) # Keep the instance we've just read
39
+ else
40
+ ptr
41
+ end
42
+ end
43
+
44
+ def read_pointer_id(name) # :nodoc:
45
+ ptr = read_attribute(name)
46
+ return nil if ptr.blank?
47
+ ptr.is_a?(String) ? ptr : ptr.id
48
+ end
49
+
50
+ end
51
+ end
@@ -101,6 +101,8 @@ module OceanDynamo
101
101
  def type_cast_attribute_for_write(name, value, metadata=fields[name],
102
102
  type: metadata[:type])
103
103
  case type
104
+ when :reference
105
+ return value
104
106
  when :string
105
107
  return nil if value == nil
106
108
  return value.collect(&:to_s) if value.is_a?(Array)
@@ -131,7 +133,7 @@ module OceanDynamo
131
133
 
132
134
 
133
135
  def serialized_attributes
134
- result = {}
136
+ result = Hash.new
135
137
  fields.each do |attribute, metadata|
136
138
  serialized = serialize_attribute(attribute, read_attribute(attribute), metadata)
137
139
  result[attribute] = serialized unless serialized == nil
@@ -141,11 +143,21 @@ module OceanDynamo
141
143
 
142
144
 
143
145
  def serialize_attribute(attribute, value, metadata=fields[attribute],
144
- type: metadata[:type])
146
+ target_class: metadata[:target_class],
147
+ type: metadata[:type],
148
+ no_save: metadata[:no_save]
149
+ )
145
150
  return nil if value == nil
146
151
  case type
152
+ when :reference
153
+ return nil if no_save
154
+ raise DynamoError, ":reference must always have a :target_class" unless target_class
155
+ return value if value.is_a?(String)
156
+ return value.id if value.is_a?(target_class)
157
+ raise AssociationTypeMismatch, "can't save a #{value.class} in a #{target_class} :reference"
147
158
  when :string
148
- ["", []].include?(value) ? nil : value
159
+ return nil if ["", []].include?(value)
160
+ value
149
161
  when :integer
150
162
  value == [] ? nil : value
151
163
  when :float
@@ -164,6 +176,8 @@ module OceanDynamo
164
176
 
165
177
  def deserialize_attribute(value, metadata, type: metadata[:type])
166
178
  case type
179
+ when :reference
180
+ return value
167
181
  when :string
168
182
  return "" if value == nil
169
183
  value.is_a?(Set) ? value.to_a : value
@@ -52,4 +52,6 @@ module OceanDynamo
52
52
 
53
53
  class MultiparameterAssignmentErrors < DynamoError; end
54
54
 
55
+ class AssociationTypeMismatch < DynamoError; end
56
+
55
57
  end
@@ -237,8 +237,9 @@ module OceanDynamo
237
237
 
238
238
  def _dynamo_read_attributes(consistent_read: false) # :nodoc:
239
239
  hash = _dynamo_read_raw_attributes(consistent_read)
240
- result = {}
240
+ result = Hash.new
241
241
  fields.each do |attribute, metadata|
242
+ next if metadata[:no_save]
242
243
  result[attribute] = deserialize_attribute(hash[attribute], metadata)
243
244
  end
244
245
  result
@@ -4,7 +4,7 @@ module OceanDynamo
4
4
  def self.find(hash, range=nil, consistent: false)
5
5
  _late_connect?
6
6
  item = dynamo_items[hash, range]
7
- raise RecordNotFound unless item.exists?
7
+ raise RecordNotFound, "can't find a #{self} with primary key ['#{hash}', #{range.inspect}]" unless item.exists?
8
8
  new.send(:dynamo_unpersist, item, consistent)
9
9
  end
10
10
 
@@ -61,10 +61,10 @@ module OceanDynamo
61
61
  end
62
62
 
63
63
 
64
- def self.attribute(name, type=:string, **pairs)
64
+ def self.attribute(name, type=:string, default: nil, **extra)
65
65
  raise DangerousAttributeError, "#{name} is defined by OceanDynamo" if self.dangerous_attributes.include?(name.to_s)
66
66
  attr_accessor name
67
- fields[name.to_s] = {type: type, default: pairs[:default]}
67
+ fields[name.to_s] = {type: type, default: default}.merge(extra)
68
68
  end
69
69
 
70
70
 
@@ -1,3 +1,3 @@
1
1
  module OceanDynamo
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
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.3.3
4
+ version: 0.3.4
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-13 00:00:00.000000000 Z
11
+ date: 2013-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -160,6 +160,7 @@ extensions: []
160
160
  extra_rdoc_files: []
161
161
  files:
162
162
  - config/routes.rb
163
+ - lib/ocean-dynamo/associations.rb
163
164
  - lib/ocean-dynamo/attributes.rb
164
165
  - lib/ocean-dynamo/base.rb
165
166
  - lib/ocean-dynamo/callbacks.rb