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.
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?