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.
Files changed (37) hide show
  1. data/README.rdoc +15 -0
  2. data/Rakefile +1 -1
  3. data/lib/gom.rb +1 -0
  4. data/lib/gom/object.rb +15 -19
  5. data/lib/gom/object/builder.rb +35 -33
  6. data/lib/gom/object/cached_builder.rb +23 -31
  7. data/lib/gom/object/collection.rb +49 -57
  8. data/lib/gom/object/draft.rb +17 -25
  9. data/lib/gom/object/id.rb +14 -22
  10. data/lib/gom/object/inspector.rb +46 -54
  11. data/lib/gom/object/mapping.rb +31 -47
  12. data/lib/gom/object/proxy.rb +25 -33
  13. data/lib/gom/spec.rb +11 -0
  14. data/lib/gom/spec/acceptance/adapter_that_needs_setup.rb +58 -0
  15. data/lib/gom/spec/acceptance/adapter_with_stateful_storage.rb +19 -21
  16. data/lib/gom/spec/acceptance/read_only_adapter_with_stateless_storage.rb +9 -8
  17. data/lib/gom/spec/object.rb +8 -0
  18. data/lib/gom/storage.rb +30 -26
  19. data/lib/gom/storage/adapter.rb +26 -43
  20. data/lib/gom/storage/configuration.rb +75 -68
  21. data/lib/gom/storage/configuration/view.rb +3 -16
  22. data/lib/gom/storage/configuration/view/class.rb +5 -22
  23. data/lib/gom/storage/configuration/view/map_reduce.rb +7 -24
  24. data/lib/gom/storage/fetcher.rb +24 -32
  25. data/lib/gom/storage/remover.rb +27 -35
  26. data/lib/gom/storage/saver.rb +35 -43
  27. data/spec/acceptance/adapter_spec.rb +16 -4
  28. data/spec/acceptance/fake_adapter_spec.rb +11 -0
  29. data/spec/acceptance/object_spec.rb +4 -1
  30. data/spec/fake_adapter.rb +12 -3
  31. data/spec/lib/gom/object/builder_spec.rb +5 -5
  32. data/spec/lib/gom/object/inspector_spec.rb +5 -9
  33. data/spec/lib/gom/object/mapping_spec.rb +27 -57
  34. data/spec/lib/gom/storage/adapter_spec.rb +1 -1
  35. data/spec/lib/gom/storage/configuration_spec.rb +33 -3
  36. data/spec/lib/gom/storage_spec.rb +19 -0
  37. metadata +50 -46
@@ -5,20 +5,24 @@ shared_examples_for "a read-only adapter connected to a stateless 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
  describe "fetching an object" do
9
13
 
10
14
  it "should return the correct object" do
11
15
  object = GOM::Storage.fetch "test_storage:object_1"
12
- object.should be_instance_of(Object)
13
- object.instance_variable_get(:@number).should == 5
16
+ object.should be_instance_of(GOM::Spec::Object)
17
+ object.number.should == 5
14
18
  GOM::Object.id(object).should == "test_storage:object_1"
15
19
  end
16
20
 
17
21
  it "should return proxy objects that fetches the related objects" do
18
22
  object = GOM::Storage.fetch "test_storage:object_1"
19
- related_object = object.instance_variable_get :@related_object
23
+ related_object = object.related_object
20
24
  related_object.should be_instance_of(GOM::Object::Proxy)
21
- related_object.object.instance_variable_get(:@test).should == "test value"
25
+ related_object.object.number.should == 7
22
26
  end
23
27
 
24
28
  end
@@ -58,10 +62,7 @@ shared_examples_for "a read-only adapter connected to a stateless storage" do
58
62
  collection = GOM::Storage.collection :test_storage, :test_object_class_view
59
63
  collection.size > 0
60
64
  collection.each do |object_proxy|
61
- (
62
- object_proxy.object.instance_variable_get(:@number) == 5 ||
63
- object_proxy.object.instance_variable_get(:@test) == "test value"
64
- ).should be_true
65
+ [ 5, 7 ].should include(object_proxy.object.number)
65
66
  end
66
67
  end
67
68
 
@@ -0,0 +1,8 @@
1
+
2
+ # A dummy test class
3
+ class GOM::Spec::Object
4
+
5
+ attr_accessor :number
6
+ attr_accessor :related_object
7
+
8
+ end
data/lib/gom/storage.rb CHANGED
@@ -1,39 +1,43 @@
1
1
 
