rom-core 4.2.1 → 5.0.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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -2
  3. data/lib/rom-core.rb +2 -0
  4. data/lib/rom/array_dataset.rb +2 -0
  5. data/lib/rom/association_set.rb +2 -0
  6. data/lib/rom/associations/abstract.rb +2 -0
  7. data/lib/rom/associations/definitions.rb +2 -0
  8. data/lib/rom/associations/definitions/abstract.rb +2 -0
  9. data/lib/rom/associations/definitions/many_to_many.rb +2 -0
  10. data/lib/rom/associations/definitions/many_to_one.rb +2 -0
  11. data/lib/rom/associations/definitions/one_to_many.rb +2 -0
  12. data/lib/rom/associations/definitions/one_to_one.rb +2 -0
  13. data/lib/rom/associations/definitions/one_to_one_through.rb +2 -0
  14. data/lib/rom/associations/many_to_many.rb +2 -0
  15. data/lib/rom/associations/many_to_one.rb +2 -0
  16. data/lib/rom/associations/one_to_many.rb +2 -0
  17. data/lib/rom/associations/one_to_one.rb +2 -0
  18. data/lib/rom/associations/one_to_one_through.rb +2 -0
  19. data/lib/rom/associations/through_identifier.rb +2 -0
  20. data/lib/rom/attribute.rb +58 -72
  21. data/lib/rom/auto_curry.rb +2 -0
  22. data/lib/rom/cache.rb +2 -0
  23. data/lib/rom/command.rb +7 -5
  24. data/lib/rom/command_compiler.rb +2 -0
  25. data/lib/rom/command_proxy.rb +2 -0
  26. data/lib/rom/command_registry.rb +13 -7
  27. data/lib/rom/commands.rb +2 -0
  28. data/lib/rom/commands/class_interface.rb +4 -2
  29. data/lib/rom/commands/composite.rb +2 -0
  30. data/lib/rom/commands/create.rb +2 -0
  31. data/lib/rom/commands/delete.rb +2 -0
  32. data/lib/rom/commands/graph.rb +2 -0
  33. data/lib/rom/commands/graph/class_interface.rb +2 -0
  34. data/lib/rom/commands/graph/input_evaluator.rb +2 -0
  35. data/lib/rom/commands/lazy.rb +2 -0
  36. data/lib/rom/commands/lazy/create.rb +2 -0
  37. data/lib/rom/commands/lazy/delete.rb +2 -0
  38. data/lib/rom/commands/lazy/update.rb +2 -0
  39. data/lib/rom/commands/update.rb +2 -0
  40. data/lib/rom/configuration.rb +2 -0
  41. data/lib/rom/configuration_dsl.rb +2 -0
  42. data/lib/rom/configuration_dsl/command.rb +2 -0
  43. data/lib/rom/configuration_dsl/command_dsl.rb +2 -0
  44. data/lib/rom/configuration_dsl/relation.rb +2 -0
  45. data/lib/rom/configuration_plugin.rb +2 -0
  46. data/lib/rom/constants.rb +3 -0
  47. data/lib/rom/container.rb +2 -0
  48. data/lib/rom/core.rb +4 -1
  49. data/lib/rom/create_container.rb +2 -0
  50. data/lib/rom/data_proxy.rb +2 -0
  51. data/lib/rom/enumerable_dataset.rb +2 -0
  52. data/lib/rom/environment.rb +2 -0
  53. data/lib/rom/gateway.rb +2 -0
  54. data/lib/rom/global.rb +2 -0
  55. data/lib/rom/global/plugin_dsl.rb +2 -0
  56. data/lib/rom/header.rb +198 -0
  57. data/lib/rom/header/attribute.rb +192 -0
  58. data/lib/rom/initializer.rb +2 -0
  59. data/lib/rom/lint/enumerable_dataset.rb +2 -0
  60. data/lib/rom/lint/gateway.rb +2 -0
  61. data/lib/rom/lint/linter.rb +2 -0
  62. data/lib/rom/lint/spec.rb +2 -0
  63. data/lib/rom/lint/test.rb +2 -0
  64. data/lib/rom/mapper.rb +100 -0
  65. data/lib/rom/mapper/attribute_dsl.rb +480 -0
  66. data/lib/rom/mapper/builder.rb +39 -0
  67. data/lib/rom/mapper/configuration_plugin.rb +28 -0
  68. data/lib/rom/mapper/dsl.rb +123 -0
  69. data/lib/rom/mapper/mapper_dsl.rb +45 -0
  70. data/lib/rom/mapper/model_dsl.rb +60 -0
  71. data/lib/rom/mapper_compiler.rb +84 -0
  72. data/lib/rom/mapper_registry.rb +2 -0
  73. data/lib/rom/memory.rb +2 -0
  74. data/lib/rom/memory/associations.rb +2 -0
  75. data/lib/rom/memory/associations/many_to_many.rb +2 -0
  76. data/lib/rom/memory/associations/many_to_one.rb +2 -0
  77. data/lib/rom/memory/associations/one_to_many.rb +2 -0
  78. data/lib/rom/memory/associations/one_to_one.rb +2 -0
  79. data/lib/rom/memory/commands.rb +2 -0
  80. data/lib/rom/memory/dataset.rb +2 -0
  81. data/lib/rom/memory/gateway.rb +2 -0
  82. data/lib/rom/memory/mapper_compiler.rb +2 -0
  83. data/lib/rom/memory/relation.rb +2 -0
  84. data/lib/rom/memory/schema.rb +2 -0
  85. data/lib/rom/memory/storage.rb +2 -0
  86. data/lib/rom/memory/types.rb +2 -0
  87. data/lib/rom/model_builder.rb +103 -0
  88. data/lib/rom/open_struct.rb +37 -0
  89. data/lib/rom/pipeline.rb +2 -0
  90. data/lib/rom/plugin.rb +2 -0
  91. data/lib/rom/plugin_base.rb +2 -0
  92. data/lib/rom/plugin_registry.rb +2 -0
  93. data/lib/rom/plugins/command/schema.rb +2 -0
  94. data/lib/rom/plugins/command/timestamps.rb +2 -0
  95. data/lib/rom/plugins/relation/instrumentation.rb +2 -0
  96. data/lib/rom/plugins/relation/registry_reader.rb +2 -0
  97. data/lib/rom/plugins/schema/timestamps.rb +8 -1
  98. data/lib/rom/processor.rb +30 -0
  99. data/lib/rom/processor/transproc.rb +417 -0
  100. data/lib/rom/registry.rb +2 -0
  101. data/lib/rom/relation.rb +4 -2
  102. data/lib/rom/relation/class_interface.rb +2 -0
  103. data/lib/rom/relation/combined.rb +2 -0
  104. data/lib/rom/relation/commands.rb +2 -0
  105. data/lib/rom/relation/composite.rb +2 -0
  106. data/lib/rom/relation/curried.rb +3 -1
  107. data/lib/rom/relation/graph.rb +2 -0
  108. data/lib/rom/relation/loaded.rb +2 -0
  109. data/lib/rom/relation/materializable.rb +2 -0
  110. data/lib/rom/relation/name.rb +2 -0
  111. data/lib/rom/relation/view_dsl.rb +2 -0
  112. data/lib/rom/relation/wrap.rb +2 -0
  113. data/lib/rom/relation_registry.rb +2 -0
  114. data/lib/rom/schema.rb +39 -6
  115. data/lib/rom/schema/associations_dsl.rb +5 -3
  116. data/lib/rom/schema/dsl.rb +41 -11
  117. data/lib/rom/schema/inferrer.rb +21 -3
  118. data/lib/rom/schema_plugin.rb +2 -0
  119. data/lib/rom/setup.rb +2 -0
  120. data/lib/rom/setup/auto_registration.rb +2 -0
  121. data/lib/rom/setup/auto_registration_strategies/base.rb +3 -1
  122. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +2 -0
  123. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +2 -0
  124. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +2 -0
  125. data/lib/rom/setup/finalize.rb +2 -0
  126. data/lib/rom/setup/finalize/finalize_commands.rb +2 -0
  127. data/lib/rom/setup/finalize/finalize_mappers.rb +2 -0
  128. data/lib/rom/setup/finalize/finalize_relations.rb +2 -0
  129. data/lib/rom/struct.rb +108 -0
  130. data/lib/rom/struct_compiler.rb +110 -0
  131. data/lib/rom/support/configurable.rb +2 -0
  132. data/lib/rom/support/inflector.rb +2 -0
  133. data/lib/rom/support/memoizable.rb +2 -0
  134. data/lib/rom/support/notifications.rb +2 -0
  135. data/lib/rom/transaction.rb +2 -0
  136. data/lib/rom/transformer.rb +34 -0
  137. data/lib/rom/types.rb +10 -3
  138. data/lib/rom/version.rb +3 -1
  139. metadata +37 -21
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  require 'rom/initializer'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/core/class_attributes'
2
4
 
