vorpal 0.0.7.rc1 → 0.0.7.rc2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +5 -4
- data/lib/vorpal/aggregate_repository.rb +50 -244
- data/lib/vorpal/configuration.rb +5 -5
- data/lib/vorpal/db_driver.rb +44 -3
- data/lib/vorpal/db_loader.rb +7 -1
- data/lib/vorpal/engine.rb +241 -0
- data/lib/vorpal/version.rb +1 -1
- data/lib/vorpal.rb +4 -3
- data/spec/vorpal/acceptance/aggregate_repository_spec.rb +103 -65
- data/spec/vorpal/performance/performance_spec.rb +13 -12
- data/spec/vorpal/unit/config_builder_spec.rb +1 -0
- data/vorpal.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b6b4c26a538b1aeac920b566ce3b80e0b04e4fe
|
4
|
+
data.tar.gz: 88d0f3a57930e3a8587d89d085293ac9d032fc58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0190b9231a1ecce12aec8c62a92345e62ae98470f488401f8e0947ddf37bba7573263a9b78b79635958d85614b9249ab952526542cfe48a081c1d6de179ff3d
|
7
|
+
data.tar.gz: 32e2963bc4cb79a56de8499fff09b439475f0371d6b4d6f2cfaa8bb87d5b431070965adfcf708e45546db846063418abcabd5e9e64ed8af4054e9c45fbe37be7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Please see https://github.com/nulogy/vorpal/releases
|
data/README.md
CHANGED
@@ -109,7 +109,7 @@ require 'vorpal'
|
|
109
109
|
module TreeRepository
|
110
110
|
extend self
|
111
111
|
|
112
|
-
|
112
|
+
engine = Vorpal.define do
|
113
113
|
map Tree do
|
114
114
|
attributes :name
|
115
115
|
belongs_to :gardener, owned: false
|
@@ -123,9 +123,10 @@ module TreeRepository
|
|
123
123
|
belongs_to :tree
|
124
124
|
end
|
125
125
|
end
|
126
|
+
@repository = engine.repository_for(Tree)
|
126
127
|
|
127
|
-
def find(
|
128
|
-
@repository.
|
128
|
+
def find(tree_id)
|
129
|
+
@repository.load_one(@repository.db_class.where(id: tree_id).first)
|
129
130
|
end
|
130
131
|
|
131
132
|
def save(tree)
|
@@ -137,7 +138,7 @@ module TreeRepository
|
|
137
138
|
end
|
138
139
|
|
139
140
|
def destroy_by_id(tree_id)
|
140
|
-
@repository.destroy_by_id(tree_id
|
141
|
+
@repository.destroy_by_id(tree_id)
|
141
142
|
end
|
142
143
|
end
|
143
144
|
```
|
@@ -1,286 +1,92 @@
|
|
1
1
|
require 'vorpal/identity_map'
|
2
|
-
require 'vorpal/aggregate_utils'
|
3
|
-
require 'vorpal/db_loader'
|
4
|
-
require 'vorpal/db_driver'
|
5
2
|
|
6
3
|
module Vorpal
|
7
4
|
class AggregateRepository
|
8
5
|
# @private
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@
|
6
|
+
def initialize(domain_class, engine)
|
7
|
+
@domain_class = domain_class
|
8
|
+
@engine = engine
|
12
9
|
end
|
13
10
|
|
14
|
-
# Saves
|
11
|
+
# Saves a collection of aggregates to the DB. Inserts objects that are new to an
|
15
12
|
# aggregate, updates existing objects and deletes objects that are no longer
|
16
13
|
# present.
|
17
14
|
#
|
18
|
-
# Objects that are on the boundary of
|
15
|
+
# Objects that are on the boundary of an aggregate (owned: false) will not
|
19
16
|
# be inserted, updated, or deleted. However, the relationships to these
|
20
|
-
# objects (provided they are stored within
|
17
|
+
# objects (provided they are stored within an aggregate) will be saved.
|
21
18
|
#
|
22
|
-
# @param
|
23
|
-
#
|
24
|
-
def persist(root)
|
25
|
-
persist_all([root]).first
|
26
|
-
end
|
27
|
-
|
28
|
-
# Like {#persist} but operates on multiple aggregates. Roots must
|
29
|
-
# be of the same type.
|
30
|
-
#
|
31
|
-
# @param roots [[Object]] array of aggregate roots to be saved.
|
19
|
+
# @param roots [[Object]] array of aggregate roots to be saved. Will also accept a
|
20
|
+
# single aggregate.
|
32
21
|
# @return [[Object]] array of aggregate roots.
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
all_owned_objects = all_owned_objects(roots)
|
38
|
-
mapping = {}
|
39
|
-
loaded_db_objects = load_owned_from_db(roots.map(&:id).compact, roots.first.class)
|
40
|
-
|
41
|
-
serialize(all_owned_objects, mapping, loaded_db_objects)
|
42
|
-
new_objects = get_unsaved_objects(mapping.keys)
|
43
|
-
begin
|
44
|
-
set_primary_keys(all_owned_objects, mapping)
|
45
|
-
set_foreign_keys(all_owned_objects, mapping)
|
46
|
-
remove_orphans(mapping, loaded_db_objects)
|
47
|
-
save(all_owned_objects, new_objects, mapping)
|
48
|
-
|
49
|
-
return roots
|
50
|
-
rescue Exception
|
51
|
-
nil_out_object_ids(new_objects)
|
52
|
-
raise
|
53
|
-
end
|
22
|
+
# @raise [InvalidAggregateRoot] When any of the roots are nil.
|
23
|
+
def persist(roots)
|
24
|
+
@engine.persist(roots)
|
54
25
|
end
|
55
26
|
|
56
27
|
# Loads an aggregate from the DB. Will eagerly load all objects in the
|
57
28
|
# aggregate and on the boundary (owned: false).
|
58
29
|
#
|
59
|
-
# @param
|
60
|
-
# loaded.
|
61
|
-
# @param
|
62
|
-
#
|
63
|
-
# @param identity_map [Vorpal::IdentityMap] Provide your own IdentityMap instance
|
64
|
-
# if you want entity id - unique object mapping for a greater scope than one
|
30
|
+
# @param db_root [Object] DB representation of the root of the aggregate to be
|
31
|
+
# loaded. This can be nil.
|
32
|
+
# @param identity_map [IdentityMap] Provide your own IdentityMap instance
|
33
|
+
# if you want entity id -> unique object mapping for a greater scope than one
|
65
34
|
# operation.
|
66
|
-
# @return [Object]
|
67
|
-
def
|
68
|
-
|
35
|
+
# @return [Object] Aggregate root corresponding to the given DB representation.
|
36
|
+
def load_one(db_root, identity_map=IdentityMap.new)
|
37
|
+
@engine.load_one(db_root, @domain_class, identity_map)
|
69
38
|
end
|
70
39
|
|
71
|
-
# Like {#
|
40
|
+
# Like {#load_one} but operates on multiple aggregate roots.
|
72
41
|
#
|
73
|
-
# @param
|
42
|
+
# @param db_roots [[Integer]] Array of primary key values of the roots of the
|
74
43
|
# aggregates to be loaded.
|
75
|
-
# @param
|
76
|
-
#
|
77
|
-
# if you want entity id - unique object mapping for a greater scope than one
|
44
|
+
# @param identity_map [IdentityMap] Provide your own IdentityMap instance
|
45
|
+
# if you want entity id -> unique object mapping for a greater scope than one
|
78
46
|
# operation.
|
79
|
-
# @return [[Object]]
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
loaded_db_objects = load_from_db(ids, domain_class)
|
84
|
-
objects = deserialize(loaded_db_objects, identity_map)
|
85
|
-
set_associations(loaded_db_objects, identity_map)
|
86
|
-
|
87
|
-
sorted_roots(ids, objects, domain_class)
|
88
|
-
end
|
89
|
-
|
90
|
-
# Removes an aggregate from the DB. Even if the aggregate contains unsaved
|
91
|
-
# changes this method will correctly remove everything.
|
92
|
-
#
|
93
|
-
# @param root [Object] Root of the aggregate to be destroyed.
|
94
|
-
# @return [Object] Root that was passed in.
|
95
|
-
def destroy(root)
|
96
|
-
destroy_all([root]).first
|
47
|
+
# @return [[Object]] Aggregate roots corresponding to the given DB representations.
|
48
|
+
# @raise [InvalidAggregateRoot] When any of the db_roots are nil.
|
49
|
+
def load_many(db_roots, identity_map=IdentityMap.new)
|
50
|
+
@engine.load_many(db_roots, @domain_class, identity_map)
|
97
51
|
end
|
98
52
|
|
99
|
-
#
|
100
|
-
#
|
53
|
+
# Removes a collection of aggregates from the DB. Even if an aggregate
|
54
|
+
# contains unsaved changes this method will correctly remove everything.
|
101
55
|
#
|
102
|
-
# @param roots [[Object]]
|
56
|
+
# @param roots [[Object]] Roots of the aggregates to be destroyed. Also accepts a
|
57
|
+
# single root.
|
103
58
|
# @return [[Object]] Roots that were passed in.
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
destroy_all_by_id(roots.map(&:id), roots.first.class)
|
109
|
-
roots
|
59
|
+
# @raise [InvalidAggregateRoot] When any of the roots are nil.
|
60
|
+
def destroy(roots)
|
61
|
+
@engine.destroy(roots)
|
110
62
|
end
|
111
63
|
|
112
|
-
# Removes
|
64
|
+
# Removes a collection of aggregates from the DB given their primary keys.
|
113
65
|
#
|
114
|
-
# @param
|
115
|
-
#
|
116
|
-
#
|
117
|
-
def destroy_by_id(
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
# Like {#destroy_by_id} but operates on multiple ids. Roots must
|
122
|
-
# be of the same type.
|
123
|
-
#
|
124
|
-
# @param ids [[Integer]] Ids of roots of the aggregates to be destroyed.
|
125
|
-
# @param domain_class [Class] Type of the roots of the aggregates to
|
126
|
-
# be destroyed.
|
127
|
-
def destroy_all_by_id(ids, domain_class)
|
128
|
-
raise InvalidPrimaryKeyValue, 'Nil primary key values are not allowed.' if ids.any?(&:nil?)
|
129
|
-
|
130
|
-
loaded_db_objects = load_owned_from_db(ids, domain_class)
|
131
|
-
loaded_db_objects.each do |config, db_objects|
|
132
|
-
@db_driver.destroy(config, db_objects.map(&:id))
|
133
|
-
end
|
134
|
-
ids
|
66
|
+
# @param ids [[Integer]] Ids of roots of the aggregates to be destroyed. Also
|
67
|
+
# accepts a single id.
|
68
|
+
# @raise [InvalidPrimaryKeyValue] When any of the ids are nil.
|
69
|
+
def destroy_by_id(ids)
|
70
|
+
@engine.destroy_by_id(ids, @domain_class)
|
135
71
|
end
|
136
72
|
|
137
73
|
# Returns the DB Class (e.g. ActiveRecord::Base class) that is responsible
|
138
74
|
# for accessing the associated data in the DB.
|
139
|
-
def db_class
|
140
|
-
@
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
def all_owned_objects(roots)
|
146
|
-
AggregateUtils.group_by_type(roots, @configs)
|
147
|
-
end
|
148
|
-
|
149
|
-
def load_from_db(ids, domain_class, only_owned=false)
|
150
|
-
DbLoader.new(only_owned, @db_driver).load_from_db(ids, @configs.config_for(domain_class))
|
151
|
-
end
|
152
|
-
|
153
|
-
def load_owned_from_db(ids, domain_class)
|
154
|
-
load_from_db(ids, domain_class, true)
|
155
|
-
end
|
156
|
-
|
157
|
-
def deserialize(loaded_db_objects, identity_map)
|
158
|
-
loaded_db_objects.flat_map do |config, db_objects|
|
159
|
-
db_objects.map do |db_object|
|
160
|
-
# TODO: There is a bug here when you have something in the IdentityMap that is stale and needs to be updated.
|
161
|
-
identity_map.get_and_set(db_object) { config.deserialize(db_object) }
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def set_associations(loaded_db_objects, identity_map)
|
167
|
-
loaded_db_objects.each do |config, db_objects|
|
168
|
-
db_objects.each do |db_object|
|
169
|
-
config.local_association_configs.each do |association_config|
|
170
|
-
db_remote = loaded_db_objects.find_by_id(
|
171
|
-
association_config.remote_class_config(db_object),
|
172
|
-
association_config.fk_value(db_object)
|
173
|
-
)
|
174
|
-
association_config.associate(identity_map.get(db_object), identity_map.get(db_remote))
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def sorted_roots(ids, objects, domain_class)
|
181
|
-
roots = objects.select { |obj| obj.class == domain_class }
|
182
|
-
roots_by_id = roots.reduce({}) { |h, root| h[root.id] = root; h }
|
183
|
-
ids.map { |id| roots_by_id[id] }.compact
|
184
|
-
end
|
185
|
-
|
186
|
-
def serialize(owned_objects, mapping, loaded_db_objects)
|
187
|
-
owned_objects.each do |config, objects|
|
188
|
-
objects.each do |object|
|
189
|
-
db_object = serialize_object(object, config, loaded_db_objects)
|
190
|
-
mapping[object] = db_object
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
def serialize_object(object, config, loaded_db_objects)
|
196
|
-
if config.serialization_required?
|
197
|
-
attributes = config.serialize(object)
|
198
|
-
if object.id.nil?
|
199
|
-
config.build_db_object(attributes)
|
200
|
-
else
|
201
|
-
db_object = loaded_db_objects.find_by_id(config, object.id)
|
202
|
-
config.set_db_object_attributes(db_object, attributes)
|
203
|
-
db_object
|
204
|
-
end
|
205
|
-
else
|
206
|
-
object
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def set_primary_keys(owned_objects, mapping)
|
211
|
-
owned_objects.each do |config, objects|
|
212
|
-
in_need_of_primary_keys = objects.find_all { |obj| obj.id.nil? }
|
213
|
-
primary_keys = @db_driver.get_primary_keys(config, in_need_of_primary_keys.length)
|
214
|
-
in_need_of_primary_keys.zip(primary_keys).each do |object, primary_key|
|
215
|
-
mapping[object].id = primary_key
|
216
|
-
object.id = primary_key
|
217
|
-
end
|
218
|
-
end
|
219
|
-
mapping.rehash # needs to happen because setting the id on an AR::Base model changes its hash value
|
220
|
-
end
|
221
|
-
|
222
|
-
def set_foreign_keys(owned_objects, mapping)
|
223
|
-
owned_objects.each do |config, objects|
|
224
|
-
objects.each do |object|
|
225
|
-
config.has_manys.each do |has_many_config|
|
226
|
-
if has_many_config.owned
|
227
|
-
children = has_many_config.get_children(object)
|
228
|
-
children.each do |child|
|
229
|
-
has_many_config.set_foreign_key(mapping[child], object)
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
config.has_ones.each do |has_one_config|
|
235
|
-
if has_one_config.owned
|
236
|
-
child = has_one_config.get_child(object)
|
237
|
-
has_one_config.set_foreign_key(mapping[child], object)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
config.belongs_tos.each do |belongs_to_config|
|
242
|
-
child = belongs_to_config.get_child(object)
|
243
|
-
belongs_to_config.set_foreign_key(mapping[object], child)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
def save(owned_objects, new_objects, mapping)
|
250
|
-
grouped_new_objects = new_objects.group_by { |obj| @configs.config_for(obj.class) }
|
251
|
-
owned_objects.each do |config, objects|
|
252
|
-
objects_to_insert = grouped_new_objects[config] || []
|
253
|
-
db_objects_to_insert = objects_to_insert.map { |obj| mapping[obj] }
|
254
|
-
@db_driver.insert(config, db_objects_to_insert)
|
255
|
-
|
256
|
-
objects_to_update = objects - objects_to_insert
|
257
|
-
db_objects_to_update = objects_to_update.map { |obj| mapping[obj] }
|
258
|
-
@db_driver.update(config, db_objects_to_update)
|
259
|
-
end
|
75
|
+
def db_class
|
76
|
+
@engine.db_class(@domain_class)
|
260
77
|
end
|
261
78
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
@db_driver.destroy(config, orphans)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def get_unsaved_objects(objects)
|
273
|
-
objects.find_all { |object| object.id.nil? }
|
79
|
+
# Access to the underlying mapping {Engine}. Provided in case access to another aggregate
|
80
|
+
# or another db_class is required.
|
81
|
+
#
|
82
|
+
# @return [Engine] Mapping interface not specific to a particular aggregate root.
|
83
|
+
def engine
|
84
|
+
@engine
|
274
85
|
end
|
275
86
|
|
276
|
-
def
|
277
|
-
|
278
|
-
|
87
|
+
def query
|
88
|
+
# db_class.unscoped.extending(ArelQueryMethods.new(self))
|
89
|
+
@engine.query(@domain_class)
|
279
90
|
end
|
280
91
|
end
|
281
|
-
|
282
|
-
class InvalidPrimaryKeyValue < StandardError
|
283
|
-
end
|
284
|
-
class InvalidAggregateRoot < StandardError
|
285
|
-
end
|
286
92
|
end
|
data/lib/vorpal/configuration.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
require 'vorpal/
|
1
|
+
require 'vorpal/engine'
|
2
2
|
require 'vorpal/config_builder'
|
3
3
|
|
4
4
|
module Vorpal
|
5
5
|
module Configuration
|
6
6
|
|
7
|
-
# Configures and creates a {
|
7
|
+
# Configures and creates a {Engine} instance.
|
8
8
|
#
|
9
9
|
# @param options [Hash] Global configuration options for the repository instance.
|
10
10
|
# @option options [Object] :db_driver (Object that will be used to interact with the DB.)
|
11
|
-
# Must be duck-type compatible with {
|
11
|
+
# Must be duck-type compatible with {DbDriver}.
|
12
12
|
#
|
13
|
-
# @return [
|
13
|
+
# @return [Engine] Instance of the mapping engine.
|
14
14
|
def define(options={}, &block)
|
15
15
|
master_config = build_config(&block)
|
16
16
|
db_driver = options.fetch(:db_driver, DbDriver.new)
|
17
|
-
|
17
|
+
Engine.new(db_driver, master_config)
|
18
18
|
end
|
19
19
|
|
20
20
|
# Maps a domain class to a relational table.
|
data/lib/vorpal/db_driver.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Vorpal
|
2
|
-
#
|
2
|
+
# Interface between the database and Vorpal
|
3
3
|
#
|
4
|
-
# Currently only works for PostgreSQL.
|
4
|
+
# Currently only works for PostgreSQL via ActiveRecord.
|
5
5
|
class DbDriver
|
6
6
|
def initialize
|
7
7
|
@sequence_names = {}
|
@@ -29,13 +29,16 @@ module Vorpal
|
|
29
29
|
|
30
30
|
# Loads instances of the given class by primary key.
|
31
31
|
#
|
32
|
+
# @param class_config [ClassConfig]
|
32
33
|
# @return [[Object]] An array of entities.
|
33
34
|
def load_by_id(class_config, ids)
|
34
|
-
class_config.db_class.where(id: ids)
|
35
|
+
class_config.db_class.where(id: ids).all
|
35
36
|
end
|
36
37
|
|
37
38
|
# Loads instances of the given class whose foreign key has the given value.
|
38
39
|
#
|
40
|
+
# @param class_config [ClassConfig]
|
41
|
+
# @param foreign_key_info [ForeignKeyInfo]
|
39
42
|
# @return [[Object]] An array of entities.
|
40
43
|
def load_by_foreign_key(class_config, id, foreign_key_info)
|
41
44
|
arel = class_config.db_class.where(foreign_key_info.fk_column => id)
|
@@ -45,6 +48,7 @@ module Vorpal
|
|
45
48
|
|
46
49
|
# Fetches primary key values to be used for new entities.
|
47
50
|
#
|
51
|
+
# @param class_config [ClassConfig] Config of the entity whose primary keys are being fetched.
|
48
52
|
# @return [[Integer]] An array of unused primary keys.
|
49
53
|
def get_primary_keys(class_config, count)
|
50
54
|
result = execute("select nextval($1) from generate_series(1,$2);", [sequence_name(class_config), count])
|
@@ -53,6 +57,7 @@ module Vorpal
|
|
53
57
|
|
54
58
|
# Builds an ORM Class for accessing data in the given DB table.
|
55
59
|
#
|
60
|
+
# @param table_name [String] Name of the DB table the DB class should interface with.
|
56
61
|
# @return [Class] ActiveRecord::Base Class
|
57
62
|
def build_db_class(table_name)
|
58
63
|
db_class = Class.new(ActiveRecord::Base)
|
@@ -60,6 +65,13 @@ module Vorpal
|
|
60
65
|
db_class
|
61
66
|
end
|
62
67
|
|
68
|
+
# Builds a composable query object (e.g. ActiveRecord::Relation) with Vorpal methods mixed in.
|
69
|
+
#
|
70
|
+
# @param class_config [ClassConfig] Config of the entity whose db representations should be returned.
|
71
|
+
def query(class_config)
|
72
|
+
class_config.db_class.unscoped.extending(ArelQueryMethods.new(self))
|
73
|
+
end
|
74
|
+
|
63
75
|
private
|
64
76
|
|
65
77
|
def sequence_name(class_config)
|
@@ -74,4 +86,33 @@ module Vorpal
|
|
74
86
|
ActiveRecord::Base.connection.exec_query(sql, 'SQL', binds)
|
75
87
|
end
|
76
88
|
end
|
89
|
+
|
90
|
+
class ArelQueryMethods < Module
|
91
|
+
def initialize(repository)
|
92
|
+
@repository = repository
|
93
|
+
end
|
94
|
+
|
95
|
+
def extended(descendant)
|
96
|
+
super
|
97
|
+
descendant.extend(Methods)
|
98
|
+
descendant.vorpal_aggregate_repository = @repository
|
99
|
+
end
|
100
|
+
|
101
|
+
# Methods in this module will appear on any composable
|
102
|
+
module Methods
|
103
|
+
attr_writer :vorpal_aggregate_repository
|
104
|
+
|
105
|
+
# See {AggregateRepository#load_many}.
|
106
|
+
def load_many
|
107
|
+
db_roots = self.all
|
108
|
+
@vorpal_aggregate_repository.load_many(db_roots)
|
109
|
+
end
|
110
|
+
|
111
|
+
# See {AggregateRepository#load_one}.
|
112
|
+
def load_one
|
113
|
+
db_root = self.first
|
114
|
+
@vorpal_aggregate_repository.load_one(db_root)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
77
118
|
end
|
data/lib/vorpal/db_loader.rb
CHANGED
@@ -13,9 +13,15 @@ module Vorpal
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def load_from_db(ids, config)
|
16
|
+
db_roots = @db_driver.load_by_id(config, ids)
|
17
|
+
load_from_db_objects(db_roots, config)
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_from_db_objects(db_roots, config)
|
16
21
|
@loaded_objects = LoadedObjects.new
|
22
|
+
@loaded_objects.add(config, db_roots)
|
17
23
|
@lookup_instructions = LookupInstructions.new
|
18
|
-
|
24
|
+
explore_objects(config, db_roots)
|
19
25
|
|
20
26
|
until @lookup_instructions.empty?
|
21
27
|
lookup = @lookup_instructions.next_lookup
|