2
- module GOM
2
+ module GOM::Storage
3
3
 
4
- module Storage
4
+ autoload :Adapter, File.join(File.dirname(__FILE__), "storage", "adapter")
5
+ autoload :Configuration, File.join(File.dirname(__FILE__), "storage", "configuration")
6
+ autoload :Fetcher, File.join(File.dirname(__FILE__), "storage", "fetcher")
7
+ autoload :Remover, File.join(File.dirname(__FILE__), "storage", "remover")
8
+ autoload :Saver, File.join(File.dirname(__FILE__), "storage", "saver")
5
9
 
6
- autoload :Adapter, File.join(File.dirname(__FILE__), "storage", "adapter")
7
- autoload :Configuration, File.join(File.dirname(__FILE__), "storage", "configuration")
8
- autoload :Fetcher, File.join(File.dirname(__FILE__), "storage", "fetcher")
9
- autoload :Remover, File.join(File.dirname(__FILE__), "storage", "remover")
10
- autoload :Saver, File.join(File.dirname(__FILE__), "storage", "saver")
10
+ # This error can be thrown by the setup method if the given adapter name isn't registered
11
+ class AdapterNotFoundError < StandardError; end
11
12
 
12
- # This error can be thrown by an adapter if it's doesn't support write operations
13
- class ReadOnlyError < StandardError; end
13
+ # This error can be thrown by an adapter if it's doesn't support write operations
14
+ class ReadOnlyError < StandardError; end
14
15
 
15
- def self.setup
16
- Configuration.setup_all
17
- end
16
+ def self.setup
17
+ GOM::Object::Mapping.clear!
18
+ Configuration.setup_all
19
+ end
18
20
 
19
- def self.fetch(id_string)
20
- id = id_string.is_a?(String) ? GOM::Object::Id.new(id_string) : nil
21
- Fetcher.new(id).object
22
- end
21
+ def self.teardown
22
+ Configuration.teardown_all
23
+ end
23
24
 
24
- def self.store(object, storage_name = nil)
25
- Saver.new(object, storage_name).perform
26
- end
25
+ def self.fetch(id_string)
26
+ id = id_string.is_a?(String) ? GOM::Object::Id.new(id_string) : nil
27
+ Fetcher.new(id).object
28
+ end
27
29
 
28
- def self.remove(object_or_id)
29
- object_or_id = GOM::Object::Id.new object_or_id if object_or_id.is_a?(String)
30
- Remover.new(object_or_id).perform
31
- end
30
+ def self.store(object, storage_name = nil)
31
+ Saver.new(object, storage_name).perform
32
+ end
32
33
 
33
- def self.collection(storage_name, *arguments)
34
- Configuration[storage_name].adapter.collection *arguments
35
- end
34
+ def self.remove(object_or_id)
35
+ object_or_id = GOM::Object::Id.new object_or_id if object_or_id.is_a?(String)
36
+ Remover.new(object_or_id).perform
37
+ end
36
38
 
39
+ def self.collection(storage_name, *arguments)
40
+ Configuration[storage_name].adapter.collection *arguments
37
41
  end
38
42
 
39
43
  end
@@ -1,58 +1,41 @@
1
1
 
2
- module GOM
2
+ # Base class for a storage adapter
3
+ class GOM::Storage::Adapter
3
4
 
4
- module Storage
5
+ # If the adapter is used without a setup, this error is may raised.
6
+ class NoSetupError < StandardError; end
5
7
 
6
- # Base class for a storage adapter
7
- class Adapter
8
+ # If a view could not be found, this error is raised.
9
+ class ViewNotFoundError < StandardError; end
8
10
 
9
- # If a view could not be found, this error is raised.
10
- class ViewNotFoundError < StandardError; end
11
+ attr_reader :configuration
11
12
 
12
- attr_reader :configuration
13
-
14
- def initialize(configuration)
15
- @configuration = configuration
16
- end
17
-
18
- def setup(*arguments)
19
- not_implemented "setup"
20
- end
21
-
22
- def fetch(*arguments)
23
- not_implemented "fetch"
24
- end
25
-
26
- def store(*arguments)
27
- not_implemented "store"
28
- end
29
-
30
- def remove(*arguments)
31
- not_implemented "remove"
32
- end
13
+ def initialize(configuration)
14
+ @configuration = configuration
15
+ end
33
16
 