3
5
  require 'rom/struct'
@@ -279,7 +281,7 @@ module ROM
279
281
 
280
282
  # Create a graph node for a given association identifier
281
283
  #
282
- # @param [Symbol, Relation::Name]
284
+ # @param [Symbol, Relation::Name] name
283
285
  #
284
286
  # @return [Relation]
285
287
  #
@@ -292,7 +294,7 @@ module ROM
292
294
 
293
295
  # Return a graph node prepared by the given association
294
296
  #
295
- # @param [Association] An association object
297
+ # @param [Association] assoc An association object
296
298
  #
297
299
  # @return [Relation]
298
300
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  require 'rom/support/inflector'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/relation/graph'
2
4
  require 'rom/relation/commands'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  class Relation
3
5
  # Extensions for relation classes which provide access to commands
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/relation/loaded'
2
4
  require 'rom/relation/materializable'
3
5
  require 'rom/pipeline'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  require 'rom/types'
@@ -35,7 +37,7 @@ module ROM
35
37
 
36
38
  # @!attribute [r] arity
37
39
  # @return [Integer] View's arity
38
- option :arity, type: Types::Strict::Int
40
+ option :arity, type: Types::Strict::Integer
39
41
 
40
42
  # @!attribute [r] curry_args
41
43
  # @return [Array] Arguments that will be passed to curried view
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  require 'rom/initializer'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  class Relation
3
5
  # Interface for objects that can be materialized into a loaded relation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
  require 'concurrent/map'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ROM
