rom-core 4.0.0.beta3 → 4.0.0.rc1

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -1
  3. data/lib/rom/association_set.rb +3 -0
  4. data/lib/rom/associations/abstract.rb +72 -1
  5. data/lib/rom/associations/definitions/abstract.rb +22 -6
  6. data/lib/rom/associations/definitions/many_to_many.rb +3 -0
  7. data/lib/rom/associations/definitions/many_to_one.rb +1 -0
  8. data/lib/rom/associations/definitions/one_to_many.rb +1 -0
  9. data/lib/rom/associations/definitions/one_to_one.rb +1 -0
  10. data/lib/rom/associations/definitions/one_to_one_through.rb +1 -0
  11. data/lib/rom/associations/many_to_many.rb +44 -0
  12. data/lib/rom/associations/many_to_one.rb +26 -0
  13. data/lib/rom/associations/one_to_many.rb +26 -0
  14. data/lib/rom/associations/one_to_one.rb +3 -0
  15. data/lib/rom/associations/one_to_one_through.rb +3 -0
  16. data/lib/rom/attribute.rb +2 -2
  17. data/lib/rom/auto_curry.rb +11 -0
  18. data/lib/rom/cache.rb +29 -0
  19. data/lib/rom/command_compiler.rb +4 -4
  20. data/lib/rom/command_registry.rb +9 -5
  21. data/lib/rom/commands/class_interface.rb +7 -7
  22. data/lib/rom/commands/graph/input_evaluator.rb +33 -3
  23. data/lib/rom/commands/lazy.rb +4 -0
  24. data/lib/rom/commands/lazy/create.rb +10 -0
  25. data/lib/rom/commands/lazy/delete.rb +10 -0
  26. data/lib/rom/commands/lazy/update.rb +10 -0
  27. data/lib/rom/configuration.rb +34 -14
  28. data/lib/rom/configuration_dsl.rb +0 -2
  29. data/lib/rom/constants.rb +10 -0
  30. data/lib/rom/container.rb +16 -0
  31. data/lib/rom/create_container.rb +7 -0
  32. data/lib/rom/environment.rb +3 -2
  33. data/lib/rom/gateway.rb +16 -1
  34. data/lib/rom/global.rb +1 -1
  35. data/lib/rom/global/plugin_dsl.rb +3 -1
  36. data/lib/rom/initializer.rb +25 -13
  37. data/lib/rom/mapper_registry.rb +4 -1
  38. data/lib/rom/memory/dataset.rb +29 -2
  39. data/lib/rom/memory/schema.rb +7 -0
  40. data/lib/rom/plugin_base.rb +1 -1
  41. data/lib/rom/plugin_registry.rb +2 -2
  42. data/lib/rom/plugins/command/schema.rb +7 -0
  43. data/lib/rom/plugins/relation/instrumentation.rb +10 -0
  44. data/lib/rom/plugins/relation/registry_reader.rb +0 -3
  45. data/lib/rom/registry.rb +15 -3
  46. data/lib/rom/relation.rb +38 -23
  47. data/lib/rom/relation/class_interface.rb +15 -6
  48. data/lib/rom/relation/combined.rb +7 -2
  49. data/lib/rom/relation/curried.rb +23 -0
  50. data/lib/rom/relation/graph.rb +25 -14
  51. data/lib/rom/relation/loaded.rb +7 -4
  52. data/lib/rom/relation/materializable.rb +2 -2
  53. data/lib/rom/relation/view_dsl.rb +2 -1
  54. data/lib/rom/relation/wrap.rb +14 -0
  55. data/lib/rom/relation_registry.rb +2 -0
  56. data/lib/rom/schema.rb +25 -4
  57. data/lib/rom/schema/associations_dsl.rb +9 -0
  58. data/lib/rom/schema/dsl.rb +27 -4
  59. data/lib/rom/setup.rb +20 -7
  60. data/lib/rom/setup/auto_registration.rb +27 -0
  61. data/lib/rom/setup/auto_registration_strategies/base.rb +7 -2
  62. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +17 -0
  63. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +11 -0
  64. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +9 -0
  65. data/lib/rom/setup/finalize/finalize_mappers.rb +4 -2
  66. data/lib/rom/setup/finalize/finalize_relations.rb +1 -1
  67. data/lib/rom/support/configurable.rb +19 -0
  68. data/lib/rom/support/notifications.rb +29 -2
  69. data/lib/rom/types.rb +53 -8
  70. data/lib/rom/version.rb +1 -1
  71. metadata +7 -13
