vorpal 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +38 -21
- data/Rakefile +9 -1
- data/lib/vorpal/aggregate_repository.rb +7 -4
- data/lib/vorpal/config_builder.rb +5 -5
- data/lib/vorpal/configs.rb +3 -7
- data/lib/vorpal/configuration.rb +2 -2
- data/lib/vorpal/version.rb +1 -1
- data/spec/integration_spec_helper.rb +0 -8
- data/spec/vorpal/aggregate_repository_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTFlNjY4ZjU3YWRhNmY2ZDFmZmFiMTBiMTk3ZWY5ZjVhYjc1NTAzYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
N2FkZmQzZDBiMjg1MWU5MzJjYzcwMzUxNGNjMzk1NGE0NjkyMjNkYw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NTA5MTJmMWMzM2I5YzE5MmNkYjYzNDhlMzA0NjczZThkMzE1M2M2NDBiYzFj
|
10
|
+
ZGE3OTU0Zjc0NGNlNzA4Y2RiNTM4OTgyZjk1ZmY2MjgzNjY4NTNmM2NkMDI4
|
11
|
+
MjFlMGYwNzQzZWNiN2FiYTA1MzE3YTk1YmNmZTRmOTNlYzM2MWI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTJhOTJhMjFkZmYwMDJlYmQwZDVmZWY0MzkwMzgyNzRhZDA0NWYyZGFlM2Iy
|
14
|
+
NDZmYzc5MzUyNGM4MzFiOTIwYWIxMDRiNWUzMzJlYTcwY2YwMWEzNjRmOGM3
|
15
|
+
MGM4Nzg1MzRjMzUxNzgzZmFjOTg2YjU3ZDQ2ZmM0NTlkZDNkMWE=
|
data/README.md
CHANGED
@@ -108,41 +108,41 @@ require 'vorpal'
|
|
108
108
|
|
109
109
|
module TreeRepository
|
110
110
|
extend self
|
111
|
-
|
111
|
+
|
112
|
+
class TreeDB < ActiveRecord::Base
|
113
|
+
self.table_name = 'trees'
|
114
|
+
end
|
115
|
+
|
116
|
+
class BranchDB < ActiveRecord::Base
|
117
|
+
self.table_name = 'branches'
|
118
|
+
end
|
119
|
+
|
112
120
|
@repository = Vorpal.define do
|
113
|
-
map Tree do
|
121
|
+
map Tree, to: TreeDB do
|
114
122
|
fields :name
|
115
123
|
belongs_to :gardener, owned: false
|
116
124
|
has_many :branches
|
117
125
|
end
|
118
126
|
|
119
|
-
map Gardener
|
120
|
-
|
121
|
-
map Branch do
|
127
|
+
map Gardener, to: Gardener
|
128
|
+
|
129
|
+
map Branch, to: BranchDB do
|
122
130
|
fields :length, :diameter
|
123
131
|
belongs_to :tree
|
124
132
|
end
|
125
133
|
end
|
126
|
-
|
134
|
+
|
127
135
|
def find(id)
|
128
136
|
@repository.load(id, Tree)
|
129
137
|
end
|
130
|
-
|
138
|
+
|
131
139
|
def save(tree)
|
132
140
|
@repository.persist(tree)
|
133
141
|
end
|
134
|
-
|
142
|
+
|
135
143
|
def destroy(tree)
|
136
144
|
@repository.destroy(tree)
|
137
145
|
end
|
138
|
-
|
139
|
-
class ARTree < ActiveRecord::Base
|
140
|
-
self.table_name = 'trees'
|
141
|
-
end
|
142
|
-
|
143
|
-
class ARBranch < ActiveRecord::Base
|
144
|
-
self.table_name = 'branches'
|
145
|
-
end
|
146
146
|
end
|
147
147
|
```
|
148
148
|
|
@@ -184,12 +184,12 @@ It also does not do some things that you might expect from other ORMs:
|
|
184
184
|
|
185
185
|
## Future Enhancements
|
186
186
|
* Aggregate updated_at.
|
187
|
-
* Support for other DBMSs
|
187
|
+
* Support for other DBMSs (no MySQL support until ids can be generated without inserting into a table!)
|
188
188
|
* Support for other ORMs.
|
189
189
|
* Value objects.
|
190
|
-
* Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions?)
|
191
|
-
* More efficient object loading (use fewer queries.)
|
192
|
-
*
|
190
|
+
* Remove dependency on ActiveRecord (optimistic locking? updated_at, created_at support? Data type conversions? TimeZone support?)
|
191
|
+
* More efficient object loading and persisting (use fewer queries.)
|
192
|
+
* Nicer DSL for specifying field that have different names in the domain model than in the DB.
|
193
193
|
|
194
194
|
## FAQ
|
195
195
|
|
@@ -203,7 +203,16 @@ It also does not do some things that you might expect from other ORMs:
|
|
203
203
|
|
204
204
|
**Q.** How do I do more complicated queries against the DB without direct access to ActiveRecord?
|
205
205
|
|
206
|
-
**A.** Create a method on a [Repository](http://martinfowler.com/eaaCatalog/repository.html)! They have full access to the DB/ORM so you can use [Arel](https://github.com/rails/arel) and go [crazy](http://asciicasts.com/episodes/239-activerecord-relation-walkthrough) or use direct SQL if you want.
|
206
|
+
**A.** Create a method on a [Repository](http://martinfowler.com/eaaCatalog/repository.html)! They have full access to the DB/ORM so you can use [Arel](https://github.com/rails/arel) and go [crazy](http://asciicasts.com/episodes/239-activerecord-relation-walkthrough) or use direct SQL if you want.
|
207
|
+
|
208
|
+
For example:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
def find_all
|
212
|
+
ids = TreeDB.pluck(:id) # use an AR query to determine the aggregate ids
|
213
|
+
@repository.load_all(ids, Tree) # use the repository to load all the aggregates
|
214
|
+
end
|
215
|
+
```
|
207
216
|
|
208
217
|
**Q.** How do I do validations now that I don't have access to ActiveRecord anymore?
|
209
218
|
|
@@ -223,6 +232,14 @@ It also does not do some things that you might expect from other ORMs:
|
|
223
232
|
|
224
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.
|
225
234
|
|
235
|
+
## Running Tests
|
236
|
+
|
237
|
+
1. Start a PostgreSQL server.
|
238
|
+
2. Either:
|
239
|
+
* Create a DB user called `vorpal` with password `pass` and a DB called `vorpal_test`. OR:
|
240
|
+
* Modify `spec/integration_spec_helper.rb`.
|
241
|
+
3. Run `rake` from the terminal.
|
242
|
+
|
226
243
|
## Contributors
|
227
244
|
|
228
245
|
* [Sean Kirby](https://github.com/sskirby)
|
data/Rakefile
CHANGED
@@ -1,2 +1,10 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks associated with creating new versions of the gem.'
|
6
|
+
end
|
2
7
|
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
task :default => :spec
|
@@ -36,8 +36,6 @@ class AggregateRepository
|
|
36
36
|
#
|
37
37
|
# @param objects [[Object]] array of aggregate roots to be saved.
|
38
38
|
# @return [[Object]] array of aggregate roots.
|
39
|
-
#
|
40
|
-
# TODO: Nil out object ids if one of the objects can't be saved?
|
41
39
|
def persist_all(objects)
|
42
40
|
objects.map(&method(:persist))
|
43
41
|
end
|
@@ -49,6 +47,9 @@ class AggregateRepository
|
|
49
47
|
# loaded.
|
50
48
|
# @param domain_class [Class] Type of the root of the aggregate to
|
51
49
|
# be loaded.
|
50
|
+
# @param identity_map [Vorpal::IdentityMap] Provide your own IdentityMap instance
|
51
|
+
# if you want entity id - unique object mapping for a greater scope than one
|
52
|
+
# operation.
|
52
53
|
# @return [Object] Entity with the given primary key value and type.
|
53
54
|
def load(id, domain_class, identity_map=IdentityMap.new)
|
54
55
|
db_object = @configs.config_for(domain_class).load_by_id(id)
|
@@ -60,6 +61,9 @@ class AggregateRepository
|
|
60
61
|
# @param ids [[Integer]] Array of primary key values of the roots of the
|
61
62
|
# aggregates to be loaded.
|
62
63
|
# @param domain_class [Class] Type of the roots of the aggregate to be loaded.
|
64
|
+
# @param identity_map [Vorpal::IdentityMap] Provide your own IdentityMap instance
|
65
|
+
# if you want entity id - unique object mapping for a greater scope than one
|
66
|
+
# operation.
|
63
67
|
# @return [[Object]] Entities with the given primary key values and type.
|
64
68
|
def load_all(ids, domain_class, identity_map=IdentityMap.new)
|
65
69
|
ids.map { |id| load(id, domain_class, identity_map) }
|
@@ -83,8 +87,7 @@ class AggregateRepository
|
|
83
87
|
# @param objects [[Object]] Array of roots of the aggregates to be destroyed.
|
84
88
|
# @return [[Object]] Roots that were passed in.
|
85
89
|
def destroy_all(objects)
|
86
|
-
objects.
|
87
|
-
objects
|
90
|
+
objects.map(&method(:destroy))
|
88
91
|
end
|
89
92
|
|
90
93
|
private
|
@@ -77,18 +77,18 @@ class ConfigBuilder
|
|
77
77
|
def build_class_config
|
78
78
|
Vorpal::ClassConfig.new(
|
79
79
|
domain_class: @domain_class,
|
80
|
-
|
80
|
+
db_class: @class_options[:to] || db_class,
|
81
81
|
serializer: @class_options[:serializer] || serializer(fields_with_id),
|
82
82
|
deserializer: @class_options[:deserializer] || deserializer(fields_with_id),
|
83
83
|
)
|
84
84
|
end
|
85
85
|
|
86
|
-
def
|
87
|
-
|
86
|
+
def db_class
|
87
|
+
"#{@domain_class.name}DB".constantize
|
88
88
|
end
|
89
89
|
|
90
|
-
def
|
91
|
-
@
|
90
|
+
def fields_with_id
|
91
|
+
[:id].concat @fields
|
92
92
|
end
|
93
93
|
|
94
94
|
def build_has_manys
|
data/lib/vorpal/configs.rb
CHANGED
@@ -39,7 +39,7 @@ end
|
|
39
39
|
|
40
40
|
# @private
|
41
41
|
class ClassConfig
|
42
|
-
attr_reader :serializer, :deserializer, :domain_class, :
|
42
|
+
attr_reader :serializer, :deserializer, :domain_class, :db_class
|
43
43
|
attr_accessor :has_manys, :belongs_tos, :has_ones
|
44
44
|
|
45
45
|
def initialize(attrs)
|
@@ -57,10 +57,6 @@ class ClassConfig
|
|
57
57
|
result.column_values(0).map(&:to_i)
|
58
58
|
end
|
59
59
|
|
60
|
-
def db_class
|
61
|
-
@db_class ||= ActiveRecord::Base.descendants.detect { |ar| ar.table_name == table_name }
|
62
|
-
end
|
63
|
-
|
64
60
|
def find_in_db(object)
|
65
61
|
db_class.find(object.id)
|
66
62
|
end
|
@@ -119,7 +115,7 @@ class ClassConfig
|
|
119
115
|
private
|
120
116
|
|
121
117
|
def sequence_name
|
122
|
-
"#{table_name}_id_seq"
|
118
|
+
"#{db_class.table_name}_id_seq"
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
@@ -143,7 +139,7 @@ end
|
|
143
139
|
# Object associations:
|
144
140
|
# - All object associations are uni-directional
|
145
141
|
# - The end that holds the association is the 'Parent' and the end that
|
146
|
-
# is
|
142
|
+
# is referred to is the 'Child' or 'Children'
|
147
143
|
#
|
148
144
|
# Relational associations:
|
149
145
|
# - Local end: has FK
|
data/lib/vorpal/configuration.rb
CHANGED
@@ -18,8 +18,8 @@ module Configuration
|
|
18
18
|
#
|
19
19
|
# @param domain_class [Class] Type of the domain model to be mapped
|
20
20
|
# @param options [Hash] Configure how to map the domain model
|
21
|
-
# @option options [String] :
|
22
|
-
#
|
21
|
+
# @option options [String] :to (Class with the same name as the domain class with a 'DB' appended.)
|
22
|
+
# Class of the ActiveRecord object that will map this domain class to the DB.
|
23
23
|
# @option options [Object] :serializer (map the {ConfigBuilder#fields} directly)
|
24
24
|
# Object that will convert the domain objects into a hash.
|
25
25
|
#
|
data/lib/vorpal/version.rb
CHANGED
@@ -12,14 +12,6 @@ ActiveRecord::Base.establish_connection(
|
|
12
12
|
)
|
13
13
|
|
14
14
|
RSpec.configure do |config|
|
15
|
-
# ## Mock Framework
|
16
|
-
#
|
17
|
-
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
18
|
-
#
|
19
|
-
# config.mock_with :mocha
|
20
|
-
# config.mock_with :flexmock
|
21
|
-
# config.mock_with :rr
|
22
|
-
|
23
15
|
# implements use_transactional_fixtures = true
|
24
16
|
# from lib/active_record/fixtures.rb
|
25
17
|
# works with Rails 3.2. Probably not with Rails 4
|
@@ -643,7 +643,7 @@ private
|
|
643
643
|
belongs_to :environment, owned: false, fk: :environment_id, fk_type: :environment_type, child_class: Swamp
|
644
644
|
end
|
645
645
|
|
646
|
-
map Swamp
|
646
|
+
map Swamp, to: Swamp
|
647
647
|
end
|
648
648
|
end
|
649
649
|
|
@@ -727,7 +727,7 @@ private
|
|
727
727
|
fields :length
|
728
728
|
end
|
729
729
|
|
730
|
-
map Fissure
|
730
|
+
map Fissure, to: Fissure
|
731
731
|
end
|
732
732
|
end
|
733
733
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vorpal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
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-
|
11
|
+
date: 2015-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|