rom-core 4.2.1 → 5.0.0

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