@@ -6,10 +6,21 @@ require 'rom/setup/auto_registration_strategies/base'
6
6
 
7
7
  module ROM
8
8
  module AutoRegistrationStrategies
9
+ # NoNamespace strategy assumes components are not defined within a namespace
10
+ #
11
+ # @api private
9
12
  class NoNamespace < Base
13
+ # @!attribute [r] directory
14
+ # @return [Pathname] The path to dir with components
10
15
  option :directory, type: PathnameType
16
+
17
+ # @!attribute [r] entity
18
+ # @return [Symbol] Component identifier
11
19
  option :entity, type: Types::Strict::Symbol
12
20
 
21
+ # Load components
22
+ #
23
+ # @api private
13
24
  def call
14
25
  Dry::Core::Inflector.camelize(
15
26
  file.sub(/^#{directory}\/#{entity}\//, '').sub(EXTENSION_REGEX, '')
@@ -5,9 +5,18 @@ require 'rom/setup/auto_registration_strategies/base'
5
5
 
6
6
  module ROM
7
7
  module AutoRegistrationStrategies
8
+ # WithNamespace strategy assumes components are defined within a namespace
9
+ # that matches top-level directory name.
10
+ #
11
+ # @api private
8
12
  class WithNamespace < Base
13
+ # @!attribute [r] directory
14
+ # @return [Pathname] The path to dir with components
9
15
  option :directory, type: PathnameType
10
16
 
17
+ # Load components
18
+ #
19
+ # @api private
11
20
  def call
12
21
  Dry::Core::Inflector.camelize(
13
22
  file.sub(/^#{directory.dirname}\//, '').sub(EXTENSION_REGEX, '')
@@ -20,6 +20,8 @@ module ROM
20
20
 
21
21
  # @api private
22
22
  def run!
23
+ cache = Cache.new
24
+
23
25
  mappers = registry_hash.each_with_object({}) do |(relation_name, relation_mappers), h|
24
26
  relation_mappers.update(build_mappers(relation_name))
25
27
 
@@ -27,10 +29,10 @@ module ROM
27
29
  relation_mappers.update(mapper_objects[relation_name])
28
30
  end
29
31
 
30
- h[relation_name] = MapperRegistry.new(relation_mappers)
32
+ h[relation_name] = MapperRegistry.new(relation_mappers, cache: cache)
31
33
  end
32
34
 
33
- Registry.new(mappers)
35
+ Registry.new(mappers, cache: cache)
34
36
  end
35
37
 
36
38
  private
@@ -101,7 +101,7 @@ module ROM
101
101
  dataset: dataset, relation: klass, adapter: klass.adapter
102
102
  )
103
103
 
104
- mappers = @mappers.key?(rel_key) ? @mappers[rel_key] : MapperRegistry.new
104
+ mappers = @mappers.key?(rel_key) ? @mappers[rel_key] : MapperRegistry.new({}, cache: @mappers.cache)
105
105
 
106
106
  options = { __registry__: registry, mappers: mappers, schema: schema, **plugin_options }
107
107
 
@@ -1,9 +1,14 @@
1
1
  module ROM
2
+ # This extension is only used for environment objects to configure arbitrary options, each
3
+ # adapter can use them according to what they need.
4
+ #
2
5
  # @api private
3
6
  module Configurable
4
7
  class Config
5
8
  WRITER_REGEXP = /=$/.freeze
6
9
 
10
+ # @!attribute [r] settings
11
+ # @return [Hash] A hash with defined settings
7
12
  attr_reader :settings
8
13
 
9
14
  # @api private
@@ -11,6 +16,10 @@ module ROM
11
16
  @settings = settings
12
17
  end
13
18
 
19
+ # Return a setting
20
+ #
21
+ # @return [Mixed]
22
+ #
14
23
  # @api public
15
24
  def [](name)
16
25
  public_send(name)
@@ -36,6 +45,7 @@ module ROM
36
45
  true
37
46
  end
38
47
 
48
+ # @api private
39
49
  def dup
40
50
  self.class.new(dup_settings(settings))
41
51
  end
@@ -72,10 +82,19 @@ module ROM
72
82
  end
73
83
  end
74
84
 
85
+ # Return config instance
86
+ #
87
+ # @return [Config]
88
+ #
89
+ # @api private
75
90
  def config
76
91
  @config ||= Config.new
77
92
  end
78
93
 
94
+ # Yield config instance
95
+ #
96
+ # @return [self]
97
+ #
79
98
  # @api public
80
99
  def configure
81
100
  yield(config)
@@ -38,6 +38,9 @@ module ROM
38
38
  module Notifications
39
39
  LISTENERS_HASH = Hash.new { |h, k| h[k] = [] }
40
40
 
41
+ # Extension used for classes that can trigger events
42
+ #
43
+ # @api public
41
44
  module Publisher
42
45
  # Subscribe to events.
43
46
  # If the query parameter is provided, filters events by payload.
@@ -74,10 +77,18 @@ module ROM
74
77
  class Event
75
78
  include Dry::Equalizer(:id, :payload)
76
79
 
77
- # @attr_reader [String] id Event ID
80
+ # @!attribute [r] id
81
+ # @return [Symbol] The event identifier
78
82
  attr_reader :id
79
83
 
80
- # @api public
84
+ # Initialize a new event
85
+ #
86
+ # @param [Symbol] id The event identifier
87
+ # @param [Hash] payload Optional payload
88
+ #
89
+ # @return [Event]
90
+ #
91
+ # @api private
81
92
  def initialize(id, payload = EMPTY_HASH)
82
93
  @id = id
83
94
  @payload = payload
@@ -158,6 +169,8 @@ module ROM
158
169
  EventBus.new(id, events: events.dup, listeners: listeners.dup)
159
170
  end
160
171
 
172
+ # Extension for objects that can listen to events
173
+ #
161
174
  # @api public
162
175
  module Listener
163
176
  # Subscribe to events
@@ -180,10 +193,24 @@ module ROM
180
193
  class EventBus
181
194
  include Publisher
182
195
 
196
+ # @!attribute [r] id
197
+ # @return [Symbol] The bus identifier
183
198
  attr_reader :id
199
+
200
+ # @!attribute [r] events
201
+ # @return [Hash] A hash with events registered within a bus
184
202
  attr_reader :events
203
+
204
+ # @!attribute [r] listeners
205
+ # @return [Hash] A hash with event listeners registered within a bus
185
206
  attr_reader :listeners
186
207
 
208
+ # Initialize a new event bus
209
+ #
210
+ # @param [Symbol] id The bus identifier
211
+ # @param [Hash] events A hash with events
212
+ # @param [Hash] listeners A hash with listeners
213
+ #
187
214
  # @api public
188
215
  def initialize(id, events: EMPTY_HASH, listeners: LISTENERS_HASH.dup)
189
216
  @id = id
data/lib/rom/types.rb CHANGED
@@ -1,26 +1,71 @@
1
1
  require 'dry-types'
2
+ require 'json'
2
3
 
3
4
  module ROM
5
+ # Default namespace with built-in attribute types
6
+ #
7
+ # @api public
4
8
  module Types
5
9
  include Dry::Types.module
6
10
 
11
+ # @api private
7
12
  def self.included(other)
8
13
  other.extend(Methods)
9
14
  super
10
15
  end
11
16
 
12
- def self.Definition(primitive)
13
- Dry::Types::Definition.new(primitive)
14
- end
15
-
16
- def self.Constructor(primitive, &block)
17
- Types.Definition(primitive).constructor(&block)
18
- end
19
-
17
+ # Type extensions
18
+ #
19
+ # @api public
20
20
  module Methods
21
+ # Shortcut for defining a foreign key attribute type
22
+ #
23
+ # @param [Symbol] relation The name of the target relation
24
+ # @param [Object] type The type of an attribute
25
+ #
26
+ # @return [Dry::Types::Definition]
27
+ #
28
+ # @api public
21
29
  def ForeignKey(relation, type = Types::Int)
22
30
  type.meta(foreign_key: true, target: relation)
23
31
  end
24
32
  end
33
+
34
+ # Define a json-to-hash attribute type
35
+ #
36
+ # @return [Dry::Types::Constructor]
37
+ #
38
+ # @api public
39
+ def Coercible.JSONHash(symbol_keys: false, type: Types::Hash)
40
+ Types.Constructor(type) do |value|
41
+ begin
42
+ ::JSON.parse(value.to_s, symbolize_names: symbol_keys)
43
+ rescue ::JSON::ParserError
44
+ value
45
+ end
46
+ end
47
+ end
48
+
49
+ # Define a hash-to-json attribute type
50
+ #
51
+ # @return [Dry::Types::Constructor]
52
+ #
53
+ # @api public
54
+ def Coercible.HashJSON(type: Types::String)
55
+ Types.Constructor(type) { |value| ::JSON.dump(value) }
56
+ end
57
+
58
+ # Define a json type with json-to-hash read type
59
+ #
60
+ # @return [Dry::Types::Constructor]
61
+ #
62
+ # @api public
63
+ def Coercible.JSON(symbol_keys: false)
64
+ self.HashJSON.meta(read: self.JSONHash(symbol_keys: symbol_keys))
65
+ end
66
+
67
+ Coercible::JSON = Coercible.JSON
68
+ Coercible::JSONHash = Coercible.JSONHash
69
+ Coercible::HashJSON = Coercible.HashJSON
25
70
  end
26
71
  end
data/lib/rom/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module Core
3
- VERSION = '4.0.0.beta3'.freeze
3
+ VERSION = '4.0.0.rc1'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta3
4
+ version: 4.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-14 00:00:00.000000000 Z
11
+ date: 2017-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -58,20 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.11'
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: 0.11.1
61
+ version: '0.12'
65
62
  type: :runtime
66
63
  prerelease: false
67
64
  version_requirements: !ruby/object:Gem::Requirement
68
65
  requirements:
69
66
  - - "~>"
70
67
  - !ruby/object:Gem::Version
71
- version: '0.11'
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: 0.11.1
68
+ version: '0.12'
75
69
  - !ruby/object:Gem::Dependency
76
70
  name: dry-core
77
71
  requirement: !ruby/object:Gem::Requirement
@@ -92,14 +86,14 @@ dependencies:
92
86
  requirements:
93
87
  - - "~>"
94
88
  - !ruby/object:Gem::Version
95
- version: '1.3'
89
+ version: '2.0'
96
90
  type: :runtime
97
91
  prerelease: false
98
92
  version_requirements: !ruby/object:Gem::Requirement
99
93
  requirements:
100
94
  - - "~>"
101
95
  - !ruby/object:Gem::Version
102
- version: '1.3'
96
+ version: '2.0'
103
97
  - !ruby/object:Gem::Dependency
104
98
  name: rom-mapper
105
99
  requirement: !ruby/object:Gem::Requirement
@@ -279,7 +273,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
279
273
  requirements:
280
274
  - - ">="
281
275
  - !ruby/object:Gem::Version
282
- version: '0'
276
+ version: 2.3.0
283
277
  required_rubygems_version: !ruby/object:Gem::Requirement
284
278
  requirements:
285
279
  - - ">"