rom-core 5.1.2 → 5.2.1

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rom/array_dataset.rb +4 -4
  3. data/lib/rom/association_set.rb +2 -3
  4. data/lib/rom/associations/definitions/abstract.rb +2 -2
  5. data/lib/rom/associations/many_to_many.rb +1 -0
  6. data/lib/rom/attribute.rb +5 -4
  7. data/lib/rom/auto_curry.rb +2 -0
  8. data/lib/rom/command.rb +6 -6
  9. data/lib/rom/command_compiler.rb +5 -7
  10. data/lib/rom/commands/class_interface.rb +7 -7
  11. data/lib/rom/commands/composite.rb +1 -1
  12. data/lib/rom/commands/graph/input_evaluator.rb +1 -1
  13. data/lib/rom/commands/lazy.rb +2 -1
  14. data/lib/rom/commands/lazy/create.rb +1 -1
  15. data/lib/rom/commands/lazy/update.rb +3 -3
  16. data/lib/rom/configuration.rb +5 -5
  17. data/lib/rom/configuration_dsl/relation.rb +1 -1
  18. data/lib/rom/constants.rb +1 -1
  19. data/lib/rom/core/version.rb +1 -1
  20. data/lib/rom/data_proxy.rb +3 -2
  21. data/lib/rom/enumerable_dataset.rb +4 -4
  22. data/lib/rom/environment.rb +0 -1
  23. data/lib/rom/header/attribute.rb +2 -4
  24. data/lib/rom/initializer.rb +9 -7
  25. data/lib/rom/lint/gateway.rb +1 -3
  26. data/lib/rom/lint/linter.rb +3 -4
  27. data/lib/rom/lint/spec.rb +2 -2
  28. data/lib/rom/mapper.rb +4 -3
  29. data/lib/rom/mapper/attribute_dsl.rb +5 -5
  30. data/lib/rom/mapper/dsl.rb +2 -5
  31. data/lib/rom/mapper/model_dsl.rb +2 -1
  32. data/lib/rom/mapper_compiler.rb +2 -1
  33. data/lib/rom/mapper_registry.rb +3 -3
  34. data/lib/rom/memory/dataset.rb +4 -3
  35. data/lib/rom/pipeline.rb +3 -1
  36. data/lib/rom/plugin.rb +3 -3
  37. data/lib/rom/plugin_registry.rb +1 -1
  38. data/lib/rom/plugins/command/schema.rb +2 -2
  39. data/lib/rom/plugins/relation/instrumentation.rb +1 -1
  40. data/lib/rom/plugins/relation/registry_reader.rb +4 -3
  41. data/lib/rom/plugins/schema/timestamps.rb +4 -6
  42. data/lib/rom/processor.rb +1 -1
  43. data/lib/rom/processor/transproc.rb +16 -19
  44. data/lib/rom/registry.rb +17 -12
  45. data/lib/rom/relation.rb +6 -6
  46. data/lib/rom/relation/class_interface.rb +9 -8
  47. data/lib/rom/relation/curried.rb +3 -2
  48. data/lib/rom/relation/loaded.rb +1 -0
  49. data/lib/rom/relation/materializable.rb +1 -0
  50. data/lib/rom/relation/name.rb +1 -1
  51. data/lib/rom/relation_registry.rb +1 -1
  52. data/lib/rom/schema.rb +22 -22
  53. data/lib/rom/schema/associations_dsl.rb +17 -17
  54. data/lib/rom/schema/dsl.rb +6 -6
  55. data/lib/rom/schema/inferrer.rb +2 -4
  56. data/lib/rom/setup.rb +2 -2
  57. data/lib/rom/setup/auto_registration.rb +1 -1
  58. data/lib/rom/setup/auto_registration_strategies/base.rb +1 -1
  59. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -4
  60. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +1 -1
  61. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +1 -1
  62. data/lib/rom/setup/finalize/finalize_commands.rb +7 -4
  63. data/lib/rom/setup/finalize/finalize_mappers.rb +9 -8
  64. data/lib/rom/setup/finalize/finalize_relations.rb +2 -2
  65. data/lib/rom/struct.rb +1 -1
  66. data/lib/rom/struct_compiler.rb +6 -5
  67. data/lib/rom/support/memoizable.rb +3 -2
  68. data/lib/rom/transaction.rb +1 -1
  69. data/lib/rom/transformer.rb +1 -0
  70. metadata +3 -3
@@ -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
- definitions.
26
- reject { |_, d| d.option }.
27
- keys.
28
- join(', ')
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 = EMPTY_HASH)
37
+ def with(**new_options)
36
38
  if new_options.empty?
37
39
  self
38
40
  else
