rom-core 5.3.1 → 5.4.0

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rom/array_dataset.rb +5 -5
  3. data/lib/rom/association_set.rb +1 -2
  4. data/lib/rom/associations/definitions/abstract.rb +5 -3
  5. data/lib/rom/associations/many_to_many.rb +1 -2
  6. data/lib/rom/attribute.rb +15 -37
  7. data/lib/rom/auto_curry.rb +34 -23
  8. data/lib/rom/cache.rb +9 -21
  9. data/lib/rom/command.rb +19 -37
  10. data/lib/rom/command_compiler.rb +12 -14
  11. data/lib/rom/command_proxy.rb +6 -10
  12. data/lib/rom/command_registry.rb +4 -8
  13. data/lib/rom/commands/class_interface.rb +20 -20
  14. data/lib/rom/commands/composite.rb +3 -0
  15. data/lib/rom/commands/graph/class_interface.rb +3 -1
  16. data/lib/rom/commands/graph/input_evaluator.rb +3 -1
  17. data/lib/rom/commands/graph.rb +3 -0
  18. data/lib/rom/commands/lazy/create.rb +2 -0
  19. data/lib/rom/commands/lazy/update.rb +2 -0
  20. data/lib/rom/commands/lazy.rb +2 -3
  21. data/lib/rom/configuration.rb +14 -16
  22. data/lib/rom/configuration_dsl/command.rb +2 -2
  23. data/lib/rom/configuration_dsl/command_dsl.rb +9 -5
  24. data/lib/rom/configuration_dsl/mapper_dsl.rb +12 -3
  25. data/lib/rom/configuration_dsl/relation.rb +4 -2
  26. data/lib/rom/configuration_dsl.rb +8 -10
  27. data/lib/rom/constants.rb +26 -26
  28. data/lib/rom/container.rb +15 -15
  29. data/lib/rom/core/version.rb +1 -1
  30. data/lib/rom/core.rb +0 -1
  31. data/lib/rom/create_container.rb +3 -5
  32. data/lib/rom/data_proxy.rb +13 -15
  33. data/lib/rom/enumerable_dataset.rb +6 -6
  34. data/lib/rom/environment.rb +5 -5
  35. data/lib/rom/gateway.rb +4 -12
  36. data/lib/rom/global/plugin_dsl.rb +4 -4
  37. data/lib/rom/global.rb +2 -2
  38. data/lib/rom/header/attribute.rb +1 -1
  39. data/lib/rom/header.rb +13 -35
  40. data/lib/rom/initializer.rb +11 -15
  41. data/lib/rom/lint/enumerable_dataset.rb +2 -1
  42. data/lib/rom/lint/gateway.rb +3 -1
  43. data/lib/rom/lint/linter.rb +2 -2
  44. data/lib/rom/lint/test.rb +4 -6
  45. data/lib/rom/mapper/attribute_dsl.rb +39 -27
  46. data/lib/rom/mapper/builder.rb +2 -2
  47. data/lib/rom/mapper/dsl.rb +2 -3
  48. data/lib/rom/mapper/model_dsl.rb +5 -1
  49. data/lib/rom/mapper.rb +2 -4
  50. data/lib/rom/mapper_compiler.rb +3 -2
  51. data/lib/rom/mapper_registry.rb +2 -4
  52. data/lib/rom/memory/commands.rb +1 -1
  53. data/lib/rom/memory/dataset.rb +7 -5
  54. data/lib/rom/memory/gateway.rb +1 -0
  55. data/lib/rom/model_builder.rb +14 -14
  56. data/lib/rom/open_struct.rb +1 -1
  57. data/lib/rom/pipeline.rb +17 -20
  58. data/lib/rom/plugin_registry.rb +4 -10
  59. data/lib/rom/plugins/command/timestamps.rb +9 -5
  60. data/lib/rom/plugins/relation/instrumentation.rb +7 -2
  61. data/lib/rom/plugins/relation/registry_reader.rb +3 -15
  62. data/lib/rom/plugins.rb +1 -3
  63. data/lib/rom/processor/transproc.rb +14 -4
  64. data/lib/rom/processor.rb +1 -0
  65. data/lib/rom/registry.rb +20 -29
  66. data/lib/rom/relation/class_interface.rb +18 -16
  67. data/lib/rom/relation/combined.rb +7 -4
  68. data/lib/rom/relation/composite.rb +2 -6
  69. data/lib/rom/relation/curried.rb +12 -11
  70. data/lib/rom/relation/graph.rb +4 -12
  71. data/lib/rom/relation/loaded.rb +8 -16
  72. data/lib/rom/relation/materializable.rb +6 -14
  73. data/lib/rom/relation/name.rb +5 -14
  74. data/lib/rom/relation/view_dsl.rb +7 -9
  75. data/lib/rom/relation/wrap.rb +3 -9
  76. data/lib/rom/relation.rb +39 -81
  77. data/lib/rom/schema/associations_dsl.rb +4 -8
  78. data/lib/rom/schema/dsl.rb +14 -13
  79. data/lib/rom/schema/inferrer.rb +5 -3
  80. data/lib/rom/schema.rb +27 -41
  81. data/lib/rom/setup/auto_registration.rb +4 -6
  82. data/lib/rom/setup/auto_registration_strategies/base.rb +1 -1
  83. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +4 -8
  84. data/lib/rom/setup/finalize/finalize_commands.rb +3 -0
  85. data/lib/rom/setup/finalize/finalize_mappers.rb +16 -14
  86. data/lib/rom/setup/finalize/finalize_relations.rb +30 -4
  87. data/lib/rom/setup/finalize.rb +17 -3
  88. data/lib/rom/setup.rb +5 -4
  89. data/lib/rom/struct.rb +20 -18
  90. data/lib/rom/struct_compiler.rb +4 -7
  91. data/lib/rom/support/configurable.rb +10 -20
  92. data/lib/rom/support/memoizable.rb +10 -9
  93. data/lib/rom/support/notifications.rb +4 -8
  94. data/lib/rom/transaction.rb +2 -4
  95. data/lib/rom/transformer.rb +6 -10
  96. data/lib/rom/types.rb +3 -6
  97. metadata +15 -57
