rom 3.3.3 → 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -599
  3. data/lib/rom/version.rb +1 -1
  4. data/lib/rom.rb +3 -44
  5. metadata +19 -295
  6. data/.gitignore +0 -24
  7. data/.rspec +0 -3
  8. data/.rubocop.yml +0 -87
  9. data/.rubocop_todo.yml +0 -46
  10. data/.travis.yml +0 -24
  11. data/.yardopts +0 -2
  12. data/CODE_OF_CONDUCT.md +0 -13
  13. data/CONTRIBUTING.md +0 -1
  14. data/Gemfile +0 -54
  15. data/Guardfile +0 -24
  16. data/Rakefile +0 -28
  17. data/lib/rom/array_dataset.rb +0 -44
  18. data/lib/rom/association_set.rb +0 -49
  19. data/lib/rom/auto_curry.rb +0 -55
  20. data/lib/rom/command.rb +0 -494
  21. data/lib/rom/command_registry.rb +0 -148
  22. data/lib/rom/commands/class_interface.rb +0 -270
  23. data/lib/rom/commands/composite.rb +0 -53
  24. data/lib/rom/commands/create.rb +0 -13
  25. data/lib/rom/commands/delete.rb +0 -14
  26. data/lib/rom/commands/graph/builder.rb +0 -176
  27. data/lib/rom/commands/graph/class_interface.rb +0 -62
  28. data/lib/rom/commands/graph/input_evaluator.rb +0 -62
  29. data/lib/rom/commands/graph.rb +0 -95
  30. data/lib/rom/commands/lazy/create.rb +0 -23
  31. data/lib/rom/commands/lazy/delete.rb +0 -27
  32. data/lib/rom/commands/lazy/update.rb +0 -34
  33. data/lib/rom/commands/lazy.rb +0 -99
  34. data/lib/rom/commands/result.rb +0 -96
  35. data/lib/rom/commands/update.rb +0 -14
  36. data/lib/rom/commands.rb +0 -3
  37. data/lib/rom/configuration.rb +0 -90
  38. data/lib/rom/configuration_dsl/command.rb +0 -41
  39. data/lib/rom/configuration_dsl/command_dsl.rb +0 -35
  40. data/lib/rom/configuration_dsl/mapper.rb +0 -36
  41. data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -43
  42. data/lib/rom/configuration_dsl/relation.rb +0 -26
  43. data/lib/rom/configuration_dsl.rb +0 -107
  44. data/lib/rom/configuration_plugin.rb +0 -17
  45. data/lib/rom/constants.rb +0 -36
  46. data/lib/rom/container.rb +0 -233
  47. data/lib/rom/create_container.rb +0 -60
  48. data/lib/rom/data_proxy.rb +0 -94
  49. data/lib/rom/enumerable_dataset.rb +0 -68
  50. data/lib/rom/environment.rb +0 -70
  51. data/lib/rom/gateway.rb +0 -196
  52. data/lib/rom/global/plugin_dsl.rb +0 -47
  53. data/lib/rom/global.rb +0 -58
  54. data/lib/rom/initializer.rb +0 -26
  55. data/lib/rom/lint/enumerable_dataset.rb +0 -54
  56. data/lib/rom/lint/gateway.rb +0 -120
  57. data/lib/rom/lint/linter.rb +0 -78
  58. data/lib/rom/lint/spec.rb +0 -20
  59. data/lib/rom/lint/test.rb +0 -98
  60. data/lib/rom/mapper_registry.rb +0 -35
  61. data/lib/rom/memory/commands.rb +0 -56
  62. data/lib/rom/memory/dataset.rb +0 -97
  63. data/lib/rom/memory/gateway.rb +0 -64
  64. data/lib/rom/memory/relation.rb +0 -62
  65. data/lib/rom/memory/schema.rb +0 -13
  66. data/lib/rom/memory/storage.rb +0 -59
  67. data/lib/rom/memory/types.rb +0 -9
  68. data/lib/rom/memory.rb +0 -4
  69. data/lib/rom/pipeline.rb +0 -122
  70. data/lib/rom/plugin.rb +0 -20
  71. data/lib/rom/plugin_base.rb +0 -40
  72. data/lib/rom/plugin_registry.rb +0 -173
  73. data/lib/rom/plugins/command/schema.rb +0 -37
  74. data/lib/rom/plugins/configuration/configuration_dsl.rb +0 -21
  75. data/lib/rom/plugins/relation/instrumentation.rb +0 -51
  76. data/lib/rom/plugins/relation/key_inference.rb +0 -48
  77. data/lib/rom/plugins/relation/registry_reader.rb +0 -33
  78. data/lib/rom/registry.rb +0 -50
  79. data/lib/rom/relation/class_interface.rb +0 -356
  80. data/lib/rom/relation/composite.rb +0 -46
  81. data/lib/rom/relation/curried.rb +0 -109
  82. data/lib/rom/relation/graph.rb +0 -125
  83. data/lib/rom/relation/loaded.rb +0 -127
  84. data/lib/rom/relation/materializable.rb +0 -66
  85. data/lib/rom/relation/name.rb +0 -102
  86. data/lib/rom/relation/view_dsl.rb +0 -64
  87. data/lib/rom/relation.rb +0 -250
  88. data/lib/rom/relation_registry.rb +0 -9
  89. data/lib/rom/schema/attribute.rb +0 -390
  90. data/lib/rom/schema/dsl.rb +0 -67
  91. data/lib/rom/schema.rb +0 -407
  92. data/lib/rom/setup/auto_registration.rb +0 -74
  93. data/lib/rom/setup/auto_registration_strategies/base.rb +0 -16
  94. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +0 -63
  95. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +0 -20
  96. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +0 -18
  97. data/lib/rom/setup/finalize/finalize_commands.rb +0 -47
  98. data/lib/rom/setup/finalize/finalize_mappers.rb +0 -36
  99. data/lib/rom/setup/finalize/finalize_relations.rb +0 -83
  100. data/lib/rom/setup/finalize.rb +0 -152
  101. data/lib/rom/setup.rb +0 -65
  102. data/lib/rom/support/configurable.rb +0 -85
  103. data/lib/rom/transaction.rb +0 -24
  104. data/lib/rom/types.rb +0 -49
  105. data/log/.gitkeep +0 -0
  106. data/rakelib/benchmark.rake +0 -15
  107. data/rakelib/mutant.rake +0 -19
  108. data/rakelib/rubocop.rake +0 -18
  109. data/rom.gemspec +0 -25
  110. data/spec/fixtures/app/commands/create_user.rb +0 -2
  111. data/spec/fixtures/app/mappers/user_list.rb +0 -2
  112. data/spec/fixtures/app/my_commands/create_user.rb +0 -2
  113. data/spec/fixtures/app/my_mappers/user_list.rb +0 -2
  114. data/spec/fixtures/app/my_relations/users.rb +0 -2
  115. data/spec/fixtures/app/relations/users.rb +0 -2
  116. data/spec/fixtures/custom/commands/create_user.rb +0 -6
  117. data/spec/fixtures/custom/mappers/user_list.rb +0 -6
  118. data/spec/fixtures/custom/relations/users.rb +0 -6
  119. data/spec/fixtures/custom_namespace/commands/create_customer.rb +0 -8
  120. data/spec/fixtures/custom_namespace/mappers/customer_list.rb +0 -8
  121. data/spec/fixtures/custom_namespace/relations/customers.rb +0 -8
  122. data/spec/fixtures/lib/persistence/commands/create_user.rb +0 -6
  123. data/spec/fixtures/lib/persistence/mappers/user_list.rb +0 -6
  124. data/spec/fixtures/lib/persistence/my_commands/create_user.rb +0 -6
  125. data/spec/fixtures/lib/persistence/my_mappers/user_list.rb +0 -6
  126. data/spec/fixtures/lib/persistence/my_relations/users.rb +0 -6
  127. data/spec/fixtures/lib/persistence/relations/users.rb +0 -6
  128. data/spec/fixtures/wrong/commands/create_customer.rb +0 -8
  129. data/spec/fixtures/wrong/mappers/customer_list.rb +0 -8
  130. data/spec/fixtures/wrong/relations/customers.rb +0 -8
  131. data/spec/integration/command_registry_spec.rb +0 -47
  132. data/spec/integration/commands/create_spec.rb +0 -157
  133. data/spec/integration/commands/delete_spec.rb +0 -67
  134. data/spec/integration/commands/error_handling_spec.rb +0 -25
  135. data/spec/integration/commands/graph_builder_spec.rb +0 -213
  136. data/spec/integration/commands/graph_spec.rb +0 -294
  137. data/spec/integration/commands/update_spec.rb +0 -86
  138. data/spec/integration/commands_spec.rb +0 -67
  139. data/spec/integration/gateways/extending_relations_spec.rb +0 -58
  140. data/spec/integration/gateways/setting_logger_spec.rb +0 -34
  141. data/spec/integration/mappers/combine_spec.rb +0 -117
  142. data/spec/integration/mappers/deep_embedded_spec.rb +0 -44
  143. data/spec/integration/mappers/definition_dsl_spec.rb +0 -206
  144. data/spec/integration/mappers/embedded_spec.rb +0 -62
  145. data/spec/integration/mappers/exclude_spec.rb +0 -27
  146. data/spec/integration/mappers/fold_spec.rb +0 -71
  147. data/spec/integration/mappers/group_spec.rb +0 -163
  148. data/spec/integration/mappers/overwrite_attributes_value_spec.rb +0 -51
  149. data/spec/integration/mappers/prefix_separator_spec.rb +0 -52
  150. data/spec/integration/mappers/prefix_spec.rb +0 -48
  151. data/spec/integration/mappers/prefixing_attributes_spec.rb +0 -37
  152. data/spec/integration/mappers/registering_custom_mappers_spec.rb +0 -28
  153. data/spec/integration/mappers/renaming_attributes_spec.rb +0 -125
  154. data/spec/integration/mappers/reusing_mappers_spec.rb +0 -43
  155. data/spec/integration/mappers/step_spec.rb +0 -119
  156. data/spec/integration/mappers/symbolizing_attributes_spec.rb +0 -77
  157. data/spec/integration/mappers/unfold_spec.rb +0 -92
  158. data/spec/integration/mappers/ungroup_spec.rb +0 -126
  159. data/spec/integration/mappers/unwrap_spec.rb +0 -93
  160. data/spec/integration/mappers/wrap_spec.rb +0 -155
  161. data/spec/integration/memory/commands/create_spec.rb +0 -23
  162. data/spec/integration/memory/commands/delete_spec.rb +0 -23
  163. data/spec/integration/memory/commands/update_spec.rb +0 -23
  164. data/spec/integration/multi_env_spec.rb +0 -69
  165. data/spec/integration/multi_repo_spec.rb +0 -46
  166. data/spec/integration/relations/default_dataset_spec.rb +0 -38
  167. data/spec/integration/relations/inheritance_spec.rb +0 -37
  168. data/spec/integration/relations/reading_spec.rb +0 -169
  169. data/spec/integration/relations/registry_dsl_spec.rb +0 -45
  170. data/spec/integration/setup_spec.rb +0 -193
  171. data/spec/shared/command_behavior.rb +0 -28
  172. data/spec/shared/command_graph.rb +0 -54
  173. data/spec/shared/container.rb +0 -9
  174. data/spec/shared/enumerable_dataset.rb +0 -52
  175. data/spec/shared/gateway_only.rb +0 -6
  176. data/spec/shared/materializable.rb +0 -36
  177. data/spec/shared/no_container.rb +0 -16
  178. data/spec/shared/one_behavior.rb +0 -26
  179. data/spec/shared/proxy.rb +0 -0
  180. data/spec/shared/users_and_tasks.rb +0 -10
  181. data/spec/spec_helper.rb +0 -59
  182. data/spec/support/constant_leak_finder.rb +0 -14
  183. data/spec/support/mutant.rb +0 -10
  184. data/spec/support/schema.rb +0 -14
  185. data/spec/support/types.rb +0 -5
  186. data/spec/test/memory_repository_lint_test.rb +0 -27
  187. data/spec/unit/rom/array_dataset_spec.rb +0 -59
  188. data/spec/unit/rom/association_set_spec.rb +0 -48
  189. data/spec/unit/rom/auto_curry_spec.rb +0 -71
  190. data/spec/unit/rom/commands/graph_spec.rb +0 -192
  191. data/spec/unit/rom/commands/lazy_spec.rb +0 -310
  192. data/spec/unit/rom/commands/pre_and_post_processors_spec.rb +0 -343
  193. data/spec/unit/rom/commands/result_spec.rb +0 -70
  194. data/spec/unit/rom/commands_spec.rb +0 -188
  195. data/spec/unit/rom/configurable_spec.rb +0 -49
  196. data/spec/unit/rom/configuration_spec.rb +0 -61
  197. data/spec/unit/rom/container_spec.rb +0 -109
  198. data/spec/unit/rom/create_container_spec.rb +0 -151
  199. data/spec/unit/rom/enumerable_dataset_spec.rb +0 -15
  200. data/spec/unit/rom/environment_spec.rb +0 -123
  201. data/spec/unit/rom/gateway_spec.rb +0 -146
  202. data/spec/unit/rom/mapper_registry_spec.rb +0 -25
  203. data/spec/unit/rom/memory/commands_spec.rb +0 -43
  204. data/spec/unit/rom/memory/dataset_spec.rb +0 -31
  205. data/spec/unit/rom/memory/gateway_spec.rb +0 -12
  206. data/spec/unit/rom/memory/inheritance_spec.rb +0 -32
  207. data/spec/unit/rom/memory/relation_spec.rb +0 -121
  208. data/spec/unit/rom/memory/storage_spec.rb +0 -45
  209. data/spec/unit/rom/plugin_spec.rb +0 -150
  210. data/spec/unit/rom/plugins/command/schema_spec.rb +0 -66
  211. data/spec/unit/rom/plugins/relation/instrumentation_spec.rb +0 -44
  212. data/spec/unit/rom/plugins/relation/key_inference_spec.rb +0 -85
  213. data/spec/unit/rom/registry_spec.rb +0 -86
  214. data/spec/unit/rom/relation/attribute_reader_spec.rb +0 -17
  215. data/spec/unit/rom/relation/call_spec.rb +0 -51
  216. data/spec/unit/rom/relation/composite_spec.rb +0 -106
  217. data/spec/unit/rom/relation/curried_spec.rb +0 -67
  218. data/spec/unit/rom/relation/graph_spec.rb +0 -106
  219. data/spec/unit/rom/relation/lazy/combine_spec.rb +0 -165
  220. data/spec/unit/rom/relation/lazy/graph_spec.rb +0 -165
  221. data/spec/unit/rom/relation/lazy_spec.rb +0 -214
  222. data/spec/unit/rom/relation/loaded_spec.rb +0 -53
  223. data/spec/unit/rom/relation/name_spec.rb +0 -58
  224. data/spec/unit/rom/relation/output_schema_spec.rb +0 -28
  225. data/spec/unit/rom/relation/schema_spec.rb +0 -259
  226. data/spec/unit/rom/relation/view_spec.rb +0 -158
  227. data/spec/unit/rom/relation_spec.rb +0 -252
  228. data/spec/unit/rom/schema/accessing_attributes_spec.rb +0 -52
  229. data/spec/unit/rom/schema/append_spec.rb +0 -17
  230. data/spec/unit/rom/schema/exclude_spec.rb +0 -15
  231. data/spec/unit/rom/schema/finalize_spec.rb +0 -59
  232. data/spec/unit/rom/schema/key_predicate_spec.rb +0 -15
  233. data/spec/unit/rom/schema/merge_spec.rb +0 -17
  234. data/spec/unit/rom/schema/prefix_spec.rb +0 -16
  235. data/spec/unit/rom/schema/project_spec.rb +0 -15
  236. data/spec/unit/rom/schema/rename_spec.rb +0 -22
  237. data/spec/unit/rom/schema/type_spec.rb +0 -49
  238. data/spec/unit/rom/schema/uniq_spec.rb +0 -21
  239. data/spec/unit/rom/schema/wrap_spec.rb +0 -18
  240. data/spec/unit/rom/schema_spec.rb +0 -10
  241. data/spec/unit/rom/setup/auto_registration_spec.rb +0 -214
