gom 0.3.1 → 0.4.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 CHANGED
@@ -10,15 +10,14 @@ is plugged-in via an adapter interface. Currently, the following adapters are pr
10
10
 
11
11
  == Configuration
12
12
 
13
- At the beginning of your program the configuration should be read with the following command.
13
+ At the beginning of your program the storage configuration should be done with the <tt>GOM::Storage.configure</tt>
14
+ command.
14
15
 
15
- GOM::Storage::Configuration.read filename
16
-
17
- The configuration file should be written in the YML format and look like...
18
-
19
- storage_name:
20
- adapter: filesystem
21
- directory: /var/project-name/data
16
+ GOM::Storage.configure {
17
+ name :storage_name
18
+ adapter :filesystem
19
+ directory "/var/project-name/data"
20
+ }
22
21
 
23
22
  Look at the adapter pages to see the adapter-specific configuration values.
24
23
 
@@ -124,13 +123,16 @@ of results at runtime. There are several kinds of views.
124
123
  There views simply provides a collection of all object of a specified class. They are defined at the storage
125
124
  configuration.
126
125
 
127
- storage_name:
128
- adapter: filesystem
129
- directory: /var/project-name/data
130
- views:
131
- users:
132
- type: class
133
- class: User
126
+ GOM::Storage.configure {
127
+ name :storage_name
128
+ adapter :filesystem
129
+ directory "/var/project-name/data"
130
+ view {
131
+ name :users
132
+ type :class
133
+ model_class User
134
+ }
135
+ }
134
136
 
135
137
  The example defines a class view for all objects of the class <tt>User</tt>. The result can be fetched via...
136
138
 
@@ -143,21 +145,26 @@ array.
143
145
 
144
146
  These views are also defined in the storage configuration.
145
147
 