39
- self.class.new(#{ seq_names }options.merge(new_options))
41
+ self.class.new(#{seq_names}**options, **new_options)
40
42
  end
41
43
  end
42
44
  RUBY
@@ -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!
@@ -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
@@ -3,7 +3,7 @@
3
3
  require 'rom/lint/gateway'
4
4
  require 'rom/lint/enumerable_dataset'
5
5
 
6
- RSpec.shared_examples "a rom gateway" do
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 "a rom enumerable dataset" do
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)
@@ -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
- :prefix, :prefix_separator, :inherit_header, :reject_keys
15
+ :prefix, :prefix_separator, :inherit_header, :reject_keys
16
16
 
17
17
  inherit_header true
18
18
  reject_keys false
19
- prefix_separator '_'.freeze
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
- raise(MapperMisconfiguredError, "cannot mix outer attributes and steps")
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
- raise ArgumentError,
82
- "can't specify type and block at the same time" if options[:type] && block
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
@@ -49,11 +49,7 @@ module ROM
49
49
  #
50
50
  # @api private
51
51
  def base_relation
52
- if superclass.relation
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
@@ -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.call(included_attrs.map(&:first)) if builder
57
+ builder&.call(included_attrs.map(&:first))
57
58
  end
58
59
  end
59
60
  end
@@ -25,12 +25,13 @@ module ROM
25
25
 
26
26
  attr_reader :mapper_options
27
27
 
28
- def initialize(*args)
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))) }
@@ -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: -> do
18
- MapperCompiler.new(cache: cache)
19
- end
17
+ option :compiler, default: lambda {
18
+ MapperCompiler.new(EMPTY_HASH, cache: cache)
19
+ }
20
20
 
21
21
  # @see Registry
22
22
  # @api public
@@ -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.reject { |key| !names.include?(key) } }
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
- (nils_first ^ b.nil?) ? -1 : 1
122
+
123
+ nils_first ^ b.nil? ? -1 : 1
123
124
  end
124
125
  end
125
126
  end
@@ -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(respond_to_missing? block_given?)).each(&method(:undef_method))
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
@@ -32,11 +32,11 @@ module ROM
32
32
  # @param [Class,Object] target
33
33
  #
34
34
  # @api private
35
- def apply_to(target, options = EMPTY_HASH)
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
@@ -78,7 +78,7 @@ module ROM
78
78
  #
79
79
  # @api private
80
80
  def register(name, mod, options)
81
- elements[name] = plugin_type.new(name, mod, options)
81
+ elements[name] = plugin_type.new(name, mod, **options)
82
82
  end
83
83
 
84
84
  # @api private
@@ -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.merge(input: input_handler))
37
+ super(relation, **options, input: input_handler)
38
38
  end
39
39
  end
40
40
  end
@@ -54,7 +54,7 @@ module ROM
54
54
  private
55
55
 
56
56
  # @api private
57
- def notification_payload(relation)
57
+ def notification_payload(_relation)
58
58
  EMPTY_HASH
59
59
  end
60
60
  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.new(EMPTY_HASH).freeze
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(created_at updated_at).freeze
26
+ DEFAULT_TIMESTAMPS = %i[created_at updated_at].freeze
27
27
 
28
28
  # @api private
29
- def self.apply(schema, options)
30
- type = options.fetch(:type, Types::Time)
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(attributes, schema.attr_class)
38
+ schema.class.attributes(attrs, schema.attr_class)
41
39
  )
42
40
  end
43
41
 
@@ -24,7 +24,7 @@ module ROM
24
24
  #
25
25
  # @api private
26
26
  def self.build
27
- raise NotImplementedError, "+build+ must be implemented"
27
+ raise NotImplementedError, '+build+ must be implemented'
28
28
  end
29
29
  end
30
30
  end
@@ -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
- def self.identity(tuple)
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] if !coercer
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
- if preprocess
319
- name = attribute.name
320
- header = attribute.header
321
- keys = attribute.pop_keys
322
- key = keys.first
315
+ return unless preprocess
323
316
 
324
- others = header.postprocessed
317
+ name = attribute.name
318
+ header = attribute.header
319
+ keys = attribute.pop_keys
320
+ key = keys.first
325
321
 
326
- compose do |ops|
327
- ops << others.map { |attr|
328
- t(:map_array, t(:map_value, name, visit(attr, true)))
329
- }
330
- ops << t(:map_array, t(:map_value, name, t(:insert_key, key)))
331
- ops << t(:map_array, t(:reject_keys, [key] - [name]))
332
- ops << t(:ungroup, name, [key])
333
- end
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
 
@@ -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
- case args.size
31
- when 0
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(*args)
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(&block)
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.new('key cannot be nil') if key.nil?
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?