vorpal 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTFlNjY4ZjU3YWRhNmY2ZDFmZmFiMTBiMTk3ZWY5ZjVhYjc1NTAzYw==
4
+ YWYyMjQxMmIzZmI2MDc1Zjg0MWNkNGNmZDBjZmE1YWFmMjRkYmYzZQ==
5
5
  data.tar.gz: !binary |-
6
- N2FkZmQzZDBiMjg1MWU5MzJjYzcwMzUxNGNjMzk1NGE0NjkyMjNkYw==
6
+ ZjhmMTY1ZmY3Y2QwZmE3ZGM4ZjNlOGM0MTFjM2EyZjRiZTI0ZWY0Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTA5MTJmMWMzM2I5YzE5MmNkYjYzNDhlMzA0NjczZThkMzE1M2M2NDBiYzFj
10
- ZGE3OTU0Zjc0NGNlNzA4Y2RiNTM4OTgyZjk1ZmY2MjgzNjY4NTNmM2NkMDI4
11
- MjFlMGYwNzQzZWNiN2FiYTA1MzE3YTk1YmNmZTRmOTNlYzM2MWI=
9
+ MzI5ZjJkNTkwMGViNDViNWFjNTYzMzYwNTY3ZjRlYzkxZTY2ZjZiZDVjNGVh
10
+ ODY0MjcxNzA3OTY5MWY1ZjM3MmRjMDRmZmU2OGQ3NTQ5MjkxM2RjYjliZTdl
11
+ ZGE4NjdhYzM1YjM5YTUzMmJjNWM3Yjk1YThhNTNmNjA4OWIwMjM=
12
12
  data.tar.gz: !binary |-
13
- YTJhOTJhMjFkZmYwMDJlYmQwZDVmZWY0MzkwMzgyNzRhZDA0NWYyZGFlM2Iy
14
- NDZmYzc5MzUyNGM4MzFiOTIwYWIxMDRiNWUzMzJlYTcwY2YwMWEzNjRmOGM3
15
- MGM4Nzg1MzRjMzUxNzgzZmFjOTg2YjU3ZDQ2ZmM0NTlkZDNkMWE=
13
+ NDc0MTcxNzdiZmJlMGIwYmZmZWVlOTEyZDU1YjIxMmViNTQ0NTk1ZjM2Zjhl
14
+ MzZjZWU4ZWVmNDM0NjE0ZTlmNzNhOTA3NjM5YzUyYjBjZjE0MjZmYjYxMzdl
15
+ Y2E1M2U4ODQ1NDM4MDMxZmNkZjNlN2MxNjgwY2Q5ZDQ0MzNmMzg=
data/README.md CHANGED
@@ -230,7 +230,7 @@ For example:
230
230
 
231
231
  **Q.** How do I get serialization?
232
232
 
