rom-core 4.0.0.beta3 → 4.0.0.rc1

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