146
- storage_name:
147
- adapter: couchdb
148
- views:
149
- active_user_count:
150
- type: map_reduce
151
- map:
152
- function(document) {
153
- if (document['model_class'] == 'User' && document['active']) {
154
- emit(document['_id'], 1);
155
- }
156
- }
157
- reduce:
158
- function(keys, values, rereduce) {
159
- return sum(values);
148
+ GOM::Storage.configure {
149
+ name :storage_name
150
+ adapter :couchdb
151
+ view {
152
+ name :active_user_count
153
+ type :map_reduce
154
+ map_function """
155
+ function(document) {
156
+ if (document['model_class'] == 'User' && document['active']) {
157
+ emit(document['_id'], 1);
160
158
  }
159
+ }
160
+ """
161
+ reduce_function """
162
+ function(keys, values, rereduce) {
163
+ return sum(values);
164
+ }
165
+ """
166
+ }
167
+ }
161
168
 
162
169
  The example defined a map/reduce view that results in a single row with the count of all active users. This row can be
163
170
  fetched by...
@@ -168,17 +175,21 @@ fetched by...
168
175
  If no <tt>reduce</tt> method is given, <tt>GOM</tt> will try to map the fetched data back to ruby-objects. The
169
176
  definition would be...
170
177
 
171
- storage_name:
172
- adapter: couchdb
173
- views:
174
- active_users:
175
- type: map_reduce
176
- map:
177
- function(document) {
178
- if (document['model_class'] == 'User') {
179
- emit(document['_id'], null);
180
- }
178
+ GOM::Storage.configure {
179
+ name :storage_name
180
+ adapter :couchdb
181
+ view {
182
+ name :active_users
183
+ type :map_reduce
184
+ map_function """
185
+ function(document) {
186
+ if (document['model_class'] == 'User') {
187
+ emit(document['_id'], null);
181
188
  }
189
+ }
190
+ """
191
+ }
192
+ }
182
193
 
183
194
  ...and the fetch is done by...
184
195
 
data/lib/gom/storage.rb CHANGED
@@ -14,6 +14,10 @@ module GOM::Storage
14
14
  # This error can be thrown by an adapter if it's doesn't support write operations
15
15
  class ReadOnlyError < StandardError; end
16
16
 
17
+ def self.configure(&block)
18
+ Configuration.configure &block
19
+ end
20
+
17
21
  def self.setup
18
22
  GOM::Object::Mapping.clear!
19
23
  Configuration.setup_all
@@ -1,15 +1,29 @@
1
1
  require 'yaml'
2
+ require 'configure'
2
3
 
3
4
  # Stores all information to configure a storage.
4
5
  class GOM::Storage::Configuration
5
6
 
6
7
  autoload :View, File.join(File.dirname(__FILE__), "configuration", "view")
7
8
 
8
- attr_reader :name
9
+ SCHEMA = Configure::Schema.build{
10
+ only :storage
11
+ nested {
12
+ storage {
13
+ not_nil :name, :adapter
14
+ nested {
15
+ view {
16
+ not_nil :name, :type
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }.freeze
22
+
9
23
  attr_reader :hash
10
24
 
11
- def initialize(name, hash)
12
- @name, @hash = name, { }
25
+ def initialize(hash)
26
+ @hash = { }
13
27
  hash.each{ |key, value| @hash[key.to_sym] = value }
14
28
  end
15
29
 
@@ -22,6 +36,10 @@ class GOM::Storage::Configuration
22
36
  clear_adapter
23
37
  end
24
38
 
39
+ def name
40
+ @hash[:name].to_s
41
+ end
42
+
25
43
  def adapter
26
44
  @adapter ||= adapter_class.new self
27
45
  end
@@ -41,7 +59,8 @@ class GOM::Storage::Configuration
41
59
  def views
42
60
  @views ||= begin
43
61
  result = { }
44
- (self["views"] || { }).each do |name, hash|
62
+ [ @hash[:view] ].flatten.compact.each do |hash|
63
+ name = hash[:name]
45
64
  result[name.to_sym] = self.class.view hash
46
65
  end
47
66
  result
@@ -54,26 +73,28 @@ class GOM::Storage::Configuration
54
73
  @adapter, @adapter_class = nil, nil
55
74
  end
56
75
 
76
+ def self.configure(&block)
77
+ @configurations = { }
78
+ configurations = Configure.process SCHEMA, &block
79
+ [ configurations[:storage] ].flatten.compact.each do |hash|
80
+ name = hash[:name]
81
+ @configurations[name.to_sym] = self.new hash
82
+ end
83
+ end
84
+
57
85
  def self.view(hash)
58
- type = hash["type"]
86
+ type = hash[:type]
59
87
  method_name = :"#{type}_view"
60
88
  raise NotImplementedError, "the view type '#{type}' doesn't exists" unless self.respond_to?(method_name)
61
89
  self.send method_name, hash
62
90
  end
63
91
 
64
92
  def self.class_view(hash)
65
- View::Class.new hash["class"]
93
+ View::Class.new hash[:model_class]
66
94
  end
67
95
 
68
96
  def self.map_reduce_view(hash)
69
- View::MapReduce.new *hash.values_at("map", "reduce")
70
- end
71
-
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
97
+ View::MapReduce.new *hash.values_at(:map_function, :reduce_function)
77
98
  end
78
99
 
79
100
  def self.setup_all
@@ -1,7 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
2
 
3
- GOM::Storage::Configuration.read File.join(File.dirname(__FILE__), "..", "storage.configuration")
4
-
5
3
  describe "adapter" do
6
4
 
7
5
  before :each do
@@ -19,4 +17,4 @@ describe "adapter" do
19
17
 
20
18
  end
21
19
 
22
- end
20
+ end
@@ -1,7 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
2
 
3
- GOM::Storage::Configuration.read File.join(File.dirname(__FILE__), "..", "storage.configuration")
4
-
5
3
  describe "fake adapter" do
6
4
 
7
5
  it_should_behave_like "an adapter that needs setup"
@@ -1,7 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
2
 
3
- GOM::Storage::Configuration.read File.join(File.dirname(__FILE__), "..", "storage.configuration")
4
-
5
3
  describe "object" do
6
4
 
7
5
  before :each do
@@ -5,13 +5,29 @@ describe GOM::Storage::Configuration do
5
5
  before :each do
6
6
  @adapter = mock GOM::Storage::Adapter, :setup => nil
7
7
  @adapter_class = mock Class, :new => @adapter
8
- GOM::Storage::Adapter.stub(:[]).and_return(@adapter_class)
9
-
10
- described_class.read File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "storage.configuration"))
8
+ GOM::Storage::Adapter.stub :[] => @adapter_class
9
+
10
+ described_class.configure {
11
+ storage {
12
+ name :test_storage
13
+ adapter :test
14
+ view {
15
+ name :test_object_class_view
16
+ type :class
17
+ model_class Object
18
+ }
19
+ view {
20
+ name :test_map_view
21
+ type :map_reduce
22
+ map_function "function(document) { }"
23
+ reduce_function "function(key, values) { }"
24
+ }
25
+ }
26
+ }
11
27
  @configuration = described_class[:test_storage]
12
28
  end
13
29
 
14
- describe "setup" do
30
+ describe "#setup" do
15
31
 
16
32
  it "should call setup on the adapter instance" do
17
33
  @adapter.should_receive(:setup)
@@ -20,7 +36,7 @@ describe GOM::Storage::Configuration do
20
36
 
21
37
  end
22
38
 
23
- describe "teardown" do
39
+ describe "#teardown" do
24
40
 
25
41
  it "should call teardown on the adapter instance" do
26
42
  @adapter.should_receive(:teardown)
@@ -29,7 +45,12 @@ describe GOM::Storage::Configuration do
29
45
 
30
46
  end
31
47
 
32
- describe "adapter_class" do
48
+ describe "#adapter_class" do
49
+
50
+ it "should fetch the right adapter class" do
51
+ GOM::Storage::Adapter.should_receive(:[]).with(:test).and_return(@adapter_class)
52
+ @configuration.adapter_class
53
+ end
33
54
 
34
55
  it "should return the adapter class" do
35
56
  adapter_class = @configuration.adapter_class
@@ -45,28 +66,43 @@ describe GOM::Storage::Configuration do
45
66
 
46
67
  end
47
68
 
48
- describe "[]" do
69
+ describe "#[]" do
49
70
 
50
71
  it "should return the configuration value" do
51
- @configuration[:test].should == "test value"
72
+ @configuration[:name].should == :test_storage
52
73
  end
53
74
 
54
75
  end
55
76
 
56
- describe "values_at" do
77
+ describe "#values_at" do
57
78
 
58
79
  it "should return multiple configuration values" do
59
- @configuration.values_at(:adapter, :test).should == [ "fake_adapter", "test value" ]
80
+ @configuration.values_at(:adapter, :name).should == [ :test, :test_storage ]
81
+ end
82
+
83
+ end
84
+
85
+ describe "#self.configure" do
86
+
87
+ before :each do
88
+ @block = Proc.new { }
89
+ @configuration = { :storage => { :name => :test } }
90
+ Configure.stub :process => @configuration
91
+ end
92
+
93
+ it "should pass the given block to Configure.process along with the configuration schema" do
94
+ Configure.should_receive(:process).with(described_class::SCHEMA, &@block).and_return(@configuration)
95
+ described_class.configure &@block
60
96
  end
61
97
 
62
98
  end
63
99
 
64
- describe "views" do
100
+ describe "#self.views" do
65
101
 
66
102
  it "should return a hash including class views" do
67
103
  view = @configuration.views[:test_object_class_view]
68
104
  view.should be_instance_of(described_class::View::Class)
69
- view.class_name.should == "Object"
105
+ view.class_name.should == Object
70
106
  end
71
107
 
72
108
  it "should return a hash including map reduce views" do
@@ -77,7 +113,7 @@ describe GOM::Storage::Configuration do
77
113
  end
78
114
 
79
115
  it "should raise a #{NotImplementedError} if the view type is invalid" do
80
- @configuration["views"]["test_invalid_view"] = { "type" => "invalid" }
116
+ @configuration["view"] << { :name => "test", :type => "invalid" }
81
117
  lambda do
82
118
  @configuration.views[:test_invalid_view]
83
119
  end.should raise_error(NotImplementedError)
@@ -90,24 +126,7 @@ describe GOM::Storage::Configuration do
90
126
 
91
127
  end
92
128
 
93
- describe "read" do
94
-
95
- it "should read the configuration file" do
96
- @configuration.should be_instance_of(described_class)
97
- end
98
-
99
- it "should initialize the right adapter class" do
100
- @configuration.adapter_class.should == @adapter_class
101
- end
102
-
103
- it "should create an adapter instance if requested" do
104
- @adapter_class.should_receive(:new).with(@configuration).and_return(@adapter)
105
- @configuration.adapter.should == @adapter
106
- end
107
-
108
- end
109
-
110
- describe "setup_all" do
129
+ describe "#self.setup_all" do
111
130
 
112
131
  before :each do
113
132
  @configuration.stub(:setup)
@@ -120,7 +139,7 @@ describe GOM::Storage::Configuration do
120
139
 
121
140
  end
122
141
 
123
- describe "teardown_all" do
142
+ describe "#self.teardown_all" do
124
143
 
125
144
  before :each do
126
145
  @configuration.stub(:teardown)
@@ -133,7 +152,7 @@ describe GOM::Storage::Configuration do
133
152
 
134
153
  end
135
154
 
136
- describe "default" do
155
+ describe "#self.default" do
137
156
 
138
157
  it "should select the first configuration" do
139
158
  described_class.default.should == GOM::Storage::Configuration[:test_storage]
@@ -7,11 +7,25 @@ describe GOM::Storage do
7
7
  @object = Object.new
8
8
  end
9
9
 
10
- describe "setup" do
10
+ describe "#self.configure" do
11
11
 
12
12
  before :each do
13
- GOM::Object::Mapping.stub(:clear!)
14
- described_class::Configuration.stub(:setup_all)
13
+ @block = Proc.new { }
14
+ described_class::Configuration.stub :configure => nil
15
+ end
16
+
17
+ it "should call :configure on the configuration class" do
18
+ described_class::Configuration.should_receive(:configure).with(&@block)
19
+ described_class.configure &@block
20
+ end
21
+
22
+ end
23
+
24
+ describe "#self.setup" do
25
+
26
+ before :each do
27
+ GOM::Object::Mapping.stub :clear! => nil
28
+ described_class::Configuration.stub :setup_all => nil
15
29
  end
16
30
 
17
31
  it "should clear the mapping" do
@@ -26,10 +40,10 @@ describe GOM::Storage do
26
40
 
27
41
  end
28
42
 
29
- describe "teardown" do
43
+ describe "#self.teardown" do
30
44
 
31
45
  before :each do
32
- described_class::Configuration.stub(:teardown_all)
46
+ described_class::Configuration.stub :teardown_all => nil
33
47
  end
34
48
 
35
49
  it "should teardown all storage configurations" do
@@ -39,11 +53,11 @@ describe GOM::Storage do
39
53
 
40
54
  end
41
55
 
42
- describe "fetch" do
56
+ describe "#self.fetch" do
43
57
 
44
58
  before :each do
45
59
  @id = mock GOM::Object::Id
46
- GOM::Object::Id.stub(:new).and_return(@id)
60
+ GOM::Object::Id.stub :new => @id
47
61
 
48
62
  @fetcher = mock GOM::Storage::Fetcher, :object => @object
49
63
  described_class::Fetcher.stub(:new).and_return(@fetcher)
@@ -65,19 +79,19 @@ describe GOM::Storage do
65
79
 
66
80
  it "should return nil if nil is given" do
67
81
  described_class::Fetcher.should_receive(:new).with(nil).and_return(@fetcher)
68
- @fetcher.stub(:object).and_return(nil)
82
+ @fetcher.stub :object => nil
69
83
 
70
84
  described_class.fetch(nil).should be_nil
71
85
  end
72
86
 
73
87
  end
74
88
 
75
- describe "store" do
89
+ describe "#self.store" do
76
90
 
77
91
  before :each do
78
92
  @storage_name = "another_test_storage"
79
93
  @saver = mock described_class::Saver, :perform => nil
80
- described_class::Saver.stub(:new).and_return(@saver)
94
+ described_class::Saver.stub :new => @saver
81
95
  end
82
96
 
83
97
  it "should initialize the saver correctly" do
@@ -92,14 +106,14 @@ describe GOM::Storage do
92
106
 
93
107
  end
94
108
 
95
- describe "remove" do
109
+ describe "#self.remove" do
96
110
 
97
111
  before :each do
98
112
  @id = mock GOM::Object::Id
99
- GOM::Object::Id.stub(:new).and_return(@id)
113
+ GOM::Object::Id.stub :new => @id
100
114
 
101
115
  @remover = mock described_class::Remover, :perform => nil
102
- described_class::Remover.stub(:new).and_return(@remover)
116
+ described_class::Remover.stub :new => @remover
103
117
  end
104
118
 
105
119
  it "should initialize the remover correctly" do
@@ -120,11 +134,11 @@ describe GOM::Storage do
120
134
 
121
135
  end
122
136
 
123
- describe "count" do
137
+ describe "#self.count" do
124
138
 
125
139
  before :each do
126
140
  @counter = mock described_class::Counter, :perform => 1
127
- described_class::Counter.stub(:new).and_return(@counter)
141
+ described_class::Counter.stub :new => @counter
128
142
  end
129
143
 
130
144
  it "should initialize the counter" do
@@ -139,7 +153,7 @@ describe GOM::Storage do
139
153
 
140
154
  end
141
155
 
142
- describe "collection" do
156
+ describe "#self.collection" do
143
157
 
144
158
  before :each do
145
159
  @collection = mock GOM::Object::Collection
data/spec/spec_helper.rb CHANGED
@@ -5,3 +5,21 @@ require 'rspec'
5
5
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "gom"))
6
6
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "gom", "spec"))
7
7
  require File.join(File.dirname(__FILE__), "fake_adapter")