34
- def collection(*arguments)
35
- not_implemented "collection"
36
- end
17
+ [ :setup, :teardown, :fetch, :store, :remove, :collection ].each do |key|
37
18
 
38
- private
19
+ define_method key do |*arguments|
20
+ not_implemented key
21
+ end
39
22
 
40
- def not_implemented(method_name)
41
- raise NotImplementedError, "The adapter has no #{method_name} method implemented"
42
- end
23
+ end
43
24
 
44
- def self.register(id, adapter_class)
45
- @adapter_classes ||= { }
46
- @adapter_classes[id.to_sym] = adapter_class
47
- end
25
+ private
48
26
 
49
- def self.[](id)
50
- @adapter_classes ||= { }
51
- @adapter_classes[id.to_sym]
52
- end
27
+ def not_implemented(method_name)
28
+ raise NotImplementedError, "The adapter has no #{method_name} method implemented"
29
+ end
53
30
 
54
- end
31
+ def self.register(id, adapter_class)
32
+ @adapter_classes ||= { }
33
+ @adapter_classes[id.to_sym] = adapter_class
34
+ end
55
35
 
36
+ def self.[](id)
37
+ @adapter_classes ||= { }
38
+ @adapter_classes[id.to_sym]
56
39
  end
57
40
 
58
41
  end
@@ -1,94 +1,101 @@
1
- require File.join(File.dirname(__FILE__), "adapter")
2
1
  require 'yaml'
3
2
 
4
- module GOM
3
+ # Stores all information to configure a storage.
4
+ class GOM::Storage::Configuration
5
5
 
6
- module Storage
6
+ autoload :View, File.join(File.dirname(__FILE__), "configuration", "view")
7
7
 
8
- # Stores all information to configure a storage.
9
- class Configuration
8
+ attr_reader :name
9
+ attr_reader :hash
10
10
 
11
- autoload :View, File.join(File.dirname(__FILE__), "configuration", "view")
12
-
13
- attr_reader :name
11
+ def initialize(name, hash)
12
+ @name, @hash = name, { }
13
+ hash.each{ |key, value| @hash[key.to_sym] = value }
14
+ end
14
15
 
15
- def initialize(name, hash)
16
- @name, @hash = name, { }
17
- hash.each{ |key, value| @hash[key.to_sym] = value }
18
- end
16
+ def setup
17
+ adapter.setup
18
+ end
19
19
 
20
- def setup
21
- adapter.setup
22
- end
20
+ def teardown
21
+ adapter.teardown
22
+ clear_adapter
23
+ end
23
24
 
24
- def adapter
25
- @adapter ||= adapter_class.new self
26
- end
25
+ def adapter
26
+ @adapter ||= adapter_class.new self
27
+ end
27
28
 
28
- def adapter_class
29
- @adapter_class ||= Adapter[@hash[:adapter]]
30
- end
29
+ def adapter_class
30
+ @adapter_class ||= GOM::Storage::Adapter[@hash[:adapter]] || raise(GOM::Storage::AdapterNotFoundError)
31
+ end
31
32
 
32
- def [](key)
33
- @hash[key.to_sym]
34
- end
33
+ def [](key)
34
+ @hash[key.to_sym]
35
+ end
35
36
 
36
- def values_at(*arguments)
37
- arguments.map{ |argument| self[argument] }
38
- end
37
+ def values_at(*arguments)
38
+ arguments.map{ |argument| self[argument] }
39
+ end
39
40
 
40
- def views
41
- @views ||= begin
42
- result = { }
43
- (self["views"] || { }).each do |name, hash|
44
- result[name.to_sym] = self.class.view hash
45
- end
46
- result
47
- end
41
+ def views
42
+ @views ||= begin
43
+ result = { }
44
+ (self["views"] || { }).each do |name, hash|
45
+ result[name.to_sym] = self.class.view hash
48
46
  end
47
+ result
48
+ end
49
+ end
49
50
 
50
- private
51
-
52
- def self.view(hash)
53
- type = hash["type"]
54
- method_name = :"#{type}_view"
55
- raise NotImplementedError, "the view type '#{type}' doesn't exists" unless self.respond_to?(method_name)
56
- self.send method_name, hash
57
- end
51
+ private
58
52
 
59
- def self.class_view(hash)
60
- View::Class.new hash["class"]
61
- end
53
+ def clear_adapter
54
+ @adapter, @adapter_class = nil, nil
55
+ end
62
56
 