233
- **A.** You can use [ActiveModel::Serialization](http://api.rubyonrails.org/classes/ActiveModel/Serialization.html) or [ActiveModel::Serializers](https://github.com/rails-api/active_model_serializers) but they are not heartily recommended. The former is too coupled to the model and the latter is too coupled to Rails controllers. Vorpal includes the [SimpleSerializer](http://rubydoc.info/github/nulogy/vorpal/master/SimpleSerializer) and [SimpleDeserializer](http://rubydoc.info/github/nulogy/vorpal/master/SimpleDeserializer) for this purpose.
233
+ **A.** You can use [ActiveModel::Serialization](http://api.rubyonrails.org/classes/ActiveModel/Serialization.html) or [ActiveModel::Serializers](https://github.com/rails-api/active_model_serializers) but they are not heartily recommended. The former is too coupled to the model and the latter is too coupled to Rails controllers. Vorpal uses [SimpleSerializer](https://github.com/nulogy/simple_serializer) for this purpose.
234
234
 
235
235
  ## Running Tests
236
236
 
@@ -1,4 +1,5 @@
1
1
  require 'vorpal/identity_map'
2
+ require 'vorpal/traversal'
2
3
 
3
4
  module Vorpal
4
5
  class AggregateRepository
@@ -52,8 +53,7 @@ class AggregateRepository
52
53
  # operation.
53
54
  # @return [Object] Entity with the given primary key value and type.
54
55
  def load(id, domain_class, identity_map=IdentityMap.new)
55
- db_object = @configs.config_for(domain_class).load_by_id(id)
56
- hydrate(db_object, identity_map)
56
+ load_all([id], domain_class, identity_map).first
57
57
  end
58
58
 
59
59
  # Like {#load} but operates on multiple ids.
@@ -66,7 +66,10 @@ class AggregateRepository
66
66
  # operation.
67
67
  # @return [[Object]] Entities with the given primary key values and type.
68
68
  def load_all(ids, domain_class, identity_map=IdentityMap.new)
69
- ids.map { |id| load(id, domain_class, identity_map) }
69
+ ids.map do |id|
70
+ db_object = @configs.config_for(domain_class).load_by_id(id)
71
+ hydrate(db_object, identity_map)
72
+ end
70
73
  end
71
74
 
72
75
  # Removes an aggregate from the DB. Even if the aggregate contains unsaved
@@ -146,104 +149,6 @@ class AggregateRepository
146
149
  end
147
150
  end
148
151
 
149
- # @private
150
- class Traversal
151
- def initialize(configs)
152
- @configs = configs
153
- end
154
-
155
- def accept_for_domain(object, visitor, already_visited=[])
156
- return if object.nil?
157
-
158
- config = @configs.config_for(object.class)
159
- return if config.nil?
160
-
161
- return if already_visited.include?(object)
162
- already_visited << object
163
-
164
- visitor.visit_object(object, config)
165
-
166
- config.belongs_tos.each do |belongs_to_config|
167
- child = belongs_to_config.get_child(object)
168
- accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(belongs_to_config)
169
-
170
- visitor.visit_belongs_to(object, child, belongs_to_config)
171
- end
172
-
173
- config.has_ones.each do |has_one_config|
174
- child = has_one_config.get_child(object)
175
- accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(has_one_config)
176
-
177
- visitor.visit_has_one(object, child, has_one_config)
178
- end
179
-
180
- config.has_manys.each do |has_many_config|
181
- children = has_many_config.get_children(object)
182
- children.each do |child|
183
- accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(has_many_config)
184
- end
185
- visitor.visit_has_many(object, children, has_many_config)
186
- end
187
- end
188
-
189
- def accept_for_db(db_object, visitor, already_visited=[])
190
- return if db_object.nil?
191
-
192
- config = @configs.config_for_db(db_object.class)
193
- return if config.nil?
194
-
195
- return if already_visited.include?(db_object)
196
- already_visited << db_object
197
-
198
- visitor.visit_object(db_object, config)
199
-
200
- config.belongs_tos.each do |belongs_to_config|
201
- child = belongs_to_config.load_child(db_object)
202
- accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(belongs_to_config)
203
-
204
- visitor.visit_belongs_to(db_object, child, belongs_to_config)
205
- end
206
-
207
- config.has_ones.each do |has_one_config|
208
- child = has_one_config.load_child(db_object)
209
- accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(has_one_config)
210
-
211
- visitor.visit_belongs_to(db_object, child, has_one_config)
212
- end
213
-
214
- config.has_manys.each do |has_many_config|
215
- children = has_many_config.load_children(db_object)
216
- children.each do |child|
217
- accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(has_many_config)
218
- end
219
- visitor.visit_has_many(db_object, children, has_many_config)
220
- end
221
- end
222
- end
223
-
224
- # @private
225
- module AggregateVisitorTemplate
226
- def visit_object(object, config)
227
- # override me!
228
- end
229
-
230
- def visit_belongs_to(parent, child, belongs_to_config)
231
- # override me!
232
- end
233
-
234
- def visit_has_one(parent, child, has_one_config)
235
- # override me!
236
- end
237
-
238
- def visit_has_many(parent, children, has_many_config)
239
- # override me!
240
- end
241
-
242
- def continue_traversal?(association_config)
243
- true
244
- end
245
- end
246
-
247
152
  # @private
248
153
  class SerializeVisitor
249
154
  include AggregateVisitorTemplate
@@ -1,5 +1,5 @@
1
- require 'simple_serializer/simple_serializer'
2
- require 'simple_serializer/simple_deserializer'
1
+ require 'simple_serializer/serializer'
2
+ require 'simple_serializer/deserializer'
3
3
  require 'vorpal/configs'
4
4
 
5
5
  module Vorpal
@@ -134,13 +134,13 @@ class ConfigBuilder
134
134
  end
135
135
 
136
136
  def serializer(attrs)
137
- Class.new(SimpleSerializer) do
137
+ Class.new(SimpleSerializer::Serializer) do
138
138
  attributes *attrs
139
139
  end
140
140
  end
141
141
 
142
142
  def deserializer(attrs)
143
- Class.new(SimpleDeserializer) do
143
+ Class.new(SimpleSerializer::Deserializer) do
144
144
  data_attributes *attrs
145
145
  end
146
146
  end
@@ -58,7 +58,7 @@ class ClassConfig
58
58
  end
59
59
 
60
60
  def find_in_db(object)
61
- db_class.find(object.id)
61
+ load_by_id(object.id)
62
62
  end
63
63
 
64
64
  def load_by_id(id)
@@ -5,22 +5,30 @@ class IdentityMap
5
5
  end
6
6
 
7
7
  def get(key_object)
8
- @entities[key_object]
8
+ @entities[key(key_object)]
9
9
  end
10
10
 
11
11
  def set(key_object, object)
12
- @entities[key_object] = object
12
+ @entities[key(key_object)] = object
13
13
  end
14
14
 
15
15
  def get_and_set(key_object)
16
16
  object = get(key_object)
17
- object = yield(key_object) if object.nil?
17
+ object = yield if object.nil?
18
18
  set(key_object, object)
19
19
  object
20
20
  end
21
21
 
22
22
  def map(key_objects)
23
- key_objects.map { |k| @entities[k] }
23
+ key_objects.map { |k| @entities[key(k)] }
24
+ end
25
+
26
+ private
27
+
28
+ def key(key_object)
29
+ return nil unless key_object
30
+ raise "Cannot put entity '#{key_object.inspect}' into IdentityMap without an id." if key_object.id.nil?
31
+ [key_object.id, key_object.class.name]
24
32
  end
25
33
  end
26
34
  end
@@ -0,0 +1,98 @@
1
+
2
+ # @private
3
+ class Traversal
4
+ def initialize(configs)
5
+ @configs = configs
6
+ end
7
+
8
+ def accept_for_domain(object, visitor, already_visited=[])
9
+ return if object.nil?
10
+
11
+ config = @configs.config_for(object.class)
12
+ return if config.nil?
13
+
14
+ return if already_visited.include?(object)
15
+ already_visited << object
16
+
17
+ visitor.visit_object(object, config)
18
+
19
+ config.belongs_tos.each do |belongs_to_config|
20
+ child = belongs_to_config.get_child(object)
21
+ accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(belongs_to_config)
22
+
23
+ visitor.visit_belongs_to(object, child, belongs_to_config)
24
+ end
25
+
26
+ config.has_ones.each do |has_one_config|
27
+ child = has_one_config.get_child(object)
28
+ accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(has_one_config)
29
+
30
+ visitor.visit_has_one(object, child, has_one_config)
31
+ end
32
+
33
+ config.has_manys.each do |has_many_config|
34
+ children = has_many_config.get_children(object)
35
+ children.each do |child|
36
+ accept_for_domain(child, visitor, already_visited) if visitor.continue_traversal?(has_many_config)
37
+ end
38
+ visitor.visit_has_many(object, children, has_many_config)
39
+ end
40
+ end
41
+
42
+ def accept_for_db(db_object, visitor, already_visited=[])
43
+ return if db_object.nil?
44
+
45
+ config = @configs.config_for_db(db_object.class)
46
+ return if config.nil?
47
+
48
+ return if already_visited.include?(db_object)
49
+ already_visited << db_object
50
+
51
+ visitor.visit_object(db_object, config)
52
+
53
+ config.belongs_tos.each do |belongs_to_config|
54
+ child = belongs_to_config.load_child(db_object)
55
+ accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(belongs_to_config)
56
+
57
+ visitor.visit_belongs_to(db_object, child, belongs_to_config)
58
+ end
59
+
60
+ config.has_ones.each do |has_one_config|
61
+ child = has_one_config.load_child(db_object)
62
+ accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(has_one_config)
63
+
64
+ visitor.visit_belongs_to(db_object, child, has_one_config)
65
+ end
66
+
67
+ config.has_manys.each do |has_many_config|
68
+ children = has_many_config.load_children(db_object)
69
+ children.each do |child|
70
+ accept_for_db(child, visitor, already_visited) if visitor.continue_traversal?(has_many_config)
71
+ end
72
+ visitor.visit_has_many(db_object, children, has_many_config)
73
+ end
74
+ end
75
+ end
76
+
77
+ # @private
78
+ module AggregateVisitorTemplate
79
+ def visit_object(object, config)
80
+ # override me!
81
+ end
82
+
83
+ def visit_belongs_to(parent, child, belongs_to_config)
84
+ # override me!
85
+ end
86
+
87
+ def visit_has_one(parent, child, has_one_config)
88
+ # override me!
89
+ end
90
+
91
+ def visit_has_many(parent, children, has_many_config)
92
+ # override me!
93
+ end
94
+
95
+ def continue_traversal?(association_config)
96
+ true
97
+ end
98
+ end
@@ -1,3 +1,3 @@
1
1
  module Vorpal
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
File without changes
@@ -1,4 +1,4 @@
1
- require 'integration_spec_helper'
1
+ require 'unit_spec_helper'
2
2
 
3
3
  require 'vorpal/config_builder'
4
4
 
@@ -6,8 +6,8 @@ describe Vorpal::ConfigBuilder do
6
6
  class Tester; end
7
7
 
8
8
  it 'includes the primary key in the list of fields' do
9
- builder = Vorpal::ConfigBuilder.new(Tester, {})
10
- config = builder.build
9
+ # builder = Vorpal::ConfigBuilder.new(Tester, {})
10
+ # config = builder.build
11
11
  # config.field
12
12
  end
13
13
  end
@@ -0,0 +1,51 @@
1
+ require 'unit_spec_helper'
2
+
3
+ require 'vorpal/identity_map'
4
+
5
+ describe Vorpal::IdentityMap do
6
+ let(:map) { Vorpal::IdentityMap.new }
7
+
8
+ it 'does not rely on the key objects implementation of hash and eql?' do
9
+ funny1 = build_funny_entity(1)
10
+ map.set(funny1, 'funny 1')
11
+
12
+ funny2 = build_funny_entity(2)
13
+ map.set(funny2, 'funny 2')
14
+
15
+ expect(map.get(funny1)).to eq('funny 1')
16
+ end
17
+
18
+ it 'raises an exception when the key object does not have an id set' do
19
+ entity = build_entity(nil)
20
+
21
+ expect { map.set(entity, 'something') }.to raise_error(/Cannot put entity/)
22
+ end
23
+
24
+ def build_entity(id)
25
+ entity = Entity.new
26
+ entity.id = id
27
+ entity
28
+ end
29
+
30
+ class Entity
31
+ attr_accessor :id
32
+ end
33
+
34
+ def build_funny_entity(id)
35
+ funny1 = Funny.new
36
+ funny1.id = id
37
+ funny1
38
+ end
39
+
40
+ class Funny
41
+ attr_accessor :id
42
+
43
+ def hash
44
+ 1
45
+ end
46
+
47
+ def eql?(other)
48
+ true
49
+ end
50
+ end
51
+ end
data/vorpal.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_runtime_dependency "simple_serializer", "~> 0.0.1"
21
22
 
22
23
  spec.add_development_dependency "rake", "~> 10.0"
23
24
  spec.add_development_dependency "rspec", "~> 3.0.0"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vorpal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Kirby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-02 00:00:00.000000000 Z
11
+ date: 2015-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: simple_serializer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.1
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,8 +108,6 @@ files:
94
108
  - LICENSE.txt
95
109
  - README.md
96
110
  - Rakefile
97
- - lib/simple_serializer/simple_deserializer.rb
98
- - lib/simple_serializer/simple_serializer.rb
99
111
  - lib/vorpal.rb
100
112
  - lib/vorpal/aggregate_repository.rb
101
113
  - lib/vorpal/config_builder.rb
@@ -103,10 +115,13 @@ files:
103
115
  - lib/vorpal/configuration.rb
104
116
  - lib/vorpal/hash_initialization.rb
105
117
  - lib/vorpal/identity_map.rb
118
+ - lib/vorpal/traversal.rb
106
119
  - lib/vorpal/version.rb
107
120
  - spec/integration_spec_helper.rb
121
+ - spec/unit_spec_helper.rb
108
122
  - spec/vorpal/aggregate_repository_spec.rb
109
123
  - spec/vorpal/class_config_builder_spec.rb
124
+ - spec/vorpal/identity_map_spec.rb
110
125
  - vorpal.gemspec
111
126
  homepage: https://github.com/nulogy/vorpal
112
127
  licenses:
@@ -134,5 +149,7 @@ specification_version: 4
134
149
  summary: Separate your domain model from your persistence mechanism.
135
150
  test_files:
136
151
  - spec/integration_spec_helper.rb
152
+ - spec/unit_spec_helper.rb
137
153
  - spec/vorpal/aggregate_repository_spec.rb
138
154
  - spec/vorpal/class_config_builder_spec.rb
155
+ - spec/vorpal/identity_map_spec.rb
@@ -1,67 +0,0 @@
1
- # Simple framelet for deserialization
2
- #
3
- # class SomeDeserializer < SimpleDeserializer
4
- # data_attributes :site_id, :name, :category_id, :integration_key
5
- #
6
- # def integration_key(old_integration_key)
7
- # "XX#{@data[:other_attr]}XX#{old_integration_key}XX"
8
- # end
9
- #
10
- # def set_category_id(category_id)
11
- # object.category = InventoryStatusCategory.from_id(category_id)
12
- # end
13
- # end
14
- #
15
- # Usage:
16
- #
17
- # SomeDeserializer.deserialize(object, data)
18
- # SomeDeserializer.new(object, data).deserialize
19
- #
20
- # SomeDeserializer.deserialize_array([object1, object2, ...], [data1, data2, ...])
21
- #
22
- class SimpleDeserializer
23
- class << self
24
- attr_accessor :_attributes
25
-
26
- def inherited(base)
27
- base._attributes = []
28
- end
29
-
30
- def data_attributes(*attrs)
31
- @_attributes.concat attrs
32
-
33
- attrs.each do |attr|
34
- define_method attr do |datum|
35
- datum
36
- end unless method_defined?(attr)
37
-
38
- define_method "set_#{attr}" do |datum|
39
- object.send("#{attr}=", send(attr, datum))
40
- end unless method_defined?("set_#{attr}")
41
- end
42
- end
43
-
44
- def deserialize_array(objects, data)
45
- objects.zip(data).map { |obj, datum| deserialize(obj, datum) }
46
- end
47
-
48
- def deserialize(object, data)
49
- self.new(object, data).deserialize
50
- end
51
- end
52
-
53
- attr_accessor :object
54
-
55
- def initialize(object, data)
56
- @object = object
57
- @data = data
58
- end
59
-
60
- def deserialize
61
- self.class._attributes.dup.each do |name|
62
- next unless @data.has_key?(name)
63
- send("set_#{name}", @data[name])
64
- end
65
- object
66
- end
67
- end
@@ -1,72 +0,0 @@
1
- # Simple framelet for serialization.
2
- #
3
- # API compatible with ActiveModel::Serializer but without all the complexity
4
- # and dependence on ActiveModel
5
- #
6
- # class SomeSerializer < SimpleSerializer
7
- # attributes :id, :name, :category_id, :errors
8
- #
9
- # def category_id
10
- # object.category.try(:id)
11
- # end
12
- #
13
- # def errors
14
- # ActiveModelErrorsSerializer.serialize_errors(object.errors, true) if object.errors.any?
15
- # end
16
- # end
17
- #
18
- # Usage:
19
- #
20
- # SomeSerializer.serialize(object)
21
- # SomeSerializer.new(object).serialize
22
- #
23
- # SomeSerializer.serialize_array([object])
24
- #
25
- class SimpleSerializer
26
- class << self
27
- attr_accessor :_attributes
28
-
29
- def inherited(base)
30
- base._attributes = []
31
- end
32
-
33
- def attributes(*attrs)
34
- @_attributes.concat attrs
35
-
36
- attrs.each do |attr|
37
- define_method attr do
38
- object.send(attr)
39
- end unless method_defined?(attr)
40
- end
41
- end
42
-
43
- def serialize_array(objects)
44
- objects.map { |obj| serialize(obj) }
45
- end
46
-
47
- def serialize(object)
48
- self.new(object).serialize
49
- end
50
-
51
- alias :as_json :serialize
52
- end
53
-
54
- attr_accessor :object
55
-
56
- def initialize(object, _={})
57
- @object = object
58
- end
59
-
60
- def attributes
61
- self.class._attributes.dup.each_with_object({}) do |name, hash|
62
- hash[name] = send(name)
63
- end
64
- end
65
-
66
- def serialize(_={})
67
- return nil if object.nil?
68
- attributes
69
- end
70
- alias :as_json :serialize
71
- end
72
-