data/lib/rom/schema.rb DELETED
@@ -1,407 +0,0 @@
1
- require 'dry-equalizer'
2
-
3
- require 'rom/schema/attribute'
4
- require 'rom/schema/dsl'
5
- require 'rom/association_set'
6
-
7
- module ROM
8
- # Relation schema
9
- #
10
- # Schemas hold detailed information about relation tuples, including their
11
- # primitive types (String, Integer, Hash, etc. or custom classes), as well as
12
- # various meta information like primary/foreign key and literally any other
13
- # information that a given database adapter may need.
14
- #
15
- # Adapters can extend this class and it can be used in adapter-specific relations.
16
- # In example rom-sql extends schema with Association DSL and many additional
17
- # SQL-specific APIs in schema types.
18
- #
19
- # Schemas are used for projecting canonical relations into other relations and
20
- # every relation object maintains its schema. This means that we always have
21
- # all information about relation tuples, even when a relation was projected and
22
- # diverged from its canonical form.
23
- #
24
- # Furthermore schema attributes know their source relations, which makes it
25
- # possible to merge schemas from multiple relations and maintain information
26
- # about the source relations. In example when two relations are joined, their
27
- # schemas are merged, and we know which attributes belong to which relation.
28
- #
29
- # @api public
30
- class Schema
31
- EMPTY_ASSOCIATION_SET = AssociationSet.new(EMPTY_HASH).freeze
32
-
33
- DEFAULT_INFERRER = proc { [EMPTY_ARRAY, EMPTY_ARRAY].freeze }
34
-
35
- MissingAttributesError = Class.new(StandardError) do
36
- def initialize(name, attributes)
37
- super("missing attributes in #{name.inspect} schema: #{attributes.map(&:inspect).join(', ')}")
38
- end
39
- end
40
-
41
- include Dry::Equalizer(:name, :attributes, :associations)
42
- include Enumerable
43
-
44
- # @!attribute [r] name
45
- # @return [Symbol] The name of this schema
46
- attr_reader :name
47
-
48
- # @!attribute [r] attributes
49
- # @return [Array] Array with schema attributes
50
- attr_reader :attributes
51
-
52
- # @!attribute [r] associations
53
- # @return [AssociationSet] Optional association set (this is adapter-specific)
54
- attr_reader :associations
55
-
56
- # @!attribute [r] inferrer
57
- # @return [#call] An optional inferrer object used in `finalize!`
58
- attr_reader :inferrer
59
-
60
- # @api private
61
- attr_reader :options
62
-
63
- # @api private
64
- attr_reader :relations
65
-
66
- alias_method :to_ary, :attributes
67
-
68
- # Define a relation schema from plain rom types
69
- #
70
- # Resulting schema will decorate plain rom types with adapter-specific types
71
- # By default `Schema::Attribute` will be used
72
- #
73
- # @param [Relation::Name, Symbol] name The schema name, typically ROM::Relation::Name
74
- #
75
- # @return [Schema]
76
- #
77
- # @api public
78
- def self.define(name, attr_class: Attribute, attributes: EMPTY_ARRAY, associations: EMPTY_ASSOCIATION_SET, inferrer: DEFAULT_INFERRER)
79
- new(
80
- name,
81
- attributes: attributes(attributes, attr_class),
82
- associations: associations,
83
- inferrer: inferrer,
84
- attr_class: attr_class
85
- )
86
- end
87
-
88
- # @api private
89
- def self.attributes(attributes, attr_class)
90
- attributes.map { |type| attr_class.new(type) }
91
- end
92
-
93
- # @api private
94
- def initialize(name, options)
95
- @name = name
96
- @options = options
97
- @attributes = options[:attributes] || EMPTY_ARRAY
98
- @associations = options[:associations]
99
- @inferrer = options[:inferrer] || DEFAULT_INFERRER
100
- @relations = options[:relations] || EMPTY_HASH
101
- end
102
-
103
- # Abstract method for creating a new relation based on schema definition
104
- #
105
- # This can be used by views to generate a new relation automatically.
106
- # In example a schema can project a relation, join any additional relations
107
- # if it uncludes attributes from other relations etc.
108
- #
109
- # Default implementation is a no-op and it simply returns back untouched relation
110
- #
111
- # @param [Relation]
112
- #
113
- # @return [Relation]
114
- #
115
- # @api public
116
- def call(relation)
117
- relation
118
- end
119
-
120
- # Iterate over schema's attributes
121
- #
122
- # @yield [Schema::Attribute]
123
- #
124
- # @api public
125
- def each(&block)
126
- attributes.each(&block)
127
- end
128
-
129
- # Check if schema has any attributes
130
- #
131
- # @return [TrueClass, FalseClass]
132
- #
133
- # @api public
134
- def empty?
135
- attributes.size == 0
136
- end
137
-
138
- # Coerce schema into a <AttributeName=>Attribute> Hash
139
- #
140
- # @return [Hash]
141
- #
142
- # @api public
143
- def to_h
144
- each_with_object({}) { |attr, h| h[attr.name] = attr }
145
- end
146
-
147
- # Return attribute
148
- #
149
- # @param [Symbol] key The attribute name
150
- # @param [Symbol, Relation::Name] src The source relation (for merged schemas)
151
- #
152
- # @raise KeyError
153
- #
154
- # @api public
155
- def [](key, src = name.to_sym)
156
- attr =
157
- if count_index[key].equal?(1)
158
- name_index[key]
159
- else
160
- source_index[src][key]
161
- end
162
-
163
- unless attr
164
- raise(KeyError, "#{key.inspect} attribute doesn't exist in #{src} schema")
165
- end
166
-
167
- attr
168
- end
169
-
170
- # Project a schema to include only specified attributes
171
- #
172
- # @param [*Array<Symbol, Schema::Attribute>] names Attribute names
173
- #
174
- # @return [Schema]
175
- #
176
- # @api public
177
- def project(*names)
178
- new(names.map { |name| name.is_a?(Symbol) ? self[name] : name })
179
- end
180
-
181
- # Exclude provided attributes from a schema
182
- #
183
- # @param [*Array] names Attribute names
184
- #
185
- # @return [Schema]
186
- #
187
- # @api public
188
- def exclude(*names)
189
- project(*(map(&:name) - names))
190
- end
191
-
192
- # Project a schema with renamed attributes
193
- #
194
- # @param [Hash] mapping The attribute mappings
195
- #
196
- # @return [Schema]
197
- #
198
- # @api public
199
- def rename(mapping)
200
- new_attributes = map do |attr|
201
- alias_name = mapping[attr.name]
202
- alias_name ? attr.aliased(alias_name) : attr
203
- end
204
-
205
- new(new_attributes)
206
- end
207
-
208
- # Project a schema with renamed attributes using provided prefix
209
- #
210
- # @param [Symbol] prefix The name of the prefix
211
- #
212
- # @return [Schema]
213
- #
214
- # @api public
215
- def prefix(prefix)
216
- new(map { |attr| attr.prefixed(prefix) })
217
- end
218
-
219
- # Return new schema with all attributes marked as prefixed and wrapped
220
- #
221
- # This is useful when relations are joined and the right side should be marked
222
- # as wrapped
223
- #
224
- # @param [Symbol] prefix The prefix used for aliasing wrapped attributes
225
- #
226
- # @return [Schema]
227
- #
228
- # @api public
229
- def wrap(prefix = name.dataset)
230
- new(map { |attr| attr.wrapped? ? attr : attr.wrapped(prefix) })
231
- end
232
-
233
- # Return FK attribute for a given relation name
234
- #
235
- # @return [Schema::Attribute]
236
- #
237
- # @api public
238
- def foreign_key(relation)
239
- detect { |attr| attr.foreign_key? && attr.target == relation }
240
- end
241
-
242
- # Return primary key attributes
243
- #
244
- # @return [Array<Schema::Attribute>]
245
- #
246
- # @api public
247
- def primary_key
248
- select(&:primary_key?)
249
- end
250
-
251
- # Merge with another schema
252
- #
253
- # @param [Schema] other Other schema
254
- #
255
- # @return [Schema]
256
- #
257
- # @api public
258
- def merge(other)
259
- append(*other)
260
- end
261
- alias_method :+, :merge
262
-
263
- # Append more attributes to the schema
264
- #
265
- # This returns a new schema instance
266
- #
267
- # @param [*Array<Schema::Attribute>]
268
- #
269
- # @return [Schema]
270
- #
271
- # @api public
272
- def append(*new_attributes)
273
- new(attributes + new_attributes)
274
- end
275
-
276
- # Return a new schema with uniq attributes
277
- #
278
- # @param [*Array<Schema::Attribute>]
279
- #
280
- # @return [Schema]
281
- #
282
- # @api public
283
- def uniq(&block)
284
- if block
285
- new(attributes.uniq(&block))
286
- else
287
- new(attributes.uniq(&:name))
288
- end
289
- end
290
-
291
- # Return if a schema includes an attribute with the given name
292
- #
293
- # @param [Symbol] name The name of the attribute
294
- #
295
- # @return [Boolean]
296
- #
297
- # @api public
298
- def key?(name)
299
- ! attributes.detect { |attr| attr.name == name }.nil?
300
- end
301
-
302
- # This hook is called when relation is being build during container finalization
303
- #
304
- # When block is provided it'll be called just before freezing the instance
305
- # so that additional ivars can be set
306
- #
307
- # @return [self]
308
- #
309
- # @api private
310
- def finalize!(gateway: nil, relations: nil, &block)
311
- return self if frozen?
312
-
313
- inferred, missing = inferrer.call(name, gateway)
314
-
315
- attr_names = map(&:name)
316
- inferred_attrs = self.class.attributes(inferred, attr_class).
317
- reject { |attr| attr_names.include?(attr.name) }
318
-
319
- attributes.concat(inferred_attrs)
320
-
321
- missing_attributes = missing - map(&:name)
322
-
323
- if missing_attributes.size > 0
324
- raise MissingAttributesError.new(name, missing_attributes)
325
- end
326
-
327
- block.call if block
328
-
329
- count_index
330
- name_index
331
- source_index
332
-
333
- freeze
334
- end
335
-
336
- # Return coercion function using attribute read types
337
- #
338
- # This is used for `output_schema` in relations
339
- #
340
- # @return [Dry::Types::Hash]
341
- #
342
- # @api private
343
- def to_output_hash
344
- Types::Coercible::Hash.schema(
345
- map { |attr| [attr.key, attr.to_read_type] }.to_h
346
- )
347
- end
348
-
349
- # Return coercion function using attribute types
350
- #
351
- # This is used for `input_schema` in relations, typically commands use it
352
- # for processing input
353
- #
354
- # @return [Dry::Types::Hash]
355
- #
356
- # @api private
357
- def to_input_hash
358
- Types::Coercible::Hash.schema(
359
- map { |attr| [attr.name, attr] }.to_h
360
- )
361
- end
362
-
363
- # Return a new schema with new options
364
- #
365
- # @example
366
- # schema.with(inferrer: my_inferrer)
367
- #
368
- # @param [Hash] new_options
369
- #
370
- # @return [Schema]
371
- #
372
- # @api public
373
- def with(new_options)
374
- self.class.new(name, options.merge(new_options))
375
- end
376
-
377
- private
378
-
379
- # @api private
380
- def count_index
381
- @count_index ||= map(&:name).map { |name| [name, count { |attr| attr.name == name }] }.to_h
382
- end
383
-
384
- # @api private
385
- def name_index
386
- @name_index ||= map { |attr| [attr.name, attr] }.to_h
387
- end
388
-
389
- # @api private
390
- def source_index
391
- @source_index ||= select(&:source).
392
- group_by(&:source).
393
- map { |src, grp| [src.to_sym, grp.map { |attr| [attr.name, attr] }.to_h] }.
394
- to_h
395
- end
396
-
397
- # @api private
398
- def attr_class
399
- options.fetch(:attr_class)
400
- end
401
-
402
- # @api private
403
- def new(attributes)
404
- self.class.new(name, options.merge(attributes: attributes))
405
- end
406
- end
407
- end
@@ -1,74 +0,0 @@
1
- require 'pathname'
2
-
3
- require 'dry/core/inflector'
4
-
5
- require 'rom/types'
6
- require 'rom/initializer'
7
- require 'rom/setup/auto_registration_strategies/no_namespace'
8
- require 'rom/setup/auto_registration_strategies/with_namespace'
9
- require 'rom/setup/auto_registration_strategies/custom_namespace'
10
-
11
- module ROM
12
- class AutoRegistration
13
- extend Initializer
14
-
15
- NamespaceType = Types::Strict::Bool | Types::Strict::String
16
- PathnameType = Types.Constructor(Pathname, &Kernel.method(:Pathname))
17
- DEFAULT_MAPPING = {
18
- relations: :relations,
19
- mappers: :mappers,
20
- commands: :commands
21
- }.freeze
22
-
23
- param :directory, type: PathnameType
24
-
25
- option :namespace, type: NamespaceType, default: -> { true }
26
-
27
- option :component_dirs, type: Types::Strict::Hash, default: -> { DEFAULT_MAPPING }
28
-
29
- option :globs, default: -> {
30
- Hash[
31
- component_dirs.map { |component, path|
32
- [component, directory.join("#{path}/**/*.rb")]
33
- }
34
- ]
35
- }
36
-
37
- def relations
38
- load_entities(:relations)
39
- end
40
-
41
- def commands
42
- load_entities(:commands)
43
- end
44
-
45
- def mappers
46
- load_entities(:mappers)
47
- end
48
-
49
- private
50
-
51
- def load_entities(entity)
52
- Dir[globs[entity]].map do |file|
53
- require file
54
- klass_name =
55
- case namespace
56
- when String
57
- AutoRegistrationStrategies::CustomNamespace.new(
58
- namespace: namespace, file: file, directory: directory
59
- ).call
60
- when TrueClass
61
- AutoRegistrationStrategies::WithNamespace.new(
62
- file: file, directory: directory
63
- ).call
64
- when FalseClass
65
- AutoRegistrationStrategies::NoNamespace.new(
66
- file: file, directory: directory, entity: component_dirs.fetch(entity)
67
- ).call
68
- end
69
-
70
- Dry::Core::Inflector.constantize(klass_name)
71
- end
72
- end
73
- end
74
- end
@@ -1,16 +0,0 @@
1
- require 'rom/types'
2
- require 'rom/initializer'
3
-
4
- module ROM
5
- module AutoRegistrationStrategies
6
- class Base
7
- extend Initializer
8
-
9
- PathnameType = Types.Definition(Pathname).constrained(type: Pathname)
10
-
11
- option :file, type: Types::Strict::String
12
-
13
- EXTENSION_REGEX = /\.rb\z/
14
- end
15
- end
16
- end
@@ -1,63 +0,0 @@
1
- require 'pathname'
2
-
3
- require 'dry/core/inflector'
4
- require 'rom/types'
5
- require 'rom/setup/auto_registration_strategies/base'
6
-
7
- module ROM
8
- module AutoRegistrationStrategies
9
- class CustomNamespace < Base
10
- option :directory, type: PathnameType
11
- option :namespace, type: Types::Strict::String
12
-
13
- def call
14
- potential = []
15
- attempted = []
16
-
17
- path_arr.reverse.each do |dir|
18
- const_fragment = potential.unshift(
19
- Dry::Core::Inflector.camelize(dir)
20
- ).join("::")
21
-
22
- constant = "#{namespace}::#{const_fragment}"
23
-
24
- return constant if ns_const.const_defined?(const_fragment)
25
-
26
- attempted << constant
27
- end
28
-
29
- # If we have reached this point, its means constant is not defined and
30
- # NameError will be thrown if we attempt to camelize something like:
31
- # `"#{namespace}::#{Dry::Core::Inflector.camelize(filename)}"`
32
- # so we can assume naming convention was not respected in required
33
- # file.
34
-
35
- raise NameError, name_error_message(attempted)
36
- end
37
-
38
- private
39
-
40
- def name_error_message(attempted)
41
- "required file does not define expected constant name; either " \
42
- "register your constant explicitly of try following the path" \
43
- "naming convention like:\n\n\t- #{attempted.join("\n\t- ")}\n"
44
- end
45
-
46
- def filename
47
- Pathname(file).basename('.rb')
48
- end
49
-
50
- def ns_const
51
- @namespace_constant ||= Dry::Core::Inflector.constantize(namespace)
52
- end
53
-
54
- def path_arr
55
- file_path << filename
56
- end
57
-
58
- def file_path
59
- File.dirname(file).split("/") - directory.to_s.split("/")
60
- end
61
- end
62
- end
63
- end
@@ -1,20 +0,0 @@
1
- require 'pathname'
2
-
3
- require 'dry/core/inflector'
4
- require 'rom/types'
5
- require 'rom/setup/auto_registration_strategies/base'
6
-
7
- module ROM
8
- module AutoRegistrationStrategies
9
- class NoNamespace < Base
10
- option :directory, type: PathnameType
11
- option :entity, type: Types::Strict::Symbol
12
-
13
- def call
14
- Dry::Core::Inflector.camelize(
15
- file.sub(/^#{directory}\/#{entity}\//, '').sub(EXTENSION_REGEX, '')
16
- )
17
- end
18
- end
19
- end
20
- end
@@ -1,18 +0,0 @@
1
- require 'pathname'
2
-
3
- require 'dry/core/inflector'
4
- require 'rom/setup/auto_registration_strategies/base'
5
-
6
- module ROM
7
- module AutoRegistrationStrategies
8
- class WithNamespace < Base
9
- option :directory, type: PathnameType
10
-
11
- def call
12
- Dry::Core::Inflector.camelize(
13
- file.sub(/^#{directory.dirname}\//, '').sub(EXTENSION_REGEX, '')
14
- )
15
- end
16
- end
17
- end
18
- end
@@ -1,47 +0,0 @@
1
- require 'rom/registry'
2
- require 'rom/command_registry'
3
-
4
- module ROM
5
- class Finalize
6
- class FinalizeCommands
7
- # Build command registry hash for provided relations
8
- #
9
- # @param [RelationRegistry] relations registry
10
- # @param [Hash] gateways
11
- # @param [Array] command_classes a list of command subclasses
12
- #
13
- # @api private
14
- def initialize(relations, gateways, command_classes)
15
- @relations = relations
16
- @gateways = gateways
17
- @command_classes = command_classes
18
- end
19
-
20
- # @return [Hash]
21
- #
22
- # @api private
23
- def run!
24
- registry = @command_classes.each_with_object({}) do |klass, h|
25
- rel_name = klass.relation
26
- next unless rel_name
27
-
28
- relation = @relations[rel_name]
29
- name = klass.register_as || klass.default_name
30
-
31
- gateway = @gateways[relation.class.gateway]
32
- gateway.extend_command_class(klass, relation.dataset)
33
-
34
- klass.extend_for_relation(relation) if klass.restrictable
35
-
36
- (h[rel_name] ||= {})[name] = klass.build(relation)
37
- end
38
-
39
- commands = registry.each_with_object({}) do |(name, rel_commands), h|
40
- h[name] = CommandRegistry.new(name, rel_commands)
41
- end
42
-
43
- Registry.new(commands)
44
- end
45
- end
46
- end
47
- end
@@ -1,36 +0,0 @@
1
- require 'rom/registry'
2
-
3
- module ROM
4
- class Finalize
5
- class FinalizeMappers
6
- # @api private
7
- def initialize(mapper_classes, mapper_objects)
8
- @mapper_classes = mapper_classes
9
- @mapper_objects = mapper_objects
10
- end
11
-
12
- # @api private
13
- def run!
14
- registry = @mapper_classes.each_with_object({}) do |klass, h|
15
- name = klass.register_as || klass.relation
16
- (h[klass.base_relation] ||= {})[name] = klass.build
17
- end
18
-
19
- registry_hash = registry.each_with_object({}).each { |(relation, mappers), h|
20
- h[relation] = MapperRegistry.new(mappers)
21
- }
22
-
23
- @mapper_objects.each do |relation, mappers|
24
- if registry_hash.key?(relation)
25
- mappers_registry = registry_hash[relation]
26
- mappers.each { |name, mapper| mappers_registry[name] = mapper }
27
- else
28
- registry_hash[relation] = MapperRegistry.new(mappers)
29
- end
30
- end
31
-
32
- Registry.new(registry_hash)
33
- end
34
- end
35
- end
36
- end