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
@@ -1,356 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
|
-
require 'dry/core/inflector'
|
4
|
-
require 'dry/core/deprecations'
|
5
|
-
require 'dry/core/constants'
|
6
|
-
|
7
|
-
require 'rom/auto_curry'
|
8
|
-
require 'rom/relation/curried'
|
9
|
-
require 'rom/relation/name'
|
10
|
-
require 'rom/relation/view_dsl'
|
11
|
-
require 'rom/schema'
|
12
|
-
|
13
|
-
module ROM
|
14
|
-
class Relation
|
15
|
-
# @api public
|
16
|
-
module ClassInterface
|
17
|
-
extend Dry::Core::Deprecations[:rom]
|
18
|
-
|
19
|
-
include Dry::Core::Constants
|
20
|
-
|
21
|
-
# Register adapter relation subclasses during setup phase
|
22
|
-
#
|
23
|
-
# In adition those subclasses are extended with an interface for accessing
|
24
|
-
# relation registry and to define `register_as` setting
|
25
|
-
#
|
26
|
-
# @api private
|
27
|
-
def inherited(klass)
|
28
|
-
super
|
29
|
-
|
30
|
-
if respond_to?(:adapter) && adapter.nil?
|
31
|
-
raise MissingAdapterIdentifierError,
|
32
|
-
"relation class +#{self}+ is missing the adapter identifier"
|
33
|
-
end
|
34
|
-
|
35
|
-
klass.defines :adapter
|
36
|
-
|
37
|
-
# Extend with functionality required by adapters *only* if this is a direct
|
38
|
-
# descendant of an adapter-specific relation subclass
|
39
|
-
return unless respond_to?(:adapter) && klass.superclass == ROM::Relation[adapter]
|
40
|
-
|
41
|
-
klass.class_eval do
|
42
|
-
use :registry_reader
|
43
|
-
|
44
|
-
defines :gateway, :dataset, :dataset_proc, :register_as
|
45
|
-
|
46
|
-
gateway :default
|
47
|
-
|
48
|
-
dataset default_name
|
49
|
-
|
50
|
-
# skip defining :name option if it's a class that already has this method
|
51
|
-
# which can happen when an adapter's relation class inherits from another
|
52
|
-
# adapter's relation class (ie YAML::Relation < Memory::Relation)
|
53
|
-
unless instance_methods.include?(:name)
|
54
|
-
# Relation's dataset name
|
55
|
-
#
|
56
|
-
# In example a table name in an SQL database
|
57
|
-
#
|
58
|
-
# @return [Symbol]
|
59
|
-
#
|
60
|
-
# @api public
|
61
|
-
option :name, default: -> { Name.new(self.class.register_as, self.class.dataset) }
|
62
|
-
end
|
63
|
-
|
64
|
-
# Set dataset name
|
65
|
-
#
|
66
|
-
# If a block is passed it will be evaluated in the context of the dataset
|
67
|
-
# to define the default dataset which will be injected into a relation
|
68
|
-
# when setting up relation registry
|
69
|
-
#
|
70
|
-
# @example
|
71
|
-
# class Relations::Users < ROM::Relation[:memory]
|
72
|
-
# dataset :users
|
73
|
-
# end
|
74
|
-
#
|
75
|
-
# class Users < ROM::Relation[:memory]
|
76
|
-
# dataset { sort_by(:id) }
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# @param [Symbol] value The name of the dataset
|
80
|
-
#
|
81
|
-
# @api public
|
82
|
-
def self.dataset(*args, deprecation: true, &block)
|
83
|
-
if block
|
84
|
-
dataset_proc(block)
|
85
|
-
elsif args.size > 0
|
86
|
-
if deprecation
|
87
|
-
warn("Relation.dataset is deprecated in favor of schema settings\n\n#{caller[0..5].join("\n")}")
|
88
|
-
end
|
89
|
-
end
|
90
|
-
super(*args)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Set or get name under which a relation will be registered
|
94
|
-
#
|
95
|
-
# This defaults to `dataset` or `default_name` for descendant relations
|
96
|
-
#
|
97
|
-
# @return [Symbol]
|
98
|
-
#
|
99
|
-
# @api public
|
100
|
-
def self.register_as(*args, deprecation: true)
|
101
|
-
if deprecation && args.size > 0
|
102
|
-
warn("Relation.register_as is deprecated in favor of schema settings\n\n#{caller[0..5].join("\n")}")
|
103
|
-
end
|
104
|
-
|
105
|
-
if args.empty?
|
106
|
-
return @register_as if defined?(@register_as)
|
107
|
-
|
108
|
-
super_val = super()
|
109
|
-
|
110
|
-
if superclass == ROM::Relation[adapter]
|
111
|
-
super_val || dataset
|
112
|
-
else
|
113
|
-
super_val == dataset ? default_name : super_val
|
114
|
-
end
|
115
|
-
else
|
116
|
-
super(*args)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# Return name of the source gateway of this relation
|
121
|
-
#
|
122
|
-
# @return [Symbol]
|
123
|
-
#
|
124
|
-
# @api private
|
125
|
-
def gateway
|
126
|
-
self.class.gateway
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
klass.extend(AutoCurry)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Return adapter-specific relation subclass
|
134
|
-
#
|
135
|
-
# @example
|
136
|
-
# ROM::Relation[:memory]
|
137
|
-
# # => ROM::Memory::Relation
|
138
|
-
#
|
139
|
-
# @return [Class]
|
140
|
-
#
|
141
|
-
# @api public
|
142
|
-
def [](adapter)
|
143
|
-
ROM.adapters.fetch(adapter).const_get(:Relation)
|
144
|
-
rescue KeyError
|
145
|
-
raise AdapterNotPresentError.new(adapter, :relation)
|
146
|
-
end
|
147
|
-
|
148
|
-
# Specify canonical schema for a relation
|
149
|
-
#
|
150
|
-
# With a schema defined commands will set up a type-safe input handler
|
151
|
-
# automatically
|
152
|
-
#
|
153
|
-
# @example
|
154
|
-
# class Users < ROM::Relation[:sql]
|
155
|
-
# schema do
|
156
|
-
# attribute :id, Types::Serial
|
157
|
-
# attribute :name, Types::String
|
158
|
-
# end
|
159
|
-
# end
|
160
|
-
#
|
161
|
-
# # access schema
|
162
|
-
# Users.schema
|
163
|
-
#
|
164
|
-
# @return [Schema]
|
165
|
-
#
|
166
|
-
# @param [Symbol] dataset An optional dataset name
|
167
|
-
# @param [Boolean] infer Whether to do an automatic schema inferring
|
168
|
-
#
|
169
|
-
# @api public
|
170
|
-
def schema(dataset = nil, as: nil, infer: false, &block)
|
171
|
-
if defined?(@schema)
|
172
|
-
@schema
|
173
|
-
elsif block || infer
|
174
|
-
self.dataset(dataset, deprecation: false) if dataset
|
175
|
-
|
176
|
-
if as
|
177
|
-
self.register_as(as, deprecation: false)
|
178
|
-
else
|
179
|
-
self.register_as(self.dataset, deprecation: false) unless register_as
|
180
|
-
end
|
181
|
-
|
182
|
-
name = Name[register_as, self.dataset]
|
183
|
-
inferrer = infer ? schema_inferrer : nil
|
184
|
-
|
185
|
-
unless schema_class
|
186
|
-
raise MissingSchemaClassError.new(self)
|
187
|
-
end
|
188
|
-
|
189
|
-
dsl = schema_dsl.new(name, schema_class: schema_class, inferrer: inferrer, &block)
|
190
|
-
|
191
|
-
@schema = dsl.call
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# Define a relation view with a specific schema
|
196
|
-
#
|
197
|
-
# Explicit relation views allow relation composition with auto-mapping
|
198
|
-
# in repositories. It's useful for cases like defining custom views
|
199
|
-
# for associations where relations (even from different databases) can
|
200
|
-
# be composed together and automatically mapped in memory to structs.
|
201
|
-
#
|
202
|
-
# @overload view(name, schema, &block)
|
203
|
-
# @example View with the canonical schema
|
204
|
-
# class Users < ROM::Relation[:sql]
|
205
|
-
# view(:listing, schema) do
|
206
|
-
# order(:name)
|
207
|
-
# end
|
208
|
-
# end
|
209
|
-
#
|
210
|
-
# @example View with a projected schema
|
211
|
-
# class Users < ROM::Relation[:sql]
|
212
|
-
# view(:listing, schema.project(:id, :name)) do
|
213
|
-
# order(:name)
|
214
|
-
# end
|
215
|
-
# end
|
216
|
-
#
|
217
|
-
# @overload view(name, &block)
|
218
|
-
# @example View with the canonical schema and arguments
|
219
|
-
# class Users < ROM::Relation[:sql]
|
220
|
-
# view(:by_name) do |name|
|
221
|
-
# where(name: name)
|
222
|
-
# end
|
223
|
-
# end
|
224
|
-
#
|
225
|
-
# @example View with projected schema and arguments
|
226
|
-
# class Users < ROM::Relation[:sql]
|
227
|
-
# view(:by_name) do
|
228
|
-
# schema { project(:id, :name) }
|
229
|
-
# relation { |name| where(name: name) }
|
230
|
-
# end
|
231
|
-
# end
|
232
|
-
#
|
233
|
-
# @example View with a schema extended with foreign attributes
|
234
|
-
# class Users < ROM::Relation[:sql]
|
235
|
-
# view(:index) do
|
236
|
-
# schema { append(relations[:tasks][:title]) }
|
237
|
-
# relation { |name| where(name: name) }
|
238
|
-
# end
|
239
|
-
# end
|
240
|
-
#
|
241
|
-
# @return [Symbol] view method name
|
242
|
-
#
|
243
|
-
# @api public
|
244
|
-
def view(*args, &block)
|
245
|
-
if args.size == 1 && block.arity > 0
|
246
|
-
raise ArgumentError, "header must be set as second argument"
|
247
|
-
end
|
248
|
-
|
249
|
-
name, new_schema_fn, relation_block =
|
250
|
-
if args.size == 1
|
251
|
-
ViewDSL.new(*args, schema, &block).call
|
252
|
-
else
|
253
|
-
[*args, block]
|
254
|
-
end
|
255
|
-
|
256
|
-
schemas[name] =
|
257
|
-
if args.size == 2
|
258
|
-
schema.project(*args[1])
|
259
|
-
else
|
260
|
-
new_schema_fn
|
261
|
-
end
|
262
|
-
|
263
|
-
if relation_block.arity > 0
|
264
|
-
auto_curry_guard do
|
265
|
-
define_method(name, &relation_block)
|
266
|
-
|
267
|
-
auto_curry(name) do
|
268
|
-
schemas[name].(self)
|
269
|
-
end
|
270
|
-
end
|
271
|
-
else
|
272
|
-
define_method(name) do
|
273
|
-
schemas[name].(instance_exec(&relation_block))
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
name
|
278
|
-
end
|
279
|
-
|
280
|
-
# Dynamically define a method that will forward to the dataset and wrap
|
281
|
-
# response in the relation itself
|
282
|
-
#
|
283
|
-
# @example
|
284
|
-
# class SomeAdapterRelation < ROM::Relation
|
285
|
-
# forward :super_query
|
286
|
-
# end
|
287
|
-
#
|
288
|
-
# @api public
|
289
|
-
def forward(*methods)
|
290
|
-
methods.each do |method|
|
291
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
292
|
-
def #{method}(*args, &block)
|
293
|
-
new(dataset.__send__(:#{method}, *args, &block))
|
294
|
-
end
|
295
|
-
RUBY
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
# Include a registered plugin in this relation class
|
300
|
-
#
|
301
|
-
# @param [Symbol] plugin
|
302
|
-
# @param [Hash] options
|
303
|
-
# @option options [Symbol] :adapter (:default) first adapter to check for plugin
|
304
|
-
#
|
305
|
-
# @api public
|
306
|
-
def use(plugin, _options = EMPTY_HASH)
|
307
|
-
ROM.plugin_registry.relations.fetch(plugin, adapter).apply_to(self)
|
308
|
-
end
|
309
|
-
|
310
|
-
# Return default relation name used for `register_as` setting
|
311
|
-
#
|
312
|
-
# @return [Symbol]
|
313
|
-
#
|
314
|
-
# @api private
|
315
|
-
def default_name
|
316
|
-
return unless name
|
317
|
-
Dry::Core::Inflector.underscore(name).tr('/', '_').to_sym
|
318
|
-
end
|
319
|
-
|
320
|
-
# @api private
|
321
|
-
def curried
|
322
|
-
Curried
|
323
|
-
end
|
324
|
-
|
325
|
-
# @api private
|
326
|
-
def view_methods
|
327
|
-
ancestor_methods = ancestors.reject { |klass| klass == self }
|
328
|
-
.map(&:instance_methods).flatten(1)
|
329
|
-
|
330
|
-
instance_methods - ancestor_methods + auto_curried_methods
|
331
|
-
end
|
332
|
-
|
333
|
-
# @api private
|
334
|
-
def schemas
|
335
|
-
@schemas ||= {}
|
336
|
-
end
|
337
|
-
|
338
|
-
# @api private
|
339
|
-
def default_schema(relation)
|
340
|
-
relation_class = relation.class
|
341
|
-
relation_class.schema || relation_class.schema_class.define(relation_class.default_name)
|
342
|
-
end
|
343
|
-
|
344
|
-
# Hook to finalize a relation after its instance was created
|
345
|
-
#
|
346
|
-
# @api private
|
347
|
-
def finalize(registry, relation)
|
348
|
-
schemas = relation.schemas.reduce({}) do |h, (a, e)|
|
349
|
-
h.update(a => e.is_a?(Proc) ? instance_exec(registry, &e) : e)
|
350
|
-
end
|
351
|
-
relation.schemas.update(schemas)
|
352
|
-
relation
|
353
|
-
end
|
354
|
-
end
|
355
|
-
end
|
356
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'rom/relation/loaded'
|
2
|
-
require 'rom/relation/materializable'
|
3
|
-
require 'rom/pipeline'
|
4
|
-
|
5
|
-
module ROM
|
6
|
-
class Relation
|
7
|
-
# Left-to-right relation composition used for data-pipelining
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
class Composite < Pipeline::Composite
|
11
|
-
include Materializable
|
12
|
-
|
13
|
-
# Call the pipeline by passing results from left to right
|
14
|
-
#
|
15
|
-
# Optional args are passed to the left object
|
16
|
-
#
|
17
|
-
# @return [Loaded]
|
18
|
-
#
|
19
|
-
# @api public
|
20
|
-
def call(*args)
|
21
|
-
relation = left.call(*args)
|
22
|
-
response = right.call(relation)
|
23
|
-
|
24
|
-
if response.is_a?(Loaded)
|
25
|
-
response
|
26
|
-
elsif relation.is_a?(Loaded)
|
27
|
-
relation.new(response)
|
28
|
-
else
|
29
|
-
Loaded.new(relation, response)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
alias_method :[], :call
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
# @api private
|
37
|
-
#
|
38
|
-
# @see Pipeline::Proxy#decorate?
|
39
|
-
#
|
40
|
-
# @api private
|
41
|
-
def decorate?(response)
|
42
|
-
super || response.is_a?(Graph)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/lib/rom/relation/curried.rb
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
require 'rom/types'
|
2
|
-
require 'rom/initializer'
|
3
|
-
require 'rom/pipeline'
|
4
|
-
require 'rom/relation/name'
|
5
|
-
require 'rom/relation/materializable'
|
6
|
-
|
7
|
-
module ROM
|
8
|
-
class Relation
|
9
|
-
class Curried
|
10
|
-
extend Initializer
|
11
|
-
include Materializable
|
12
|
-
include Pipeline
|
13
|
-
|
14
|
-
param :relation
|
15
|
-
|
16
|
-
option :name, optional: true, type: Types::Strict::Symbol
|
17
|
-
option :arity, type: Types::Strict::Int, default: -> { -1 }
|
18
|
-
option :curry_args, default: -> { EMPTY_ARRAY }
|
19
|
-
|
20
|
-
# Relation name
|
21
|
-
#
|
22
|
-
# @return [ROM::Relation::Name]
|
23
|
-
#
|
24
|
-
# @api public
|
25
|
-
def name
|
26
|
-
@name ? relation.name.with(@name) : relation.name
|
27
|
-
end
|
28
|
-
|
29
|
-
# Load relation if args match the arity
|
30
|
-
#
|
31
|
-
# @return [Loaded,Curried]
|
32
|
-
#
|
33
|
-
# @api public
|
34
|
-
def call(*args)
|
35
|
-
if arity != -1
|
36
|
-
all_args = curry_args + args
|
37
|
-
|
38
|
-
if all_args.empty?
|
39
|
-
raise ArgumentError, "curried #{relation.class}##{name.to_sym} relation was called without any arguments"
|
40
|
-
end
|
41
|
-
|
42
|
-
if args.empty?
|
43
|
-
self
|
44
|
-
elsif arity == all_args.size
|
45
|
-
Loaded.new(relation.__send__(name.relation, *all_args))
|
46
|
-
else
|
47
|
-
__new__(relation, curry_args: all_args)
|
48
|
-
end
|
49
|
-
else
|
50
|
-
super
|
51
|
-
end
|
52
|
-
end
|
53
|
-
alias_method :[], :call
|
54
|
-
|
55
|
-
# @api public
|
56
|
-
def to_a
|
57
|
-
raise(
|
58
|
-
ArgumentError,
|
59
|
-
"#{relation.class}##{name.relation} arity is #{arity} " \
|
60
|
-
"(#{curry_args.size} args given)"
|
61
|
-
)
|
62
|
-
end
|
63
|
-
alias_method :to_ary, :to_a
|
64
|
-
|
65
|
-
# Return if this lazy relation is curried
|
66
|
-
#
|
67
|
-
# @return [true]
|
68
|
-
#
|
69
|
-
# @api private
|
70
|
-
def curried?
|
71
|
-
true
|
72
|
-
end
|
73
|
-
|
74
|
-
# @api private
|
75
|
-
def respond_to_missing?(name, include_private = false)
|
76
|
-
super || relation.respond_to?(name, include_private)
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
# @api private
|
82
|
-
def __new__(relation, new_opts = EMPTY_HASH)
|
83
|
-
self.class.new(relation, new_opts.empty? ? options : options.merge(new_opts))
|
84
|
-
end
|
85
|
-
|
86
|
-
# @api private
|
87
|
-
def composite_class
|
88
|
-
Relation::Composite
|
89
|
-
end
|
90
|
-
|
91
|
-
# @api private
|
92
|
-
def method_missing(meth, *args, &block)
|
93
|
-
if relation.respond_to?(meth)
|
94
|
-
response = relation.__send__(meth, *args, &block)
|
95
|
-
|
96
|
-
super if response.is_a?(self.class)
|
97
|
-
|
98
|
-
if response.is_a?(Relation) || response.is_a?(Graph)
|
99
|
-
__new__(response)
|
100
|
-
else
|
101
|
-
response
|
102
|
-
end
|
103
|
-
else
|
104
|
-
super
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
data/lib/rom/relation/graph.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
require 'dry/core/deprecations'
|
2
|
-
|
3
|
-
require 'rom/relation/loaded'
|
4
|
-
require 'rom/relation/composite'
|
5
|
-
require 'rom/relation/materializable'
|
6
|
-
require 'rom/pipeline'
|
7
|
-
|
8
|
-
module ROM
|
9
|
-
class Relation
|
10
|
-
# Compose relations using join-keys
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# class Users < ROM::Relation[:memory]
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# class Tasks < ROM::Relation[:memory]
|
17
|
-
# def for_users(users)
|
18
|
-
# restrict(user: users.map { |user| user[:name] })
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# rom.relations[:users] << { name: 'Jane' }
|
23
|
-
# rom.relations[:tasks] << { user: 'Jane', title: 'Do something' }
|
24
|
-
#
|
25
|
-
# rom.relation(:users).combine(rom.relation(:tasks).for_users)
|
26
|
-
#
|
27
|
-
# @api public
|
28
|
-
class Graph
|
29
|
-
extend Dry::Core::Deprecations[:rom]
|
30
|
-
|
31
|
-
include Materializable
|
32
|
-
include Pipeline
|
33
|
-
include Pipeline::Proxy
|
34
|
-
|
35
|
-
# Root aka parent relation
|
36
|
-
#
|
37
|
-
# @return [Relation::Lazy]
|
38
|
-
#
|
39
|
-
# @api private
|
40
|
-
attr_reader :root
|
41
|
-
|
42
|
-
# Child relation nodes
|
43
|
-
#
|
44
|
-
# @return [Array<Relation::Lazy>]
|
45
|
-
#
|
46
|
-
# @api private
|
47
|
-
attr_reader :nodes
|
48
|
-
|
49
|
-
alias_method :left, :root
|
50
|
-
alias_method :right, :nodes
|
51
|
-
|
52
|
-
# @api private
|
53
|
-
def self.build(root, nodes)
|
54
|
-
if nodes.any? { |node| node.instance_of?(Composite) }
|
55
|
-
raise UnsupportedRelationError,
|
56
|
-
"Combining with composite relations is not supported"
|
57
|
-
else
|
58
|
-
new(root, nodes)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# @api private
|
63
|
-
def initialize(root, nodes)
|
64
|
-
@root = root
|
65
|
-
@nodes = nodes
|
66
|
-
end
|
67
|
-
|
68
|
-
# @api public
|
69
|
-
def with_nodes(nodes)
|
70
|
-
self.class.new(root, nodes)
|
71
|
-
end
|
72
|
-
|
73
|
-
# Return if this is a graph relation
|
74
|
-
#
|
75
|
-
# @return [true]
|
76
|
-
#
|
77
|
-
# @api private
|
78
|
-
def graph?
|
79
|
-
true
|
80
|
-
end
|
81
|
-
|
82
|
-
# Combine this graph with more nodes
|
83
|
-
#
|
84
|
-
# @param [Array<Relation::Lazy>]
|
85
|
-
#
|
86
|
-
# @return [Graph]
|
87
|
-
#
|
88
|
-
# @api public
|
89
|
-
def graph(*others)
|
90
|
-
self.class.new(root, nodes + others)
|
91
|
-
end
|
92
|
-
deprecate :combine, :graph
|
93
|
-
|
94
|
-
# Materialize this relation graph
|
95
|
-
#
|
96
|
-
# @return [Loaded]
|
97
|
-
#
|
98
|
-
# @api public
|
99
|
-
def call(*args)
|
100
|
-
left = root.call(*args)
|
101
|
-
|
102
|
-
right =
|
103
|
-
if left.empty?
|
104
|
-
nodes.map { |node| Loaded.new(node, EMPTY_ARRAY) }
|
105
|
-
else
|
106
|
-
nodes.map { |node| node.call(left) }
|
107
|
-
end
|
108
|
-
|
109
|
-
Loaded.new(self, [left, right])
|
110
|
-
end
|
111
|
-
|
112
|
-
private
|
113
|
-
|
114
|
-
# @api private
|
115
|
-
def decorate?(other)
|
116
|
-
super || other.is_a?(Curried)
|
117
|
-
end
|
118
|
-
|
119
|
-
# @api private
|
120
|
-
def composite_class
|
121
|
-
Relation::Composite
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|