rom-core 4.0.0.beta1 → 4.0.0.beta2
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 +2 -0
- data/lib/rom/command.rb +3 -14
- data/lib/rom/command_registry.rb +0 -28
- data/lib/rom/commands/graph.rb +2 -2
- data/lib/rom/commands/graph/class_interface.rb +1 -1
- data/lib/rom/relation.rb +33 -22
- data/lib/rom/relation/class_interface.rb +9 -9
- data/lib/rom/relation/combined.rb +116 -0
- data/lib/rom/relation/curried.rb +3 -0
- data/lib/rom/relation/graph.rb +14 -125
- data/lib/rom/relation/loaded.rb +3 -0
- data/lib/rom/relation/wrap.rb +2 -18
- data/lib/rom/version.rb +1 -1
- metadata +3 -3
- data/lib/rom/commands/result.rb +0 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ea3d114fd7800efddd98a8efe19a01586625c9f
|
4
|
+
data.tar.gz: 59a3cc776cfd019cd54583caf4ef8ee759d90f09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4349071ed68f65de26faf701b930653f56be802e14f63b82510d04c091ad0a7d0687eb23bb0e6a22b6330d6f83ec32184811701d29cd41934140d10c00ec54e6
|
7
|
+
data.tar.gz: 31885902cc6c78cf78c2f1357ee76edcf082eea550deaa293588029534a68e09d01c6a31ef14bd7e09523ad7678344184b2e3eec8f384a767ff11c94f5948f1f
|
data/CHANGELOG.md
CHANGED
@@ -28,6 +28,8 @@ Previous `rom` gem was renamed to `rom-core`
|
|
28
28
|
* [BREAKING] `Relation#as` now returns a new relation with aliased name, use `Relation#map_with(*list-of-mapper-ids)` or `Relation#map_to(model)` if you just want to map to custom models (solnic)
|
29
29
|
* [BREAKING] `Relation.register_as(:bar)` is removed in favor of `schema(:foo, as: :bar)` (solnic)
|
30
30
|
* [BREAKING] `Relation.dataset(:foo)` is removed in favor of `schema(:foo)`. Passing a block still works like before (solnic)
|
31
|
+
* [BREAKING] `CommandRegistry#try` is removed (solnic)
|
32
|
+
* [BREAKING] `Command#with` changed behavior, use `Command#curry` instead (solnic)
|
31
33
|
* Separation between relations that are standalone or registrable in a registry is gone. All relations have names and schemas now.
|
32
34
|
They are automatically set to defaults. In practice this means you can instantiate a relation object manually and it'll Just Work (solnic)
|
33
35
|
* Mapper and command objects are cached locally within a given rom container (solnic)
|
data/lib/rom/command.rb
CHANGED
@@ -23,13 +23,14 @@ module ROM
|
|
23
23
|
#
|
24
24
|
# @api public
|
25
25
|
class Command
|
26
|
+
extend Dry::Core::ClassAttributes
|
26
27
|
extend Initializer
|
28
|
+
extend ClassInterface
|
29
|
+
|
27
30
|
include Dry::Equalizer(:relation, :options)
|
28
31
|
include Commands
|
29
32
|
include Pipeline::Operator
|
30
33
|
|
31
|
-
extend Dry::Core::ClassAttributes
|
32
|
-
extend ClassInterface
|
33
34
|
|
34
35
|
# @!method self.adapter
|
35
36
|
# Get or set adapter identifier
|
@@ -316,7 +317,6 @@ module ROM
|
|
316
317
|
self.class.build(relation, **options, curry_args: args)
|
317
318
|
end
|
318
319
|
end
|
319
|
-
alias_method :with, :curry
|
320
320
|
|
321
321
|
# Compose this command with other commands
|
322
322
|
#
|
@@ -338,17 +338,6 @@ module ROM
|
|
338
338
|
curry_args.size > 0
|
339
339
|
end
|
340
340
|
|
341
|
-
# Return a new command with new options
|
342
|
-
#
|
343
|
-
# @param [Hash] new_opts A hash with new options
|
344
|
-
#
|
345
|
-
# @return [Command]
|
346
|
-
#
|
347
|
-
# @api public
|
348
|
-
def with_opts(new_opts)
|
349
|
-
self.class.new(relation, options.merge(new_opts))
|
350
|
-
end
|
351
|
-
|
352
341
|
# Return a new command with appended before hooks
|
353
342
|
#
|
354
343
|
# @param [Array<Hash>] hooks A list of before hooks configurations
|
data/lib/rom/command_registry.rb
CHANGED
@@ -2,15 +2,12 @@ require 'concurrent/map'
|
|
2
2
|
|
3
3
|
require 'rom/constants'
|
4
4
|
require 'rom/registry'
|
5
|
-
require 'rom/commands/result'
|
6
5
|
|
7
6
|
module ROM
|
8
7
|
# Specialized registry class for commands
|
9
8
|
#
|
10
9
|
# @api public
|
11
10
|
class CommandRegistry < Registry
|
12
|
-
include Commands
|
13
|
-
|
14
11
|
# Internal command registry
|
15
12
|
#
|
16
13
|
# @return [Registry]
|
@@ -35,31 +32,6 @@ module ROM
|
|
35
32
|
CommandNotFoundError
|
36
33
|
end
|
37
34
|
|
38
|
-
# Try to execute a command in a block
|
39
|
-
#
|
40
|
-
# @yield [command] Passes command to the block
|
41
|
-
#
|
42
|
-
# @example
|
43
|
-
#
|
44
|
-
# rom.commands[:users].try { create(name: 'Jane') }
|
45
|
-
# rom.commands[:users].try { update(:by_id, 1).call(name: 'Jane Doe') }
|
46
|
-
# rom.commands[:users].try { delete(:by_id, 1) }
|
47
|
-
#
|
48
|
-
# @return [Commands::Result]
|
49
|
-
#
|
50
|
-
# @api public
|
51
|
-
def try(&block)
|
52
|
-
response = block.call
|
53
|
-
|
54
|
-
if response.is_a?(Command) || response.is_a?(Composite)
|
55
|
-
try { response.call }
|
56
|
-
else
|
57
|
-
Result::Success.new(response)
|
58
|
-
end
|
59
|
-
rescue CommandError => e
|
60
|
-
Result::Failure.new(e)
|
61
|
-
end
|
62
|
-
|
63
35
|
# Return a command from the registry
|
64
36
|
#
|
65
37
|
# If mapper is set command will be turned into a composite command with
|
data/lib/rom/commands/graph.rb
CHANGED
@@ -39,8 +39,8 @@ module ROM
|
|
39
39
|
# create_task = rom.commands[:tasks].create
|
40
40
|
#
|
41
41
|
# command = create_user
|
42
|
-
# .
|
43
|
-
# .combine(create_task.
|
42
|
+
# .curry(name: 'Jane')
|
43
|
+
# .combine(create_task.curry(title: 'Task'))
|
44
44
|
#
|
45
45
|
# command.call
|
46
46
|
#
|
data/lib/rom/relation.rb
CHANGED
@@ -15,7 +15,7 @@ require 'rom/command_registry'
|
|
15
15
|
require 'rom/relation/loaded'
|
16
16
|
require 'rom/relation/curried'
|
17
17
|
require 'rom/relation/composite'
|
18
|
-
require 'rom/relation/
|
18
|
+
require 'rom/relation/combined'
|
19
19
|
require 'rom/relation/wrap'
|
20
20
|
require 'rom/relation/materializable'
|
21
21
|
require 'rom/relation/commands'
|
@@ -172,17 +172,6 @@ module ROM
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
-
# Composes with other relations
|
176
|
-
#
|
177
|
-
# @param [Array<Relation>] others The other relation(s) to compose with
|
178
|
-
#
|
179
|
-
# @return [Relation::Graph]
|
180
|
-
#
|
181
|
-
# @api public
|
182
|
-
def graph(*others)
|
183
|
-
Graph.build(self, others)
|
184
|
-
end
|
185
|
-
|
186
175
|
# Combine with other relations
|
187
176
|
#
|
188
177
|
# @overload combine(*associations)
|
@@ -196,21 +185,34 @@ module ROM
|
|
196
185
|
#
|
197
186
|
# @api public
|
198
187
|
def combine(*args)
|
199
|
-
|
188
|
+
combine_with(*nodes(*args))
|
189
|
+
end
|
190
|
+
|
191
|
+
# Composes with other relations
|
192
|
+
#
|
193
|
+
# @param [Array<Relation>] others The other relation(s) to compose with
|
194
|
+
#
|
195
|
+
# @return [Relation::Graph]
|
196
|
+
#
|
197
|
+
# @api public
|
198
|
+
def combine_with(*others)
|
199
|
+
Combined.new(self, others)
|
200
200
|
end
|
201
201
|
|
202
202
|
# @api private
|
203
203
|
def nodes(*args)
|
204
|
-
args.
|
204
|
+
args.reduce([]) do |acc, arg|
|
205
205
|
case arg
|
206
206
|
when Symbol
|
207
|
-
node(arg)
|
207
|
+
acc << node(arg)
|
208
208
|
when Hash
|
209
|
-
arg.reduce(self)
|
209
|
+
acc << arg.reduce(self) do |root, (name, *opts)|
|
210
|
+
root.node(name).combine(*opts)
|
211
|
+
end
|
210
212
|
when Array
|
211
|
-
arg.map { |opts| nodes(opts) }
|
213
|
+
acc.concat(arg.map { |opts| nodes(opts) }.reduce(:concat))
|
212
214
|
end
|
213
|
-
end
|
215
|
+
end
|
214
216
|
end
|
215
217
|
|
216
218
|
# @api public
|
@@ -236,18 +238,27 @@ module ROM
|
|
236
238
|
assoc.preload(self, other)
|
237
239
|
end
|
238
240
|
|
239
|
-
# Wrap other relations
|
241
|
+
# Wrap other relations using association names
|
240
242
|
#
|
241
243
|
# @example
|
242
244
|
# tasks.wrap(:owner)
|
243
245
|
#
|
244
246
|
# @param [Hash] options
|
245
247
|
#
|
246
|
-
# @return [
|
248
|
+
# @return [Relation]
|
247
249
|
#
|
248
250
|
# @api public
|
249
251
|
def wrap(*names)
|
250
|
-
|
252
|
+
wrap_around(*names.map { |n| associations[n].wrap })
|
253
|
+
end
|
254
|
+
|
255
|
+
# Wrap around other relations
|
256
|
+
#
|
257
|
+
# @return [Relation::Wrap]
|
258
|
+
#
|
259
|
+
# @api public
|
260
|
+
def wrap_around(*others)
|
261
|
+
wrap_class.new(self, others)
|
251
262
|
end
|
252
263
|
|
253
264
|
# Loads relation
|
@@ -431,7 +442,7 @@ module ROM
|
|
431
442
|
#
|
432
443
|
# @param [Array<Symbol>] mappers A list of mapper identifiers
|
433
444
|
#
|
434
|
-
# @return [
|
445
|
+
# @return [Relation] A new relation proxy with pipelined relation
|
435
446
|
#
|
436
447
|
# @api public
|
437
448
|
def map_with(*names, **opts)
|
@@ -95,15 +95,15 @@ module ROM
|
|
95
95
|
|
96
96
|
@relation_name = Name[relation, ds_name]
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
98
|
+
@schema_proc = proc do |*args, &inner_block|
|
99
|
+
schema_dsl.new(
|
100
|
+
relation_name,
|
101
|
+
schema_class: schema_class,
|
102
|
+
attr_class: schema_attr_class,
|
103
|
+
inferrer: schema_inferrer.with(enabled: infer),
|
104
|
+
&block
|
105
|
+
).call(*args, &inner_block)
|
106
|
+
end
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'rom/relation/graph'
|
2
|
+
require 'rom/relation/commands'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
class Relation
|
6
|
+
# Represents a relation graphs which combines root relation
|
7
|
+
# with other relation nodes
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
class Combined < Graph
|
11
|
+
include Commands
|
12
|
+
|
13
|
+
# Create a new relation combined with others
|
14
|
+
#
|
15
|
+
# @param [Relation] root
|
16
|
+
# @param [Array<Relation>] nodes
|
17
|
+
#
|
18
|
+
# @return [Combined]
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def self.new(root, nodes)
|
22
|
+
root_ns = root.options[:struct_namespace]
|
23
|
+
super(root, nodes.map { |node| node.struct_namespace(root_ns) })
|
24
|
+
end
|
25
|
+
|
26
|
+
# Combine this graph with more nodes
|
27
|
+
#
|
28
|
+
# @param [Array<Relation::Lazy>]
|
29
|
+
#
|
30
|
+
# @return [Graph]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def combine_with(*others)
|
34
|
+
self.class.new(root, nodes + others)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api public
|
38
|
+
# @see Relation#combine
|
39
|
+
def combine(*args)
|
40
|
+
self.class.new(root, nodes + root.combine(*args).nodes)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Materialize combined relation
|
44
|
+
#
|
45
|
+
# @return [Loaded]
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
def call(*args)
|
49
|
+
left = root.with(auto_struct: false).call(*args)
|
50
|
+
|
51
|
+
right =
|
52
|
+
if left.empty?
|
53
|
+
nodes.map { |node| Loaded.new(node, EMPTY_ARRAY) }
|
54
|
+
else
|
55
|
+
nodes.map { |node| node.call(left) }
|
56
|
+
end
|
57
|
+
|
58
|
+
if auto_map?
|
59
|
+
Loaded.new(self, mapper.([left, right]))
|
60
|
+
else
|
61
|
+
Loaded.new(self, [left, right])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return a new combined relation with adjusted node returned from a block
|
66
|
+
#
|
67
|
+
# @example with a node identifier
|
68
|
+
# aggregate(:tasks).node(:tasks) { |tasks| tasks.prioritized }
|
69
|
+
#
|
70
|
+
# @example with a nested path
|
71
|
+
# aggregate(tasks: :tags).node(tasks: :tags) { |tags| tags.where(name: 'red') }
|
72
|
+
#
|
73
|
+
# @param [Symbol] name The node relation name
|
74
|
+
#
|
75
|
+
# @yieldparam [Relation] The relation node
|
76
|
+
# @yieldreturn [Relation] The new relation node
|
77
|
+
#
|
78
|
+
# @return [Relation]
|
79
|
+
#
|
80
|
+
# @api public
|
81
|
+
def node(name, &block)
|
82
|
+
if name.is_a?(Symbol) && !nodes.map { |n| n.name.key }.include?(name)
|
83
|
+
raise ArgumentError, "#{name.inspect} is not a valid aggregate node name"
|
84
|
+
end
|
85
|
+
|
86
|
+
new_nodes = nodes.map { |node|
|
87
|
+
case name
|
88
|
+
when Symbol
|
89
|
+
name == node.name.key ? yield(node) : node
|
90
|
+
when Hash
|
91
|
+
other, *rest = name.flatten(1)
|
92
|
+
if other == node.name.key
|
93
|
+
nodes.detect { |n| n.name.key == other }.node(*rest, &block)
|
94
|
+
else
|
95
|
+
node
|
96
|
+
end
|
97
|
+
else
|
98
|
+
node
|
99
|
+
end
|
100
|
+
}
|
101
|
+
|
102
|
+
with_nodes(new_nodes)
|
103
|
+
end
|
104
|
+
|
105
|
+
# @api public
|
106
|
+
def to_ast
|
107
|
+
[:relation, [name.to_sym, attr_ast + node_ast, meta_ast]]
|
108
|
+
end
|
109
|
+
|
110
|
+
# @api private
|
111
|
+
def node_ast
|
112
|
+
nodes.map(&:to_ast)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/rom/relation/curried.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/equalizer'
|
2
|
+
|
1
3
|
require 'rom/types'
|
2
4
|
require 'rom/initializer'
|
3
5
|
require 'rom/pipeline'
|
@@ -9,6 +11,7 @@ module ROM
|
|
9
11
|
class Curried
|
10
12
|
extend Initializer
|
11
13
|
|
14
|
+
include Dry::Equalizer(:relation, :options)
|
12
15
|
include Materializable
|
13
16
|
include Pipeline
|
14
17
|
|
data/lib/rom/relation/graph.rb
CHANGED
@@ -1,45 +1,39 @@
|
|
1
|
+
require 'dry/equalizer'
|
2
|
+
|
3
|
+
require 'rom/initializer'
|
4
|
+
|
1
5
|
require 'rom/relation/loaded'
|
2
6
|
require 'rom/relation/composite'
|
3
7
|
require 'rom/relation/materializable'
|
4
|
-
require 'rom/relation/commands'
|
5
8
|
require 'rom/pipeline'
|
6
9
|
|
7
10
|
module ROM
|
8
11
|
class Relation
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @example
|
12
|
-
# class Users < ROM::Relation[:memory]
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# class Tasks < ROM::Relation[:memory]
|
16
|
-
# def for_users(users)
|
17
|
-
# restrict(user: users.map { |user| user[:name] })
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# rom.relations[:users] << { name: 'Jane' }
|
22
|
-
# rom.relations[:tasks] << { user: 'Jane', title: 'Do something' }
|
23
|
-
#
|
24
|
-
# rom.relations[:users].combine(rom.relations[:tasks].for_users)
|
12
|
+
# Abstract relation graph class
|
25
13
|
#
|
26
14
|
# @api public
|
27
15
|
class Graph
|
16
|
+
extend Initializer
|
17
|
+
|
18
|
+
param :root
|
19
|
+
|
20
|
+
param :nodes
|
21
|
+
|
22
|
+
include Dry::Equalizer(:root, :nodes)
|
28
23
|
include Materializable
|
29
|
-
include Commands
|
30
24
|
include Pipeline
|
31
25
|
include Pipeline::Proxy
|
32
26
|
|
33
27
|
# Root aka parent relation
|
34
28
|
#
|
35
|
-
# @return [Relation
|
29
|
+
# @return [Relation]
|
36
30
|
#
|
37
31
|
# @api private
|
38
32
|
attr_reader :root
|
39
33
|
|
40
34
|
# Child relation nodes
|
41
35
|
#
|
42
|
-
# @return [Array<Relation
|
36
|
+
# @return [Array<Relation>]
|
43
37
|
#
|
44
38
|
# @api private
|
45
39
|
attr_reader :nodes
|
@@ -47,23 +41,6 @@ module ROM
|
|
47
41
|
alias_method :left, :root
|
48
42
|
alias_method :right, :nodes
|
49
43
|
|
50
|
-
# @api private
|
51
|
-
def self.build(root, nodes)
|
52
|
-
if nodes.any? { |node| node.instance_of?(Composite) }
|
53
|
-
raise UnsupportedRelationError,
|
54
|
-
"Combining with composite relations is not supported"
|
55
|
-
else
|
56
|
-
new(root, nodes)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# @api private
|
61
|
-
def initialize(root, nodes)
|
62
|
-
root_ns = root.options[:struct_namespace]
|
63
|
-
@root = root
|
64
|
-
@nodes = nodes.map { |node| node.struct_namespace(root_ns) }
|
65
|
-
end
|
66
|
-
|
67
44
|
# @api public
|
68
45
|
def with_nodes(nodes)
|
69
46
|
self.class.new(root, nodes)
|
@@ -78,44 +55,6 @@ module ROM
|
|
78
55
|
true
|
79
56
|
end
|
80
57
|
|
81
|
-
# Combine this graph with more nodes
|
82
|
-
#
|
83
|
-
# @param [Array<Relation::Lazy>]
|
84
|
-
#
|
85
|
-
# @return [Graph]
|
86
|
-
#
|
87
|
-
# @api public
|
88
|
-
def graph(*others)
|
89
|
-
self.class.new(root, nodes + others)
|
90
|
-
end
|
91
|
-
|
92
|
-
# @api public
|
93
|
-
def combine(*args)
|
94
|
-
self.class.new(root, nodes + root.combine(*args).nodes)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Materialize this relation graph
|
98
|
-
#
|
99
|
-
# @return [Loaded]
|
100
|
-
#
|
101
|
-
# @api public
|
102
|
-
def call(*args)
|
103
|
-
left = root.with(auto_struct: false).call(*args)
|
104
|
-
|
105
|
-
right =
|
106
|
-
if left.empty?
|
107
|
-
nodes.map { |node| Loaded.new(node, EMPTY_ARRAY) }
|
108
|
-
else
|
109
|
-
nodes.map { |node| node.call(left) }
|
110
|
-
end
|
111
|
-
|
112
|
-
if auto_map?
|
113
|
-
Loaded.new(self, mapper.([left, right]))
|
114
|
-
else
|
115
|
-
Loaded.new(self, [left, right])
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
58
|
# @api public
|
120
59
|
def map_with(*args)
|
121
60
|
self.class.new(root.map_with(*args), nodes)
|
@@ -126,56 +65,6 @@ module ROM
|
|
126
65
|
self.class.new(root.map_to(klass), nodes)
|
127
66
|
end
|
128
67
|
|
129
|
-
# Return a new graph with adjusted node returned from a block
|
130
|
-
#
|
131
|
-
# @example with a node identifier
|
132
|
-
# aggregate(:tasks).node(:tasks) { |tasks| tasks.prioritized }
|
133
|
-
#
|
134
|
-
# @example with a nested path
|
135
|
-
# aggregate(tasks: :tags).node(tasks: :tags) { |tags| tags.where(name: 'red') }
|
136
|
-
#
|
137
|
-
# @param [Symbol] name The node relation name
|
138
|
-
#
|
139
|
-
# @yieldparam [RelationProxy] The relation node
|
140
|
-
# @yieldreturn [RelationProxy] The new relation node
|
141
|
-
#
|
142
|
-
# @return [RelationProxy]
|
143
|
-
#
|
144
|
-
# @api public
|
145
|
-
def node(name, &block)
|
146
|
-
if name.is_a?(Symbol) && !nodes.map { |n| n.name.key }.include?(name)
|
147
|
-
raise ArgumentError, "#{name.inspect} is not a valid aggregate node name"
|
148
|
-
end
|
149
|
-
|
150
|
-
new_nodes = nodes.map { |node|
|
151
|
-
case name
|
152
|
-
when Symbol
|
153
|
-
name == node.name.key ? yield(node) : node
|
154
|
-
when Hash
|
155
|
-
other, *rest = name.flatten(1)
|
156
|
-
if other == node.name.key
|
157
|
-
nodes.detect { |n| n.name.key == other }.node(*rest, &block)
|
158
|
-
else
|
159
|
-
node
|
160
|
-
end
|
161
|
-
else
|
162
|
-
node
|
163
|
-
end
|
164
|
-
}
|
165
|
-
|
166
|
-
with_nodes(new_nodes)
|
167
|
-
end
|
168
|
-
|
169
|
-
# @api public
|
170
|
-
def to_ast
|
171
|
-
[:relation, [name.to_sym, attr_ast + node_ast, meta_ast]]
|
172
|
-
end
|
173
|
-
|
174
|
-
# @api private
|
175
|
-
def node_ast
|
176
|
-
nodes.map(&:to_ast)
|
177
|
-
end
|
178
|
-
|
179
68
|
# @api private
|
180
69
|
def mapper
|
181
70
|
mappers[to_ast]
|
data/lib/rom/relation/loaded.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/equalizer'
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
class Relation
|
3
5
|
# Materializes a relation and exposes interface to access the data
|
@@ -5,6 +7,7 @@ module ROM
|
|
5
7
|
# @api public
|
6
8
|
class Loaded
|
7
9
|
include Enumerable
|
10
|
+
include Dry::Equalizer(:source, :collection)
|
8
11
|
|
9
12
|
# Coerce loaded relation to an array
|
10
13
|
#
|
data/lib/rom/relation/wrap.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
|
-
require 'rom/
|
2
|
-
require 'rom/relation/loaded'
|
3
|
-
require 'rom/relation/composite'
|
4
|
-
require 'rom/relation/materializable'
|
5
|
-
require 'rom/pipeline'
|
1
|
+
require 'rom/relation/graph'
|
6
2
|
|
7
3
|
module ROM
|
8
4
|
class Relation
|
9
5
|
# Relation wrapping other relations
|
10
6
|
#
|
11
7
|
# @api public
|
12
|
-
class Wrap
|
8
|
+
class Wrap < Graph
|
13
9
|
extend Initializer
|
14
10
|
|
15
11
|
include Materializable
|
@@ -58,11 +54,6 @@ module ROM
|
|
58
54
|
nodes.map(&:to_ast)
|
59
55
|
end
|
60
56
|
|
61
|
-
# @api private
|
62
|
-
def mapper
|
63
|
-
mappers[to_ast]
|
64
|
-
end
|
65
|
-
|
66
57
|
# Return if this is a wrap relation
|
67
58
|
#
|
68
59
|
# @return [true]
|
@@ -71,13 +62,6 @@ module ROM
|
|
71
62
|
def wrap?
|
72
63
|
true
|
73
64
|
end
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
# @api private
|
78
|
-
def decorate?(other)
|
79
|
-
super || other.is_a?(Composite) || other.is_a?(Curried)
|
80
|
-
end
|
81
65
|
end
|
82
66
|
end
|
83
67
|
end
|
data/lib/rom/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -180,7 +180,6 @@ files:
|
|
180
180
|
- lib/rom/commands/lazy/create.rb
|
181
181
|
- lib/rom/commands/lazy/delete.rb
|
182
182
|
- lib/rom/commands/lazy/update.rb
|
183
|
-
- lib/rom/commands/result.rb
|
184
183
|
- lib/rom/commands/update.rb
|
185
184
|
- lib/rom/configuration.rb
|
186
185
|
- lib/rom/configuration_dsl.rb
|
@@ -230,6 +229,7 @@ files:
|
|
230
229
|
- lib/rom/registry.rb
|
231
230
|
- lib/rom/relation.rb
|
232
231
|
- lib/rom/relation/class_interface.rb
|
232
|
+
- lib/rom/relation/combined.rb
|
233
233
|
- lib/rom/relation/commands.rb
|
234
234
|
- lib/rom/relation/composite.rb
|
235
235
|
- lib/rom/relation/curried.rb
|
data/lib/rom/commands/result.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module Commands
|
3
|
-
# Abstract result class for success and error results
|
4
|
-
#
|
5
|
-
# @api public
|
6
|
-
class Result
|
7
|
-
# Return command execution result
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
attr_reader :value
|
11
|
-
|
12
|
-
# Return potential command execution result error
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
attr_reader :error
|
16
|
-
|
17
|
-
# Coerce result to an array
|
18
|
-
#
|
19
|
-
# @abstract
|
20
|
-
#
|
21
|
-
# @api public
|
22
|
-
def to_ary
|
23
|
-
raise NotImplementedError
|
24
|
-
end
|
25
|
-
alias_method :to_a, :to_ary
|
26
|
-
|
27
|
-
# Return true if command successful
|
28
|
-
#
|
29
|
-
# @api public
|
30
|
-
def success?
|
31
|
-
is_a?(Success)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Return true if command failed
|
35
|
-
#
|
36
|
-
# @api public
|
37
|
-
def failure?
|
38
|
-
is_a?(Failure)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Success result has a value and no error
|
42
|
-
#
|
43
|
-
# @api public
|
44
|
-
class Success < Result
|
45
|
-
# @api private
|
46
|
-
def initialize(value)
|
47
|
-
@value = value.is_a?(self.class) ? value.value : value
|
48
|
-
end
|
49
|
-
|
50
|
-
# Call next command on continuation
|
51
|
-
#
|
52
|
-
# @api public
|
53
|
-
def >(other)
|
54
|
-
other.call(value)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Return the value
|
58
|
-
#
|
59
|
-
# @return [Array]
|
60
|
-
#
|
61
|
-
# @api public
|
62
|
-
def to_ary
|
63
|
-
value.to_ary
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Failure result has an error and no value
|
68
|
-
#
|
69
|
-
# @api public
|
70
|
-
class Failure < Result
|
71
|
-
# @api private
|
72
|
-
def initialize(error)
|
73
|
-
@error = error
|
74
|
-
end
|
75
|
-
|
76
|
-
# Do not call next command on continuation
|
77
|
-
#
|
78
|
-
# @return [self]
|
79
|
-
#
|
80
|
-
# @api public
|
81
|
-
def >(_other)
|
82
|
-
self
|
83
|
-
end
|
84
|
-
|
85
|
-
# Return the error
|
86
|
-
#
|
87
|
-
# @return [Array<CommandError>]
|
88
|
-
#
|
89
|
-
# @api public
|
90
|
-
def to_ary
|
91
|
-
error
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|