rom-core 5.1.2 → 5.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rom/array_dataset.rb +4 -4
- data/lib/rom/association_set.rb +2 -3
- data/lib/rom/associations/definitions/abstract.rb +2 -2
- data/lib/rom/associations/many_to_many.rb +1 -0
- data/lib/rom/attribute.rb +5 -4
- data/lib/rom/auto_curry.rb +2 -0
- data/lib/rom/command.rb +6 -6
- data/lib/rom/command_compiler.rb +5 -7
- data/lib/rom/commands/class_interface.rb +7 -7
- data/lib/rom/commands/composite.rb +1 -1
- data/lib/rom/commands/graph/input_evaluator.rb +1 -1
- data/lib/rom/commands/lazy.rb +2 -1
- data/lib/rom/commands/lazy/create.rb +1 -1
- data/lib/rom/commands/lazy/update.rb +3 -3
- data/lib/rom/configuration.rb +5 -5
- data/lib/rom/configuration_dsl/relation.rb +1 -1
- data/lib/rom/constants.rb +1 -1
- data/lib/rom/core/version.rb +1 -1
- data/lib/rom/data_proxy.rb +3 -2
- data/lib/rom/enumerable_dataset.rb +4 -4
- data/lib/rom/environment.rb +0 -1
- data/lib/rom/header/attribute.rb +2 -4
- data/lib/rom/initializer.rb +9 -7
- data/lib/rom/lint/gateway.rb +1 -3
- data/lib/rom/lint/linter.rb +3 -4
- data/lib/rom/lint/spec.rb +2 -2
- data/lib/rom/mapper.rb +4 -3
- data/lib/rom/mapper/attribute_dsl.rb +5 -5
- data/lib/rom/mapper/dsl.rb +2 -5
- data/lib/rom/mapper/model_dsl.rb +2 -1
- data/lib/rom/mapper_compiler.rb +2 -1
- data/lib/rom/mapper_registry.rb +3 -3
- data/lib/rom/memory/dataset.rb +4 -3
- data/lib/rom/pipeline.rb +3 -1
- data/lib/rom/plugin.rb +3 -3
- data/lib/rom/plugin_registry.rb +1 -1
- data/lib/rom/plugins/command/schema.rb +2 -2
- data/lib/rom/plugins/relation/instrumentation.rb +1 -1
- data/lib/rom/plugins/relation/registry_reader.rb +4 -3
- data/lib/rom/plugins/schema/timestamps.rb +4 -6
- data/lib/rom/processor.rb +1 -1
- data/lib/rom/processor/transproc.rb +16 -19
- data/lib/rom/registry.rb +17 -12
- data/lib/rom/relation.rb +6 -6
- data/lib/rom/relation/class_interface.rb +9 -8
- data/lib/rom/relation/curried.rb +3 -2
- data/lib/rom/relation/loaded.rb +1 -0
- data/lib/rom/relation/materializable.rb +1 -0
- data/lib/rom/relation/name.rb +1 -1
- data/lib/rom/relation_registry.rb +1 -1
- data/lib/rom/schema.rb +22 -22
- data/lib/rom/schema/associations_dsl.rb +17 -17
- data/lib/rom/schema/dsl.rb +6 -6
- data/lib/rom/schema/inferrer.rb +2 -4
- data/lib/rom/setup.rb +2 -2
- data/lib/rom/setup/auto_registration.rb +1 -1
- data/lib/rom/setup/auto_registration_strategies/base.rb +1 -1
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -4
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +1 -1
- data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +1 -1
- data/lib/rom/setup/finalize/finalize_commands.rb +7 -4
- data/lib/rom/setup/finalize/finalize_mappers.rb +9 -8
- data/lib/rom/setup/finalize/finalize_relations.rb +2 -2
- data/lib/rom/struct.rb +1 -1
- data/lib/rom/struct_compiler.rb +6 -5
- data/lib/rom/support/memoizable.rb +3 -2
- data/lib/rom/transaction.rb +1 -1
- data/lib/rom/transformer.rb +1 -0
- metadata +3 -3
data/lib/rom/initializer.rb
CHANGED
@@ -11,6 +11,7 @@ module ROM
|
|
11
11
|
def param(*)
|
12
12
|
super.tap { __define_with__ }
|
13
13
|
end
|
14
|
+
ruby2_keywords(:param) if respond_to?(:ruby2_keywords, true)
|
14
15
|
|
15
16
|
# @api private
|
16
17
|
def option(*)
|
@@ -18,25 +19,26 @@ module ROM
|
|
18
19
|
__define_with__ unless method_defined?(:with)
|
19
20
|
end
|
20
21
|
end
|
22
|
+
ruby2_keywords(:option) if respond_to?(:ruby2_keywords, true)
|
21
23
|
|
22
24
|
# @api private
|
23
25
|
def __define_with__
|
24
|
-
seq_names = dry_initializer
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
seq_names = dry_initializer
|
27
|
+
.definitions
|
28
|
+
.reject { |_, d| d.option }
|
29
|
+
.keys
|
30
|
+
.join(', ')
|
29
31
|
|
30
32
|
seq_names << ', ' unless seq_names.empty?
|
31
33
|
|
32
34
|
undef_method(:with) if method_defined?(:with)
|
33
35
|
|
34
36
|
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
35
|
-
def with(new_options
|
37
|
+
def with(**new_options)
|
36
38
|
if new_options.empty?
|
37
39
|
self
|
38
40
|
else
|
39
|
-
self.class.new(#{
|
41
|
+
self.class.new(#{seq_names}**options, **new_options)
|
40
42
|
end
|
41
43
|
end
|
42
44
|
RUBY
|
data/lib/rom/lint/gateway.rb
CHANGED
@@ -77,9 +77,7 @@ module ROM
|
|
77
77
|
def lint_transaction_support
|
78
78
|
result = gateway_instance.transaction { 1 }
|
79
79
|
|
80
|
-
if result != 1
|
81
|
-
complain "#{gateway_instance} must return the result of a transaction block"
|
82
|
-
end
|
80
|
+
complain "#{gateway_instance} must return the result of a transaction block" if result != 1
|
83
81
|
|
84
82
|
gateway_instance.transaction do |t|
|
85
83
|
t.rollback!
|
data/lib/rom/lint/linter.rb
CHANGED
@@ -27,6 +27,7 @@ module ROM
|
|
27
27
|
# @api public
|
28
28
|
def self.each_lint
|
29
29
|
return to_enum unless block_given?
|
30
|
+
|
30
31
|
lints.each { |lint| yield lint, self }
|
31
32
|
end
|
32
33
|
|
@@ -67,14 +68,12 @@ module ROM
|
|
67
68
|
# Hook method executed before each lint method run
|
68
69
|
#
|
69
70
|
# @api private
|
70
|
-
def before_lint
|
71
|
-
end
|
71
|
+
def before_lint; end
|
72
72
|
|
73
73
|
# Hook method executed after each lint method run
|
74
74
|
#
|
75
75
|
# @api private
|
76
|
-
def after_lint
|
77
|
-
end
|
76
|
+
def after_lint; end
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
data/lib/rom/lint/spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'rom/lint/gateway'
|
4
4
|
require 'rom/lint/enumerable_dataset'
|
5
5
|
|
6
|
-
RSpec.shared_examples
|
6
|
+
RSpec.shared_examples 'a rom gateway' do
|
7
7
|
ROM::Lint::Gateway.each_lint do |name, linter|
|
8
8
|
it name do
|
9
9
|
result = linter.new(identifier, gateway, uri).lint(name)
|
@@ -12,7 +12,7 @@ RSpec.shared_examples "a rom gateway" do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
RSpec.shared_examples
|
15
|
+
RSpec.shared_examples 'a rom enumerable dataset' do
|
16
16
|
ROM::Lint::EnumerableDataset.each_lint do |name, linter|
|
17
17
|
it name do
|
18
18
|
result = linter.new(dataset, data).lint(name)
|
data/lib/rom/mapper.rb
CHANGED
@@ -12,11 +12,11 @@ module ROM
|
|
12
12
|
include Dry::Equalizer(:transformers, :header)
|
13
13
|
|
14
14
|
defines :relation, :register_as, :symbolize_keys, :copy_keys,
|
15
|
-
|
15
|
+
:prefix, :prefix_separator, :inherit_header, :reject_keys
|
16
16
|
|
17
17
|
inherit_header true
|
18
18
|
reject_keys false
|
19
|
-
prefix_separator '_'
|
19
|
+
prefix_separator '_'
|
20
20
|
|
21
21
|
# @return [Object] transformers object built by a processor
|
22
22
|
#
|
@@ -53,7 +53,8 @@ module ROM
|
|
53
53
|
def self.headers(header)
|
54
54
|
return [header] if steps.empty?
|
55
55
|
return steps.map(&:header) if attributes.empty?
|
56
|
-
|
56
|
+
|
57
|
+
raise(MapperMisconfiguredError, 'cannot mix outer attributes and steps')
|
57
58
|
end
|
58
59
|
|
59
60
|
# Build a mapper using provided processor type
|
@@ -78,8 +78,10 @@ module ROM
|
|
78
78
|
# @api public
|
79
79
|
def attribute(name, options = EMPTY_HASH, &block)
|
80
80
|
with_attr_options(name, options) do |attr_options|
|
81
|
-
|
82
|
-
|
81
|
+
if options[:type] && block
|
82
|
+
raise ArgumentError,
|
83
|
+
"can't specify type and block at the same time"
|
84
|
+
end
|
83
85
|
attr_options[:coercer] = block if block
|
84
86
|
add_attribute(name, attr_options)
|
85
87
|
end
|
@@ -370,9 +372,7 @@ module ROM
|
|
370
372
|
attr_options[:from] = attr_options[:from].to_sym if name.is_a? Symbol
|
371
373
|
end
|
372
374
|
|
373
|
-
if symbolize_keys
|
374
|
-
attr_options.update(from: attr_options.fetch(:from) { name }.to_s)
|
375
|
-
end
|
375
|
+
attr_options.update(from: attr_options.fetch(:from) { name }.to_s) if symbolize_keys
|
376
376
|
|
377
377
|
yield(attr_options)
|
378
378
|
end
|
data/lib/rom/mapper/dsl.rb
CHANGED
@@ -49,11 +49,7 @@ module ROM
|
|
49
49
|
#
|
50
50
|
# @api private
|
51
51
|
def base_relation
|
52
|
-
|
53
|
-
superclass.relation
|
54
|
-
else
|
55
|
-
relation
|
56
|
-
end
|
52
|
+
superclass.relation || relation
|
57
53
|
end
|
58
54
|
|
59
55
|
# Return header of the mapper
|
@@ -117,6 +113,7 @@ module ROM
|
|
117
113
|
super
|
118
114
|
end
|
119
115
|
end
|
116
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
120
117
|
end
|
121
118
|
end
|
122
119
|
end
|
data/lib/rom/mapper/model_dsl.rb
CHANGED
@@ -50,10 +50,11 @@ module ROM
|
|
50
50
|
# @api private
|
51
51
|
def build_class
|
52
52
|
return klass if klass
|
53
|
+
|
53
54
|
included_attrs = attributes.reject do |_name, opts|
|
54
55
|
opts && opts[:exclude]
|
55
56
|
end
|
56
|
-
builder
|
57
|
+
builder&.call(included_attrs.map(&:first))
|
57
58
|
end
|
58
59
|
end
|
59
60
|
end
|
data/lib/rom/mapper_compiler.rb
CHANGED
@@ -25,12 +25,13 @@ module ROM
|
|
25
25
|
|
26
26
|
attr_reader :mapper_options
|
27
27
|
|
28
|
-
def initialize(*
|
28
|
+
def initialize(*)
|
29
29
|
super
|
30
30
|
@struct_compiler = StructCompiler.new(cache: cache)
|
31
31
|
@cache = cache.namespaced(:mappers)
|
32
32
|
@mapper_options = self.class.mapper_options
|
33
33
|
end
|
34
|
+
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
34
35
|
|
35
36
|
def call(ast)
|
36
37
|
cache.fetch_or_store(ast.hash) { Mapper.build(Header.coerce(*visit(ast))) }
|
data/lib/rom/mapper_registry.rb
CHANGED
@@ -14,9 +14,9 @@ module ROM
|
|
14
14
|
|
15
15
|
# @!attribute [r] compiler
|
16
16
|
# @return [MapperCompiler] A mapper compiler instance
|
17
|
-
option :compiler, default:
|
18
|
-
MapperCompiler.new(cache: cache)
|
19
|
-
|
17
|
+
option :compiler, default: lambda {
|
18
|
+
MapperCompiler.new(EMPTY_HASH, cache: cache)
|
19
|
+
}
|
20
20
|
|
21
21
|
# @see Registry
|
22
22
|
# @api public
|
data/lib/rom/memory/dataset.rb
CHANGED
@@ -31,7 +31,7 @@ module ROM
|
|
31
31
|
join_map[tuple].map { |other| tuple.merge(other) }
|
32
32
|
}
|
33
33
|
|
34
|
-
self.class.new(tuples, options)
|
34
|
+
self.class.new(tuples, **options)
|
35
35
|
end
|
36
36
|
|
37
37
|
# Restrict a dataset
|
@@ -63,7 +63,7 @@ module ROM
|
|
63
63
|
#
|
64
64
|
# @api public
|
65
65
|
def project(*names)
|
66
|
-
map { |tuple| tuple.
|
66
|
+
map { |tuple| tuple.select { |key| names.include?(key) } }
|
67
67
|
end
|
68
68
|
|
69
69
|
# Sort a dataset
|
@@ -119,7 +119,8 @@ module ROM
|
|
119
119
|
# @api private
|
120
120
|
def __compare__(a, b, nils_first)
|
121
121
|
return a <=> b unless a.nil? ^ b.nil?
|
122
|
-
|
122
|
+
|
123
|
+
nils_first ^ b.nil? ? -1 : 1
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
data/lib/rom/pipeline.rb
CHANGED
@@ -75,13 +75,15 @@ module ROM
|
|
75
75
|
super
|
76
76
|
end
|
77
77
|
end
|
78
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
78
79
|
end
|
79
80
|
|
80
81
|
# Base composite class with left-to-right pipeline behavior
|
81
82
|
#
|
82
83
|
# @api private
|
83
84
|
class Composite
|
84
|
-
(Kernel.private_instance_methods - %i
|
85
|
+
(Kernel.private_instance_methods - %i[respond_to_missing? block_given?])
|
86
|
+
.each(&method(:undef_method))
|
85
87
|
|
86
88
|
include Dry::Equalizer(:left, :right)
|
87
89
|
include Proxy
|
data/lib/rom/plugin.rb
CHANGED
@@ -32,11 +32,11 @@ module ROM
|
|
32
32
|
# @param [Class,Object] target
|
33
33
|
#
|
34
34
|
# @api private
|
35
|
-
def apply_to(target, options
|
35
|
+
def apply_to(target, **options)
|
36
36
|
if mod.respond_to?(:apply)
|
37
|
-
mod.apply(target, options)
|
37
|
+
mod.apply(target, **options)
|
38
38
|
elsif mod.respond_to?(:new)
|
39
|
-
target.include(mod.new(options))
|
39
|
+
target.include(mod.new(**options))
|
40
40
|
elsif target.is_a?(::Module)
|
41
41
|
target.include(mod)
|
42
42
|
end
|
data/lib/rom/plugin_registry.rb
CHANGED
@@ -21,7 +21,7 @@ module ROM
|
|
21
21
|
# @return [Command]
|
22
22
|
#
|
23
23
|
# @api public
|
24
|
-
def build(relation, options
|
24
|
+
def build(relation, **options)
|
25
25
|
if options.key?(:input) || !relation.schema?
|
26
26
|
super
|
27
27
|
else
|
@@ -34,7 +34,7 @@ module ROM
|
|
34
34
|
relation.input_schema
|
35
35
|
end
|
36
36
|
|
37
|
-
super(relation, options
|
37
|
+
super(relation, **options, input: input_handler)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -10,14 +10,14 @@ module ROM
|
|
10
10
|
# For now this plugin is always enabled
|
11
11
|
#
|
12
12
|
# @api public
|
13
|
-
class RegistryReader < Module
|
14
|
-
EMPTY_REGISTRY = RelationRegistry.
|
13
|
+
class RegistryReader < ::Module
|
14
|
+
EMPTY_REGISTRY = RelationRegistry.build(EMPTY_HASH).freeze
|
15
15
|
|
16
16
|
# @api private
|
17
17
|
attr_reader :relations
|
18
18
|
|
19
19
|
# @api private
|
20
|
-
def initialize(relations)
|
20
|
+
def initialize(relations:)
|
21
21
|
@relations = relations
|
22
22
|
define_readers!
|
23
23
|
end
|
@@ -26,6 +26,7 @@ module ROM
|
|
26
26
|
def included(klass)
|
27
27
|
super
|
28
28
|
return if klass.instance_methods.include?(:__registry__)
|
29
|
+
|
29
30
|
klass.option :__registry__, default: -> { EMPTY_REGISTRY }
|
30
31
|
end
|
31
32
|
|
@@ -23,13 +23,11 @@ module ROM
|
|
23
23
|
#
|
24
24
|
# @api public
|
25
25
|
module Timestamps
|
26
|
-
DEFAULT_TIMESTAMPS = %i
|
26
|
+
DEFAULT_TIMESTAMPS = %i[created_at updated_at].freeze
|
27
27
|
|
28
28
|
# @api private
|
29
|
-
def self.apply(schema,
|
30
|
-
|
31
|
-
names = options.fetch(:attributes, DEFAULT_TIMESTAMPS)
|
32
|
-
attributes = names.map do |name|
|
29
|
+
def self.apply(schema, type: Types::Time, attributes: DEFAULT_TIMESTAMPS)
|
30
|
+
attrs = attributes.map do |name|
|
33
31
|
ROM::Schema.build_attribute_info(
|
34
32
|
type.meta(source: schema.name),
|
35
33
|
name: name
|
@@ -37,7 +35,7 @@ module ROM
|
|
37
35
|
end
|
38
36
|
|
39
37
|
schema.attributes.concat(
|
40
|
-
schema.class.attributes(
|
38
|
+
schema.class.attributes(attrs, schema.attr_class)
|
41
39
|
)
|
42
40
|
end
|
43
41
|
|
data/lib/rom/processor.rb
CHANGED
@@ -24,11 +24,8 @@ module ROM
|
|
24
24
|
import ::Transproc::HashTransformations
|
25
25
|
import ::Transproc::ClassTransformations
|
26
26
|
import ::Transproc::ProcTransformations
|
27
|
-
INVALID_INJECT_UNION_VALUE = "%s attribute: block is required for :from with union value.".freeze
|
28
27
|
|
29
|
-
|
30
|
-
tuple
|
31
|
-
end
|
28
|
+
INVALID_INJECT_UNION_VALUE = '%s attribute: block is required for :from with union value.'
|
32
29
|
|
33
30
|
def self.get(arr, idx)
|
34
31
|
arr[idx]
|
@@ -39,7 +36,7 @@ module ROM
|
|
39
36
|
end
|
40
37
|
|
41
38
|
def self.inject_union_value(tuple, name, keys, coercer)
|
42
|
-
raise ROM::MapperMisconfiguredError, INVALID_INJECT_UNION_VALUE % [name]
|
39
|
+
raise ROM::MapperMisconfiguredError, INVALID_INJECT_UNION_VALUE % [name] unless coercer
|
43
40
|
|
44
41
|
values = tuple.values_at(*keys)
|
45
42
|
result = coercer.call(*values)
|
@@ -315,22 +312,22 @@ module ROM
|
|
315
312
|
#
|
316
313
|
# @api private
|
317
314
|
def visit_unfold(attribute, preprocess = false)
|
318
|
-
|
319
|
-
name = attribute.name
|
320
|
-
header = attribute.header
|
321
|
-
keys = attribute.pop_keys
|
322
|
-
key = keys.first
|
315
|
+
return unless preprocess
|
323
316
|
|
324
|
-
|
317
|
+
name = attribute.name
|
318
|
+
header = attribute.header
|
319
|
+
keys = attribute.pop_keys
|
320
|
+
key = keys.first
|
325
321
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
322
|
+
others = header.postprocessed
|
323
|
+
|
324
|
+
compose do |ops|
|
325
|
+
ops << others.map { |attr|
|
326
|
+
t(:map_array, t(:map_value, name, visit(attr, true)))
|
327
|
+
}
|
328
|
+
ops << t(:map_array, t(:map_value, name, t(:insert_key, key)))
|
329
|
+
ops << t(:map_array, t(:reject_keys, [key] - [name]))
|
330
|
+
ops << t(:ungroup, name, [key])
|
334
331
|
end
|
335
332
|
end
|
336
333
|
|
data/lib/rom/registry.rb
CHANGED
@@ -26,21 +26,25 @@ module ROM
|
|
26
26
|
option :cache, default: -> { Cache.new }
|
27
27
|
|
28
28
|
# @api private
|
29
|
-
def self.new(*args)
|
30
|
-
|
31
|
-
|
32
|
-
super({}, {})
|
33
|
-
when 1
|
34
|
-
super(*args, {})
|
29
|
+
def self.new(*args, **kwargs)
|
30
|
+
if args.empty? && kwargs.empty?
|
31
|
+
super({}, **{})
|
35
32
|
else
|
36
|
-
super
|
33
|
+
super
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
37
|
+
# Create a registry without options
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def self.build(elements = {})
|
41
|
+
new(elements, **{})
|
42
|
+
end
|
43
|
+
|
40
44
|
# @api private
|
41
45
|
def self.[](identifier)
|
42
46
|
fetch_or_store(identifier) do
|
43
|
-
Dry::Core::ClassBuilder
|
47
|
+
::Dry::Core::ClassBuilder
|
44
48
|
.new(parent: self, name: "#{name}[:#{identifier}]")
|
45
49
|
.call
|
46
50
|
end
|
@@ -53,7 +57,7 @@ module ROM
|
|
53
57
|
|
54
58
|
# @api private
|
55
59
|
def merge(other)
|
56
|
-
self.class.new(Hash(other), options)
|
60
|
+
self.class.new(Hash(other), **options)
|
57
61
|
end
|
58
62
|
|
59
63
|
# @api private
|
@@ -62,16 +66,17 @@ module ROM
|
|
62
66
|
end
|
63
67
|
|
64
68
|
# @api private
|
65
|
-
def map
|
69
|
+
def map
|
66
70
|
new_elements = elements.each_with_object({}) do |(name, element), h|
|
67
71
|
h[name] = yield(element)
|
68
72
|
end
|
69
|
-
self.class.new(new_elements, options)
|
73
|
+
self.class.new(new_elements, **options)
|
70
74
|
end
|
71
75
|
|
72
76
|
# @api private
|
73
77
|
def each
|
74
78
|
return to_enum unless block_given?
|
79
|
+
|
75
80
|
elements.each { |element| yield(element) }
|
76
81
|
end
|
77
82
|
|
@@ -82,7 +87,7 @@ module ROM
|
|
82
87
|
|
83
88
|
# @api private
|
84
89
|
def fetch(key)
|
85
|
-
raise ArgumentError
|
90
|
+
raise ArgumentError, 'key cannot be nil' if key.nil?
|
86
91
|
|
87
92
|
elements.fetch(key.to_sym) do
|
88
93
|
return yield if block_given?
|