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/relation/loaded.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
class Relation
|
3
|
-
# Materializes a relation and exposes interface to access the data
|
4
|
-
#
|
5
|
-
# @api public
|
6
|
-
class Loaded
|
7
|
-
include Enumerable
|
8
|
-
|
9
|
-
# Coerce loaded relation to an array
|
10
|
-
#
|
11
|
-
# @return [Array]
|
12
|
-
#
|
13
|
-
# @api public
|
14
|
-
alias_method :to_ary, :to_a
|
15
|
-
|
16
|
-
# Source relation
|
17
|
-
#
|
18
|
-
# @return [Relation]
|
19
|
-
#
|
20
|
-
# @api private
|
21
|
-
attr_reader :source
|
22
|
-
|
23
|
-
# Materialized relation
|
24
|
-
#
|
25
|
-
# @return [Object]
|
26
|
-
#
|
27
|
-
# @api private
|
28
|
-
attr_reader :collection
|
29
|
-
|
30
|
-
# @api private
|
31
|
-
def initialize(source, collection = source.to_a)
|
32
|
-
@source = source
|
33
|
-
@collection = collection
|
34
|
-
end
|
35
|
-
|
36
|
-
# Yield relation tuples
|
37
|
-
#
|
38
|
-
# @yield [Hash]
|
39
|
-
#
|
40
|
-
# @api public
|
41
|
-
def each(&block)
|
42
|
-
return to_enum unless block
|
43
|
-
collection.each { |tuple| yield(tuple) }
|
44
|
-
end
|
45
|
-
|
46
|
-
# Returns a single tuple from the relation if there is one.
|
47
|
-
#
|
48
|
-
# @raise [ROM::TupleCountMismatchError] if the relation contains more than
|
49
|
-
# one tuple
|
50
|
-
#
|
51
|
-
# @api public
|
52
|
-
def one
|
53
|
-
if collection.count > 1
|
54
|
-
raise(
|
55
|
-
TupleCountMismatchError,
|
56
|
-
'The relation consists of more than one tuple'
|
57
|
-
)
|
58
|
-
else
|
59
|
-
collection.first
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Like [one], but additionally raises an error if the relation is empty.
|
64
|
-
#
|
65
|
-
# @raise [ROM::TupleCountMismatchError] if the relation does not contain
|
66
|
-
# exactly one tuple
|
67
|
-
#
|
68
|
-
# @api public
|
69
|
-
def one!
|
70
|
-
one || raise(
|
71
|
-
TupleCountMismatchError,
|
72
|
-
'The relation does not contain any tuples'
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Return a list of values under provided key
|
77
|
-
#
|
78
|
-
# @example
|
79
|
-
# all_users = rom.relations[:users].call
|
80
|
-
# all_users.pluck(:name)
|
81
|
-
# # ["Jane", "Joe"]
|
82
|
-
#
|
83
|
-
# @param [Symbol] key The key name
|
84
|
-
#
|
85
|
-
# @return [Array]
|
86
|
-
# @raises KeyError when provided key doesn't exist in any of the tuples
|
87
|
-
#
|
88
|
-
# @api public
|
89
|
-
def pluck(key)
|
90
|
-
map { |tuple| tuple.fetch(key) }
|
91
|
-
end
|
92
|
-
|
93
|
-
# Pluck primary key values
|
94
|
-
#
|
95
|
-
# This method *may not work* with adapters that don't provide relations
|
96
|
-
# that have primary key configured
|
97
|
-
#
|
98
|
-
# @example
|
99
|
-
# users = rom.relations[:users].call
|
100
|
-
# users.primary_keys
|
101
|
-
# # [1, 2, 3]
|
102
|
-
#
|
103
|
-
# @return [Array]
|
104
|
-
#
|
105
|
-
# @api public
|
106
|
-
def primary_keys
|
107
|
-
pluck(source.primary_key)
|
108
|
-
end
|
109
|
-
|
110
|
-
# Return if loaded relation is empty
|
111
|
-
#
|
112
|
-
# @return [TrueClass,FalseClass]
|
113
|
-
#
|
114
|
-
# @api public
|
115
|
-
def empty?
|
116
|
-
collection.empty?
|
117
|
-
end
|
118
|
-
|
119
|
-
# Return a loaded relation with a new collection
|
120
|
-
#
|
121
|
-
# @api public
|
122
|
-
def new(collection)
|
123
|
-
self.class.new(source, collection)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
class Relation
|
3
|
-
# Interface for objects that can be materialized into a loaded relation
|
4
|
-
#
|
5
|
-
# @api public
|
6
|
-
module Materializable
|
7
|
-
# @abstract
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
def call(*)
|
11
|
-
raise NotImplementedError, "#{self.class}#call must be implemented"
|
12
|
-
end
|
13
|
-
|
14
|
-
# Coerce the relation to an array
|
15
|
-
#
|
16
|
-
# @return [Array]
|
17
|
-
#
|
18
|
-
# @api public
|
19
|
-
def to_a
|
20
|
-
call.to_a
|
21
|
-
end
|
22
|
-
alias_method :to_ary, :to_a
|
23
|
-
|
24
|
-
# Yield relation tuples
|
25
|
-
#
|
26
|
-
# @yield [Hash,Object]
|
27
|
-
#
|
28
|
-
# @api public
|
29
|
-
def each(&block)
|
30
|
-
return to_enum unless block
|
31
|
-
to_a.each { |tuple| yield(tuple) }
|
32
|
-
end
|
33
|
-
|
34
|
-
# Delegate to loaded relation and return one object
|
35
|
-
#
|
36
|
-
# @return [Object]
|
37
|
-
#
|
38
|
-
# @see Loaded#one
|
39
|
-
#
|
40
|
-
# @api public
|
41
|
-
def one
|
42
|
-
call.one
|
43
|
-
end
|
44
|
-
|
45
|
-
# Delegate to loaded relation and return one object
|
46
|
-
#
|
47
|
-
# @return [Object]
|
48
|
-
#
|
49
|
-
# @see Loaded#one
|
50
|
-
#
|
51
|
-
# @api public
|
52
|
-
def one!
|
53
|
-
call.one!
|
54
|
-
end
|
55
|
-
|
56
|
-
# Return first tuple from a relation coerced to an array
|
57
|
-
#
|
58
|
-
# @return [Object]
|
59
|
-
#
|
60
|
-
# @api public
|
61
|
-
def first
|
62
|
-
to_a.first
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
data/lib/rom/relation/name.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'dry/equalizer'
|
2
|
-
require 'concurrent/map'
|
3
|
-
|
4
|
-
module ROM
|
5
|
-
class Relation
|
6
|
-
# Relation name container
|
7
|
-
#
|
8
|
-
# This is a simple struct with two fields.
|
9
|
-
# It handles both relation registration name (i.e. Symbol) and dataset name.
|
10
|
-
# The reason we need it is a simplification of passing around these two objects.
|
11
|
-
# It is quite common to have a dataset named differently from a relation
|
12
|
-
# built on top if you are dealing with a legacy DB and often you need both
|
13
|
-
# to support things such as associations (rom-sql as an example).
|
14
|
-
#
|
15
|
-
# @api private
|
16
|
-
class Name
|
17
|
-
include Dry::Equalizer(:relation, :dataset)
|
18
|
-
|
19
|
-
# Coerce an object to a Name instance
|
20
|
-
#
|
21
|
-
# @return [ROM::Relation::Name]
|
22
|
-
#
|
23
|
-
# @api private
|
24
|
-
def self.[](*args)
|
25
|
-
cache.fetch_or_store(args.hash) do
|
26
|
-
relation, dataset = args
|
27
|
-
|
28
|
-
if relation.is_a?(Name)
|
29
|
-
relation
|
30
|
-
else
|
31
|
-
new(relation, dataset)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# @api private
|
37
|
-
def self.cache
|
38
|
-
@cache ||= Concurrent::Map.new
|
39
|
-
end
|
40
|
-
|
41
|
-
# Relation registration name
|
42
|
-
#
|
43
|
-
# @return [Symbol]
|
44
|
-
#
|
45
|
-
# @api private
|
46
|
-
attr_reader :relation
|
47
|
-
|
48
|
-
# Underlying dataset name
|
49
|
-
#
|
50
|
-
# @return [Symbol]
|
51
|
-
#
|
52
|
-
# @api private
|
53
|
-
attr_reader :dataset
|
54
|
-
|
55
|
-
# @api private
|
56
|
-
def initialize(relation, dataset = nil)
|
57
|
-
@relation = relation
|
58
|
-
@dataset = dataset || relation
|
59
|
-
end
|
60
|
-
|
61
|
-
# Return relation name
|
62
|
-
#
|
63
|
-
# @return [String]
|
64
|
-
#
|
65
|
-
# @api private
|
66
|
-
def to_s
|
67
|
-
if relation == dataset
|
68
|
-
relation.to_s
|
69
|
-
else
|
70
|
-
"#{relation} on #{dataset}"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Alias for registration key implicitly called by ROM::Registry
|
75
|
-
#
|
76
|
-
# @return [Symbol]
|
77
|
-
#
|
78
|
-
# @api private
|
79
|
-
def to_sym
|
80
|
-
relation
|
81
|
-
end
|
82
|
-
|
83
|
-
# Return inspected relation
|
84
|
-
#
|
85
|
-
# @return [String]
|
86
|
-
#
|
87
|
-
# @api private
|
88
|
-
def inspect
|
89
|
-
"#{self.class.name}(#{to_s})"
|
90
|
-
end
|
91
|
-
|
92
|
-
# Build a new name. Useful for Curried and other relation proxies
|
93
|
-
#
|
94
|
-
# @return [ROM::Relation::Name]
|
95
|
-
#
|
96
|
-
# @api private
|
97
|
-
def with(relation)
|
98
|
-
self.class[relation, dataset]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
class Relation
|
3
|
-
# ViewDSL is exposed in `Relation.view` method
|
4
|
-
#
|
5
|
-
# This is used to establish pre-defined relation views with explicit schemas.
|
6
|
-
# Such views can be used to compose relations together, even from multiple
|
7
|
-
# adapters.
|
8
|
-
#
|
9
|
-
# @api public
|
10
|
-
class ViewDSL
|
11
|
-
# @!attribute [r] name
|
12
|
-
# @return [Symbol] The view name (relation method)
|
13
|
-
attr_reader :name
|
14
|
-
|
15
|
-
# @!attribute [r] relation_block
|
16
|
-
# @return [Proc] The relation block that will be evaluated by the view method
|
17
|
-
attr_reader :relation_block
|
18
|
-
|
19
|
-
# @!attribute [r] new_schema
|
20
|
-
# @return [Proc] The schema proc returned by the schema DSL
|
21
|
-
attr_reader :new_schema
|
22
|
-
|
23
|
-
# @api private
|
24
|
-
def initialize(name, schema, &block)
|
25
|
-
@name = name
|
26
|
-
@schema = schema
|
27
|
-
@new_schema = nil
|
28
|
-
@relation_block = nil
|
29
|
-
instance_eval(&block)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Define a schema for a relation view
|
33
|
-
#
|
34
|
-
# @return [Proc]
|
35
|
-
#
|
36
|
-
# @see Relation::ClassInterface.view
|
37
|
-
#
|
38
|
-
# @api public
|
39
|
-
def schema(&block)
|
40
|
-
@new_schema = -> relations { @schema.with(relations: relations).instance_exec(&block) }
|
41
|
-
end
|
42
|
-
|
43
|
-
# Define a relation block for a relation view
|
44
|
-
#
|
45
|
-
# @return [Proc]
|
46
|
-
#
|
47
|
-
# @see Relation::ClassInterface.view
|
48
|
-
#
|
49
|
-
# @api public
|
50
|
-
def relation(&block)
|
51
|
-
@relation_block = lambda(&block)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Return procs captured by the DSL
|
55
|
-
#
|
56
|
-
# @return [Array]
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
def call
|
60
|
-
[name, new_schema, relation_block]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
data/lib/rom/relation.rb
DELETED
@@ -1,250 +0,0 @@
|
|
1
|
-
require 'dry/core/class_attributes'
|
2
|
-
require 'dry/core/deprecations'
|
3
|
-
|
4
|
-
require 'rom/initializer'
|
5
|
-
require 'rom/relation/class_interface'
|
6
|
-
|
7
|
-
require 'rom/pipeline'
|
8
|
-
require 'rom/mapper_registry'
|
9
|
-
|
10
|
-
require 'rom/relation/loaded'
|
11
|
-
require 'rom/relation/curried'
|
12
|
-
require 'rom/relation/composite'
|
13
|
-
require 'rom/relation/graph'
|
14
|
-
require 'rom/relation/materializable'
|
15
|
-
require 'rom/association_set'
|
16
|
-
|
17
|
-
require 'rom/types'
|
18
|
-
require 'rom/schema'
|
19
|
-
|
20
|
-
module ROM
|
21
|
-
# Base relation class
|
22
|
-
#
|
23
|
-
# Relation is a proxy for the dataset object provided by the gateway. It
|
24
|
-
# can forward methods to the dataset, which is why the "native" interface of
|
25
|
-
# the underlying gateway is available in the relation. This interface,
|
26
|
-
# however, is considered private and should not be used outside of the
|
27
|
-
# relation instance.
|
28
|
-
#
|
29
|
-
# Individual adapters sets up their relation classes and provide different APIs
|
30
|
-
# depending on their persistence backend.
|
31
|
-
#
|
32
|
-
# Vanilla Relation class doesn't have APIs that are specific to ROM container setup.
|
33
|
-
# When adapter Relation class inherits from this class, these APIs are added automatically,
|
34
|
-
# so that they can be registered within a container.
|
35
|
-
#
|
36
|
-
# @see ROM::Relation::ClassInterface
|
37
|
-
#
|
38
|
-
# @api public
|
39
|
-
class Relation
|
40
|
-
# Default no-op output schema which is called in `Relation#each`
|
41
|
-
NOOP_OUTPUT_SCHEMA = -> tuple { tuple }.freeze
|
42
|
-
|
43
|
-
extend Initializer
|
44
|
-
extend ClassInterface
|
45
|
-
extend Dry::Core::Deprecations[:rom]
|
46
|
-
|
47
|
-
extend Dry::Core::ClassAttributes
|
48
|
-
defines :schema_class, :schema_inferrer, :schema_dsl
|
49
|
-
|
50
|
-
schema_dsl Schema::DSL
|
51
|
-
schema_class Schema
|
52
|
-
schema_inferrer Schema::DEFAULT_INFERRER
|
53
|
-
|
54
|
-
include Dry::Equalizer(:dataset)
|
55
|
-
include Materializable
|
56
|
-
include Pipeline
|
57
|
-
|
58
|
-
# @!attribute [r] dataset
|
59
|
-
# @return [Object] dataset used by the relation provided by relation's gateway
|
60
|
-
# @api public
|
61
|
-
param :dataset
|
62
|
-
|
63
|
-
# @!attribute [r] mappers
|
64
|
-
# @return [MapperRegistry] an optional mapper registry (empty by default)
|
65
|
-
option :mappers, default: -> { MapperRegistry.new }
|
66
|
-
|
67
|
-
# @!attribute [r] schema
|
68
|
-
# @return [Schema] relation schema, defaults to class-level canonical
|
69
|
-
# schema (if it was defined) and sets an empty one as
|
70
|
-
# the fallback
|
71
|
-
# @api public
|
72
|
-
option :schema, default: -> { self.class.default_schema(self) }
|
73
|
-
|
74
|
-
# @!attribute [r] input_schema
|
75
|
-
# @return [Object#[]] tuple processing function, uses schema or defaults to Hash[]
|
76
|
-
# @api private
|
77
|
-
option :input_schema, default: -> { schema? ? schema.to_input_hash : Hash }
|
78
|
-
|
79
|
-
# @!attribute [r] output_schema
|
80
|
-
# @return [Object#[]] tuple processing function, uses schema or defaults to NOOP_OUTPUT_SCHEMA
|
81
|
-
# @api private
|
82
|
-
option :output_schema, default: -> {
|
83
|
-
schema.any?(&:read?) ? schema.to_output_hash : NOOP_OUTPUT_SCHEMA
|
84
|
-
}
|
85
|
-
|
86
|
-
# Return schema attribute
|
87
|
-
#
|
88
|
-
# @example accessing canonical attribute
|
89
|
-
# users[:id]
|
90
|
-
# # => #<ROM::SQL::Attribute[Integer] primary_key=true name=:id source=ROM::Relation::Name(users)>
|
91
|
-
#
|
92
|
-
# @example accessing joined attribute
|
93
|
-
# tasks_with_users = tasks.join(users).select_append(tasks[:title])
|
94
|
-
# tasks_with_users[:title, :tasks]
|
95
|
-
# # => #<ROM::SQL::Attribute[String] primary_key=false name=:title source=ROM::Relation::Name(tasks)>
|
96
|
-
#
|
97
|
-
# @return [Schema::Attribute]
|
98
|
-
#
|
99
|
-
# @api public
|
100
|
-
def [](name)
|
101
|
-
schema[name]
|
102
|
-
end
|
103
|
-
|
104
|
-
# Yields relation tuples
|
105
|
-
#
|
106
|
-
# Every tuple is processed through Relation#output_schema, it's a no-op by default
|
107
|
-
#
|
108
|
-
# @yield [Hash]
|
109
|
-
#
|
110
|
-
# @return [Enumerator] if block is not provided
|
111
|
-
#
|
112
|
-
# @api public
|
113
|
-
def each(&block)
|
114
|
-
return to_enum unless block
|
115
|
-
dataset.each { |tuple| yield(output_schema[tuple]) }
|
116
|
-
end
|
117
|
-
|
118
|
-
# Composes with other relations
|
119
|
-
#
|
120
|
-
# @param [Array<Relation>] others The other relation(s) to compose with
|
121
|
-
#
|
122
|
-
# @return [Relation::Graph]
|
123
|
-
#
|
124
|
-
# @api public
|
125
|
-
def graph(*others)
|
126
|
-
Graph.build(self, others)
|
127
|
-
end
|
128
|
-
deprecate :combine, :graph
|
129
|
-
|
130
|
-
# Loads relation
|
131
|
-
#
|
132
|
-
# @return [Relation::Loaded]
|
133
|
-
#
|
134
|
-
# @api public
|
135
|
-
def call
|
136
|
-
Loaded.new(self)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Materializes a relation into an array
|
140
|
-
#
|
141
|
-
# @return [Array<Hash>]
|
142
|
-
#
|
143
|
-
# @api public
|
144
|
-
def to_a
|
145
|
-
to_enum.to_a
|
146
|
-
end
|
147
|
-
|
148
|
-
# Returns if this relation is curried
|
149
|
-
#
|
150
|
-
# @return [false]
|
151
|
-
#
|
152
|
-
# @api private
|
153
|
-
def curried?
|
154
|
-
false
|
155
|
-
end
|
156
|
-
|
157
|
-
# Returns if this relation is a graph
|
158
|
-
#
|
159
|
-
# @return [false]
|
160
|
-
#
|
161
|
-
# @api private
|
162
|
-
def graph?
|
163
|
-
false
|
164
|
-
end
|
165
|
-
|
166
|
-
# Returns true if a relation has schema defined
|
167
|
-
#
|
168
|
-
# @return [TrueClass, FalseClass]
|
169
|
-
#
|
170
|
-
# @api private
|
171
|
-
def schema?
|
172
|
-
! schema.empty?
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return a new relation with provided dataset and additional options
|
176
|
-
#
|
177
|
-
# Use this method whenever you need to use dataset API to get a new dataset
|
178
|
-
# and you want to return a relation back. Typically relation API should be
|
179
|
-
# enough though. If you find yourself using this method, it might be worth
|
180
|
-
# to consider reporting an issue that some dataset functionality is not available
|
181
|
-
# through relation API.
|
182
|
-
#
|
183
|
-
# @example with a new dataset
|
184
|
-
# users.new(users.dataset.some_method)
|
185
|
-
#
|
186
|
-
# @example with a new dataset and options
|
187
|
-
# users.new(users.dataset.some_method, other: 'options')
|
188
|
-
#
|
189
|
-
# @param [Object] dataset
|
190
|
-
# @param [Hash] new_opts Additional options
|
191
|
-
#
|
192
|
-
# @api public
|
193
|
-
def new(dataset, new_opts = EMPTY_HASH)
|
194
|
-
if new_opts.empty?
|
195
|
-
opts = options
|
196
|
-
elsif new_opts.key?(:schema)
|
197
|
-
opts = options.reject { |k, _| k == :input_schema || k == :output_schema }.merge(new_opts)
|
198
|
-
else
|
199
|
-
opts = options.merge(new_opts)
|
200
|
-
end
|
201
|
-
|
202
|
-
self.class.new(dataset, opts)
|
203
|
-
end
|
204
|
-
|
205
|
-
# Returns a new instance with the same dataset but new options
|
206
|
-
#
|
207
|
-
# @example
|
208
|
-
# users.with(output_schema: -> tuple { .. })
|
209
|
-
#
|
210
|
-
# @param new_options [Hash]
|
211
|
-
#
|
212
|
-
# @return [Relation]
|
213
|
-
#
|
214
|
-
# @api private
|
215
|
-
def with(new_options)
|
216
|
-
new(dataset, options.merge(new_options))
|
217
|
-
end
|
218
|
-
|
219
|
-
# Return all registered relation schemas
|
220
|
-
#
|
221
|
-
# This holds all schemas defined via `view` DSL
|
222
|
-
#
|
223
|
-
# @return [Hash<Symbol=>Schema>]
|
224
|
-
#
|
225
|
-
# @api public
|
226
|
-
def schemas
|
227
|
-
@schemas ||= self.class.schemas
|
228
|
-
end
|
229
|
-
|
230
|
-
# Return schema's association set (empty by default)
|
231
|
-
#
|
232
|
-
# @return [AssociationSet] Schema's association set (empty by default)
|
233
|
-
#
|
234
|
-
# @api public
|
235
|
-
def associations
|
236
|
-
@associations ||= schema.associations
|
237
|
-
end
|
238
|
-
|
239
|
-
private
|
240
|
-
|
241
|
-
# Hook used by `Pipeline` to get the class that should be used for composition
|
242
|
-
#
|
243
|
-
# @return [Class]
|
244
|
-
#
|
245
|
-
# @api private
|
246
|
-
def composite_class
|
247
|
-
Relation::Composite
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|