rom 5.2.4 → 6.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -1
- data/LICENSE +1 -1
- data/README.md +6 -6
- data/lib/rom/array_dataset.rb +46 -0
- data/lib/rom/associations/abstract.rb +217 -0
- data/lib/rom/associations/definitions/abstract.rb +150 -0
- data/lib/rom/associations/definitions/many_to_many.rb +29 -0
- data/lib/rom/associations/definitions/many_to_one.rb +14 -0
- data/lib/rom/associations/definitions/one_to_many.rb +14 -0
- data/lib/rom/associations/definitions/one_to_one.rb +14 -0
- data/lib/rom/associations/definitions/one_to_one_through.rb +14 -0
- data/lib/rom/associations/definitions.rb +7 -0
- data/lib/rom/associations/many_to_many.rb +128 -0
- data/lib/rom/associations/many_to_one.rb +65 -0
- data/lib/rom/associations/one_to_many.rb +65 -0
- data/lib/rom/associations/one_to_one.rb +13 -0
- data/lib/rom/associations/one_to_one_through.rb +13 -0
- data/lib/rom/associations/through_identifier.rb +41 -0
- data/lib/rom/attribute.rb +425 -0
- data/lib/rom/auto_curry.rb +70 -0
- data/lib/rom/cache.rb +87 -0
- data/lib/rom/changeset/associated.rb +110 -0
- data/lib/rom/changeset/create.rb +18 -0
- data/lib/rom/changeset/delete.rb +15 -0
- data/lib/rom/changeset/extensions/relation.rb +26 -0
- data/lib/rom/changeset/pipe.rb +81 -0
- data/lib/rom/changeset/pipe_registry.rb +27 -0
- data/lib/rom/changeset/stateful.rb +285 -0
- data/lib/rom/changeset/update.rb +81 -0
- data/lib/rom/changeset.rb +185 -0
- data/lib/rom/command.rb +351 -0
- data/lib/rom/command_compiler.rb +201 -0
- data/lib/rom/command_proxy.rb +36 -0
- data/lib/rom/commands/class_interface.rb +236 -0
- data/lib/rom/commands/composite.rb +55 -0
- data/lib/rom/commands/create.rb +15 -0
- data/lib/rom/commands/delete.rb +16 -0
- data/lib/rom/commands/graph/class_interface.rb +64 -0
- data/lib/rom/commands/graph/input_evaluator.rb +94 -0
- data/lib/rom/commands/graph.rb +88 -0
- data/lib/rom/commands/lazy/create.rb +35 -0
- data/lib/rom/commands/lazy/delete.rb +39 -0
- data/lib/rom/commands/lazy/update.rb +46 -0
- data/lib/rom/commands/lazy.rb +106 -0
- data/lib/rom/commands/update.rb +16 -0
- data/lib/rom/commands.rb +5 -0
- data/lib/rom/compat/auto_registration.rb +115 -0
- data/lib/rom/compat/auto_registration_strategies/base.rb +29 -0
- data/lib/rom/compat/auto_registration_strategies/custom_namespace.rb +84 -0
- data/lib/rom/compat/auto_registration_strategies/no_namespace.rb +33 -0
- data/lib/rom/compat/auto_registration_strategies/with_namespace.rb +29 -0
- data/lib/rom/compat/command.rb +74 -0
- data/lib/rom/compat/components/dsl/schema.rb +130 -0
- data/lib/rom/compat/components.rb +91 -0
- data/lib/rom/compat/global.rb +17 -0
- data/lib/rom/compat/mapper.rb +22 -0
- data/lib/rom/compat/registries.rb +47 -0
- data/lib/rom/compat/relation.rb +40 -0
- data/lib/rom/compat/schema/dsl.rb +260 -0
- data/lib/rom/compat/setting_proxy.rb +44 -0
- data/lib/rom/compat/setup.rb +151 -0
- data/lib/rom/compat/transformer.rb +49 -0
- data/lib/rom/compat.rb +22 -0
- data/lib/rom/components/association.rb +26 -0
- data/lib/rom/components/command.rb +24 -0
- data/lib/rom/components/core.rb +148 -0
- data/lib/rom/components/dataset.rb +60 -0
- data/lib/rom/components/dsl/association.rb +47 -0
- data/lib/rom/components/dsl/command.rb +60 -0
- data/lib/rom/components/dsl/core.rb +126 -0
- data/lib/rom/components/dsl/dataset.rb +33 -0
- data/lib/rom/components/dsl/gateway.rb +14 -0
- data/lib/rom/components/dsl/mapper.rb +70 -0
- data/lib/rom/components/dsl/relation.rb +49 -0
- data/lib/rom/components/dsl/schema.rb +150 -0
- data/lib/rom/components/dsl/view.rb +82 -0
- data/lib/rom/components/dsl.rb +255 -0
- data/lib/rom/components/gateway.rb +50 -0
- data/lib/rom/components/mapper.rb +29 -0
- data/lib/rom/components/provider.rb +160 -0
- data/lib/rom/components/registry.rb +154 -0
- data/lib/rom/components/relation.rb +41 -0
- data/lib/rom/components/schema.rb +61 -0
- data/lib/rom/components/view.rb +55 -0
- data/lib/rom/components.rb +55 -0
- data/lib/rom/configuration_dsl.rb +4 -0
- data/lib/rom/constants.rb +135 -0
- data/lib/rom/container.rb +182 -0
- data/lib/rom/core.rb +125 -0
- data/lib/rom/data_proxy.rb +97 -0
- data/lib/rom/enumerable_dataset.rb +70 -0
- data/lib/rom/gateway.rb +232 -0
- data/lib/rom/global.rb +56 -0
- data/lib/rom/header/attribute.rb +190 -0
- data/lib/rom/header.rb +198 -0
- data/lib/rom/inferrer.rb +55 -0
- data/lib/rom/initializer.rb +80 -0
- data/lib/rom/lint/enumerable_dataset.rb +56 -0
- data/lib/rom/lint/gateway.rb +120 -0
- data/lib/rom/lint/linter.rb +79 -0
- data/lib/rom/lint/spec.rb +22 -0
- data/lib/rom/lint/test.rb +98 -0
- data/lib/rom/loader.rb +161 -0
- data/lib/rom/mapper/attribute_dsl.rb +480 -0
- data/lib/rom/mapper/dsl.rb +107 -0
- data/lib/rom/mapper/model_dsl.rb +61 -0
- data/lib/rom/mapper.rb +99 -0
- data/lib/rom/mapper_compiler.rb +84 -0
- data/lib/rom/memory/associations/many_to_many.rb +12 -0
- data/lib/rom/memory/associations/many_to_one.rb +12 -0
- data/lib/rom/memory/associations/one_to_many.rb +12 -0
- data/lib/rom/memory/associations/one_to_one.rb +12 -0
- data/lib/rom/memory/associations.rb +6 -0
- data/lib/rom/memory/commands.rb +60 -0
- data/lib/rom/memory/dataset.rb +127 -0
- data/lib/rom/memory/gateway.rb +66 -0
- data/lib/rom/memory/mapper_compiler.rb +10 -0
- data/lib/rom/memory/relation.rb +91 -0
- data/lib/rom/memory/schema.rb +32 -0
- data/lib/rom/memory/storage.rb +61 -0
- data/lib/rom/memory/types.rb +11 -0
- data/lib/rom/memory.rb +7 -0
- data/lib/rom/model_builder.rb +103 -0
- data/lib/rom/open_struct.rb +112 -0
- data/lib/rom/pipeline.rb +111 -0
- data/lib/rom/plugin.rb +130 -0
- data/lib/rom/plugins/class_methods.rb +37 -0
- data/lib/rom/plugins/command/schema.rb +45 -0
- data/lib/rom/plugins/command/timestamps.rb +149 -0
- data/lib/rom/plugins/dsl.rb +53 -0
- data/lib/rom/plugins/relation/changeset.rb +97 -0
- data/lib/rom/plugins/relation/instrumentation.rb +66 -0
- data/lib/rom/plugins/relation/registry_reader.rb +36 -0
- data/lib/rom/plugins/schema/timestamps.rb +59 -0
- data/lib/rom/plugins.rb +100 -0
- data/lib/rom/processor/composer.rb +37 -0
- data/lib/rom/processor/transformer.rb +415 -0
- data/lib/rom/processor.rb +30 -0
- data/lib/rom/registries/associations.rb +26 -0
- data/lib/rom/registries/commands.rb +11 -0
- data/lib/rom/registries/container.rb +12 -0
- data/lib/rom/registries/datasets.rb +21 -0
- data/lib/rom/registries/gateways.rb +8 -0
- data/lib/rom/registries/mappers.rb +21 -0
- data/lib/rom/registries/nestable.rb +32 -0
- data/lib/rom/registries/relations.rb +8 -0
- data/lib/rom/registries/root.rb +203 -0
- data/lib/rom/registries/schemas.rb +44 -0
- data/lib/rom/registries/views.rb +11 -0
- data/lib/rom/relation/class_interface.rb +61 -0
- data/lib/rom/relation/combined.rb +160 -0
- data/lib/rom/relation/commands.rb +65 -0
- data/lib/rom/relation/composite.rb +53 -0
- data/lib/rom/relation/curried.rb +129 -0
- data/lib/rom/relation/graph.rb +107 -0
- data/lib/rom/relation/loaded.rb +136 -0
- data/lib/rom/relation/materializable.rb +62 -0
- data/lib/rom/relation/name.rb +122 -0
- data/lib/rom/relation/wrap.rb +64 -0
- data/lib/rom/relation.rb +625 -0
- data/lib/rom/repository/class_interface.rb +162 -0
- data/lib/rom/repository/relation_reader.rb +48 -0
- data/lib/rom/repository/root.rb +75 -0
- data/lib/rom/repository/session.rb +60 -0
- data/lib/rom/repository.rb +179 -0
- data/lib/rom/schema/associations_dsl.rb +222 -0
- data/lib/rom/schema/inferrer.rb +106 -0
- data/lib/rom/schema.rb +471 -0
- data/lib/rom/settings.rb +141 -0
- data/lib/rom/setup.rb +297 -0
- data/lib/rom/struct.rb +99 -0
- data/lib/rom/struct_compiler.rb +114 -0
- data/lib/rom/support/configurable.rb +213 -0
- data/lib/rom/support/inflector.rb +31 -0
- data/lib/rom/support/memoizable.rb +61 -0
- data/lib/rom/support/notifications.rb +238 -0
- data/lib/rom/transaction.rb +26 -0
- data/lib/rom/transformer.rb +46 -0
- data/lib/rom/types.rb +74 -0
- data/lib/rom/version.rb +1 -1
- data/lib/rom-changeset.rb +4 -0
- data/lib/rom-core.rb +3 -0
- data/lib/rom-repository.rb +4 -0
- data/lib/rom.rb +3 -3
- metadata +276 -39
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rom/transformer"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
Transformer.class_eval do
|
7
|
+
class << self
|
8
|
+
prepend SettingProxy
|
9
|
+
|
10
|
+
# Configure relation for the transformer
|
11
|
+
#
|
12
|
+
# @example with a custom name
|
13
|
+
# class UsersMapper < ROM::Transformer
|
14
|
+
# relation :users, as: :json_serializer
|
15
|
+
#
|
16
|
+
# map do
|
17
|
+
# rename_keys user_id: :id
|
18
|
+
# deep_stringify_keys
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# users.map_with(:json_serializer)
|
23
|
+
#
|
24
|
+
# @param name [Symbol]
|
25
|
+
# @param options [Hash]
|
26
|
+
# @option options :as [Symbol] Mapper identifier
|
27
|
+
#
|
28
|
+
# @deprecated
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
def relation(name = Undefined, as: name)
|
32
|
+
if name == Undefined
|
33
|
+
config.component.relation
|
34
|
+
else
|
35
|
+
config.component.relation = name
|
36
|
+
config.component.namespace = name
|
37
|
+
config.component.id = as
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def setting_mapping
|
42
|
+
@setting_mapping ||= {
|
43
|
+
register_as: [:component, :id],
|
44
|
+
relation: [:component, [:id, :relation, :namespace]]
|
45
|
+
}.freeze
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/rom/compat.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file loads a bunch of patches that maintain compatibility with rom 5.x.
|
4
|
+
# It is not loaded by default in 6.0. During 6.x release series, these patches
|
5
|
+
# will be gradually deprecated and eventually removed in rom 7.0.
|
6
|
+
|
7
|
+
require "rom/core"
|
8
|
+
|
9
|
+
# old api patches
|
10
|
+
require_relative "compat/global"
|
11
|
+
require_relative "compat/auto_registration"
|
12
|
+
require_relative "compat/setting_proxy"
|
13
|
+
require_relative "compat/setup"
|
14
|
+
require_relative "compat/relation"
|
15
|
+
require_relative "compat/command"
|
16
|
+
require_relative "compat/transformer"
|
17
|
+
require_relative "compat/mapper"
|
18
|
+
|
19
|
+
# new api patches
|
20
|
+
require_relative "compat/components/dsl/schema"
|
21
|
+
require_relative "compat/components"
|
22
|
+
require_relative "compat/registries"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "core"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Components
|
7
|
+
# @api public
|
8
|
+
class Association < Core
|
9
|
+
# @!attribute [r] definition
|
10
|
+
# @return [Association::Definition]
|
11
|
+
option :definition
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
def build
|
15
|
+
association_class.new(definition, registry.relations)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def association_class
|
22
|
+
ROM.adapters[config.adapter].const_get(:Associations).const_get(definition.type)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "core"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Components
|
7
|
+
# @api public
|
8
|
+
class Command < Core
|
9
|
+
# @!attribute [r] constant
|
10
|
+
# @return [Class] Component's target class
|
11
|
+
option :constant, type: Types.Interface(:new)
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
def build
|
15
|
+
gateway.command(constant, relation: registry.relations[config.relation])
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
def adapter
|
20
|
+
config.adapter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/effects"
|
4
|
+
require "dry/core/class_attributes"
|
5
|
+
require "dry/core/memoizable"
|
6
|
+
|
7
|
+
require "rom/constants"
|
8
|
+
require "rom/initializer"
|
9
|
+
require "rom/types"
|
10
|
+
|
11
|
+
module ROM
|
12
|
+
module Components
|
13
|
+
# Abstract component class
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
class Core
|
17
|
+
include Dry::Effects.Reader(:registry)
|
18
|
+
|
19
|
+
extend Initializer
|
20
|
+
extend Dry::Core::ClassAttributes
|
21
|
+
|
22
|
+
include Dry::Core::Memoizable
|
23
|
+
|
24
|
+
defines :type
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
def self.inherited(klass)
|
28
|
+
super
|
29
|
+
klass.type(Inflector.component_id(klass).to_sym)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @!attribute [r] provider
|
33
|
+
# @return [Object] Component's provider
|
34
|
+
option :provider
|
35
|
+
|
36
|
+
# @!attribute [r] config
|
37
|
+
# @return [Object] Component's config
|
38
|
+
option :config, type: Types.Instance(Dry::Configurable::Config)
|
39
|
+
|
40
|
+
# @!attribute [r] gateway
|
41
|
+
# @return [Proc] Optional component evaluation block
|
42
|
+
option :block, type: Types.Interface(:to_proc), optional: true
|
43
|
+
|
44
|
+
# @api public
|
45
|
+
def type
|
46
|
+
self.class.type
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api public
|
50
|
+
def abstract
|
51
|
+
config.abstract
|
52
|
+
end
|
53
|
+
alias_method :abstract?, :abstract
|
54
|
+
|
55
|
+
# Default container key
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
memoize def key
|
61
|
+
"#{namespace}.#{id}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api public
|
65
|
+
def id
|
66
|
+
config.id
|
67
|
+
end
|
68
|
+
|
69
|
+
# @api public
|
70
|
+
def namespace
|
71
|
+
config.namespace
|
72
|
+
end
|
73
|
+
|
74
|
+
# This method is meant to return a run-time component instance
|
75
|
+
#
|
76
|
+
# @api public
|
77
|
+
def build(**)
|
78
|
+
raise NotImplementedError
|
79
|
+
end
|
80
|
+
|
81
|
+
# @api public
|
82
|
+
def inflector
|
83
|
+
config.inflector
|
84
|
+
end
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
def components
|
88
|
+
provider.components
|
89
|
+
end
|
90
|
+
|
91
|
+
# @api private
|
92
|
+
def local_components
|
93
|
+
EMPTY_ARRAY
|
94
|
+
end
|
95
|
+
|
96
|
+
# @api private
|
97
|
+
def apply_plugins
|
98
|
+
already_applied = plugins.reject(&:applied?).map do |plugin|
|
99
|
+
plugin.enable(constant) unless plugin.enabled?
|
100
|
+
plugin.apply unless plugin.applied?
|
101
|
+
plugin.name
|
102
|
+
end
|
103
|
+
|
104
|
+
apply_external_plugins(gateway_plugins, already_applied) if gateway?
|
105
|
+
apply_external_plugins(provider_plugins, already_applied)
|
106
|
+
end
|
107
|
+
|
108
|
+
# @api private
|
109
|
+
def apply_external_plugins(plugins, already_applied)
|
110
|
+
plugins
|
111
|
+
.reject { |plugin| already_applied.include?(plugin.name) }
|
112
|
+
.each { |external_plugin|
|
113
|
+
config.plugins << external_plugin.configure.enable(constant).apply
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
def plugins
|
119
|
+
config.plugins.select { |plugin| plugin.type == type }
|
120
|
+
end
|
121
|
+
|
122
|
+
# @api private
|
123
|
+
def gateway_plugins
|
124
|
+
gateway.config.plugins.select { |plugin| plugin.type == type }
|
125
|
+
end
|
126
|
+
|
127
|
+
# @api private
|
128
|
+
def provider_plugins
|
129
|
+
provider.config.component.plugins.select { |plugin| plugin.type == type }
|
130
|
+
end
|
131
|
+
|
132
|
+
# @api public
|
133
|
+
def plugin_options
|
134
|
+
plugins.map(&:plugin_options).reduce(:merge) || EMPTY_HASH
|
135
|
+
end
|
136
|
+
|
137
|
+
# @api public
|
138
|
+
def gateway?
|
139
|
+
registry.gateways.key?(config[:gateway])
|
140
|
+
end
|
141
|
+
|
142
|
+
# @api public
|
143
|
+
def gateway
|
144
|
+
registry.gateways[config[:gateway]]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "core"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Components
|
7
|
+
# @api public
|
8
|
+
class Dataset < Core
|
9
|
+
# @api public
|
10
|
+
def build
|
11
|
+
if gateway?
|
12
|
+
blocks.reduce(gateway.dataset(id)) { |ds, blk| evaluate_block(ds, blk) }
|
13
|
+
elsif block
|
14
|
+
schema ? block.(schema) : block.()
|
15
|
+
else
|
16
|
+
EMPTY_ARRAY
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @api private
|
21
|
+
def blocks
|
22
|
+
[*dataset_components.map(&:block), block].compact
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def evaluate_block(ds, block)
|
27
|
+
ds.instance_exec(schema, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @api adapter
|
31
|
+
def adapter
|
32
|
+
config.adapter
|
33
|
+
end
|
34
|
+
|
35
|
+
# @api adapter
|
36
|
+
def relation_id
|
37
|
+
config.relation_id
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
memoize def schema
|
44
|
+
if id == relation_id
|
45
|
+
registry.schemas[id] if registry.schemas.key?(id)
|
46
|
+
elsif relation_id
|
47
|
+
registry.fetch("schemas.#{relation_id}.#{id}") {
|
48
|
+
registry.fetch("schemas.#{relation_id}")
|
49
|
+
}
|
50
|
+
elsif registry.schemas.key?(id)
|
51
|
+
registry.schemas[id]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# @api private
|
55
|
+
memoize def dataset_components
|
56
|
+
provider.components.datasets(abstract: true, adapter: adapter)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rom/schema/associations_dsl"
|
4
|
+
require "rom/relation/name"
|
5
|
+
|
6
|
+
require_relative "core"
|
7
|
+
|
8
|
+
module ROM
|
9
|
+
module Components
|
10
|
+
module DSL
|
11
|
+
# Setup DSL-specific relation extensions
|
12
|
+
#
|
13
|
+
# @private
|
14
|
+
class Association < Core
|
15
|
+
key :associations
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
def call
|
19
|
+
configure
|
20
|
+
|
21
|
+
backend.instance_eval(&block)
|
22
|
+
|
23
|
+
backend.call.each do |definition|
|
24
|
+
components.add(key, definition: definition, config: config.join(definition, :right))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def backend
|
30
|
+
@backend ||= ROM::Schema::AssociationsDSL.new(source, inflector)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
def source
|
35
|
+
if provider.config.component.key?(:id)
|
36
|
+
# TODO: decouple associations DSL from Relation::Name
|
37
|
+
ROM::Relation::Name[
|
38
|
+
provider.config.component.id, provider.config.component.dataset
|
39
|
+
]
|
40
|
+
else
|
41
|
+
config.source
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "core"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Components
|
7
|
+
module DSL
|
8
|
+
# Command `define` DSL used by Setup#commands
|
9
|
+
#
|
10
|
+
# @private
|
11
|
+
class Command < Core
|
12
|
+
key :commands
|
13
|
+
|
14
|
+
nested(true)
|
15
|
+
|
16
|
+
# Define a command class
|
17
|
+
#
|
18
|
+
# @param [Symbol] name of the command
|
19
|
+
# @param [Hash] options
|
20
|
+
# @option options [Symbol] :type The type of the command
|
21
|
+
#
|
22
|
+
# @return [Class] generated class
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def define(id, type: id, **options, &block)
|
26
|
+
command_type = inflector.classify(type)
|
27
|
+
parent = adapter_namespace.const_get(command_type)
|
28
|
+
|
29
|
+
constant = build_class(name: class_name(command_type), parent: parent) do |dsl|
|
30
|
+
config.update(options)
|
31
|
+
|
32
|
+
config.component.update(dsl.config)
|
33
|
+
config.component.update(id: id, adapter: dsl.adapter)
|
34
|
+
|
35
|
+
class_exec(&block) if block
|
36
|
+
end
|
37
|
+
|
38
|
+
call(constant: constant, config: constant.config.component)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
def class_name(command_type)
|
43
|
+
class_name_inferrer[
|
44
|
+
config[:relation],
|
45
|
+
type: :command,
|
46
|
+
inflector: inflector,
|
47
|
+
adapter: adapter,
|
48
|
+
command_type: command_type,
|
49
|
+
class_namespace: provider.config.class_namespace
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
def adapter_namespace
|
55
|
+
ROM::Command.adapter_namespace(adapter)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/memoizable"
|
4
|
+
require "dry/core/class_builder"
|
5
|
+
|
6
|
+
require "rom/plugins/class_methods"
|
7
|
+
require "rom/constants"
|
8
|
+
require "rom/initializer"
|
9
|
+
|
10
|
+
module ROM
|
11
|
+
module Components
|
12
|
+
module DSL
|
13
|
+
# @private
|
14
|
+
class Core
|
15
|
+
extend Initializer
|
16
|
+
extend Dry::Core::ClassAttributes
|
17
|
+
include Plugins::ClassMethods
|
18
|
+
|
19
|
+
defines(:key, :type, :nested)
|
20
|
+
|
21
|
+
include Dry::Core::Memoizable
|
22
|
+
|
23
|
+
nested false
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
option :provider
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
option :config, optional: true, default: -> { EMPTY_HASH }
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
option :block, optional: true
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
def self.inherited(klass)
|
36
|
+
super
|
37
|
+
klass.type(Inflector.component_id(klass).to_sym)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
def build_class(name: class_name, parent: class_parent, &block)
|
42
|
+
Dry::Core::ClassBuilder.new(name: name, parent: parent).call do |klass|
|
43
|
+
klass.config.component.update(config)
|
44
|
+
klass.class_exec(self, &block) if block
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def key
|
50
|
+
self.class.key
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
def type
|
55
|
+
self.class.type
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def call(**options)
|
60
|
+
components.add(key, config: configure, block: block, **options)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @api private
|
64
|
+
def configure
|
65
|
+
config.freeze
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def plugin(name, **options)
|
70
|
+
plugin = enabled_plugins[name]
|
71
|
+
plugin.config.update(options) unless options.empty?
|
72
|
+
plugin
|
73
|
+
end
|
74
|
+
|
75
|
+
# @api private
|
76
|
+
def enabled_plugins
|
77
|
+
config.plugins
|
78
|
+
.select { |plugin| plugin.type == type }
|
79
|
+
.to_h { |plugin| [plugin.name, plugin] }
|
80
|
+
end
|
81
|
+
|
82
|
+
# @api private
|
83
|
+
def enable_plugins
|
84
|
+
config.plugins.map! do |plugin|
|
85
|
+
if plugin.is_a?(Symbol)
|
86
|
+
plugins[plugin].configure.enable(self)
|
87
|
+
elsif plugin.type == type
|
88
|
+
plugin.configure.enable(respond_to?(:constant) ? constant : self)
|
89
|
+
else
|
90
|
+
plugin
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# @api private
|
98
|
+
def components
|
99
|
+
provider.components
|
100
|
+
end
|
101
|
+
|
102
|
+
# @api private
|
103
|
+
def inflector
|
104
|
+
provider.config.component.inflector
|
105
|
+
end
|
106
|
+
|
107
|
+
# @api private
|
108
|
+
def class_name_inferrer
|
109
|
+
provider.config.class_name_inferrer
|
110
|
+
end
|
111
|
+
|
112
|
+
# @api private
|
113
|
+
memoize def adapter
|
114
|
+
config.adapter || gateway_adapter
|
115
|
+
end
|
116
|
+
|
117
|
+
# @api private
|
118
|
+
def gateway_adapter
|
119
|
+
if provider.config.key?(:gateways)
|
120
|
+
provider.config.gateways[config.gateway]&.fetch(:adapter)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "core"
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Components
|
7
|
+
module DSL
|
8
|
+
# @private
|
9
|
+
class Dataset < Core
|
10
|
+
key :datasets
|
11
|
+
|
12
|
+
def configure
|
13
|
+
if relation?
|
14
|
+
config.join!({namespace: relation_id}, :right) if config.id != relation_id
|
15
|
+
|
16
|
+
config.relation_id = relation_id
|
17
|
+
end
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def relation_id
|
24
|
+
provider.config.component.id
|
25
|
+
end
|
26
|
+
|
27
|
+
def relation?
|
28
|
+
provider.config.component.type == :relation
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/class_builder"
|
4
|
+
|
5
|
+
require_relative "core"
|
6
|
+
|
7
|
+
module ROM
|
8
|
+
module Components
|
9
|
+
module DSL
|
10
|
+
# Mapper definition DSL used by Setup DSL
|
11
|
+
#
|
12
|
+
# @private
|
13
|
+
class Mapper < Core
|
14
|
+
key(:mappers)
|
15
|
+
|
16
|
+
nested(true)
|
17
|
+
|
18
|
+
# Define a mapper class
|
19
|
+
#
|
20
|
+
# @param [Symbol] id Mapper identifier
|
21
|
+
# @param [Hash] options
|
22
|
+
#
|
23
|
+
# @return [Class]
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def define(id, parent: id, **options, &block)
|
27
|
+
class_opts = {name: class_name(id), parent: class_parent(parent)}
|
28
|
+
|
29
|
+
constant = build_class(**class_opts) do |dsl|
|
30
|
+
config.update(options)
|
31
|
+
|
32
|
+
config.component.update(id: id, relation: parent)
|
33
|
+
config.component.join!({namespace: parent}, :right) if dsl.config.namespace != parent
|
34
|
+
|
35
|
+
class_eval(&block) if block
|
36
|
+
end
|
37
|
+
|
38
|
+
call(constant: constant, config: constant.config.component)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
def class_parent(parent)
|
43
|
+
components.get(:mappers, relation: parent)&.constant || ROM::Mapper
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def class_name(id)
|
48
|
+
"ROM::Mapper[#{id}]"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Register any object as a mapper for a given relation
|
52
|
+
#
|
53
|
+
# @param [Symbol] relation The relation registry id
|
54
|
+
# @param [Hash<Symbol, Object>] mappers A hash with mapper objects
|
55
|
+
#
|
56
|
+
# @return [Array<Components::Mapper>]
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
def register(namespace, mappers)
|
60
|
+
mappers.map do |id, mapper|
|
61
|
+
call(
|
62
|
+
object: mapper,
|
63
|
+
config: config.join({id: id, relation: namespace, namespace: namespace}, :right)
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|