2
4
  class Relation
3
5
  # ViewDSL is exposed in `Relation.view` method
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/relation/graph'
2
4
  require 'rom/relation/combined'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/registry'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  require 'rom/constants'
@@ -62,6 +64,19 @@ module ROM
62
64
 
63
65
  DEFAULT_INFERRER = Inferrer.new(enabled: false).freeze
64
66
 
67
+ type_transformation = lambda do |key|
68
+ k = if key.default?
69
+ key.constructor { |value| value.nil? ? Undefined : value }
70
+ else
71
+ key
72
+ end
73
+ k.required(false)
74
+ end
75
+
76
+ HASH_SCHEMA = Types::Coercible::Hash.
77
+ schema(EMPTY_HASH).
78
+ with_type_transform(type_transformation)
79
+
65
80
  extend Initializer
66
81
 
67
82
  include Dry::Equalizer(:name, :attributes, :associations)
@@ -104,7 +119,7 @@ module ROM
104
119
 
105
120
  alias_method :to_ary, :attributes
106
121
 
107
- # Define a relation schema from plain rom types
122
+ # Define a relation schema from plain rom types and optional options
108
123
  #
109
124
  # Resulting schema will decorate plain rom types with adapter-specific types
110
125
  # By default `Attribute` will be used
@@ -123,9 +138,27 @@ module ROM
123
138
  ) { |schema| yield(schema) if block_given? }
124
139
  end
125
140
 
141
+ # Builds a representation of the information needed to create an
142
+ # attribute.
143
+ #
144
+ # This representation is consumed by `Schema.define` in order to create
145
+ # the actual attributes.
146
+ #
147
+ # @return [Hash] A hash with `:type` and `:options` keys.
148
+ #
149
+ # @api private
150
+ def self.build_attribute_info(type, options)
151
+ {
152
+ type: type,
153
+ options: options
154
+ }
155
+ end
156
+
126
157
  # @api private