@@ -15,6 +15,7 @@ module ROM
15
15
  # Global class-level API for relation classes
16
16
  #
17
17
  # @api public
18
+ # rubocop:disable Metrics/ModuleLength
18
19
  module ClassInterface
19
20
  extend Notifications::Listener
20
21
 
@@ -91,10 +92,11 @@ module ROM
91
92
  # @param [Boolean] infer Whether to do an automatic schema inferring
92
93
  #
93
94
  # @api public
94
- def schema(dataset = nil, as: nil, infer: false, &block)
95
- if defined?(@schema) && !block && !infer
95
+ # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
96
+ def schema(dataset = nil, as: nil, infer: false, &)
97
+ if defined?(@schema) && !block_given? && !infer
96
98
  @schema
97
- elsif block || infer
99
+ elsif block_given? || infer
98
100
  raise MissingSchemaClassError, self unless schema_class
99
101
 
100
102
  ds_name = dataset || schema_opts.fetch(:dataset, default_name.dataset)
@@ -110,11 +112,12 @@ module ROM
110
112
  schema_class: schema_class,
111
113
  attr_class: schema_attr_class,
112
114
  inferrer: schema_inferrer.with(enabled: infer),
113
- &block
115
+ &
114
116
  ).call(*args, &inner_block)
115
117
  end
116
118
  end
117
119
  end
120
+ # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
118
121
 
119
122
  # Assign a schema to a relation class
120
123
  #
@@ -187,8 +190,9 @@ module ROM
187
190
  # @return [Symbol] view method name
188
191
  #
189
192
  # @api public
193
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
190
194
  def view(*args, &block)
