rom 2.0.2 → 5.2.5
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 +5 -5
- data/CHANGELOG.md +122 -324
- data/LICENSE +17 -17
- data/README.md +91 -22
- data/lib/rom/version.rb +3 -1
- data/lib/rom.rb +4 -46
- metadata +42 -245
- data/.gitignore +0 -24
- data/.rspec +0 -3
- data/.rubocop.yml +0 -87
- data/.rubocop_todo.yml +0 -46
- data/.travis.yml +0 -28
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -1
- data/Gemfile +0 -41
- data/Guardfile +0 -24
- data/Rakefile +0 -22
- data/lib/rom/association_set.rb +0 -26
- data/lib/rom/command.rb +0 -173
- data/lib/rom/command_registry.rb +0 -153
- data/lib/rom/commands/class_interface.rb +0 -148
- data/lib/rom/commands/composite.rb +0 -54
- data/lib/rom/commands/create.rb +0 -13
- data/lib/rom/commands/delete.rb +0 -14
- data/lib/rom/commands/graph/builder.rb +0 -176
- data/lib/rom/commands/graph/class_interface.rb +0 -62
- data/lib/rom/commands/graph/input_evaluator.rb +0 -62
- data/lib/rom/commands/graph.rb +0 -103
- data/lib/rom/commands/lazy/create.rb +0 -23
- data/lib/rom/commands/lazy/delete.rb +0 -27
- data/lib/rom/commands/lazy/update.rb +0 -34
- data/lib/rom/commands/lazy.rb +0 -99
- data/lib/rom/commands/result.rb +0 -96
- data/lib/rom/commands/update.rb +0 -14
- data/lib/rom/commands.rb +0 -3
- data/lib/rom/configuration.rb +0 -88
- data/lib/rom/configuration_dsl/command.rb +0 -43
- data/lib/rom/configuration_dsl/command_dsl.rb +0 -35
- data/lib/rom/configuration_dsl/mapper.rb +0 -37
- data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -44
- data/lib/rom/configuration_dsl/relation.rb +0 -26
- data/lib/rom/configuration_dsl.rb +0 -78
- data/lib/rom/configuration_plugin.rb +0 -17
- data/lib/rom/constants.rb +0 -30
- data/lib/rom/container.rb +0 -231
- data/lib/rom/create_container.rb +0 -61
- data/lib/rom/environment.rb +0 -70
- data/lib/rom/gateway.rb +0 -154
- data/lib/rom/global/plugin_dsl.rb +0 -49
- data/lib/rom/global.rb +0 -60
- data/lib/rom/lint/enumerable_dataset.rb +0 -54
- data/lib/rom/lint/gateway.rb +0 -94
- data/lib/rom/lint/linter.rb +0 -78
- data/lib/rom/lint/spec.rb +0 -20
- data/lib/rom/lint/test.rb +0 -98
- data/lib/rom/mapper_registry.rb +0 -35
- data/lib/rom/memory/commands.rb +0 -58
- data/lib/rom/memory/dataset.rb +0 -98
- data/lib/rom/memory/gateway.rb +0 -64
- data/lib/rom/memory/relation.rb +0 -49
- data/lib/rom/memory/storage.rb +0 -59
- data/lib/rom/memory/types.rb +0 -9
- data/lib/rom/memory.rb +0 -4
- data/lib/rom/pipeline.rb +0 -106
- data/lib/rom/plugin.rb +0 -17
- data/lib/rom/plugin_base.rb +0 -31
- data/lib/rom/plugin_registry.rb +0 -173
- data/lib/rom/plugins/command/schema.rb +0 -37
- data/lib/rom/plugins/configuration/configuration_dsl.rb +0 -17
- data/lib/rom/plugins/relation/key_inference.rb +0 -46
- data/lib/rom/plugins/relation/registry_reader.rb +0 -32
- data/lib/rom/plugins/relation/view/dsl.rb +0 -32
- data/lib/rom/plugins/relation/view.rb +0 -95
- data/lib/rom/relation/class_interface.rb +0 -230
- data/lib/rom/relation/composite.rb +0 -46
- data/lib/rom/relation/curried.rb +0 -104
- data/lib/rom/relation/graph.rb +0 -115
- data/lib/rom/relation/loaded.rb +0 -118
- data/lib/rom/relation/materializable.rb +0 -66
- data/lib/rom/relation/name.rb +0 -102
- data/lib/rom/relation.rb +0 -172
- data/lib/rom/relation_registry.rb +0 -9
- data/lib/rom/schema/dsl.rb +0 -58
- data/lib/rom/schema.rb +0 -89
- data/lib/rom/setup/auto_registration.rb +0 -69
- data/lib/rom/setup/auto_registration_strategies/base.rb +0 -11
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +0 -22
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +0 -19
- data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +0 -18
- data/lib/rom/setup/finalize/finalize_commands.rb +0 -47
- data/lib/rom/setup/finalize/finalize_mappers.rb +0 -36
- data/lib/rom/setup/finalize/finalize_relations.rb +0 -60
- data/lib/rom/setup/finalize.rb +0 -146
- data/lib/rom/setup.rb +0 -55
- data/lib/rom/support/configurable.rb +0 -80
- data/lib/rom/types.rb +0 -18
- data/log/.gitkeep +0 -0
- data/rakelib/benchmark.rake +0 -15
- data/rakelib/mutant.rake +0 -19
- data/rakelib/rubocop.rake +0 -18
- data/rom.gemspec +0 -26
- data/spec/fixtures/app/commands/create_user.rb +0 -2
- data/spec/fixtures/app/mappers/user_list.rb +0 -2
- data/spec/fixtures/app/my_commands/create_user.rb +0 -2
- data/spec/fixtures/app/my_mappers/user_list.rb +0 -2
- data/spec/fixtures/app/my_relations/users.rb +0 -2
- data/spec/fixtures/app/relations/users.rb +0 -2
- data/spec/fixtures/custom/commands/create_user.rb +0 -6
- data/spec/fixtures/custom/mappers/user_list.rb +0 -6
- data/spec/fixtures/custom/relations/users.rb +0 -6
- data/spec/fixtures/lib/persistence/commands/create_user.rb +0 -6
- data/spec/fixtures/lib/persistence/mappers/user_list.rb +0 -6
- data/spec/fixtures/lib/persistence/my_commands/create_user.rb +0 -6
- data/spec/fixtures/lib/persistence/my_mappers/user_list.rb +0 -6
- data/spec/fixtures/lib/persistence/my_relations/users.rb +0 -6
- data/spec/fixtures/lib/persistence/relations/users.rb +0 -6
- data/spec/integration/command_registry_spec.rb +0 -60
- data/spec/integration/commands/create_spec.rb +0 -177
- data/spec/integration/commands/delete_spec.rb +0 -67
- data/spec/integration/commands/error_handling_spec.rb +0 -25
- data/spec/integration/commands/graph_builder_spec.rb +0 -213
- data/spec/integration/commands/graph_spec.rb +0 -288
- data/spec/integration/commands/update_spec.rb +0 -109
- data/spec/integration/commands_spec.rb +0 -67
- data/spec/integration/mappers/combine_spec.rb +0 -117
- data/spec/integration/mappers/deep_embedded_spec.rb +0 -44
- data/spec/integration/mappers/definition_dsl_spec.rb +0 -206
- data/spec/integration/mappers/embedded_spec.rb +0 -62
- data/spec/integration/mappers/exclude_spec.rb +0 -27
- data/spec/integration/mappers/fold_spec.rb +0 -71
- data/spec/integration/mappers/group_spec.rb +0 -163
- data/spec/integration/mappers/overwrite_attributes_value_spec.rb +0 -51
- data/spec/integration/mappers/prefix_separator_spec.rb +0 -52
- data/spec/integration/mappers/prefix_spec.rb +0 -48
- data/spec/integration/mappers/prefixing_attributes_spec.rb +0 -37
- data/spec/integration/mappers/registering_custom_mappers_spec.rb +0 -28
- data/spec/integration/mappers/renaming_attributes_spec.rb +0 -125
- data/spec/integration/mappers/reusing_mappers_spec.rb +0 -43
- data/spec/integration/mappers/step_spec.rb +0 -119
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +0 -77
- data/spec/integration/mappers/unfold_spec.rb +0 -92
- data/spec/integration/mappers/ungroup_spec.rb +0 -126
- data/spec/integration/mappers/unwrap_spec.rb +0 -93
- data/spec/integration/mappers/wrap_spec.rb +0 -155
- data/spec/integration/memory/commands/create_spec.rb +0 -23
- data/spec/integration/memory/commands/delete_spec.rb +0 -23
- data/spec/integration/memory/commands/update_spec.rb +0 -23
- data/spec/integration/multi_env_spec.rb +0 -69
- data/spec/integration/multi_repo_spec.rb +0 -46
- data/spec/integration/relations/default_dataset_spec.rb +0 -38
- data/spec/integration/relations/inheritance_spec.rb +0 -37
- data/spec/integration/relations/reading_spec.rb +0 -169
- data/spec/integration/relations/registry_dsl_spec.rb +0 -45
- data/spec/integration/repositories/extending_relations_spec.rb +0 -58
- data/spec/integration/repositories/setting_logger_spec.rb +0 -34
- data/spec/integration/setup_spec.rb +0 -160
- data/spec/shared/command_behavior.rb +0 -28
- data/spec/shared/command_graph.rb +0 -50
- data/spec/shared/container.rb +0 -9
- data/spec/shared/enumerable_dataset.rb +0 -52
- data/spec/shared/gateway_only.rb +0 -6
- data/spec/shared/materializable.rb +0 -36
- data/spec/shared/no_container.rb +0 -16
- data/spec/shared/one_behavior.rb +0 -26
- data/spec/shared/proxy.rb +0 -0
- data/spec/shared/users_and_tasks.rb +0 -10
- data/spec/spec_helper.rb +0 -52
- data/spec/support/constant_leak_finder.rb +0 -14
- data/spec/support/mutant.rb +0 -10
- data/spec/support/types.rb +0 -5
- data/spec/test/memory_repository_lint_test.rb +0 -27
- data/spec/unit/rom/association_set_spec.rb +0 -23
- data/spec/unit/rom/commands/graph_spec.rb +0 -191
- data/spec/unit/rom/commands/lazy_spec.rb +0 -307
- data/spec/unit/rom/commands/result_spec.rb +0 -70
- data/spec/unit/rom/commands_spec.rb +0 -165
- data/spec/unit/rom/configurable_spec.rb +0 -49
- data/spec/unit/rom/configuration_spec.rb +0 -61
- data/spec/unit/rom/container_spec.rb +0 -99
- data/spec/unit/rom/create_container_spec.rb +0 -151
- data/spec/unit/rom/environment_spec.rb +0 -123
- data/spec/unit/rom/gateway_spec.rb +0 -146
- data/spec/unit/rom/mapper_registry_spec.rb +0 -25
- data/spec/unit/rom/memory/commands_spec.rb +0 -43
- data/spec/unit/rom/memory/dataset_spec.rb +0 -31
- data/spec/unit/rom/memory/relation_spec.rb +0 -109
- data/spec/unit/rom/memory/repository_spec.rb +0 -12
- data/spec/unit/rom/memory/storage_spec.rb +0 -45
- data/spec/unit/rom/plugin_spec.rb +0 -150
- data/spec/unit/rom/plugins/command/schema_spec.rb +0 -66
- data/spec/unit/rom/plugins/relation/key_inference_spec.rb +0 -85
- data/spec/unit/rom/plugins/relation/view_spec.rb +0 -51
- data/spec/unit/rom/relation/composite_spec.rb +0 -89
- data/spec/unit/rom/relation/curried_spec.rb +0 -52
- data/spec/unit/rom/relation/graph_spec.rb +0 -92
- data/spec/unit/rom/relation/lazy/combine_spec.rb +0 -165
- data/spec/unit/rom/relation/lazy_spec.rb +0 -214
- data/spec/unit/rom/relation/loaded_spec.rb +0 -53
- data/spec/unit/rom/relation/name_spec.rb +0 -58
- data/spec/unit/rom/relation/schema_spec.rb +0 -117
- data/spec/unit/rom/relation_spec.rb +0 -237
- data/spec/unit/rom/schema_spec.rb +0 -10
- data/spec/unit/rom/setup/auto_registration_spec.rb +0 -152
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
require 'rom/support/class_builder'
|
|
2
|
-
|
|
3
|
-
module ROM
|
|
4
|
-
# Base command class with factory class-level interface and setup-related logic
|
|
5
|
-
#
|
|
6
|
-
# @private
|
|
7
|
-
class Command
|
|
8
|
-
module ClassInterface
|
|
9
|
-
# Return adapter specific sub-class based on the adapter identifier
|
|
10
|
-
#
|
|
11
|
-
# This is a syntax sugar to make things consistent
|
|
12
|
-
#
|
|
13
|
-
# @example
|
|
14
|
-
# ROM::Commands::Create[:memory]
|
|
15
|
-
# # => ROM::Memory::Commands::Create
|
|
16
|
-
#
|
|
17
|
-
# @param [Symbol] adapter identifier
|
|
18
|
-
#
|
|
19
|
-
# @return [Class]
|
|
20
|
-
#
|
|
21
|
-
# @api public
|
|
22
|
-
def [](adapter)
|
|
23
|
-
adapter_namespace(adapter).const_get(Inflector.demodulize(name))
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Return namespaces that contains command subclasses of a specific adapter
|
|
27
|
-
#
|
|
28
|
-
# @param [Symbol] adapter identifier
|
|
29
|
-
#
|
|
30
|
-
# @return [Module]
|
|
31
|
-
#
|
|
32
|
-
# @api private
|
|
33
|
-
def adapter_namespace(adapter)
|
|
34
|
-
ROM.adapters.fetch(adapter).const_get(:Commands)
|
|
35
|
-
rescue KeyError
|
|
36
|
-
raise AdapterNotPresentError.new(adapter, :relation)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Build a command class for a specific relation with options
|
|
40
|
-
#
|
|
41
|
-
# @example
|
|
42
|
-
# class CreateUser < ROM::Commands::Create[:memory]
|
|
43
|
-
# end
|
|
44
|
-
#
|
|
45
|
-
# command = CreateUser.build(rom.relations[:users])
|
|
46
|
-
#
|
|
47
|
-
# @param [Relation] relation
|
|
48
|
-
# @param [Hash] options
|
|
49
|
-
#
|
|
50
|
-
# @return [Command]
|
|
51
|
-
#
|
|
52
|
-
# @api public
|
|
53
|
-
def build(relation, options = EMPTY_HASH)
|
|
54
|
-
new(relation, self.options.merge(options))
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Create a command class with a specific type
|
|
58
|
-
#
|
|
59
|
-
# @param [Symbol] command name
|
|
60
|
-
# @param [Class] parent class
|
|
61
|
-
#
|
|
62
|
-
# @yield [Class] create class
|
|
63
|
-
#
|
|
64
|
-
# @return [Class, Object] return result of the block if it was provided
|
|
65
|
-
#
|
|
66
|
-
# @api public
|
|
67
|
-
def create_class(name, type, &block)
|
|
68
|
-
klass = ClassBuilder
|
|
69
|
-
.new(name: "#{Inflector.classify(type)}[:#{name}]", parent: type)
|
|
70
|
-
.call
|
|
71
|
-
|
|
72
|
-
if block
|
|
73
|
-
yield(klass)
|
|
74
|
-
else
|
|
75
|
-
klass
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Use a configured plugin in this relation
|
|
80
|
-
#
|
|
81
|
-
# @example
|
|
82
|
-
# class CreateUser < ROM::Commands::Create[:memory]
|
|
83
|
-
# use :pagintion
|
|
84
|
-
#
|
|
85
|
-
# per_page 30
|
|
86
|
-
# end
|
|
87
|
-
#
|
|
88
|
-
# @param [Symbol] plugin
|
|
89
|
-
# @param [Hash] options
|
|
90
|
-
# @option options [Symbol] :adapter (:default) first adapter to check for plugin
|
|
91
|
-
#
|
|
92
|
-
# @api public
|
|
93
|
-
def use(plugin, _options = EMPTY_HASH)
|
|
94
|
-
ROM.plugin_registry.commands.fetch(plugin, adapter).apply_to(self)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Extend a command class with relation view methods
|
|
98
|
-
#
|
|
99
|
-
# @param [Relation]
|
|
100
|
-
#
|
|
101
|
-
# @return [Class]
|
|
102
|
-
#
|
|
103
|
-
# @api public
|
|
104
|
-
def extend_for_relation(relation)
|
|
105
|
-
include(relation_methods_mod(relation.class))
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Return default name of the command class based on its name
|
|
109
|
-
#
|
|
110
|
-
# During setup phase this is used by defalut as `register_as` option
|
|
111
|
-
#
|
|
112
|
-
# @return [Symbol]
|
|
113
|
-
#
|
|
114
|
-
# @api private
|
|
115
|
-
def default_name
|
|
116
|
-
Inflector.underscore(Inflector.demodulize(name)).to_sym
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Return default options based on class macros
|
|
120
|
-
#
|
|
121
|
-
# @return [Hash]
|
|
122
|
-
#
|
|
123
|
-
# @api private
|
|
124
|
-
def options
|
|
125
|
-
{ input: input, validator: validator, result: result }
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# @api private
|
|
129
|
-
def relation_methods_mod(relation_class)
|
|
130
|
-
Module.new do
|
|
131
|
-
relation_class.view_methods.each do |meth|
|
|
132
|
-
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
133
|
-
def #{meth}(*args)
|
|
134
|
-
response = relation.public_send(:#{meth}, *args)
|
|
135
|
-
|
|
136
|
-
if response.is_a?(relation.class)
|
|
137
|
-
new(response)
|
|
138
|
-
else
|
|
139
|
-
response
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
RUBY
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
require 'rom/pipeline'
|
|
2
|
-
require 'rom/support/constants'
|
|
3
|
-
|
|
4
|
-
module ROM
|
|
5
|
-
module Commands
|
|
6
|
-
# Composite command that consists of left and right commands
|
|
7
|
-
#
|
|
8
|
-
# @api public
|
|
9
|
-
class Composite < Pipeline::Composite
|
|
10
|
-
# Calls the composite command
|
|
11
|
-
#
|
|
12
|
-
# Right command is called with a result from the left one
|
|
13
|
-
#
|
|
14
|
-
# @return [Object]
|
|
15
|
-
#
|
|
16
|
-
# @api public
|
|
17
|
-
def call(*args)
|
|
18
|
-
response = left.call(*args)
|
|
19
|
-
|
|
20
|
-
if response.nil? || (many? && response.size == 0)
|
|
21
|
-
return one? ? nil : EMPTY_ARRAY
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
if one? && !graph?
|
|
25
|
-
if right.is_a?(Command) || right.is_a?(Commands::Composite)
|
|
26
|
-
right.call([response].first)
|
|
27
|
-
else
|
|
28
|
-
right.call([response]).first
|
|
29
|
-
end
|
|
30
|
-
elsif one? && graph?
|
|
31
|
-
right.call(response).first
|
|
32
|
-
else
|
|
33
|
-
right.call(response)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
alias_method :[], :call
|
|
37
|
-
|
|
38
|
-
# @api private
|
|
39
|
-
def graph?
|
|
40
|
-
left.is_a?(Graph)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# @api private
|
|
44
|
-
def result
|
|
45
|
-
left.result
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# @api private
|
|
49
|
-
def decorate?(response)
|
|
50
|
-
super || response.is_a?(Graph)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
data/lib/rom/commands/create.rb
DELETED
data/lib/rom/commands/delete.rb
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
module ROM
|
|
2
|
-
module Commands
|
|
3
|
-
class Graph
|
|
4
|
-
# Command graph builder DSL
|
|
5
|
-
#
|
|
6
|
-
# @api public
|
|
7
|
-
class Builder
|
|
8
|
-
# @api private
|
|
9
|
-
UnspecifiedRelationError = Class.new(StandardError)
|
|
10
|
-
DoubleRestrictionError = Class.new(StandardError)
|
|
11
|
-
|
|
12
|
-
# @api private
|
|
13
|
-
class Node
|
|
14
|
-
# @api private
|
|
15
|
-
Restriction = Struct.new(:relation, :proc)
|
|
16
|
-
|
|
17
|
-
# @api private
|
|
18
|
-
Command = Struct.new(:name, :relation, :key, :proc)
|
|
19
|
-
|
|
20
|
-
# @api private
|
|
21
|
-
def initialize
|
|
22
|
-
@nodes = []
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# @api public
|
|
26
|
-
def to_ast
|
|
27
|
-
[]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Any missing method called on this is treated as a ROM command
|
|
31
|
-
#
|
|
32
|
-
# @api private
|
|
33
|
-
def method_missing(*args, &block)
|
|
34
|
-
command(*args, &block)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @api public
|
|
38
|
-
def command(name, relation = nil, key = nil, proc = nil, &block)
|
|
39
|
-
if relation.is_a?(Hash)
|
|
40
|
-
key, relation = relation.to_a.first
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
raise UnspecifiedRelationError if relation.nil?
|
|
44
|
-
|
|
45
|
-
if relation.is_a?(RestrictionNode)
|
|
46
|
-
RestrictionNode.new(relation.restriction).command(name, from: key, &block)
|
|
47
|
-
else
|
|
48
|
-
key ||= relation
|
|
49
|
-
|
|
50
|
-
command = Command.new(name, relation, key, proc)
|
|
51
|
-
node = CommandNode.new(command)
|
|
52
|
-
block.call(node) if block
|
|
53
|
-
node
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# @api public
|
|
58
|
-
def restrict(name, &block)
|
|
59
|
-
RestrictionNode.new(Restriction.new(name, block), self)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# @api private
|
|
64
|
-
class CommandNode < Node
|
|
65
|
-
# @api private
|
|
66
|
-
def initialize(command = nil)
|
|
67
|
-
@command = command
|
|
68
|
-
@nodes = []
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Tiny bit of synctactic sugar
|
|
72
|
-
#
|
|
73
|
-
# @api public
|
|
74
|
-
def each(&block)
|
|
75
|
-
block.call(self)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Return command ast from this union node
|
|
79
|
-
#
|
|
80
|
-
# @return [Array]
|
|
81
|
-
#
|
|
82
|
-
# @api private
|
|
83
|
-
def to_ast
|
|
84
|
-
if @command.proc
|
|
85
|
-
command = [@command.name => @command.proc]
|
|
86
|
-
else
|
|
87
|
-
command = [@command.name]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
key_relation_map = { @command.key => @command.relation }
|
|
91
|
-
|
|
92
|
-
command << @nodes.map(&:to_ast) unless @nodes.empty?
|
|
93
|
-
|
|
94
|
-
[key_relation_map, command]
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# @api public
|
|
98
|
-
def command(*args, &block)
|
|
99
|
-
node = super
|
|
100
|
-
@nodes << node
|
|
101
|
-
node
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# @api private
|
|
106
|
-
class RestrictionNode < Node
|
|
107
|
-
attr_reader :restriction
|
|
108
|
-
|
|
109
|
-
def initialize(restriction, parent_node = nil)
|
|
110
|
-
super()
|
|
111
|
-
@restriction = restriction
|
|
112
|
-
@parent_node = parent_node
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# @api public
|
|
116
|
-
def command(name, options = {}, &block)
|
|
117
|
-
relation = @restriction.relation
|
|
118
|
-
key = options[:from] || relation
|
|
119
|
-
proc = @restriction.proc
|
|
120
|
-
|
|
121
|
-
if @parent_node
|
|
122
|
-
@parent_node.command(name, relation, key, proc, &block)
|
|
123
|
-
else
|
|
124
|
-
super(name, relation, key, proc, &block)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# @api private
|
|
129
|
-
def restrict(*args, &block)
|
|
130
|
-
raise DoubleRestrictionError
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
# @api private
|
|
135
|
-
class RootNode < Node
|
|
136
|
-
def to_ast
|
|
137
|
-
if @nodes.size > 0
|
|
138
|
-
@nodes.first.to_ast
|
|
139
|
-
else
|
|
140
|
-
[]
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def command(*args, &block)
|
|
145
|
-
node = super
|
|
146
|
-
@nodes << node
|
|
147
|
-
node
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# @api private
|
|
152
|
-
class BuilderNode < RootNode
|
|
153
|
-
def initialize(container)
|
|
154
|
-
super()
|
|
155
|
-
@container = container
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def command(*args, &block)
|
|
159
|
-
super
|
|
160
|
-
@container.command(to_ast)
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# @api public
|
|
165
|
-
def initialize(container)
|
|
166
|
-
@container = container
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
# @api private
|
|
170
|
-
def method_missing(*args, &block)
|
|
171
|
-
BuilderNode.new(@container).send(*args, &block)
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
require 'rom/commands/graph/input_evaluator'
|
|
2
|
-
|
|
3
|
-
module ROM
|
|
4
|
-
module Commands
|
|
5
|
-
class Graph
|
|
6
|
-
# Class methods for command Graph
|
|
7
|
-
#
|
|
8
|
-
# @api private
|
|
9
|
-
module ClassInterface
|
|
10
|
-
# Build a command graph recursively
|
|
11
|
-
#
|
|
12
|
-
# This is used by `Container#command` when array with options is passed in
|
|
13
|
-
#
|
|
14
|
-
# @param [Registry] registry The command registry from container
|
|
15
|
-
# @param [Array] options The options array
|
|
16
|
-
# @param [Array] path The path for input evaluator proc
|
|
17
|
-
#
|
|
18
|
-
# @return [Graph]
|
|
19
|
-
#
|
|
20
|
-
# @api private
|
|
21
|
-
def build(registry, options, path = EMPTY_ARRAY)
|
|
22
|
-
options.reduce { |spec, other| build_command(registry, spec, other, path) }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# @api private
|
|
26
|
-
def build_command(registry, spec, other, path)
|
|
27
|
-
cmd_opts, nodes = other
|
|
28
|
-
|
|
29
|
-
key, relation =
|
|
30
|
-
if spec.is_a?(Hash)
|
|
31
|
-
spec.to_a.first
|
|
32
|
-
else
|
|
33
|
-
[spec, spec]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
name, opts =
|
|
37
|
-
if cmd_opts.is_a?(Hash)
|
|
38
|
-
cmd_opts.to_a.first
|
|
39
|
-
else
|
|
40
|
-
[cmd_opts]
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
command = registry[relation][name]
|
|
44
|
-
tuple_path = Array[*path] << key
|
|
45
|
-
input_proc = InputEvaluator.build(tuple_path, nodes)
|
|
46
|
-
|
|
47
|
-
command = command.with(input_proc, opts)
|
|
48
|
-
|
|
49
|
-
if nodes
|
|
50
|
-
if nodes.all? { |node| node.is_a?(Array) }
|
|
51
|
-
command.combine(*nodes.map { |node| build(registry, node, tuple_path) })
|
|
52
|
-
else
|
|
53
|
-
command.combine(build(registry, nodes, tuple_path))
|
|
54
|
-
end
|
|
55
|
-
else
|
|
56
|
-
command
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
module ROM
|
|
2
|
-
module Commands
|
|
3
|
-
class Graph
|
|
4
|
-
class InputEvaluator
|
|
5
|
-
include Dry::Equalizer(:tuple_path, :excluded_keys)
|
|
6
|
-
|
|
7
|
-
attr_reader :tuple_path
|
|
8
|
-
|
|
9
|
-
attr_reader :excluded_keys
|
|
10
|
-
|
|
11
|
-
attr_reader :exclude_proc
|
|
12
|
-
|
|
13
|
-
def self.build(tuple_path, nodes)
|
|
14
|
-
new(tuple_path, extract_excluded_keys(nodes))
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.extract_excluded_keys(nodes)
|
|
18
|
-
return unless nodes
|
|
19
|
-
|
|
20
|
-
nodes
|
|
21
|
-
.map { |item| item.is_a?(Array) && item.size > 1 ? item.first : item }
|
|
22
|
-
.compact
|
|
23
|
-
.map { |item| item.is_a?(Hash) ? item.keys.first : item }
|
|
24
|
-
.reject { |item| item.is_a?(Array) }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def self.exclude_proc(excluded_keys)
|
|
28
|
-
-> input { input.reject { |k, _| excluded_keys.include?(k) } }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def initialize(tuple_path, excluded_keys)
|
|
32
|
-
@tuple_path = tuple_path
|
|
33
|
-
@excluded_keys = excluded_keys
|
|
34
|
-
@exclude_proc = self.class.exclude_proc(excluded_keys)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def call(*args)
|
|
38
|
-
input, index = args
|
|
39
|
-
|
|
40
|
-
value =
|
|
41
|
-
begin
|
|
42
|
-
if index
|
|
43
|
-
tuple_path[0..tuple_path.size-2]
|
|
44
|
-
.reduce(input) { |a, e| a.fetch(e) }
|
|
45
|
-
.at(index)[tuple_path.last]
|
|
46
|
-
else
|
|
47
|
-
tuple_path.reduce(input) { |a, e| a.fetch(e) }
|
|
48
|
-
end
|
|
49
|
-
rescue KeyError => e
|
|
50
|
-
raise KeyMissing, e.message
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
if excluded_keys
|
|
54
|
-
value.is_a?(Array) ? value.map(&exclude_proc) : exclude_proc[value]
|
|
55
|
-
else
|
|
56
|
-
value
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
data/lib/rom/commands/graph.rb
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
require 'rom/pipeline'
|
|
2
|
-
require 'rom/support/options'
|
|
3
|
-
require 'rom/commands/graph/class_interface'
|
|
4
|
-
|
|
5
|
-
module ROM
|
|
6
|
-
module Commands
|
|
7
|
-
# Command graph
|
|
8
|
-
#
|
|
9
|
-
# @api private
|
|
10
|
-
class Graph
|
|
11
|
-
include Dry::Equalizer(:root, :nodes)
|
|
12
|
-
|
|
13
|
-
extend ClassInterface
|
|
14
|
-
|
|
15
|
-
include Options
|
|
16
|
-
include Pipeline
|
|
17
|
-
include Pipeline::Proxy
|
|
18
|
-
|
|
19
|
-
# @attr_reader [Command] root The root command
|
|
20
|
-
attr_reader :root
|
|
21
|
-
|
|
22
|
-
# @attr_reader [Array<Command>] nodes The child commands
|
|
23
|
-
attr_reader :nodes
|
|
24
|
-
|
|
25
|
-
# @attr_reader [Symbol] root's relation name
|
|
26
|
-
attr_reader :name
|
|
27
|
-
|
|
28
|
-
alias_method :left, :root
|
|
29
|
-
alias_method :right, :nodes
|
|
30
|
-
|
|
31
|
-
option :mappers, reader: true, default: proc { MapperRegistry.new }
|
|
32
|
-
|
|
33
|
-
# @api private
|
|
34
|
-
def initialize(root, nodes, options = EMPTY_HASH)
|
|
35
|
-
super
|
|
36
|
-
@root = root
|
|
37
|
-
@nodes = nodes
|
|
38
|
-
@name = root.name
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Calls root and all nodes with the result from root
|
|
42
|
-
#
|
|
43
|
-
# Graph results are mappable through `combine` operation in mapper DSL
|
|
44
|
-
#
|
|
45
|
-
# @example
|
|
46
|
-
# create_user = rom.command(:users).create
|
|
47
|
-
# create_task = rom.command(:tasks).create
|
|
48
|
-
#
|
|
49
|
-
# command = create_user
|
|
50
|
-
# .with(name: 'Jane')
|
|
51
|
-
# .combine(create_task.with(title: 'Task'))
|
|
52
|
-
#
|
|
53
|
-
# command.call
|
|
54
|
-
#
|
|
55
|
-
# @return [Array] nested array with command results
|
|
56
|
-
#
|
|
57
|
-
# @api public
|
|
58
|
-
def call(*args)
|
|
59
|
-
left = root.call(*args)
|
|
60
|
-
|
|
61
|
-
right = nodes.map { |node|
|
|
62
|
-
response =
|
|
63
|
-
if node.lazy?
|
|
64
|
-
node.call(args.first, left)
|
|
65
|
-
else
|
|
66
|
-
node.call(left)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
if node.one? && !node.graph?
|
|
70
|
-
[response]
|
|
71
|
-
else
|
|
72
|
-
response
|
|
73
|
-
end
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if one?
|
|
77
|
-
[[left], right]
|
|
78
|
-
else
|
|
79
|
-
[left, right]
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Return a new graph with updated options
|
|
84
|
-
#
|
|
85
|
-
# @api private
|
|
86
|
-
def with(new_options)
|
|
87
|
-
self.class.new(root, nodes, options.merge(new_options))
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# @api private
|
|
91
|
-
def graph?
|
|
92
|
-
true
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
private
|
|
96
|
-
|
|
97
|
-
# @api public
|
|
98
|
-
def composite_class
|
|
99
|
-
Command::Composite
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module ROM
|
|
2
|
-
module Commands
|
|
3
|
-
class Lazy
|
|
4
|
-
class Create < Lazy
|
|
5
|
-
def call(*args)
|
|
6
|
-
first = args.first
|
|
7
|
-
last = args.last
|
|
8
|
-
size = args.size
|
|
9
|
-
|
|
10
|
-
if size > 1 && last.is_a?(Array)
|
|
11
|
-
last.map.with_index do |parent, index|
|
|
12
|
-
children = evaluator.call(first, index)
|
|
13
|
-
command_proc[command, parent, children].call(children, parent)
|
|
14
|
-
end.reduce(:concat)
|
|
15
|
-
else
|
|
16
|
-
input = evaluator.call(first)
|
|
17
|
-
command.call(input, *args[1..size-1])
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module ROM
|
|
2
|
-
module Commands
|
|
3
|
-
class Lazy
|
|
4
|
-
class Delete < Lazy
|
|
5
|
-
def call(*args)
|
|
6
|
-
first = args.first
|
|
7
|
-
last = args.last
|
|
8
|
-
size = args.size
|
|
9
|
-
|
|
10
|
-
if size > 1 && last.is_a?(Array)
|
|
11
|
-
raise NotImplementedError
|
|
12
|
-
else
|
|
13
|
-
input = evaluator.call(first)
|
|
14
|
-
|
|
15
|
-
if input.is_a?(Array)
|
|
16
|
-
input.map do |item|
|
|
17
|
-
command_proc[command, *(size > 1 ? [last, item] : [input])].call
|
|
18
|
-
end
|
|
19
|
-
else
|
|
20
|
-
command_proc[command, input].call
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|