63
- def self.map_reduce_view(hash)
64
- View::MapReduce.new *hash.values_at("map", "reduce")
65
- end
57
+ def self.view(hash)
58
+ type = hash["type"]
59
+ method_name = :"#{type}_view"
60
+ raise NotImplementedError, "the view type '#{type}' doesn't exists" unless self.respond_to?(method_name)
61
+ self.send method_name, hash
62
+ end
66
63
 
67
- def self.read(file_name)
68
- @configurations = { }
69
- YAML::load_file(file_name).each do |name, values|
70
- @configurations[name.to_sym] = self.new name, values
71
- end
72
- end
64
+ def self.class_view(hash)
65
+ View::Class.new hash["class"]
66
+ end
73
67
 
74
- def self.setup_all
75
- @configurations.values.each do |configuration|
76
- configuration.setup
77
- end
78
- end
68
+ def self.map_reduce_view(hash)
69
+ View::MapReduce.new *hash.values_at("map", "reduce")
70
+ end
79
71
 
80
- def self.[](name)
81
- @configurations ||= { }
82
- @configurations[name.to_sym]
83
- end
72
+ def self.read(file_name)
73
+ @configurations = { }
74
+ YAML::load_file(file_name).each do |name, values|
75
+ @configurations[name.to_sym] = self.new name, values
76
+ end
77
+ end
84
78
 
85
- def self.default
86
- @configurations ||= { }
87
- @configurations.values.first || raise(StandardError, "No storage configuration loaded!")
88
- end
79
+ def self.setup_all
80
+ @configurations.values.each do |configuration|
81
+ configuration.setup
82
+ end
83
+ end
89
84
 
85
+ def self.teardown_all
86
+ @configurations.values.each do |configuration|
87
+ configuration.teardown
90
88
  end
89
+ end
90
+
91
+ def self.[](name)
92
+ @configurations ||= { }
93
+ @configurations[name.to_sym]
94
+ end
91
95
 
96
+ def self.default
97
+ @configurations ||= { }
98
+ @configurations.values.first || raise(StandardError, "No storage configuration loaded!")
92
99
  end
93
100
 
94
101
  end
@@ -1,20 +1,7 @@
1
1
 
2
- module GOM
2
+ module GOM::Storage::Configuration::View
3
3
 
4
- module Storage
5
-
6
- # Stores all information to configure a storage.
7
- class Configuration
8
-
9
- module View
10
-
11
- autoload :Class, File.join(File.dirname(__FILE__), "view", "class")
12
- autoload :MapReduce, File.join(File.dirname(__FILE__), "view", "map_reduce")
13
-
14
- end
15
-
16
- end
17
-
18
- end
4
+ autoload :Class, File.join(File.dirname(__FILE__), "view", "class")
5
+ autoload :MapReduce, File.join(File.dirname(__FILE__), "view", "map_reduce")
19
6
 
20
7
  end
@@ -1,28 +1,11 @@
1
1
 
2
- module GOM
2
+ # Contains all the parameters for a class view.
3
+ class GOM::Storage::Configuration::View::Class
3
4
 
4
- module Storage
5
-
6
- # Stores all information to configure a storage.
7
- class Configuration
8
-
9
- module View
10
-
11
- # Contains all the parameters for a class view.
12
- class Class
13
-
14
- attr_accessor :class_name
15
-
16
- def initialize(class_name)
17
- @class_name = class_name
18
- end
19
-
20
- end
21
-
22
- end
23
-
24
- end
5
+ attr_accessor :class_name
25
6
 
7
+ def initialize(class_name)
8
+ @class_name = class_name
26
9
  end
27
10
 
28
11
  end
@@ -1,29 +1,12 @@
1
1
 
2
- module GOM
2
+ # Contains all parameters for a map reduce view.
3
+ class GOM::Storage::Configuration::View::MapReduce
3
4
 
4
- module Storage
5
-
6
- # Stores all information to configure a storage.
7
- class Configuration
8
-
9
- module View
10
-
11
- # Contains all parameters for a map reduce view.
12
- class MapReduce
13
-
14
- attr_accessor :map
15
- attr_accessor :reduce
16
-
17
- def initialize(map, reduce)
18
- @map, @reduce = map, reduce
19
- end
20
-
21
- end
22
-
23
- end
24
-
25
- end
5
+ attr_accessor :map
6
+ attr_accessor :reduce
26
7
 
8
+ def initialize(map, reduce)
9
+ @map, @reduce = map, reduce
27
10
  end
28
11
 
29
- end
12
+ end