rom 3.3.3 → 4.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -599
- data/lib/rom/version.rb +1 -1
- data/lib/rom.rb +3 -44
- metadata +19 -295
- data/.gitignore +0 -24
- data/.rspec +0 -3
- data/.rubocop.yml +0 -87
- data/.rubocop_todo.yml +0 -46
- data/.travis.yml +0 -24
- data/.yardopts +0 -2
- data/CODE_OF_CONDUCT.md +0 -13
- data/CONTRIBUTING.md +0 -1
- data/Gemfile +0 -54
- data/Guardfile +0 -24
- data/Rakefile +0 -28
- data/lib/rom/array_dataset.rb +0 -44
- data/lib/rom/association_set.rb +0 -49
- data/lib/rom/auto_curry.rb +0 -55
- data/lib/rom/command.rb +0 -494
- data/lib/rom/command_registry.rb +0 -148
- data/lib/rom/commands/class_interface.rb +0 -270
- data/lib/rom/commands/composite.rb +0 -53
- 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 -95
- 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 -90
- data/lib/rom/configuration_dsl/command.rb +0 -41
- data/lib/rom/configuration_dsl/command_dsl.rb +0 -35
- data/lib/rom/configuration_dsl/mapper.rb +0 -36
- data/lib/rom/configuration_dsl/mapper_dsl.rb +0 -43
- data/lib/rom/configuration_dsl/relation.rb +0 -26
- data/lib/rom/configuration_dsl.rb +0 -107
- data/lib/rom/configuration_plugin.rb +0 -17
- data/lib/rom/constants.rb +0 -36
- data/lib/rom/container.rb +0 -233
- data/lib/rom/create_container.rb +0 -60
- data/lib/rom/data_proxy.rb +0 -94
- data/lib/rom/enumerable_dataset.rb +0 -68
- data/lib/rom/environment.rb +0 -70
- data/lib/rom/gateway.rb +0 -196
- data/lib/rom/global/plugin_dsl.rb +0 -47
- data/lib/rom/global.rb +0 -58
- data/lib/rom/initializer.rb +0 -26
- data/lib/rom/lint/enumerable_dataset.rb +0 -54
- data/lib/rom/lint/gateway.rb +0 -120
- 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 -56
- data/lib/rom/memory/dataset.rb +0 -97
- data/lib/rom/memory/gateway.rb +0 -64
- data/lib/rom/memory/relation.rb +0 -62
- data/lib/rom/memory/schema.rb +0 -13
- 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 -122
- data/lib/rom/plugin.rb +0 -20
- data/lib/rom/plugin_base.rb +0 -40
- 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 -21
- data/lib/rom/plugins/relation/instrumentation.rb +0 -51
- data/lib/rom/plugins/relation/key_inference.rb +0 -48
- data/lib/rom/plugins/relation/registry_reader.rb +0 -33
- data/lib/rom/registry.rb +0 -50
- data/lib/rom/relation/class_interface.rb +0 -356
- data/lib/rom/relation/composite.rb +0 -46
- data/lib/rom/relation/curried.rb +0 -109
- data/lib/rom/relation/graph.rb +0 -125
- data/lib/rom/relation/loaded.rb +0 -127
- data/lib/rom/relation/materializable.rb +0 -66
- data/lib/rom/relation/name.rb +0 -102
- data/lib/rom/relation/view_dsl.rb +0 -64
- data/lib/rom/relation.rb +0 -250
- data/lib/rom/relation_registry.rb +0 -9
- data/lib/rom/schema/attribute.rb +0 -390
- data/lib/rom/schema/dsl.rb +0 -67
- data/lib/rom/schema.rb +0 -407
- data/lib/rom/setup/auto_registration.rb +0 -74
- data/lib/rom/setup/auto_registration_strategies/base.rb +0 -16
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +0 -63
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +0 -20
- 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 -83
- data/lib/rom/setup/finalize.rb +0 -152
- data/lib/rom/setup.rb +0 -65
- data/lib/rom/support/configurable.rb +0 -85
- data/lib/rom/transaction.rb +0 -24
- data/lib/rom/types.rb +0 -49
- 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 -25
- 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/custom_namespace/commands/create_customer.rb +0 -8
- data/spec/fixtures/custom_namespace/mappers/customer_list.rb +0 -8
- data/spec/fixtures/custom_namespace/relations/customers.rb +0 -8
- 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/fixtures/wrong/commands/create_customer.rb +0 -8
- data/spec/fixtures/wrong/mappers/customer_list.rb +0 -8
- data/spec/fixtures/wrong/relations/customers.rb +0 -8
- data/spec/integration/command_registry_spec.rb +0 -47
- data/spec/integration/commands/create_spec.rb +0 -157
- 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 -294
- data/spec/integration/commands/update_spec.rb +0 -86
- data/spec/integration/commands_spec.rb +0 -67
- data/spec/integration/gateways/extending_relations_spec.rb +0 -58
- data/spec/integration/gateways/setting_logger_spec.rb +0 -34
- 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/setup_spec.rb +0 -193
- data/spec/shared/command_behavior.rb +0 -28
- data/spec/shared/command_graph.rb +0 -54
- 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 -59
- data/spec/support/constant_leak_finder.rb +0 -14
- data/spec/support/mutant.rb +0 -10
- data/spec/support/schema.rb +0 -14
- data/spec/support/types.rb +0 -5
- data/spec/test/memory_repository_lint_test.rb +0 -27
- data/spec/unit/rom/array_dataset_spec.rb +0 -59
- data/spec/unit/rom/association_set_spec.rb +0 -48
- data/spec/unit/rom/auto_curry_spec.rb +0 -71
- data/spec/unit/rom/commands/graph_spec.rb +0 -192
- data/spec/unit/rom/commands/lazy_spec.rb +0 -310
- data/spec/unit/rom/commands/pre_and_post_processors_spec.rb +0 -343
- data/spec/unit/rom/commands/result_spec.rb +0 -70
- data/spec/unit/rom/commands_spec.rb +0 -188
- 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 -109
- data/spec/unit/rom/create_container_spec.rb +0 -151
- data/spec/unit/rom/enumerable_dataset_spec.rb +0 -15
- 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/gateway_spec.rb +0 -12
- data/spec/unit/rom/memory/inheritance_spec.rb +0 -32
- data/spec/unit/rom/memory/relation_spec.rb +0 -121
- 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/instrumentation_spec.rb +0 -44
- data/spec/unit/rom/plugins/relation/key_inference_spec.rb +0 -85
- data/spec/unit/rom/registry_spec.rb +0 -86
- data/spec/unit/rom/relation/attribute_reader_spec.rb +0 -17
- data/spec/unit/rom/relation/call_spec.rb +0 -51
- data/spec/unit/rom/relation/composite_spec.rb +0 -106
- data/spec/unit/rom/relation/curried_spec.rb +0 -67
- data/spec/unit/rom/relation/graph_spec.rb +0 -106
- data/spec/unit/rom/relation/lazy/combine_spec.rb +0 -165
- data/spec/unit/rom/relation/lazy/graph_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/output_schema_spec.rb +0 -28
- data/spec/unit/rom/relation/schema_spec.rb +0 -259
- data/spec/unit/rom/relation/view_spec.rb +0 -158
- data/spec/unit/rom/relation_spec.rb +0 -252
- data/spec/unit/rom/schema/accessing_attributes_spec.rb +0 -52
- data/spec/unit/rom/schema/append_spec.rb +0 -17
- data/spec/unit/rom/schema/exclude_spec.rb +0 -15
- data/spec/unit/rom/schema/finalize_spec.rb +0 -59
- data/spec/unit/rom/schema/key_predicate_spec.rb +0 -15
- data/spec/unit/rom/schema/merge_spec.rb +0 -17
- data/spec/unit/rom/schema/prefix_spec.rb +0 -16
- data/spec/unit/rom/schema/project_spec.rb +0 -15
- data/spec/unit/rom/schema/rename_spec.rb +0 -22
- data/spec/unit/rom/schema/type_spec.rb +0 -49
- data/spec/unit/rom/schema/uniq_spec.rb +0 -21
- data/spec/unit/rom/schema/wrap_spec.rb +0 -18
- data/spec/unit/rom/schema_spec.rb +0 -10
- 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
|