127
158
  def self.attributes(attributes, attr_class)
128
- attributes.map { |type| attr_class.new(type) }
159
+ attributes.map do |attr|
160
+ attr_class.new(attr[:type], attr.fetch(:options))
161
+ end
129
162
  end
130
163
 
131
164
  # @api private
@@ -389,7 +422,7 @@ module ROM
389
422
  #
390
423
  # @api private
391
424
  def to_output_hash
392
- Types::Coercible::Hash.schema(
425
+ HASH_SCHEMA.schema(
393
426
  map { |attr| [attr.key, attr.to_read_type] }.to_h
394
427
  )
395
428
  end
@@ -403,7 +436,7 @@ module ROM
403
436
  #
404
437
  # @api private
405
438
  def to_input_hash
406
- Types::Coercible::Hash.schema(
439
+ HASH_SCHEMA.schema(
407
440
  map { |attr| [attr.name, attr.to_write_type] }.to_h
408
441
  )
409
442
  end
@@ -451,8 +484,8 @@ module ROM
451
484
  # @api private
452
485
  def initialize_primary_key_names
453
486
  if primary_key.size > 0
454
- set!(:primary_key_name, primary_key[0].meta[:name])
455
- set!(:primary_key_names, primary_key.map { |type| type.meta[:name] })
487
+ set!(:primary_key_name, primary_key[0].name)
488
+ set!(:primary_key_names, primary_key.map(&:name))
456
489
  end
457
490
  end
458
491
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/support/inflector'
2
4
 
3
5
  require 'rom/associations/definitions'
@@ -110,7 +112,7 @@ module ROM
110
112
  # @param [Symbol] target The target relation identifier
111
113
  # @param [Hash] options A hash with additional options
112
114
  #
113
- # @return [Associations::OneToOne]
115
+ # @return [Associations::ManyToMany]
114
116
  #
115
117
  # @see #one_to_many
116
118
  #
@@ -127,7 +129,7 @@ module ROM
127
129
  # @param [Symbol] target The target relation identifier
128
130
  # @param [Hash] options A hash with additional options
129
131
  #
130
- # @return [Associations::OneToOne]
132
+ # @return [Associations::ManyToOne]
131
133
  #
132
134
  # @see #one_to_many
133
135
  #
@@ -163,7 +165,7 @@ module ROM
163
165
  #
164
166
  # @see #one_to_one
165
167
  #
166
- # @return [Associations::ManyToOne]
168
+ # @return [Associations::OneToOne]
167
169
  #
168
170
  # @api public
169
171
  def has_one(target, options = {})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
5
  require 'rom/types'
@@ -36,7 +38,10 @@ module ROM
36
38
  option :adapter, default: -> { :default }
37
39
 
38
40
  # @!attribute [r] attributes
39
- # @return [Hash] A hash with attributes defined by the DSL
41
+ # @return [Hash<Symbol, Hash>] A hash with attribute names as
42
+ # keys and attribute representations as values.
43
+ #
44
+ # @see [Schema.build_attribute_info]
40
45
  attr_reader :attributes
41
46
 
42
47
  # @!attribute [r] plugins
@@ -61,18 +66,22 @@ module ROM
61
66
  @definition = block
62
67
  end
63
68
 
64
- # Defines a relation attribute with its type
69
+ # Defines a relation attribute with its type and options.
70
+ #
71
+ # When only options are given, type is left as nil. It makes
72
+ # sense when it is used alongside an schema inferrer, which will
73
+ # populate the type.
65
74
  #
66
75
  # @see Relation.schema
67
76
  #
68
77
  # @api public
69
- def attribute(name, type, options = EMPTY_HASH)
78
+ def attribute(name, type_or_options, options = EMPTY_HASH)
70
79
  if attributes.key?(name)
71
80
  ::Kernel.raise ::ROM::AttributeAlreadyDefinedError,
72
81
  "Attribute #{ name.inspect } already defined"
73
82
  end
74
83
 
75
- attributes[name] = build_type(name, type, options)
84
+ attributes[name] = build_attribute_info(name, type_or_options, options)
76
85
  end
77
86
 
78
87
  # Define associations for a relation
@@ -108,18 +117,38 @@ module ROM
108
117
  @associations_dsl = AssociationsDSL.new(relation, &block)
109
118
  end
110
119
 
111
- # Builds a type instance from a name, options and a base type
120
+ # Builds a representation of the information needed to create an
121
+ # attribute. It returns a hash with `:type` and `:options` keys.
122
+ #
123
+ # @return [Hash]
124
+ #
125
+ # @see [Schema.build_attribute_info]
126
+ #
127
+ # @api private
128
+ def build_attribute_info(name, type_or_options, options = EMPTY_HASH)
129
+ type, options = if type_or_options.is_a?(::Hash)
130
+ [nil, type_or_options]
131
+ else
132
+ [build_type(type_or_options, options), options]
133
+ end
134
+ Schema.build_attribute_info(
135
+ type,
136
+ options.merge(name: name)
137
+ )
138
+ end
139
+
140
+ # Builds a type instance from base type and meta options
112
141
  #
113
142
  # @return [Dry::Types::Type] Type instance
114
143
  #
115
144
  # @api private
116
- def build_type(name, type, options = EMPTY_HASH)
145
+ def build_type(type, options = EMPTY_HASH)
117
146
  if options[:read]
118
- type.meta(name: name, source: relation, read: options[:read])
119
- elsif type.optional? && !type.meta[:read] && type.right.meta[:read]
120
- type.meta(name: name, source: relation, read: type.right.meta[:read].optional)
147
+ type.meta(source: relation, read: options[:read])
148
+ elsif type.optional? && type.meta[:read]
149
+ type.meta(source: relation, read: type.meta[:read].optional)
121
150
  else
122
- type.meta(name: name, source: relation)
151
+ type.meta(source: relation)
123
152
  end
124
153
  end
125
154
 
@@ -128,7 +157,8 @@ module ROM
128
157
  # @api public
129
158
  def primary_key(*names)
130
159
  names.each do |name|
131
- attributes[name] = attributes[name].meta(primary_key: true)
160
+ attributes[name][:type] =
161
+ attributes[name][:type].meta(primary_key: true)
132
162
  end
133
163
  self
134
164
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/core/class_attributes'
2
4
 
3
5
  module ROM
@@ -81,9 +83,25 @@ module ROM
81
83
 
82
84
  # @api private
83
85
  def merge_attributes(defined, inferred)
84
- defined_names = defined.map(&:name)
85
-
86
- defined + inferred.reject { |attr| defined_names.include?(attr.name) }
86
+ type_lookup = lambda do |attrs, name|
87
+ attrs.find { |a| a.name == name }.type
88
+ end
89
+ defined_with_type, defined_names =
90
+ defined.each_with_object([[], []]) do |attr, (attrs, names)|
91
+ attrs << if attr.type.nil?
92
+ attr.class.new(
93
+ type_lookup.(inferred, attr.name),
94
+ attr.options
95
+ )
96
+ else
97
+ attr
98
+ end
99
+ names << attr.name
100
+ end
101
+
102
+ defined_with_type + inferred.reject do |attr|
103
+ defined_names.include?(attr.name)
104
+ end
87
105
  end
88
106
  end
89
107
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/plugin_base'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/setup/auto_registration'
2
4
 
3
5
  module ROM
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'rom/support/inflector'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/types'
2
4
  require 'rom/initializer'
3
5
 
@@ -9,7 +11,7 @@ module ROM
9
11
  class Base
10
12
  extend Initializer
11
13
 
12
- PathnameType = Types.Definition(Pathname).constrained(type: Pathname)
14
+ PathnameType = Types.Instance(Pathname)
13
15
 
14
16
  EXTENSION_REGEX = /\.rb\z/
15
17
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'rom/support/inflector'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'rom/support/inflector'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  require 'rom/support/inflector'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/relation'
2
4
  require 'rom/command'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rom/registry'
2
4
  require 'rom/command_compiler'
3
5
  require 'rom/command_registry'