rom 5.4.2 → 6.0.0.alpha1

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.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -71
  3. data/LICENSE +1 -1
  4. data/README.md +7 -6
  5. data/lib/rom/array_dataset.rb +46 -0
  6. data/lib/rom/associations/abstract.rb +217 -0
  7. data/lib/rom/associations/definitions/abstract.rb +150 -0
  8. data/lib/rom/associations/definitions/many_to_many.rb +29 -0
  9. data/lib/rom/associations/definitions/many_to_one.rb +14 -0
  10. data/lib/rom/associations/definitions/one_to_many.rb +14 -0
  11. data/lib/rom/associations/definitions/one_to_one.rb +14 -0
  12. data/lib/rom/associations/definitions/one_to_one_through.rb +14 -0
  13. data/lib/rom/associations/definitions.rb +7 -0
  14. data/lib/rom/associations/many_to_many.rb +128 -0
  15. data/lib/rom/associations/many_to_one.rb +65 -0
  16. data/lib/rom/associations/one_to_many.rb +65 -0
  17. data/lib/rom/associations/one_to_one.rb +13 -0
  18. data/lib/rom/associations/one_to_one_through.rb +13 -0
  19. data/lib/rom/associations/through_identifier.rb +41 -0
  20. data/lib/rom/attribute.rb +425 -0
  21. data/lib/rom/auto_curry.rb +70 -0
  22. data/lib/rom/cache.rb +87 -0
  23. data/lib/rom/changeset/associated.rb +110 -0
  24. data/lib/rom/changeset/create.rb +18 -0
  25. data/lib/rom/changeset/delete.rb +15 -0
  26. data/lib/rom/changeset/extensions/relation.rb +26 -0
  27. data/lib/rom/changeset/pipe.rb +81 -0
  28. data/lib/rom/changeset/pipe_registry.rb +27 -0
  29. data/lib/rom/changeset/stateful.rb +285 -0
  30. data/lib/rom/changeset/update.rb +81 -0
  31. data/lib/rom/changeset.rb +185 -0
  32. data/lib/rom/command.rb +351 -0
  33. data/lib/rom/command_compiler.rb +201 -0
  34. data/lib/rom/command_proxy.rb +36 -0
  35. data/lib/rom/commands/class_interface.rb +236 -0
  36. data/lib/rom/commands/composite.rb +55 -0
  37. data/lib/rom/commands/create.rb +15 -0
  38. data/lib/rom/commands/delete.rb +16 -0
  39. data/lib/rom/commands/graph/class_interface.rb +64 -0
  40. data/lib/rom/commands/graph/input_evaluator.rb +94 -0
  41. data/lib/rom/commands/graph.rb +88 -0
  42. data/lib/rom/commands/lazy/create.rb +35 -0
  43. data/lib/rom/commands/lazy/delete.rb +39 -0
  44. data/lib/rom/commands/lazy/update.rb +46 -0
  45. data/lib/rom/commands/lazy.rb +106 -0
  46. data/lib/rom/commands/update.rb +16 -0
  47. data/lib/rom/commands.rb +5 -0
  48. data/lib/rom/compat/auto_registration.rb +115 -0
  49. data/lib/rom/compat/auto_registration_strategies/base.rb +29 -0
  50. data/lib/rom/compat/auto_registration_strategies/custom_namespace.rb +84 -0
  51. data/lib/rom/compat/auto_registration_strategies/no_namespace.rb +33 -0
  52. data/lib/rom/compat/auto_registration_strategies/with_namespace.rb +29 -0
  53. data/lib/rom/compat/command.rb +74 -0
  54. data/lib/rom/compat/components/dsl/schema.rb +130 -0
  55. data/lib/rom/compat/components.rb +91 -0
  56. data/lib/rom/compat/global.rb +17 -0
  57. data/lib/rom/compat/mapper.rb +22 -0
  58. data/lib/rom/compat/registries.rb +47 -0
  59. data/lib/rom/compat/relation.rb +40 -0
  60. data/lib/rom/compat/schema/dsl.rb +260 -0
  61. data/lib/rom/compat/setting_proxy.rb +44 -0
  62. data/lib/rom/compat/setup.rb +151 -0
  63. data/lib/rom/compat/transformer.rb +49 -0
  64. data/lib/rom/compat.rb +22 -0
  65. data/lib/rom/components/association.rb +26 -0
  66. data/lib/rom/components/command.rb +24 -0
  67. data/lib/rom/components/core.rb +148 -0
  68. data/lib/rom/components/dataset.rb +60 -0
  69. data/lib/rom/components/dsl/association.rb +47 -0
  70. data/lib/rom/components/dsl/command.rb +60 -0
  71. data/lib/rom/components/dsl/core.rb +126 -0
  72. data/lib/rom/components/dsl/dataset.rb +33 -0
  73. data/lib/rom/components/dsl/gateway.rb +14 -0
  74. data/lib/rom/components/dsl/mapper.rb +70 -0
  75. data/lib/rom/components/dsl/relation.rb +49 -0
  76. data/lib/rom/components/dsl/schema.rb +150 -0
  77. data/lib/rom/components/dsl/view.rb +82 -0
  78. data/lib/rom/components/dsl.rb +255 -0
  79. data/lib/rom/components/gateway.rb +50 -0
  80. data/lib/rom/components/mapper.rb +29 -0
  81. data/lib/rom/components/provider.rb +160 -0
  82. data/lib/rom/components/registry.rb +154 -0
  83. data/lib/rom/components/relation.rb +41 -0
  84. data/lib/rom/components/schema.rb +61 -0
  85. data/lib/rom/components/view.rb +55 -0
  86. data/lib/rom/components.rb +55 -0
  87. data/lib/rom/configuration_dsl.rb +4 -0
  88. data/lib/rom/constants.rb +135 -0
  89. data/lib/rom/container.rb +182 -0
  90. data/lib/rom/core.rb +125 -0
  91. data/lib/rom/data_proxy.rb +97 -0
  92. data/lib/rom/enumerable_dataset.rb +70 -0
  93. data/lib/rom/gateway.rb +232 -0
  94. data/lib/rom/global.rb +56 -0
  95. data/lib/rom/header/attribute.rb +190 -0
  96. data/lib/rom/header.rb +198 -0
  97. data/lib/rom/inferrer.rb +55 -0
  98. data/lib/rom/initializer.rb +80 -0
  99. data/lib/rom/lint/enumerable_dataset.rb +56 -0
  100. data/lib/rom/lint/gateway.rb +120 -0
  101. data/lib/rom/lint/linter.rb +79 -0
  102. data/lib/rom/lint/spec.rb +22 -0
  103. data/lib/rom/lint/test.rb +98 -0
  104. data/lib/rom/loader.rb +161 -0
  105. data/lib/rom/mapper/attribute_dsl.rb +480 -0
  106. data/lib/rom/mapper/dsl.rb +107 -0
  107. data/lib/rom/mapper/model_dsl.rb +61 -0
  108. data/lib/rom/mapper.rb +99 -0
  109. data/lib/rom/mapper_compiler.rb +84 -0
  110. data/lib/rom/memory/associations/many_to_many.rb +12 -0
  111. data/lib/rom/memory/associations/many_to_one.rb +12 -0
  112. data/lib/rom/memory/associations/one_to_many.rb +12 -0
  113. data/lib/rom/memory/associations/one_to_one.rb +12 -0
  114. data/lib/rom/memory/associations.rb +6 -0
  115. data/lib/rom/memory/commands.rb +60 -0
  116. data/lib/rom/memory/dataset.rb +127 -0
  117. data/lib/rom/memory/gateway.rb +66 -0
  118. data/lib/rom/memory/mapper_compiler.rb +10 -0
  119. data/lib/rom/memory/relation.rb +91 -0
  120. data/lib/rom/memory/schema.rb +32 -0
  121. data/lib/rom/memory/storage.rb +61 -0
  122. data/lib/rom/memory/types.rb +11 -0
  123. data/lib/rom/memory.rb +7 -0
  124. data/lib/rom/model_builder.rb +103 -0
  125. data/lib/rom/open_struct.rb +112 -0
  126. data/lib/rom/pipeline.rb +111 -0
  127. data/lib/rom/plugin.rb +130 -0
  128. data/lib/rom/plugins/class_methods.rb +37 -0
  129. data/lib/rom/plugins/command/schema.rb +45 -0
  130. data/lib/rom/plugins/command/timestamps.rb +149 -0
  131. data/lib/rom/plugins/dsl.rb +53 -0
  132. data/lib/rom/plugins/relation/changeset.rb +97 -0
  133. data/lib/rom/plugins/relation/instrumentation.rb +66 -0
  134. data/lib/rom/plugins/relation/registry_reader.rb +36 -0
  135. data/lib/rom/plugins/schema/timestamps.rb +59 -0
  136. data/lib/rom/plugins.rb +100 -0
  137. data/lib/rom/processor/composer.rb +37 -0
  138. data/lib/rom/processor/transformer.rb +415 -0
  139. data/lib/rom/processor.rb +30 -0
  140. data/lib/rom/registries/associations.rb +26 -0
  141. data/lib/rom/registries/commands.rb +11 -0
  142. data/lib/rom/registries/container.rb +12 -0
  143. data/lib/rom/registries/datasets.rb +21 -0
  144. data/lib/rom/registries/gateways.rb +8 -0
  145. data/lib/rom/registries/mappers.rb +21 -0
  146. data/lib/rom/registries/nestable.rb +32 -0
  147. data/lib/rom/registries/relations.rb +8 -0
  148. data/lib/rom/registries/root.rb +203 -0
  149. data/lib/rom/registries/schemas.rb +44 -0
  150. data/lib/rom/registries/views.rb +11 -0
  151. data/lib/rom/relation/class_interface.rb +61 -0
  152. data/lib/rom/relation/combined.rb +160 -0
  153. data/lib/rom/relation/commands.rb +65 -0
  154. data/lib/rom/relation/composite.rb +53 -0
  155. data/lib/rom/relation/curried.rb +129 -0
  156. data/lib/rom/relation/graph.rb +107 -0
  157. data/lib/rom/relation/loaded.rb +136 -0
  158. data/lib/rom/relation/materializable.rb +62 -0
  159. data/lib/rom/relation/name.rb +122 -0
  160. data/lib/rom/relation/wrap.rb +64 -0
  161. data/lib/rom/relation.rb +625 -0
  162. data/lib/rom/repository/class_interface.rb +162 -0
  163. data/lib/rom/repository/relation_reader.rb +48 -0
  164. data/lib/rom/repository/root.rb +75 -0
  165. data/lib/rom/repository/session.rb +60 -0
  166. data/lib/rom/repository.rb +179 -0
  167. data/lib/rom/schema/associations_dsl.rb +222 -0
  168. data/lib/rom/schema/inferrer.rb +106 -0
  169. data/lib/rom/schema.rb +471 -0
  170. data/lib/rom/settings.rb +141 -0
  171. data/lib/rom/setup.rb +297 -0
  172. data/lib/rom/struct.rb +99 -0
  173. data/lib/rom/struct_compiler.rb +114 -0
  174. data/lib/rom/support/configurable.rb +213 -0
  175. data/lib/rom/support/inflector.rb +31 -0
  176. data/lib/rom/support/memoizable.rb +61 -0
  177. data/lib/rom/support/notifications.rb +238 -0
  178. data/lib/rom/transaction.rb +26 -0
  179. data/lib/rom/transformer.rb +46 -0
  180. data/lib/rom/types.rb +74 -0
  181. data/lib/rom/version.rb +1 -1
  182. data/lib/rom-changeset.rb +4 -0
  183. data/lib/rom-core.rb +3 -0
  184. data/lib/rom-repository.rb +4 -0
  185. data/lib/rom.rb +3 -3
  186. metadata +302 -23
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/components/core"
4
+ require "rom/components/dataset"
5
+ require "rom/components/relation"
6
+ require "rom/components/command"
7
+
8
+ module ROM
9
+ class Components::Core
10
+ # @api private
11
+ def trigger(event, payload)
12
+ registry.trigger("configuration.#{event}", payload)
13
+ end
14
+
15
+ # @api private
16
+ def notifications
17
+ registry.notifications
18
+ end
19
+ end
20
+
21
+ class Components::Dataset < Components::Core
22
+ mod = Module.new do
23
+ # @api private
24
+ def evaluate_block(ds, block)
25
+ if block.parameters.flatten.include?(:schema)
26
+ super
27
+ else
28
+ ds.instance_exec(relation_constant, &block)
29
+ end
30
+ end
31
+
32
+ def relation_constant
33
+ registry.components.get(:relations, id: relation_id).constant
34
+ end
35
+ end
36
+
37
+ prepend(mod)
38
+ end
39
+
40
+ class Components::Relation < Components::Core
41
+ mod = Module.new do
42
+ def build
43
+ schema = local_components.get(:schemas, id: id)&.build
44
+
45
+ if schema
46
+ trigger(
47
+ "relations.schema.set",
48
+ schema: schema,
49
+ adapter: adapter,
50
+ gateway: config[:gateway],
51
+ relation: constant,
52
+ registry: registry
53
+ )
54
+ end
55
+
56
+ trigger("relations.class.ready", relation: constant, adapter: adapter)
57
+
58
+ components.update(local_components)
59
+
60
+ relation = super
61
+
62
+ trigger("relations.object.registered", registry: registry, relation: relation)
63
+
64
+ relation
65
+ end
66
+ end
67
+
68
+ prepend(mod)
69
+ end
70
+
71
+ class Components::Command < Components::Core
72
+ mod = Module.new do
73
+ def build
74
+ relation = registry.relations[config.relation]
75
+
76
+ trigger(
77
+ "commands.class.before_build",
78
+ command: constant,
79
+ gateway: registry.gateways[relation.gateway],
80
+ dataset: relation.dataset,
81
+ relation: relation,
82
+ adapter: adapter
83
+ )
84
+
85
+ super
86
+ end
87
+ end
88
+
89
+ prepend(mod)
90
+ end
91
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/container"
4
+ require "rom/global"
5
+
6
+ module ROM
7
+ # @api private
8
+ # @deprecated
9
+ alias_method :plugin_registry, :plugins
10
+
11
+ # @api public
12
+ module Global
13
+ # @api public
14
+ # @deprecated
15
+ alias_method :container, :setup
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/mapper"
4
+
5
+ module ROM
6
+ class Mapper
7
+ class << self
8
+ prepend SettingProxy
9
+
10
+ def setting_mapping
11
+ @setting_mapper ||= ROM::Transformer.setting_mapping.merge(
12
+ inherit_header: [],
13
+ reject_keys: [],
14
+ symbolize_keys: [],
15
+ copy_keys: [],
16
+ prefix: [],
17
+ prefix_separator: []
18
+ ).freeze
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/registries/root"
4
+
5
+ module ROM
6
+ # @api public
7
+ class Registries::Root
8
+ option :notifications, optional: true
9
+
10
+ # @api private
11
+ # @api deprecated
12
+ def trigger(event, payload)
13
+ notifications&.trigger(event, payload)
14
+ end
15
+
16
+ # @api public
17
+ # @deprecated
18
+ def map_with(*ids)
19
+ with(opts: {map_with: ids})
20
+ end
21
+
22
+ undef :build
23
+ # @api private
24
+ def build(key, &block)
25
+ item = components.(key, &block)
26
+
27
+ if commands? && (mappers = opts[:map_with])
28
+ item >> mappers.map { |mapper| item.relation.mappers[mapper] }.reduce(:>>)
29
+ else
30
+ item
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ # @api private
37
+ def respond_to_missing?(name, *)
38
+ super || key?(name)
39
+ end
40
+
41
+ # @api public
42
+ # @deprecated
43
+ def method_missing(name, *args, &block)
44
+ fetch(name) { super }
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/relation"
4
+ require_relative "schema/dsl"
5
+
6
+ module ROM
7
+ class Relation
8
+ class << self
9
+ prepend SettingProxy
10
+
11
+ def setting_mapping
12
+ @setting_mapping ||= {
13
+ auto_map: [],
14
+ auto_struct: [],
15
+ struct_namespace: [],
16
+ wrap_class: [],
17
+ adapter: [:component, :adapter],
18
+ gateway: [:component, :gateway],
19
+ schema_class: [:schema, :constant],
20
+ schema_dsl: [:schema, :dsl_class],
21
+ schema_attr_class: [:schema, :attr_class],
22
+ schema_inferrer: [:schema, :inferrer]
23
+ }.freeze
24
+ end
25
+ end
26
+
27
+ extend Notifications::Listener
28
+
29
+ # This is used by the deprecated command => relation view delegation syntax
30
+ # @api private
31
+ def self.view_methods
32
+ ancestor_methods = ancestors.reject { |klass| klass == self }
33
+ .map(&:instance_methods).flatten(1)
34
+
35
+ instance_methods - ancestor_methods + auto_curried_methods.to_a
36
+ end
37
+
38
+ config.schema.dsl_class = ROM::Schema::DSL
39
+ end
40
+ end
@@ -0,0 +1,260 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/support/inflector"
4
+
5
+ require "rom/initializer"
6
+ require "rom/types"
7
+ require "rom/attribute"
8
+ require "rom/schema/associations_dsl"
9
+
10
+ module ROM
11
+ class Schema
12
+ # Schema DSL exposed as `schema { .. }` in relation classes
13
+ #
14
+ # @see Components::DSL::Schema
15
+ #
16
+ # @deprecated
17
+ #
18
+ # @api public
19
+ class DSL
20
+ extend Initializer
21
+
22
+ # @!attribute [r] relation
23
+ # @return [Relation::Name] The name of the schema's relation
24
+ option :relation
25
+
26
+ # @!attribute [r] adapter
27
+ # @return [Symbol] The adapter identifier used in gateways
28
+ option :adapter
29
+
30
+ # @!attribute [r] inflector
31
+ # @return [Dry::Inflector] String inflector
32
+ # @api private
33
+ option :inflector, default: -> { Inflector }
34
+
35
+ # @!attribute [r] schema_class
36
+ # @return [Class] Schema class that should be instantiated
37
+ option :constant, default: -> { Schema }
38
+ alias_method :schema_class, :constant
39
+
40
+ # @!attribute [r] attr_class
41
+ # @return [Class] Attribute class that should be used
42
+ option :attr_class, default: -> { Attribute }
43
+
44
+ # @!attribute [r] attributes
45
+ # @return [Hash<Symbol, Hash>] A hash with attribute names as
46
+ # keys and attribute representations as values.
47
+ #
48
+ # @see [Schema.build_attribute_info]
49
+ option :attributes, default: -> { EMPTY_HASH.dup }
50
+
51
+ # @!attribute [r] definition
52
+ # @return [Class] An optional block that will be evaluated as part of this DSL
53
+ option :definition, type: Types.Instance(Proc), default: -> { proc {} }
54
+
55
+ # @!attribute [r] plugins
56
+ # @return [Array<Plugin>]
57
+ option :plugins, default: -> { EMPTY_ARRAY }
58
+
59
+ # @api private
60
+ def self.new(**options, &block)
61
+ if block
62
+ super(definition: block, **options)
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+ # Defines a relation attribute with its type and options.
69
+ #
70
+ # When only options are given, type is left as nil. It makes
71
+ # sense when it is used alongside a schema inferrer, which will
72
+ # populate the type.
73
+ #
74
+ # @see Relation.schema
75
+ #
76
+ # @api public
77
+ def attribute(name, type_or_options, options = EMPTY_HASH)
78
+ if attributes.include?(name)
79
+ raise(
80
+ ::ROM::AttributeAlreadyDefinedError,
81
+ "Attribute #{name.inspect} already defined"
82
+ )
83
+ end
84
+
85
+ build_attribute_info(name, type_or_options, options).tap do |attr_info|
86
+ attributes[name] = attr_info
87
+ end
88
+ end
89
+
90
+ # Specify which key(s) should be the primary key
91
+ #
92
+ # @api public
93
+ def primary_key(*names)
94
+ names.each do |name|
95
+ attributes[name][:type] = attributes[name][:type].meta(primary_key: true)
96
+ end
97
+ self
98
+ end
99
+
100
+ # Define associations for a relation
101
+ #
102
+ # @example
103
+ # class Users < ROM::Relation[:sql]
104
+ # schema(infer: true) do
105
+ # associations do
106
+ # has_many :tasks
107
+ # has_many :posts
108
+ # has_many :posts, as: :priority_posts, view: :prioritized
109
+ # belongs_to :account
110
+ # end
111
+ # end
112
+ # end
113
+ #
114
+ # class Posts < ROM::Relation[:sql]
115
+ # schema(infer: true) do
116
+ # associations do
117
+ # belongs_to :users, as: :author
118
+ # end
119
+ # end
120
+ #
121
+ # view(:prioritized) do
122
+ # where { priority <= 3 }
123
+ # end
124
+ # end
125
+ #
126
+ # @return [AssociationDSL]
127
+ #
128
+ # @api public
129
+ def associations(&block)
130
+ if block
131
+ __assoc_dsl__.instance_eval(&block)
132
+ else
133
+ __assoc_dsl__.registry.values
134
+ end
135
+ end
136
+
137
+ # @api private
138
+ def __assoc_dsl__
139
+ @__assoc_dsl__ ||= AssociationsDSL.new(relation, inflector)
140
+ end
141
+
142
+ # Enable a plugin in the schema DSL
143
+ #
144
+ # @param [Symbol] name Plugin name
145
+ # @param [Hash] options Plugin options
146
+ #
147
+ # @api public
148
+ def use(name, **options)
149
+ plugin = ::ROM.plugins[:schema].fetch(name, adapter).configure do |config|
150
+ config.update(options)
151
+ end
152
+ plugins << plugin.enable(self)
153
+ self
154
+ end
155
+
156
+ # @api public
157
+ def plugin(name, **options)
158
+ plugin = plugins.detect { |pl| pl.name == name }
159
+ plugin.config.update(options) unless options.empty?
160
+ plugin
161
+ end
162
+
163
+ # @api private
164
+ def call
165
+ schema_class.define(relation, **config)
166
+ end
167
+
168
+ # @api private
169
+ def config
170
+ @config ||=
171
+ begin
172
+ # Enable available plugin's
173
+ plugins.each do |plugin|
174
+ next unless plugin.type == :schema
175
+ plugin.enable(self) unless plugin.enabled?
176
+ end
177
+
178
+ # Apply custom definition block if it exists
179
+ instance_eval(&definition) if definition
180
+
181
+ # Apply plugin defaults
182
+ plugins.each do |plugin|
183
+ next unless plugin.type == :schema
184
+ plugin.__send__(:apply_to, self)
185
+ end
186
+
187
+ attributes.freeze
188
+ associations.freeze
189
+
190
+ opts.freeze
191
+ end
192
+ end
193
+
194
+ # @api public
195
+ def inspect
196
+ %(<##{self.class} relation=#{relation} attributes=#{attributes} plugins=#{plugins}>)
197
+ end
198
+
199
+ private
200
+
201
+ # Return schema opts
202
+ #
203
+ # @return [Hash]
204
+ #
205
+ # @api private
206
+ def opts
207
+ {attributes: attributes.values,
208
+ associations: associations,
209
+ attr_class: attr_class,
210
+ plugins: plugins}
211
+ end
212
+
213
+ # Builds a representation of the information needed to create an
214
+ # attribute. It returns a hash with `:type` and `:options` keys.
215
+ #
216
+ # @return [Hash]
217
+ #
218
+ # @see [Schema.build_attribute_info]
219
+ #
220
+ # @api private
221
+ def build_attribute_info(name, type_or_options, options = EMPTY_HASH)
222
+ type, options = if type_or_options.is_a?(::Hash)
223
+ [nil, type_or_options]
224
+ else
225
+ [build_type(type_or_options, options), options]
226
+ end
227
+ Schema.build_attribute_info(
228
+ type, **options, name: name
229
+ )
230
+ end
231
+
232
+ # Builds a type instance from base type and meta options
233
+ #
234
+ # @return [Dry::Types::Type] Type instance
235
+ #
236
+ # @api private
237
+ def build_type(type, options = EMPTY_HASH)
238
+ meta = Attribute::META_OPTIONS
239
+ .map { |opt| [opt, options[opt]] if options.key?(opt) }
240
+ .compact
241
+ .to_h
242
+
243
+ base =
244
+ if options[:read]
245
+ type.meta(source: relation, read: options[:read])
246
+ elsif type.optional? && type.meta[:read]
247
+ type.meta(source: relation, read: type.meta[:read].optional)
248
+ else
249
+ type.meta(source: relation)
250
+ end
251
+
252
+ if meta.empty?
253
+ base
254
+ else
255
+ base.meta(meta)
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/class_attributes"
4
+
5
+ module ROM
6
+ module SettingProxy
7
+ extend Dry::Core::ClassAttributes
8
+
9
+ private
10
+
11
+ # @api private
12
+ def respond_to_missing?(name, include_all = false)
13
+ super || setting_mapping.key?(name)
14
+ end
15
+
16
+ # Delegate to config when accessing deprecated class attributes
17
+ #
18
+ # @api private
19
+ def method_missing(name, *args, &block)
20
+ return super unless setting_mapping.key?(name)
21
+
22
+ mapping = setting_mapping[name]
23
+ ns, key = mapping
24
+
25
+ if args.empty?
26
+ if mapping.empty?
27
+ config[name]
28
+ else
29
+ config[ns][Array(key).first]
30
+ end
31
+ else
32
+ value = args.first
33
+
34
+ if mapping.empty?
35
+ config[name] = value
36
+ else
37
+ Array(key).each { |k| config[ns][k] = value }
38
+ end
39
+
40
+ value
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rom/setup"
4
+ require "rom/support/notifications"
5
+
6
+ module ROM
7
+ # @api public
8
+ class Setup
9
+ extend Notifications
10
+
11
+ register_event("configuration.relations.class.ready")
12
+ register_event("configuration.relations.object.registered")
13
+ register_event("configuration.relations.registry.created")
14
+ register_event("configuration.relations.schema.allocated")
15
+ register_event("configuration.relations.schema.set")
16
+ register_event("configuration.relations.dataset.allocated")
17
+ register_event("configuration.commands.class.before_build")
18
+
19
+ mod = Module.new do
20
+ # @api public
21
+ def finalize
22
+ super { attach_listeners }
23
+ end
24
+
25
+ # @api private
26
+ def registry_options
27
+ super.merge(notifications: notifications)
28
+ end
29
+ end
30
+
31
+ prepend(mod)
32
+
33
+ # @api public
34
+ # @deprecated
35
+ def notifications
36
+ @notifications ||= Notifications.event_bus(:configuration)
37
+ end
38
+
39
+ # @api private
40
+ def attach_listeners
41
+ # Anything can attach globally to certain events, including plugins, so here
42
+ # we're making sure that only plugins that are enabled in this configuration
43
+ # will be triggered
44
+ global_listeners = Notifications.listeners.to_a
45
+ .reject { |(src, *)| plugin_registry.map(&:mod).include?(src) }.to_h
46
+
47
+ plugin_listeners = Notifications.listeners.to_a
48
+ .select { |(src, *)| plugins.map(&:mod).include?(src) }.to_h
49
+
50
+ listeners.update(global_listeners).update(plugin_listeners)
51
+ end
52
+
53
+ # @api private
54
+ def listeners
55
+ notifications.listeners
56
+ end
57
+
58
+ # @api public
59
+ # @deprecated
60
+ def inflector=(inflector)
61
+ config.inflector = inflector
62
+ end
63
+
64
+ # Enable auto-registration for a given configuration object
65
+ #
66
+ # @param [String, Pathname] directory The root path to components
67
+ # @param [Hash] options
68
+ # @option options [Boolean, String] :namespace Toggle root namespace
69
+ # or provide a custom namespace name
70
+ #
71
+ # @return [Setup]
72
+ #
73
+ # @deprecated
74
+ #
75
+ # @see Configuration#auto_register
76
+ #
77
+ # @api public
78
+ def auto_registration(directory, **options)
79
+ auto_registration = AutoRegistration.new(directory, inflector: inflector, **options)
80
+ auto_registration.relations.each { |r| register_relation(r) }
81
+ auto_registration.commands.each { |r| register_command(r) }
82
+ auto_registration.mappers.each { |r| register_mapper(r) }
83
+ self
84
+ end
85
+
86
+ # @api private
87
+ # @deprecated
88
+ def relation_classes(gateway = nil)
89
+ if gateway
90
+ gid = gateway.is_a?(Symbol) ? gateway : gateway.config.id
91
+ components.relations.select { |r| r.config[:gateway] == gid }
92
+ else
93
+ components.relations
94
+ end.map(&:constant)
95
+ end
96
+
97
+ # @api public
98
+ # @deprecated
99
+ def command_classes
100
+ components.commands.map(&:constant)
101
+ end
102
+
103
+ # @api public
104
+ # @deprecated
105
+ def mapper_classes
106
+ components.mappers.map(&:constant)
107
+ end
108
+
109
+ # @api public
110
+ # @deprecated
111
+ def [](key)
112
+ gateways.fetch(key)
113
+ end
114
+
115
+ # @api public
116
+ # @deprecated
117
+ def gateways
118
+ @gateways ||=
119
+ begin
120
+ register_gateways
121
+ registry.gateways.map { |gateway| [gateway.config.id, gateway] }.to_h
122
+ end
123
+ end
124
+ alias_method :environment, :gateways
125
+
126
+ # @api private
127
+ # @deprecated
128
+ def gateways_map
129
+ @gateways_map ||= gateways.map(&:reverse).to_h
130
+ end
131
+
132
+ # @api private
133
+ def respond_to_missing?(name, include_all = false)
134
+ gateways.key?(name) || super
135
+ end
136
+
137
+ private
138
+
139
+ # Returns gateway if method is a name of a registered gateway
140
+ #
141
+ # @return [Gateway]
142
+ #
143
+ # @api public
144
+ # @deprecated
145
+ def method_missing(name, *)
146
+ gateways[name] || super
147
+ end
148
+ end
149
+
150
+ Configuration = Setup
151
+ end