8
+
9
+ GOM::Storage.configure {
10
+ storage {
11
+ name :test_storage
12
+ adapter :fake_adapter
13
+ view {
14
+ name :test_object_class_view
15
+ type :class
16
+ model_class Object
17
+ }
18
+ view {
19
+ name :test_map_view
20
+ type :map_reduce
21
+ map_function "function(document) { }"
22
+ reduce_function "function(key, values) { }"
23
+ }
24
+ }
25
+ }
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gom
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 3
8
- - 1
9
- version: 0.3.1
4
+ prerelease:
5
+ version: 0.4.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - "Philipp Br\xC3\xBCll"
@@ -14,36 +10,42 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-03-07 00:00:00 +01:00
13
+ date: 2011-05-10 00:00:00 +02:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
21
- name: rspec
17
+ name: configure
22
18
  prerelease: false
23
19
  requirement: &id001 !ruby/object:Gem::Requirement
24
20
  none: false
25
21
  requirements:
26
22
  - - ">="
27
23
  - !ruby/object:Gem::Version
28
- segments:
29
- - 2
24
+ version: 0.3.0
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
30
35
  version: "2"
31
36
  type: :development
32
- version_requirements: *id001
37
+ version_requirements: *id002
33
38
  - !ruby/object:Gem::Dependency
34
39
  name: reek
35
40
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
41
+ requirement: &id003 !ruby/object:Gem::Requirement
37
42
  none: false
38
43
  requirements:
39
44
  - - ">="
40
45
  - !ruby/object:Gem::Version
41
- segments:
42
- - 1
43
- - 2
44
46
  version: "1.2"
45
47
  type: :development
46
- version_requirements: *id002
48
+ version_requirements: *id003
47
49
  description: Core package of the General Object Mapper.
48
50
  email: b.phifty@gmail.com
49
51
  executables: []
@@ -119,21 +121,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
121
  requirements:
120
122
  - - ">="
121
123
  - !ruby/object:Gem::Version
122
- segments:
123
- - 0
124
124
  version: "0"
125
125
  required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  none: false
127
127
  requirements:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
- segments:
131
- - 0
132
130
  version: "0"
133
131
  requirements: []
134
132
 
135
133
  rubyforge_project: gom
136
- rubygems_version: 1.3.7
134
+ rubygems_version: 1.6.1
137
135
  signing_key:
138
136
  specification_version: 3
139
137
  summary: General Object Mapper - maps any ruby object to different kinds of storage engines and vice versa.