191
- if args.size == 1 && block.arity > 0
195
+ if args.size == 1 && block.arity.positive?
192
196
  raise ArgumentError, 'schema attribute names must be provided as the second argument'
193
197
  end
194
198
 
@@ -206,7 +210,7 @@ module ROM
206
210
  new_schema_fn
207
211
  end
208
212
 
209
- if relation_block.arity > 0
213
+ if relation_block.arity.positive?
210
214
  auto_curry_guard do
211
215
  define_method(name, &relation_block)
212
216
 
@@ -222,6 +226,7 @@ module ROM
222
226
 
223
227
  name
224
228
  end
229
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
225
230
 
226
231
  # Dynamically define a method that will forward to the dataset and wrap
227
232
  # response in the relation itself
@@ -234,10 +239,10 @@ module ROM
234
239
  # @api public
235
240
  def forward(*methods)
236
241
  methods.each do |method|
237
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
238
- def #{method}(*args, &block)
239
- new(dataset.__send__(:#{method}, *args, &block))
240
- end
242
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
243
+ def #{method}(...) # def super_query(...)
244
+ new(dataset.__send__(:#{method}, ...)) # new(dataset.__send__(:super_query, ...))
245
+ end # end
241
246
  RUBY
242
247
  end
243
248
  end
@@ -272,9 +277,7 @@ module ROM
272
277
  end
273
278
 
274
279
  # @api private
275
- def curried
276
- Curried
277
- end
280
+ def curried = Curried
278
281
 
279
282
  # @api private
280
283
  def view_methods
@@ -309,9 +312,7 @@ module ROM
309
312
  end
310
313
 
311
314
  # @api private
312
- def name
313
- super || superclass.name
314
- end
315
+ def name = super || superclass.name
315
316
 
316
317
  private
317
318
 
@@ -319,5 +320,6 @@ module ROM
319
320
  INVALID_RELATIONS_NAMES.include?(relation.to_sym)
320
321
  end
321
322
  end
323
+ # rubocop:enable Metrics/ModuleLength
322
324
  end
323
325
  end
@@ -95,7 +95,8 @@ module ROM
95
95
  # @return [Relation]
96
96
  #
97
97
  # @api public
98
- def node(name, &block)
98
+ # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
99
+ def node(name, &)
99
100
  if name.is_a?(Symbol) && !nodes.map { |n| n.name.key }.include?(name)
100
101
  raise ArgumentError, "#{name.inspect} is not a valid aggregate node name"
101
102
  end
@@ -107,7 +108,7 @@ module ROM
107
108
  when Hash
108
109
  other, *rest = name.flatten(1)
109
110
  if other == node.name.key
110
- nodes.detect { |n| n.name.key == other }.node(*rest, &block)
111
+ nodes.detect { |n| n.name.key == other }.node(*rest, &)
111
112
  else
112
113
  node
113
114
  end
@@ -118,6 +119,7 @@ module ROM
118
119
 
119
120
  with_nodes(new_nodes)
120
121
  end
122
+ # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
121
123
 
122
124
  # Return a `:create` command that can insert data from a nested hash.
123
125
  #
@@ -140,11 +142,12 @@ module ROM
140
142
  # @raise NotImplementedError when type is not `:create`
141
143
  #
142
144
  # @api public
143
- def command(type, *args)
145
+ def command(type, **)
144
146
  if type == :create
145
147
  super
146
148
  else
147
- raise NotImplementedError, "#{self.class}#command doesn't work with #{type.inspect} command type yet"
149
+ raise NotImplementedError,
150
+ "#{self.class}#command doesn't work with #{type.inspect} command type yet"
148
151
  end
149
152
  end
150
153
 
@@ -34,9 +34,7 @@ module ROM
34
34
  # @see Relation#map_to
35
35
  #
36
36
  # @api public
37
- def map_to(klass)
38
- self >> left.map_to(klass).mapper
39
- end
37
+ def map_to(klass) = self >> left.map_to(klass).mapper
40
38
 
41
39
  private
42
40
 
@@ -45,9 +43,7 @@ module ROM
45
43
  # @see Pipeline::Proxy#decorate?
46
44
  #
47
45
  # @api private
48
- def decorate?(response)
49
- super || response.is_a?(Graph)
50
- end
46
+ def decorate?(response) = super || response.is_a?(Graph)
51
47
  end
52
48
  end
53
49
  end
@@ -5,6 +5,9 @@ require 'rom/initializer'
5
5
  require 'rom/pipeline'
6
6
  require 'rom/relation/name'
7
7
  require 'rom/relation/materializable'
8
+ require 'rom/relation/graph'
9
+ require 'rom/relation/wrap'
10
+ require 'rom/relation/composite'
8
11
 
9
12
  module ROM
10
13
  class Relation
@@ -19,6 +22,8 @@ module ROM
19
22
  class Curried
20
23
  extend Initializer
21
24
 
25
+ WRAPS = [Relation, Graph, Wrap, Composite].freeze
26
+
22
27
  include Dry::Equalizer(:relation, :options)
23
28
  include Materializable
24
29
  include Pipeline
@@ -50,7 +55,8 @@ module ROM
50
55
  all_args = curry_args + args
51
56
 
52
57
  if all_args.empty?
53
- raise ArgumentError, "curried #{relation.class}##{view} relation was called without any arguments"
58
+ raise ArgumentError,
59
+ "curried #{relation.class}##{view} relation was called without any arguments"
54
60
  end
55
61
 
56
62
  if args.empty?
@@ -83,9 +89,7 @@ module ROM
83
89
  # @return [true]
84
90
  #
85
91
  # @api private
86
- def curried?
87
- true
88
- end
92
+ def curried? = true
89
93
 
90
94
  # @api private
91
95
  def respond_to_missing?(name, include_private = false)
@@ -100,18 +104,16 @@ module ROM
100
104
  end
101
105
 
102
106
  # @api private
103
- def composite_class
104
- Relation::Composite
105
- end
107
+ def composite_class = Relation::Composite
106
108
 
107
109
  # @api private
108
- def method_missing(meth, *args, &block)
110
+ def method_missing(meth, ...)
109
111
  if relation.respond_to?(meth)
110
- response = relation.__send__(meth, *args, &block)
112
+ response = relation.__send__(meth, ...)
111
113
 
112
114
  super if response.is_a?(self.class)
113
115
 
114
- if response.is_a?(Relation) || response.is_a?(Graph) || response.is_a?(Wrap) || response.is_a?(Composite)
116
+ if WRAPS.any? { |klass| response.is_a?(klass) }
115
117
  __new__(response)
116
118
  else
117
119
  response
@@ -120,7 +122,6 @@ module ROM
120
122
  super
121
123
  end
122
124
  end
123
- ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
124
125
  end
125
126
  end
126
127
  end
@@ -42,18 +42,14 @@ module ROM
42
42
  # @return [Graph]
43
43
  #
44
44
  # @api public
45
- def with_nodes(nodes)
46
- self.class.new(root, nodes)
47
- end
45
+ def with_nodes(nodes) = self.class.new(root, nodes)
48
46
 
49
47
  # Return if this is a graph relation
50
48
  #
51
49
  # @return [true]
52
50
  #
53
51
  # @api private
54
- def graph?
55
- true
56
- end
52
+ def graph? = true
57
53
 
58
54
  # Map graph tuples via custom mappers
59
55
  #
@@ -80,9 +76,7 @@ module ROM
80
76
  # @see Relation#mapper
81
77
  #
82
78
  # @api private
83
- def mapper
84
- mappers[to_ast]
85
- end
79
+ def mapper = mappers[to_ast]
86
80
 
87
81
  # @api private
88
82
  memoize def to_ast
@@ -97,9 +91,7 @@ module ROM
97
91
  end
98
92
 
99
93
  # @api private
100
- def composite_class
101
- Relation::Composite
102
- end
94
+ def composite_class = Relation::Composite
103
95
  end
104
96
  end
105
97
  end
@@ -8,8 +8,8 @@ module ROM
8
8
  #
9
9
  # @api public
10
10
  class Loaded
11
- include Enumerable
12
- include Dry::Equalizer(:source, :collection)
11
+ include ::Enumerable
12
+ include ::Dry::Equalizer(:source, :collection)
13
13
 
14
14
  # Coerce loaded relation to an array
15
15
  #
@@ -43,10 +43,10 @@ module ROM
43
43
  # @yield [Hash]
44
44
  #
45
45
  # @api public
46
- def each
46
+ def each(&)
47
47
  return to_enum unless block_given?
48
48
 
49
- collection.each { |tuple| yield(tuple) }
49
+ collection.each(&)
50
50
  end
51
51
 
52
52
  # Returns a single tuple from the relation if there is one.
@@ -93,9 +93,7 @@ module ROM
93
93
  # @raise KeyError when provided key doesn't exist in any of the tuples
94
94
  #
95
95
  # @api public
96
- def pluck(key)
97
- map { |tuple| tuple.fetch(key) }
98
- end
96
+ def pluck(key) = map { |tuple| tuple.fetch(key) }
99
97
 
100
98
  # Pluck primary key values
101
99
  #
@@ -110,25 +108,19 @@ module ROM
110
108
  # @return [Array]
111
109
  #
112
110
  # @api public
113
- def primary_keys
114
- pluck(source.primary_key)
115
- end
111
+ def primary_keys = pluck(source.primary_key)
116
112
 
117
113
  # Return if loaded relation is empty
118
114
  #
119
115
  # @return [TrueClass,FalseClass]
120
116
  #
121
117
  # @api public
122
- def empty?
123
- collection.empty?
124
- end
118
+ def empty? = collection.empty?
125
119
 
126
120
  # Return a loaded relation with a new collection
127
121
  #
128
122
  # @api public
129
- def new(collection)
130
- self.class.new(source, collection)
131
- end
123
+ def new(collection) = self.class.new(source, collection)
132
124
  end
133
125
  end
134
126
  end
@@ -11,9 +11,7 @@ module ROM
11
11
  # @return [Array]
12
12
  #
13
13
  # @api public
14
- def to_a
15
- call.to_a
16
- end
14
+ def to_a = call.to_a
17
15
  alias_method :to_ary, :to_a
18
16
 
19
17
  # Yield relation tuples
@@ -21,10 +19,10 @@ module ROM
21
19
  # @yield [Hash,Object]
22
20
  #
23
21
  # @api public
24
- def each
22
+ def each(&)
25
23
  return to_enum unless block_given?
26
24
 
27
- to_a.each { |tuple| yield(tuple) }
25
+ to_a.each(&)
28
26
  end
29
27
 
30
28
  # Delegate to loaded relation and return one object
@@ -34,9 +32,7 @@ module ROM
34
32
  # @see Loaded#one
35
33
  #
36
34
  # @api public
37
- def one
38
- call.one
39
- end
35
+ def one = call.one
40
36
 
41
37
  # Delegate to loaded relation and return one object
42
38
  #
@@ -45,18 +41,14 @@ module ROM
45
41
  # @see Loaded#one
46
42
  #
47
43
  # @api public
48
- def one!
49
- call.one!
50
- end
44
+ def one! = call.one!
51
45
 
52
46
  # Return first tuple from a relation coerced to an array
53
47
  #
54
48
  # @return [Object]
55
49
  #
56
50
  # @api public
57
- def first
58
- to_a.first
59
- end
51
+ def first = to_a.first
60
52
  end
61
53
  end
62
54
  end
@@ -15,7 +15,7 @@ module ROM
15
15
  #
16
16
  # @api private
17
17
  class Name
18
- include Dry::Equalizer(:relation, :dataset, :key)
18
+ include ::Dry::Equalizer(:relation, :dataset, :key)
19
19
 
20
20
  # Coerce an object to a Name instance
21
21
  #
@@ -54,7 +54,6 @@ module ROM
54
54
  attr_reader :dataset
55
55
 
56
56
  attr_reader :aliaz
57
-
58
57
  attr_reader :key
59
58
 
60
59
  # @api private
@@ -66,14 +65,10 @@ module ROM
66
65
  end
67
66
 
68
67
  # @api private
69
- def as(aliaz)
70
- self.class[relation, dataset, aliaz]
71
- end
68
+ def as(aliaz) = self.class[relation, dataset, aliaz]
72
69
 
73
70
  # @api private
74
- def aliased?
75
- aliaz && aliaz != relation
76
- end
71
+ def aliased? = aliaz && aliaz != relation
77
72
 
78
73
  # Return relation name
79
74
  #
@@ -95,18 +90,14 @@ module ROM
95
90
  # @return [Symbol]
96
91
  #
97
92
  # @api private
98
- def to_sym
99
- relation
100
- end
93
+ def to_sym = relation
101
94
 
102
95
  # Return inspected relation
103
96
  #
104
97
  # @return [String]
105
98
  #
106
99
  # @api private
107
- def inspect
108
- "#{self.class.name}(#{self})"
109
- end
100
+ def inspect = "#{self.class.name}(#{self})"
110
101
  end
111
102
  end
112
103
  end
@@ -24,12 +24,12 @@ module ROM
24
24
  attr_reader :new_schema
25
25
 
26
26
  # @api private
27
- def initialize(name, schema, &block)
27
+ def initialize(name, schema, &)
28
28
  @name = name
29
29
  @schema = schema
30
30
  @new_schema = nil
31
31
  @relation_block = nil
32
- instance_eval(&block)
32
+ instance_eval(&)
33
33
  end
34
34
 
35
35
  # Define a schema for a relation view
@@ -39,8 +39,8 @@ module ROM
39
39
  # @see Relation::ClassInterface.view
40
40
  #
41
41
  # @api public
42
- def schema(&block)
43
- @new_schema = -> relations { @schema.with(relations: relations).instance_exec(&block) }
42
+ def schema(&)
43
+ @new_schema = -> relations { @schema.with(relations: relations).instance_exec(&) }
44
44
  end
45
45
 
46
46
  # Define a relation block for a relation view
@@ -50,8 +50,8 @@ module ROM
50
50
  # @see Relation::ClassInterface.view
51
51
  #
52
52
  # @api public
53
- def relation(&block)
54
- @relation_block = proc(&block)
53
+ def relation(&)
54
+ @relation_block = proc(&)
55
55
  end
56
56
 
57
57
  # Return procs captured by the DSL
@@ -59,9 +59,7 @@ module ROM
59
59
  # @return [Array]
60
60
  #
61
61
  # @api private
62
- def call
63
- [name, new_schema, relation_block]
64
- end
62
+ def call = [name, new_schema, relation_block]
65
63
  end
66
64
  end
67
65
  end
@@ -40,25 +40,19 @@ module ROM
40
40
  # @abstract
41
41
  #
42
42
  # @api private
43
- def relation
44
- raise NotImplementedError
45
- end
43
+ def relation = raise ::NotImplementedError
46
44
 
47
45
  # Return if this is a wrap relation
48
46
  #
49
47
  # @return [true]
50
48
  #
51
49
  # @api private
52
- def wrap?
53
- true
54
- end
50
+ def wrap? = true
55
51
 
56
52
  private
57
53
 
58
54
  # @api private
59
- def decorate?(other)
60
- super || other.is_a?(Combined)
61
- end
55
+ def decorate?(other) = super || other.is_a?(Combined)
62
56
  end
63
57
  end
64
58
  end