ocean-dynamo 0.4.1 → 0.4.2
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 +4 -4
- data/README.rdoc +24 -26
- data/lib/ocean-dynamo/{associations → active_record_stuff}/collection_proxy.rb +0 -0
- data/lib/ocean-dynamo/active_record_stuff/reflection.rb +583 -0
- data/lib/ocean-dynamo/active_record_stuff/relation.rb +653 -0
- data/lib/ocean-dynamo/associations/belongs_to.rb +33 -33
- data/lib/ocean-dynamo/associations/has_many.rb +4 -2
- data/lib/ocean-dynamo/exceptions.rb +9 -1
- data/lib/ocean-dynamo/persistence.rb +1 -0
- data/lib/ocean-dynamo/version.rb +1 -1
- metadata +20 -18
@@ -47,23 +47,40 @@ module OceanDynamo
|
|
47
47
|
|
48
48
|
# Define accessors for instances
|
49
49
|
self.class_eval "def #{target_attr}
|
50
|
-
|
50
|
+
@#{target_attr} ||= load_target_from_id('#{target_attr_id}')
|
51
51
|
end"
|
52
52
|
|
53
|
-
self.class_eval "def #{
|
54
|
-
|
55
|
-
@#{target_attr} = value
|
53
|
+
self.class_eval "def #{target_attr_id}
|
54
|
+
read_attribute('#{target_attr_id}')
|
56
55
|
end"
|
57
56
|
|
58
|
-
self.class_eval "def #{
|
59
|
-
|
57
|
+
self.class_eval "def #{target_attr}=(value)
|
58
|
+
if !value
|
59
|
+
target_id = nil
|
60
|
+
target = nil
|
61
|
+
elsif !value.kind_of?(#{target_class})
|
62
|
+
raise AssociationTypeMismatch, \"can't save a #\{value.class\} in a #{target_class} foreign key\"
|
63
|
+
else
|
64
|
+
target_id = value.hash_key
|
65
|
+
target = value
|
66
|
+
end
|
67
|
+
write_attribute('#{target_attr_id}', target_id)
|
68
|
+
@#{target_attr} = target
|
69
|
+
value
|
60
70
|
end"
|
61
71
|
|
62
72
|
self.class_eval "def #{target_attr_id}=(value)
|
63
|
-
|
64
|
-
|
73
|
+
if !value
|
74
|
+
target_id = nil
|
75
|
+
elsif value.is_a?(String)
|
76
|
+
target_id = value
|
77
|
+
else
|
78
|
+
raise AssociationTypeMismatch, 'Foreign key #{target_attr_id} must be nil or a string'
|
79
|
+
end
|
80
|
+
write_attribute('#{target_attr_id}', target_id)
|
81
|
+
@#{target_attr} = nil
|
82
|
+
value
|
65
83
|
end"
|
66
|
-
# TODO: "?" methods
|
67
84
|
end
|
68
85
|
|
69
86
|
|
@@ -121,40 +138,23 @@ module OceanDynamo
|
|
121
138
|
end
|
122
139
|
|
123
140
|
|
124
|
-
protected
|
125
|
-
|
126
141
|
#
|
127
142
|
# This is run by #initialize and by #assign_attributes to set the
|
128
|
-
# association variables (@master, for instance) and
|
129
|
-
# (such as master_id)
|
130
|
-
# the double storage when association proxies are introduced.
|
143
|
+
# association instance variables (@master, for instance) and their associated
|
144
|
+
# attributes (such as master_id) from a given value.
|
131
145
|
#
|
132
146
|
def set_belongs_to_association(attrs) # :nodoc:
|
133
147
|
parent_class = self.class.belongs_to_class
|
134
148
|
return unless parent_class
|
135
149
|
parent_class = parent_class.to_s.underscore.to_sym
|
136
|
-
if attrs && attrs.include?(parent_class)
|
137
|
-
instance_variable_set("@#{parent_class}", attrs[parent_class])
|
138
|
-
write_attribute("#{parent_class}_id", attrs[parent_class])
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
|
143
|
-
def read_and_maybe_load_pointer(name) # :nodoc:
|
144
|
-
ptr = read_attribute(name)
|
145
|
-
return nil if ptr.blank?
|
146
|
-
if persisted? && ptr.is_a?(String)
|
147
|
-
parent = fields[name][:target_class].find(ptr, consistent: true) # TODO: true?
|
148
|
-
write_attribute(name, parent) # Keep the instance we've just read
|
149
|
-
else
|
150
|
-
ptr
|
151
|
-
end
|
150
|
+
send("#{parent_class}=", attrs[parent_class]) if attrs && attrs.include?(parent_class)
|
152
151
|
end
|
153
152
|
|
154
153
|
|
155
|
-
def
|
156
|
-
|
157
|
-
|
154
|
+
def load_target_from_id(name) # :nodoc:
|
155
|
+
v = read_attribute(name)
|
156
|
+
return nil unless v
|
157
|
+
fields[name][:target_class].find(v, consistent: true)
|
158
158
|
end
|
159
159
|
|
160
160
|
end
|
@@ -22,8 +22,10 @@ module OceanDynamo
|
|
22
22
|
children_attr = children.to_s.underscore # "children"
|
23
23
|
child_class = children_attr.singularize.camelize.constantize # Child
|
24
24
|
register_relation(child_class, :has_many)
|
25
|
+
attr_accessor children_attr
|
25
26
|
# Define accessors for instances
|
26
|
-
self.class_eval "def #{children_attr}
|
27
|
+
self.class_eval "def #{children_attr}(force_reload=false)
|
28
|
+
@#{children_attr} = false if force_reload
|
27
29
|
@#{children_attr} ||= read_children(#{child_class})
|
28
30
|
end"
|
29
31
|
self.class_eval "def #{children_attr}=(value)
|
@@ -110,7 +112,7 @@ module OceanDynamo
|
|
110
112
|
# Destroy all children not in the new set (this is not yet scalable)
|
111
113
|
read_children(klass).each do |c|
|
112
114
|
next if new_children.include?(c)
|
113
|
-
c.
|
115
|
+
c.destroy
|
114
116
|
end
|
115
117
|
end
|
116
118
|
|
@@ -48,7 +48,15 @@ module OceanDynamo
|
|
48
48
|
|
49
49
|
class UnknownAttributeError < NoMethodError; end
|
50
50
|
|
51
|
-
class AttributeAssignmentError < DynamoError
|
51
|
+
class AttributeAssignmentError < DynamoError
|
52
|
+
attr_reader :exception, :attribute
|
53
|
+
def initialize(message, exception, attribute)
|
54
|
+
super(message)
|
55
|
+
@exception = exception
|
56
|
+
@attribute = attribute
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
52
60
|
|
53
61
|
class MultiparameterAssignmentErrors < DynamoError; end
|
54
62
|
|
@@ -327,6 +327,7 @@ module OceanDynamo
|
|
327
327
|
when :reference
|
328
328
|
raise DynamoError, ":reference must always have a :target_class" unless target_class
|
329
329
|
return value if value.is_a?(String)
|
330
|
+
# The next two lines should be superfluous now
|
330
331
|
return value.id if value.kind_of?(target_class)
|
331
332
|
raise AssociationTypeMismatch, "can't save a #{value.class} in a #{target_class} :reference"
|
332
333
|
when :string
|
data/lib/ocean-dynamo/version.rb
CHANGED
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
|
+
version: 0.4.2
|
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-
|
11
|
+
date: 2013-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -138,21 +138,21 @@ dependencies:
|
|
138
138
|
version: 0.1.3
|
139
139
|
description: "== OceanDynamo\n\nOceanDynamo is a massively scalable Amazon DynamoDB
|
140
140
|
near drop-in replacement for \nActiveRecord.\n\nAs one important use case for OceanDynamo
|
141
|
-
is to facilitate the conversion of SQL
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
+
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
141
|
+
is to facilitate the conversion of SQL\ndatabases to no-SQL DynamoDB databases,
|
142
|
+
it is important that the syntax and semantics\nof OceanDynamo are as close as possible
|
143
|
+
to those of ActiveRecord. This includes\ncallbacks, exceptions and method chaining
|
144
|
+
semantics. OceanDynamo follows this pattern \nclosely and is of course based on
|
145
|
+
ActiveModel.\n\nThe attribute and persistence layer of OceanDynamo is modeled on
|
146
|
+
that of ActiveRecord:\nthere's +save+, +save!+, +create+, +update+, +update!+, +update_attributes+,
|
147
|
+
+find_each+,\n+destroy_all+, +delete_all+ and all the other methods you're used
|
148
|
+
to. The design goal \nis always to implement as much of the ActiveRecord interface
|
149
|
+
as possible, without \ncompromising scalability. This makes the task of switching
|
150
|
+
from SQL to no-SQL much easier.\n\nThanks to its structural similarity to ActiveRecord,
|
151
|
+
OceanDynamo works with FactoryGirl.\nTo facilitate testing, future versions will
|
152
|
+
keep track of and delete instances after tests.\n\nOceanDynamo uses primary indices
|
153
|
+
to retrieve related table items, \nwhich means it will scale without limits.\n\nSee
|
154
|
+
also Ocean, a Rails framework for creating highly scalable SOAs in the cloud, in
|
155
|
+
which\nocean-dynamo is used as a central component: http://wiki.oceanframework.net"
|
156
156
|
email:
|
157
157
|
- peter@peterbengtson.com
|
158
158
|
executables: []
|
@@ -160,9 +160,11 @@ extensions: []
|
|
160
160
|
extra_rdoc_files: []
|
161
161
|
files:
|
162
162
|
- config/routes.rb
|
163
|
+
- lib/ocean-dynamo/active_record_stuff/collection_proxy.rb
|
164
|
+
- lib/ocean-dynamo/active_record_stuff/reflection.rb
|
165
|
+
- lib/ocean-dynamo/active_record_stuff/relation.rb
|
163
166
|
- lib/ocean-dynamo/associations/associations.rb
|
164
167
|
- lib/ocean-dynamo/associations/belongs_to.rb
|
165
|
-
- lib/ocean-dynamo/associations/collection_proxy.rb
|
166
168
|
- lib/ocean-dynamo/associations/has_many.rb
|
167
169
|
- lib/ocean-dynamo/attributes.rb
|
168
170
|
- lib/ocean-dynamo/basal.rb
|