rom-core 5.3.2 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
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 +6 -15
  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