gom 0.2.0 → 0.3.0
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.
- data/README.rdoc +15 -0
- data/Rakefile +1 -1
- data/lib/gom.rb +1 -0
- data/lib/gom/object.rb +15 -19
- data/lib/gom/object/builder.rb +35 -33
- data/lib/gom/object/cached_builder.rb +23 -31
- data/lib/gom/object/collection.rb +49 -57
- data/lib/gom/object/draft.rb +17 -25
- data/lib/gom/object/id.rb +14 -22
- data/lib/gom/object/inspector.rb +46 -54
- data/lib/gom/object/mapping.rb +31 -47
- data/lib/gom/object/proxy.rb +25 -33
- data/lib/gom/spec.rb +11 -0
- data/lib/gom/spec/acceptance/adapter_that_needs_setup.rb +58 -0
- data/lib/gom/spec/acceptance/adapter_with_stateful_storage.rb +19 -21
- data/lib/gom/spec/acceptance/read_only_adapter_with_stateless_storage.rb +9 -8
- data/lib/gom/spec/object.rb +8 -0
- data/lib/gom/storage.rb +30 -26
- data/lib/gom/storage/adapter.rb +26 -43
- data/lib/gom/storage/configuration.rb +75 -68
- data/lib/gom/storage/configuration/view.rb +3 -16
- data/lib/gom/storage/configuration/view/class.rb +5 -22
- data/lib/gom/storage/configuration/view/map_reduce.rb +7 -24
- data/lib/gom/storage/fetcher.rb +24 -32
- data/lib/gom/storage/remover.rb +27 -35
- data/lib/gom/storage/saver.rb +35 -43
- data/spec/acceptance/adapter_spec.rb +16 -4
- data/spec/acceptance/fake_adapter_spec.rb +11 -0
- data/spec/acceptance/object_spec.rb +4 -1
- data/spec/fake_adapter.rb +12 -3
- data/spec/lib/gom/object/builder_spec.rb +5 -5
- data/spec/lib/gom/object/inspector_spec.rb +5 -9
- data/spec/lib/gom/object/mapping_spec.rb +27 -57
- data/spec/lib/gom/storage/adapter_spec.rb +1 -1
- data/spec/lib/gom/storage/configuration_spec.rb +33 -3
- data/spec/lib/gom/storage_spec.rb +19 -0
- metadata +50 -46
data/lib/gom/object/inspector.rb
CHANGED
@@ -1,69 +1,61 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
# Inspect an object and returns it's class and it's properties
|
3
|
+
class GOM::Object::Inspector
|
3
4
|
|
4
|
-
|
5
|
+
attr_accessor :object
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
attr_accessor :object
|
10
|
-
|
11
|
-
def initialize(object)
|
12
|
-
@object = object
|
13
|
-
end
|
14
|
-
|
15
|
-
def draft
|
16
|
-
initialize_draft
|
17
|
-
set_class
|
18
|
-
set_properties
|
19
|
-
set_relations
|
20
|
-
@draft
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def initialize_draft
|
26
|
-
@draft = Draft.new
|
27
|
-
end
|
7
|
+
def initialize(object)
|
8
|
+
@object = object
|
9
|
+
end
|
28
10
|
|
29
|
-
|
30
|
-
|
31
|
-
|
11
|
+
def draft
|
12
|
+
initialize_draft
|
13
|
+
set_class
|
14
|
+
set_properties
|
15
|
+
set_relations
|
16
|
+
@draft
|
17
|
+
end
|
32
18
|
|
33
|
-
|
34
|
-
properties = { }
|
35
|
-
read_instance_variables do |key, value|
|
36
|
-
properties[key] = value if self.class.property_value?(value)
|
37
|
-
end
|
38
|
-
@draft.properties = properties
|
39
|
-
end
|
19
|
+
private
|
40
20
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
relations[key] = value if self.class.relation_value?(value)
|
45
|
-
end
|
46
|
-
@draft.relations = relations
|
47
|
-
end
|
21
|
+
def initialize_draft
|
22
|
+
@draft = GOM::Object::Draft.new
|
23
|
+
end
|
48
24
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
value = @object.instance_variable_get name
|
53
|
-
yield key, value
|
54
|
-
end
|
55
|
-
end
|
25
|
+
def set_class
|
26
|
+
@draft.class_name = @object.class.to_s
|
27
|
+
end
|
56
28
|
|
57
|
-
|
58
|
-
|
59
|
-
|
29
|
+
def set_properties
|
30
|
+
properties = { }
|
31
|
+
read_instance_variables do |key, value|
|
32
|
+
properties[key] = value if self.class.property_value?(value)
|
33
|
+
end
|
34
|
+
@draft.properties = properties
|
35
|
+
end
|
60
36
|
|
61
|
-
|
62
|
-
|
63
|
-
|
37
|
+
def set_relations
|
38
|
+
relations = { }
|
39
|
+
read_instance_variables do |key, value|
|
40
|
+
relations[key] = value if self.class.relation_value?(value)
|
41
|
+
end
|
42
|
+
@draft.relations = relations
|
43
|
+
end
|
64
44
|
|
45
|
+
def read_instance_variables
|
46
|
+
@object.instance_variables.each do |name|
|
47
|
+
key = name.to_s.sub(/^@/, "").to_sym
|
48
|
+
value = @object.instance_variable_get name
|
49
|
+
yield key, value
|
65
50
|
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.property_value?(value)
|
54
|
+
!relation_value?(value)
|
55
|
+
end
|
66
56
|
|
57
|
+
def self.relation_value?(value)
|
58
|
+
value.is_a?(GOM::Object::Proxy)
|
67
59
|
end
|
68
60
|
|
69
61
|
end
|
data/lib/gom/object/mapping.rb
CHANGED
@@ -1,61 +1,45 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
# Provides a mapping between objects and ids
|
3
|
+
class GOM::Object::Mapping
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class Mapping
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@map = { }
|
11
|
-
end
|
12
|
-
|
13
|
-
def put(object, id)
|
14
|
-
@map[object] = id
|
15
|
-
end
|
16
|
-
|
17
|
-
def object_by_id(id)
|
18
|
-
@map.respond_to?(:key) ? @map.key(id) : @map.index(id)
|
19
|
-
end
|
20
|
-
|
21
|
-
def id_by_object(object)
|
22
|
-
@map[object]
|
23
|
-
end
|
24
|
-
|
25
|
-
def remove_by_id(id)
|
26
|
-
@map.delete object_by_id(id)
|
27
|
-
end
|
5
|
+
def initialize
|
6
|
+
@map = { }
|
7
|
+
end
|
28
8
|
|
29
|
-
|
30
|
-
|
31
|
-
|
9
|
+
def put(object, id)
|
10
|
+
@map[object] = id
|
11
|
+
end
|
32
12
|
|
33
|
-
|
34
|
-
|
35
|
-
|
13
|
+
def object_by_id(id)
|
14
|
+
@map.respond_to?(:key) ? @map.key(id) : @map.index(id)
|
15
|
+
end
|
36
16
|
|
37
|
-
|
38
|
-
|
39
|
-
|
17
|
+
def id_by_object(object)
|
18
|
+
@map[object]
|
19
|
+
end
|
40
20
|
|
41
|
-
|
42
|
-
|
43
|
-
|
21
|
+
def remove_by_id(id)
|
22
|
+
@map.delete object_by_id(id)
|
23
|
+
end
|
44
24
|
|
45
|
-
|
46
|
-
|
47
|
-
|
25
|
+
def remove_by_object(object)
|
26
|
+
@map.delete object
|
27
|
+
end
|
48
28
|
|
49
|
-
|
50
|
-
|
51
|
-
|
29
|
+
def size
|
30
|
+
@map.size
|
31
|
+
end
|
52
32
|
|
53
|
-
|
54
|
-
|
55
|
-
|
33
|
+
def clear!
|
34
|
+
@map.clear
|
35
|
+
end
|
56
36
|
|
57
|
-
|
37
|
+
def self.singleton
|
38
|
+
@mapping ||= self.new
|
39
|
+
end
|
58
40
|
|
41
|
+
def self.method_missing(method_name, *arguments, &block)
|
42
|
+
self.singleton.send method_name, *arguments, &block
|
59
43
|
end
|
60
44
|
|
61
45
|
end
|
data/lib/gom/object/proxy.rb
CHANGED
@@ -1,44 +1,36 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
# The proxy that fetches an object if it's needed and simply passes method calls to it.
|
3
|
+
class GOM::Object::Proxy
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(object_or_id)
|
10
|
-
@object, @id = object_or_id.is_a?(GOM::Object::Id) ?
|
11
|
-
[ nil, object_or_id ] :
|
12
|
-
[ object_or_id, nil ]
|
13
|
-
end
|
14
|
-
|
15
|
-
def object
|
16
|
-
fetch_object unless @object
|
17
|
-
@object
|
18
|
-
end
|
19
|
-
|
20
|
-
def id
|
21
|
-
fetch_id unless @id
|
22
|
-
@id
|
23
|
-
end
|
5
|
+
def initialize(object_or_id)
|
6
|
+
@object, @id = object_or_id.is_a?(GOM::Object::Id) ?
|
7
|
+
[ nil, object_or_id ] :
|
8
|
+
[ object_or_id, nil ]
|
9
|
+
end
|
24
10
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
11
|
+
def object
|
12
|
+
fetch_object unless @object
|
13
|
+
@object
|
14
|
+
end
|
29
15
|
|
30
|
-
|
16
|
+
def id
|
17
|
+
fetch_id unless @id
|
18
|
+
@id
|
19
|
+
end
|
31
20
|
|
32
|
-
|
33
|
-
|
34
|
-
|
21
|
+
def method_missing(method_name, *arguments, &block)
|
22
|
+
fetch_object unless @object
|
23
|
+
@object.send method_name, *arguments, &block
|
24
|
+
end
|
35
25
|
|
36
|
-
|
37
|
-
@id = GOM::Object::Mapping.id_by_object @object
|
38
|
-
end
|
26
|
+
private
|
39
27
|
|
40
|
-
|
28
|
+
def fetch_object
|
29
|
+
@object = GOM::Storage::Fetcher.new(@id).object
|
30
|
+
end
|
41
31
|
|
32
|
+
def fetch_id
|
33
|
+
@id = GOM::Object::Mapping.id_by_object @object
|
42
34
|
end
|
43
35
|
|
44
36
|
end
|
data/lib/gom/spec.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
|
3
|
+
require File.join(File.dirname(__FILE__), "spec", "acceptance", "adapter_that_needs_setup")
|
3
4
|
require File.join(File.dirname(__FILE__), "spec", "acceptance", "adapter_with_stateful_storage")
|
4
5
|
require File.join(File.dirname(__FILE__), "spec", "acceptance", "read_only_adapter_with_stateless_storage")
|
6
|
+
|
7
|
+
module GOM
|
8
|
+
|
9
|
+
module Spec
|
10
|
+
|
11
|
+
autoload :Object, File.join(File.dirname(__FILE__), "spec", "object")
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
shared_examples_for "an adapter that needs setup" do
|
3
|
+
|
4
|
+
before :each do
|
5
|
+
GOM::Storage.teardown
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "fetching an object" do
|
9
|
+
|
10
|
+
it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
|
11
|
+
lambda do
|
12
|
+
GOM::Storage.fetch "test_storage:object_1"
|
13
|
+
end.should raise_error(GOM::Storage::Adapter::NoSetupError)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "storing an object" do
|
19
|
+
|
20
|
+
it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
|
21
|
+
lambda do
|
22
|
+
GOM::Storage.store :object
|
23
|
+
end.should raise_error(GOM::Storage::Adapter::NoSetupError)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "removing an object" do
|
29
|
+
|
30
|
+
it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
|
31
|
+
lambda do
|
32
|
+
GOM::Storage.remove "test_storage:object_1"
|
33
|
+
end.should raise_error(GOM::Storage::Adapter::NoSetupError)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "fetching a class collection" do
|
39
|
+
|
40
|
+
it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
|
41
|
+
lambda do
|
42
|
+
GOM::Storage.collection :test_storage, :test_object_class_view
|
43
|
+
end.should raise_error(GOM::Storage::Adapter::NoSetupError)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "fetching a map collection" do
|
49
|
+
|
50
|
+
it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
|
51
|
+
lambda do
|
52
|
+
GOM::Storage.collection :test_storage, :test_map_view
|
53
|
+
end.should raise_error(GOM::Storage::Adapter::NoSetupError)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -5,20 +5,24 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
5
5
|
GOM::Storage.setup
|
6
6
|
end
|
7
7
|
|
8
|
+
after :all do
|
9
|
+
GOM::Storage.teardown
|
10
|
+
end
|
11
|
+
|
8
12
|
before :each do
|
9
|
-
@related_object = Object.new
|
10
|
-
@related_object.
|
13
|
+
@related_object = GOM::Spec::Object.new
|
14
|
+
@related_object.number = 16
|
11
15
|
|
12
|
-
@object = Object.new
|
13
|
-
@object.
|
14
|
-
@object.
|
16
|
+
@object = GOM::Spec::Object.new
|
17
|
+
@object.number = 11
|
18
|
+
@object.related_object = GOM::Object.reference @related_object
|
15
19
|
end
|
16
20
|
|
17
21
|
describe "fetching an object" do
|
18
22
|
|
19
23
|
before :each do
|
20
24
|
GOM::Storage.store @object, :test_storage
|
21
|
-
@id = GOM::Object.id
|
25
|
+
@id = GOM::Object.id @object
|
22
26
|
|
23
27
|
@object = GOM::Storage.fetch @id
|
24
28
|
end
|
@@ -29,11 +33,11 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
29
33
|
end
|
30
34
|
|
31
35
|
it "should return an object of the correct class" do
|
32
|
-
@object.class.should == Object
|
36
|
+
@object.class.should == GOM::Spec::Object
|
33
37
|
end
|
34
38
|
|
35
39
|
it "should set the object's instance variables" do
|
36
|
-
@object.
|
40
|
+
@object.number.should == 11
|
37
41
|
end
|
38
42
|
|
39
43
|
it "should assign an object id" do
|
@@ -41,9 +45,9 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
41
45
|
end
|
42
46
|
|
43
47
|
it "should also fetch the related object" do
|
44
|
-
related_object_proxy = @object.
|
48
|
+
related_object_proxy = @object.related_object
|
45
49
|
related_object_proxy.should be_instance_of(GOM::Object::Proxy)
|
46
|
-
related_object_proxy.object.
|
50
|
+
related_object_proxy.object.number.should == 16
|
47
51
|
end
|
48
52
|
|
49
53
|
end
|
@@ -74,7 +78,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
74
78
|
it "should store the related object" do
|
75
79
|
GOM::Storage.store @object, :test_storage
|
76
80
|
related_object = GOM::Storage.fetch GOM::Object.id(@related_object)
|
77
|
-
related_object.
|
81
|
+
related_object.number.should == 16
|
78
82
|
end
|
79
83
|
|
80
84
|
end
|
@@ -115,8 +119,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
115
119
|
describe "fetching a class collection" do
|
116
120
|
|
117
121
|
before :each do
|
118
|
-
@another_object =
|
119
|
-
@another_object.instance_variable_set :@number, 17
|
122
|
+
@another_object = Object.new
|
120
123
|
|
121
124
|
GOM::Storage.store @object, :test_storage
|
122
125
|
GOM::Storage.store @another_object, :test_storage
|
@@ -138,13 +141,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
138
141
|
collection.size.should > 0
|
139
142
|
collection.each do |object_proxy|
|
140
143
|
object_proxy.should be_instance_of(GOM::Object::Proxy)
|
141
|
-
|
142
|
-
@object.instance_variable_get(:@number),
|
143
|
-
@related_object.instance_variable_get(:@number)
|
144
|
-
].should include(object_proxy.object.instance_variable_get(:@number))
|
145
|
-
[
|
146
|
-
@another_object.instance_variable_get(:@number)
|
147
|
-
].should_not include(object_proxy.object.instance_variable_get(:@number))
|
144
|
+
object_proxy.object.should be_instance_of(GOM::Spec::Object)
|
148
145
|
end
|
149
146
|
end
|
150
147
|
|
@@ -171,7 +168,8 @@ shared_examples_for "an adapter connected to a stateful storage" do
|
|
171
168
|
collection.size.should > 0
|
172
169
|
collection.each do |object_proxy|
|
173
170
|
object_proxy.should be_instance_of(GOM::Object::Proxy)
|
174
|
-
object_proxy.object.
|
171
|
+
object_proxy.object.should be_instance_of(GOM::Spec::Object)
|
172
|
+
object_proxy.object.number.should == @object.number
|
175
173
|
end
|
176
174
|
end
|
177
175
|
|