rom-core 4.0.2 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1cea9b3d9020f60a964a7105e7ac77e32e954126
4
- data.tar.gz: 1e74ac03ad226c75e291d58163ffb0e3caff57eb
3
+ metadata.gz: b493c6e32485de5b046e45b4d152c132da1cc72e
4
+ data.tar.gz: 6950b1e104d52dcfdfcbe4e65bf195862589a9d4
5
5
  SHA512:
6
- metadata.gz: 776153acc7f3bce777c713d37a706456e58165e78c0c4c7ffbe598c301250de2bb93b845524fe1b6f2b04b10bfdf109e46f166e5bda33471040aaa254949130e
7
- data.tar.gz: b1bc73e397c05f2c5372d16d5dba21f153669dde45b89a2129bf01b45adafbfbe325969d0b6cbac7c84225f7b7bfd1d5d1418decb266e601bafa0226b3a99f87
6
+ metadata.gz: 72e458a263d518a0886f281b0f2eed44b0e819b3405b2f79e9bcd8f23cb8e505a40929721c975b3a0e1862bf81714a46785d2747a6f867b6cc7cde9f642461ab
7
+ data.tar.gz: 6d7b2eaf896b27e9b773867c3a92780e27f517fb1e40cb191356472c781c10bb6b121aeabed42c495efcddd3d7af86ebabead413d9b50f16fc42e53acd601856
@@ -1,3 +1,23 @@
1
+ # v4.1.0 2017-11-17
2
+
3
+ ## Added
4
+
5
+ * Support for providing a custom mapper compiler by adapters (solnic)
6
+ * Support for aliased attributes in auto-mapping (solnic)
7
+ * Support for command plugin options, ie `use :timestamps, timestamps: %i(created_at, updated_at), datestamps: %i(:written_on)` (GustavoCaso)
8
+ * `''configuration.relations.class.ready''` event is triggered with `:adapter` filter (solnic)
9
+
10
+ ## Fixed
11
+
12
+ * `'configuration.commands.class.before_build'` event is triggered with `:adapter` set, so that adapters can subscribe only to their events. This fixes a bug where an incorrect adapter would try to handle this event with a command class coming from another adapter (solnic)
13
+ * Command compiler no longer uses global temporary registry (solnic)
14
+
15
+ ## Changed
16
+
17
+ * Uses `dry-inflector` now (solnic)
18
+
19
+ [Compare v4.0.2...v4.1.0](https://github.com/rom-rb/rom/compare/v4.0.2...v4.1.0)
20
+
1
21
  # v4.0.2 2017-11-02
2
22
 
3
23
  ## Added
data/README.md CHANGED
@@ -11,7 +11,7 @@ Core API for rom-rb and its adapters and extensions.
11
11
  Resources:
12
12
 
13
13
  * [User documentation](http://rom-rb.org/learn/core)
14
- * [API documentation](http://rubydoc.info/gems/rom-core)
14
+ * [API documentation](http://api.rom-rb.org/rom/)
15
15
 
16
16
  ## License
17
17
 
@@ -124,7 +124,7 @@ module ROM
124
124
  #
125
125
  # @api public
126
126
  def type
127
- Dry::Core::Inflector.demodulize(self.class.name).to_sym
127
+ Inflector.demodulize(self.class.name).to_sym
128
128
  end
129
129
  end
130
130
  end
@@ -1,4 +1,4 @@
1
- require 'dry/core/inflector'
1
+ require 'rom/support/inflector'
2
2
 
3
3
  module ROM
4
4
  module Associations
@@ -20,7 +20,7 @@ module ROM
20
20
 
21
21
  # @api private
22
22
  def self.default_assoc_name(relation)
23
- Dry::Core::Inflector.singularize(relation).to_sym
23
+ Inflector.singularize(relation).to_sym
24
24
  end
25
25
 
26
26
  # @api private
@@ -1,4 +1,4 @@
1
- require 'dry/core/inflector'
1
+ require 'rom/support/inflector'
2
2
 
3
3
  require 'rom/initializer'
4
4
  require 'rom/commands'
@@ -17,7 +17,7 @@ module ROM
17
17
 
18
18
  # @api private
19
19
  def self.registry
20
- @__registry__ ||= Hash.new { |h, k| h[k] = {} }
20
+ Hash.new { |h, k| h[k] = {} }
21
21
  end
22
22
 
23
23
  # @!attribute [r] gateways
@@ -52,6 +52,10 @@ module ROM
52
52
  # @return [Array<Symbol>] a list of optional plugins that will be enabled for commands
53
53
  option :plugins, optional: true, default: -> { EMPTY_ARRAY }
54
54
 
55
+ # @!attribute [r] plugins_options
56
+ # @return [Hash] a hash of options for the plugins
57
+ option :plugins_options, optional: true, default: -> { EMPTY_HASH }
58
+
55
59
  # @!attribute [r] meta
56
60
  # @return [Array<Symbol>] Meta data for a command
57
61
  option :meta, optional: true
@@ -82,12 +86,13 @@ module ROM
82
86
  # @api private
83
87
  def call(*args)
84
88
  cache.fetch_or_store(args.hash) do
85
- type, adapter, ast, plugins, meta = args
89
+ type, adapter, ast, plugins, plugins_options, meta = args
86
90
 
87
91
  compiler = with(
88
92
  id: type,
89
93
  adapter: adapter,
90
94
  plugins: Array(plugins),
95
+ plugins_options: plugins_options,
91
96
  meta: meta
92
97
  )
93
98
 
@@ -107,7 +112,7 @@ module ROM
107
112
 
108
113
  # @api private
109
114
  def type
110
- @_type ||= Commands.const_get(Dry::Core::Inflector.classify(id))[adapter]
115
+ @_type ||= Commands.const_get(Inflector.classify(id))[adapter]
111
116
  rescue NameError
112
117
  nil
113
118
  end
@@ -132,7 +137,7 @@ module ROM
132
137
  if meta[:combine_type] == :many
133
138
  name
134
139
  else
135
- { Dry::Core::Inflector.singularize(name).to_sym => name }
140
+ { Inflector.singularize(name).to_sym => name }
136
141
  end
137
142
 
138
143
  mapping =
@@ -191,14 +196,15 @@ module ROM
191
196
  end
192
197
 
193
198
  plugins.each do |plugin|
194
- klass.use(plugin)
199
+ plugin_options = plugins_options.fetch(plugin) { EMPTY_HASH }
200
+ klass.use(plugin, plugin_options)
195
201
  end
196
202
 
197
203
  gateway = gateways[relation.gateway]
198
204
 
199
205
  notifications.trigger(
200
206
  'configuration.commands.class.before_build',
201
- command: klass, gateway: gateway, dataset: relation.dataset
207
+ command: klass, gateway: gateway, dataset: relation.dataset, adapter: adapter
202
208
  )
203
209
 
204
210
  klass.extend_for_relation(relation) if klass.restrictable
@@ -227,7 +233,7 @@ module ROM
227
233
  if relation.associations.key?(parent_relation)
228
234
  parent_relation
229
235
  else
230
- singular_name = Dry::Core::Inflector.singularize(parent_relation).to_sym
236
+ singular_name = Inflector.singularize(parent_relation).to_sym
231
237
  singular_name if relation.associations.key?(singular_name)
232
238
  end
233
239
 
@@ -1,4 +1,4 @@
1
- require 'dry/core/inflector'
1
+ require 'rom/support/inflector'
2
2
 
3
3
  module ROM
4
4
  # TODO: look into making command graphs work without the root key in the input
@@ -9,7 +9,7 @@ module ROM
9
9
  attr_reader :command, :root
10
10
 
11
11
  # @api private
12
- def initialize(command, root = Dry::Core::Inflector.singularize(command.name.relation).to_sym)
12
+ def initialize(command, root = Inflector.singularize(command.name.relation).to_sym)
13
13
  @command = command
14
14
  @root = root
15
15
  end
@@ -1,5 +1,5 @@
1
1
  require 'dry/core/class_builder'
2
- require 'dry/core/inflector'
2
+ require 'rom/support/inflector'
3
3
 
4
4
  module ROM
5
5
  # Base command class with factory class-level interface and setup-related logic
@@ -39,7 +39,7 @@ module ROM
39
39
  #
40
40
  # @api public
41
41
  def [](adapter)
42
- adapter_namespace(adapter).const_get(Dry::Core::Inflector.demodulize(name))
42
+ adapter_namespace(adapter).const_get(Inflector.demodulize(name))
43
43
  end
44
44
 
45
45
  # Return namespaces that contains command subclasses of a specific adapter
@@ -85,7 +85,7 @@ module ROM
85
85
  # @api public
86
86
  def create_class(name, type, &block)
87
87
  klass = Dry::Core::ClassBuilder
88
- .new(name: "#{Dry::Core::Inflector.classify(type)}[:#{name}]", parent: type)
88
+ .new(name: "#{Inflector.classify(type)}[:#{name}]", parent: type)
89
89
  .call
90
90
 
91
91
  if block
@@ -109,8 +109,8 @@ module ROM
109
109
  # @option _options [Symbol] :adapter (:default) first adapter to check for plugin
110
110
  #
111
111
  # @api public
112
- def use(plugin, _options = EMPTY_HASH)
113
- ROM.plugin_registry.commands.fetch(plugin, adapter).apply_to(self)
112
+ def use(plugin, options = EMPTY_HASH)
113
+ ROM.plugin_registry.commands.fetch(plugin, adapter).apply_to(self, options)
114
114
  end
115
115
 
116
116
  # Extend a command class with relation view methods
@@ -235,7 +235,7 @@ module ROM
235
235
  #
236
236
  # @api private
237
237
  def default_name
238
- Dry::Core::Inflector.underscore(Dry::Core::Inflector.demodulize(name)).to_sym
238
+ Inflector.underscore(Inflector.demodulize(name)).to_sym
239
239
  end
240
240
 
241
241
  # Return default options based on class macros
@@ -1,4 +1,4 @@
1
- require 'dry/core/inflector'
1
+ require 'rom/support/inflector'
2
2
  require 'dry/core/class_builder'
3
3
 
4
4
  module ROM
@@ -14,7 +14,7 @@ module ROM
14
14
  # @api private
15
15
  def self.build_class(name, relation, options = EMPTY_HASH, &block)
16
16
  type = options.fetch(:type) { name }
17
- command_type = Dry::Core::Inflector.classify(type)
17
+ command_type = Inflector.classify(type)
18
18
  adapter = options.fetch(:adapter)
19
19
  parent = ROM::Command.adapter_namespace(adapter).const_get(command_type)
20
20
  class_name = generate_class_name(adapter, command_type, relation)
@@ -31,9 +31,9 @@ module ROM
31
31
  # @api private
32
32
  def self.generate_class_name(adapter, command_type, relation)
33
33
  pieces = ['ROM']
34
- pieces << Dry::Core::Inflector.classify(adapter)
34
+ pieces << Inflector.classify(adapter)
35
35
  pieces << 'Commands'
36
- pieces << "#{command_type}[#{Dry::Core::Inflector.classify(relation)}s]"
36
+ pieces << "#{command_type}[#{Inflector.classify(relation)}s]"
37
37
  pieces.join('::')
38
38
  end
39
39
  end
@@ -1,5 +1,5 @@
1
1
  require 'dry/core/class_builder'
2
- require 'dry/core/inflector'
2
+ require 'rom/support/inflector'
3
3
 
4
4
  module ROM
5
5
  module ConfigurationDSL
@@ -13,7 +13,7 @@ module ROM
13
13
  #
14
14
  # @api private
15
15
  def self.build_class(name, options = EMPTY_HASH)
16
- class_name = "ROM::Relation[#{Dry::Core::Inflector.camelize(name)}]"
16
+ class_name = "ROM::Relation[#{Inflector.camelize(name)}]"
17
17
  adapter = options.fetch(:adapter)
18
18
 
19
19
  Dry::Core::ClassBuilder.new(name: class_name, parent: ROM::Relation[adapter]).call do |klass|
@@ -29,6 +29,7 @@ require 'rom/create_container'
29
29
  require 'rom/plugins/relation/registry_reader'
30
30
  require 'rom/plugins/relation/instrumentation'
31
31
  require 'rom/plugins/command/schema'
32
+ require 'rom/plugins/command/timestamps'
32
33
  require 'rom/plugins/schema/timestamps'
33
34
 
34
35
  module ROM
@@ -40,5 +41,6 @@ module ROM
40
41
  register :registry_reader, ROM::Plugins::Relation::RegistryReader, type: :relation
41
42
  register :instrumentation, ROM::Plugins::Relation::Instrumentation, type: :relation
42
43
  register :schema, ROM::Plugins::Command::Schema, type: :command
44
+ register :timestamps, ROM::Plugins::Command::Timestamps, type: :command
43
45
  end
44
46
  end
@@ -32,6 +32,22 @@ module ROM
32
32
  # @param [Symbol] adapter The adapter identifier
33
33
  defines :adapter
34
34
 
35
+ # @!method self.mapper_compiler
36
+ # Get or set gateway-specific mapper compiler class
37
+ #
38
+ # @overload mapper_compiler
39
+ # Return mapper compiler class
40
+ # @return [Class]
41
+ #
42
+ # @overload mapper_compiler(klass)
43
+ # @example
44
+ # class MyGateway < ROM::Gateway
45
+ # mapper_compiler MyMapperCompiler
46
+ # end
47
+ #
48
+ # @param [Class] klass The mapper compiler class
49
+ defines :mapper_compiler
50
+
35
51
  # @!attribute [r] connection
36
52
  # @return [Object] The gateway's connection object (type varies across adapters)
37
53
  attr_reader :connection
@@ -178,6 +194,15 @@ module ROM
178
194
  transaction_runner(opts).run(opts, &block)
179
195
  end
180
196
 
197
+ # Return configured mapper compiler class
198
+ #
199
+ # @return [Class]
200
+ #
201
+ # @api private
202
+ def mapper_compiler
203
+ self.class.mapper_compiler
204
+ end
205
+
181
206
  private
182
207
 
183
208
  # @api private
@@ -12,7 +12,9 @@ module ROM
12
12
 
13
13
  # @!attribute [r] compiler
14
14
  # @return [MapperCompiler] A mapper compiler instance
15
- option :compiler, default: -> { MapperCompiler.new(cache: cache) }
15
+ option :compiler, default: -> do
16
+ MapperCompiler.new(cache: cache)
17
+ end
16
18
 
17
19
  # @see Registry
18
20
  # @api public
@@ -1,4 +1,5 @@
1
1
  require 'rom/memory/gateway'
2
2
  require 'rom/memory/relation'
3
+ require 'rom/memory/mapper_compiler'
3
4
 
4
5
  ROM.register_adapter(:memory, ROM::Memory)
@@ -0,0 +1,8 @@
1
+ require 'rom/mapper_compiler'
2
+
3
+ module ROM
4
+ module Memory
5
+ class MapperCompiler < ROM::MapperCompiler
6
+ end
7
+ end
8
+ end
@@ -30,6 +30,13 @@ module ROM
30
30
  schema.project(*names).(self)
31
31
  end
32
32
 
33
+ # Rename attributes in a relation
34
+ #
35
+ # @api public
36
+ def rename(mapping)
37
+ schema.rename(mapping).(self)
38
+ end
39
+
33
40
  # Insert tuples into the relation
34
41
  #
35
42
  # @example
@@ -15,7 +15,7 @@ module ROM
15
15
  #
16
16
  # @api private
17
17
  def apply_to(klass, options = EMPTY_HASH)
18
- if options.any?
18
+ if mod.respond_to?(:new)
19
19
  klass.send(:include, mod.new(options))
20
20
  else
21
21
  klass.send(:include, mod)
@@ -0,0 +1,150 @@
1
+ require 'set'
2
+
3
+ module ROM
4
+ module Plugins
5
+ module Command
6
+ # A plugin for automatically adding timestamp values
7
+ # when executing a command
8
+ #
9
+ # Set up attributes to timestamp when the command is called
10
+ #
11
+ # @example
12
+ # class CreateTask < ROM::Commands::Create[:sql]
13
+ # result :one
14
+ # use :timestamps, timestamps: %i(created_at, updated_at), datestamps: %i(:written)
15
+ # end
16
+ #
17
+ # create_user = rom.command(:user).create.curry(name: 'Jane')
18
+ #
19
+ # result = create_user.call
20
+ # result[:created_at] #=> Time.now.utc
21
+ #
22
+ # @api public
23
+ class Timestamps < Module
24
+ attr_reader :timestamps, :datestamps
25
+ def initialize(timestamps: [], datestamps: [])
26
+ @timestamps = store_attributes(timestamps)
27
+ @datestamps = store_attributes(datestamps)
28
+ end
29
+
30
+ # @api private
31
+ def store_attributes(attr)
32
+ attr.is_a?(Array) ? attr : Array[attr]
33
+ end
34
+
35
+ # @api private
36
+ def included(klass)
37
+ initialize_timestamp_attributes(klass)
38
+ klass.include(InstanceMethods)
39
+ klass.extend(ClassInterface)
40
+ super
41
+ end
42
+
43
+ def initialize_timestamp_attributes(klass)
44
+ klass.defines :timestamp_columns, :datestamp_columns
45
+ klass.timestamp_columns Set.new
46
+ klass.datestamp_columns Set.new
47
+ klass.before :set_timestamps
48
+ klass.timestamp_columns klass.timestamp_columns.merge(timestamps) if timestamps.any?
49
+ klass.datestamp_columns klass.datestamp_columns.merge(datestamps) if datestamps.any?
50
+ end
51
+
52
+ module InstanceMethods
53
+ # @api private
54
+ def timestamp_columns
55
+ self.class.timestamp_columns
56
+ end
57
+
58
+ # @api private
59
+ def datestamp_columns
60
+ self.class.datestamp_columns
61
+ end
62
+
63
+ # Set the timestamp attributes on the given tuples
64
+ #
65
+ # @param [Array<Hash>, Hash] tuples the input tuple(s)
66
+ #
67
+ # @return [Array<Hash>, Hash]
68
+ #
69
+ # @api private
70
+ def set_timestamps(tuples, *)
71
+ timestamps = build_timestamps
72
+
73
+ case tuples
74
+ when Hash
75
+ timestamps.merge(tuples)
76
+ when Array
77
+ tuples.map { |t| timestamps.merge(t) }
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ # @api private
84
+ def build_timestamps
85
+ time = Time.now.utc
86
+ date = Date.today
87
+ timestamps = {}
88
+
89
+ timestamp_columns.each do |column|
90
+ timestamps[column.to_sym] = time
91
+ end
92
+
93
+ datestamp_columns.each do |column|
94
+ timestamps[column.to_sym] = date
95
+ end
96
+
97
+ timestamps
98
+ end
99
+ end
100
+
101
+ module ClassInterface
102
+ # @api private
103
+ # Set up attributes to timestamp when the command is called
104
+ #
105
+ # @example
106
+ # class CreateTask < ROM::Commands::Create[:sql]
107
+ # result :one
108
+ # use :timestamps
109
+ # timestamps :created_at, :updated_at
110
+ # end
111
+ #
112
+ # create_user = rom.command(:user).create.curry(name: 'Jane')
113
+ #
114
+ # result = create_user.call
115
+ # result[:created_at] #=> Time.now.utc
116
+ #
117
+ # @param [Array<Symbol>] names A list of attribute names
118
+ #
119
+ # @api public
120
+ def timestamps(*names)
121
+ timestamp_columns timestamp_columns.merge(names)
122
+ end
123
+ alias timestamp timestamps
124
+
125
+ # Set up attributes to datestamp when the command is called
126
+ #
127
+ # @example
128
+ # class CreateTask < ROM::Commands::Create[:sql]
129
+ # result :one
130
+ # use :timestamps
131
+ # datestamps :created_on, :updated_on
132
+ # end
133
+ #
134
+ # create_user = rom.command(:user).create.curry(name: 'Jane')
135
+ #
136
+ # result = create_user.call
137
+ # result[:created_at] #=> Date.today
138
+ #
139
+ # @param [Array<Symbol>] names A list of attribute names
140
+ #
141
+ # @api public
142
+ def datestamps(*names)
143
+ datestamp_columns datestamp_columns.merge(names)
144
+ end
145
+ alias datestamp datestamps
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -37,6 +37,16 @@ module ROM
37
37
  ElementNotFoundError
38
38
  end
39
39
 
40
+ # @api private
41
+ def merge(other)
42
+ self.class.new(Hash(other), options)
43
+ end
44
+
45
+ # @api private
46
+ def to_hash
47
+ elements
48
+ end
49
+
40
50
  # @api private
41
51
  def map(&block)
42
52
  new_elements = elements.each_with_object({}) do |(name, element), h|
@@ -175,7 +175,7 @@ module ROM
175
175
 
176
176
  # @!attribute [r] mappers
177
177
  # @return [MapperRegistry] an optional mapper registry (empty by default)
178
- option :mappers, default: -> { MapperRegistry.new }
178
+ option :mappers, default: -> { self.class.mapper_registry }
179
179
 
180
180
  # @!attribute [r] commands
181
181
  # @return [CommandRegistry] Command registry
@@ -602,7 +602,7 @@ module ROM
602
602
  if attr
603
603
  attr.name
604
604
  else
605
- :"#{Dry::Core::Inflector.singularize(name.dataset)}_id"
605
+ :"#{Inflector.singularize(name.dataset)}_id"
606
606
  end
607
607
  end
608
608
 
@@ -1,6 +1,6 @@
1
1
  require 'set'
2
2
 
3
- require 'dry/core/inflector'
3
+ require 'rom/support/inflector'
4
4
 
5
5
  require 'rom/constants'
6
6
  require 'rom/relation/name'
@@ -250,6 +250,24 @@ module ROM
250
250
  ROM.plugin_registry.relations.fetch(plugin, adapter).apply_to(self, options)
251
251
  end
252
252
 
253
+ # Build default mapper registry
254
+ #
255
+ # @return [MapperRegistry]
256
+ #
257
+ # @api private
258
+ def mapper_registry(opts = EMPTY_HASH)
259
+ adapter_ns = ROM.adapters[adapter]
260
+
261
+ compiler =
262
+ if adapter_ns && adapter_ns.const_defined?(:MapperCompiler)
263
+ adapter_ns.const_get(:MapperCompiler)
264
+ else
265
+ MapperCompiler
266
+ end
267
+
268
+ MapperRegistry.new({}, { compiler: compiler.new(opts) }.merge(opts))
269
+ end
270
+
253
271
  # @api private
254
272
  def curried
255
273
  Curried
@@ -274,7 +292,7 @@ module ROM
274
292
  #
275
293
  # @api private
276
294
  def default_name
277
- Name[Dry::Core::Inflector.underscore(name).tr('/', '_').to_sym]
295
+ Name[Inflector.underscore(name).tr('/', '_').to_sym]
278
296
  end
279
297
 
280
298
  # @api private
@@ -70,10 +70,10 @@ module ROM
70
70
  # Return a new combined relation with adjusted node returned from a block
71
71
  #
72
72
  # @example with a node identifier
73
- # aggregate(:tasks).node(:tasks) { |tasks| tasks.prioritized }
73
+ # combine(:tasks).node(:tasks) { |tasks| tasks.prioritized }
74
74
  #
75
75
  # @example with a nested path
76
- # aggregate(tasks: :tags).node(tasks: :tags) { |tags| tags.where(name: 'red') }
76
+ # combine(tasks: :tags).node(tasks: :tags) { |tags| tags.where(name: 'red') }
77
77
  #
78
78
  # @param [Symbol] name The node relation name
79
79
  #
@@ -35,8 +35,8 @@ module ROM
35
35
  # @return [ROM::Command]
36
36
  #
37
37
  # @api public
38
- def command(type, mapper: nil, use: EMPTY_ARRAY, **opts)
39
- base_command = commands.key?(type) ? commands[type] : commands[type, adapter, to_ast, use, opts]
38
+ def command(type, mapper: nil, use: EMPTY_ARRAY, plugins_options: EMPTY_HASH, **opts)
39
+ base_command = commands.key?(type) ? commands[type] : commands[type, adapter, to_ast, use, plugins_options, opts]
40
40
 
41
41
  command =
42
42
  if mapper
@@ -1,4 +1,4 @@
1
- require 'dry/core/inflector'
1
+ require 'rom/support/inflector'
2
2
 
3
3
  require 'rom/associations/definitions'
4
4
 
@@ -197,7 +197,7 @@ module ROM
197
197
 
198
198
  # @api private
199
199
  def dataset_name(name)
200
- ::Dry::Core::Inflector.pluralize(name).to_sym
200
+ Inflector.pluralize(name).to_sym
201
201
  end
202
202
  end
203
203
  end
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
- require 'dry/core/inflector'
3
+ require 'rom/support/inflector'
4
4
 
5
5
  require 'rom/types'
6
6
  require 'rom/initializer'
@@ -94,7 +94,7 @@ module ROM
94
94
  ).call
95
95
  end
96
96
 
97
- Dry::Core::Inflector.constantize(klass_name)
97
+ Inflector.constantize(klass_name)
98
98
  end
99
99
  end
100
100
  end
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
- require 'dry/core/inflector'
3
+ require 'rom/support/inflector'
4
4
  require 'rom/types'
5
5
  require 'rom/setup/auto_registration_strategies/base'
6
6
 
@@ -28,7 +28,7 @@ module ROM
28
28
 
29
29
  path_arr.reverse.each do |dir|
30
30
  const_fragment = potential.unshift(
31
- Dry::Core::Inflector.camelize(dir)
31
+ Inflector.camelize(dir)
32
32
  ).join("::")
33
33
 
34
34
  constant = "#{namespace}::#{const_fragment}"
@@ -40,7 +40,7 @@ module ROM
40
40
 
41
41
  # If we have reached this point, its means constant is not defined and
42
42
  # NameError will be thrown if we attempt to camelize something like:
43
- # `"#{namespace}::#{Dry::Core::Inflector.camelize(filename)}"`
43
+ # `"#{namespace}::#{Inflector.camelize(filename)}"`
44
44
  # so we can assume naming convention was not respected in required
45
45
  # file.
46
46
 
@@ -63,7 +63,7 @@ module ROM
63
63
 
64
64
  # @api private
65
65
  def ns_const
66
- @namespace_constant ||= Dry::Core::Inflector.constantize(namespace)
66
+ @namespace_constant ||= Inflector.constantize(namespace)
67
67
  end
68
68
 
69
69
  # @api private
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
- require 'dry/core/inflector'
3
+ require 'rom/support/inflector'
4
4
  require 'rom/types'
5
5
  require 'rom/setup/auto_registration_strategies/base'
6
6
 
@@ -22,7 +22,7 @@ module ROM
22
22
  #
23
23
  # @api private
24
24
  def call
25
- Dry::Core::Inflector.camelize(
25
+ Inflector.camelize(
26
26
  file.sub(/^#{directory}\/#{entity}\//, '').sub(EXTENSION_REGEX, '')
27
27
  )
28
28
  end
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
 
3
- require 'dry/core/inflector'
3
+ require 'rom/support/inflector'
4
4
  require 'rom/setup/auto_registration_strategies/base'
5
5
 
6
6
  module ROM
@@ -18,7 +18,7 @@ module ROM
18
18
  #
19
19
  # @api private
20
20
  def call
21
- Dry::Core::Inflector.camelize(
21
+ Inflector.camelize(
22
22
  file.sub(/^#{directory.dirname}\//, '').sub(EXTENSION_REGEX, '')
23
23
  )
24
24
  end
@@ -31,7 +31,7 @@ module ROM
31
31
 
32
32
  notifications.trigger(
33
33
  'configuration.commands.class.before_build',
34
- command: klass, gateway: gateway, dataset: relation.dataset
34
+ command: klass, gateway: gateway, dataset: relation.dataset, adapter: relation.adapter
35
35
  )
36
36
 
37
37
  klass.extend_for_relation(relation) if klass.restrictable
@@ -43,7 +43,7 @@ module ROM
43
43
 
44
44
  klass.use(:registry_reader, relation_names)
45
45
 
46
- notifications.trigger('configuration.relations.class.ready', relation: klass)
46
+ notifications.trigger('configuration.relations.class.ready', relation: klass, adapter: klass.adapter)
47
47
 
48
48
  relations[key] = build_relation(klass, registry)
49
49
  end
@@ -101,13 +101,22 @@ 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({}, cache: @mappers.cache)
105
-
106
- options = { __registry__: registry, mappers: mappers, schema: schema, **plugin_options }
104
+ options = { __registry__: registry, mappers: mapper_registry(rel_key, klass), schema: schema, **plugin_options }
107
105
 
108
106
  klass.new(dataset, options)
109
107
  end
110
108
 
109
+ # @api private
110
+ def mapper_registry(rel_key, rel_class)
111
+ registry = rel_class.mapper_registry(cache: @mappers.cache)
112
+
113
+ if @mappers.key?(rel_key)
114
+ registry.merge(@mappers[rel_key])
115
+ else
116
+ registry
117
+ end
118
+ end
119
+
111
120
  # @api private
112
121
  def plugin_options
113
122
  relation_plugins.map(&:config).map(&:to_hash).reduce(:merge) || EMPTY_HASH
@@ -0,0 +1,7 @@
1
+ require 'dry/inflector'
2
+
3
+ module ROM
4
+ Inflector = Dry::Inflector.new do |i|
5
+ i.plural(/people\z/i, 'people')
6
+ end
7
+ end
@@ -103,6 +103,16 @@ module ROM
103
103
  @payload.fetch(name)
104
104
  end
105
105
 
106
+ # Coerce an event to a hash
107
+ #
108
+ # @return [Hash]
109
+ #
110
+ # @api public
111
+ def to_h
112
+ @payload
113
+ end
114
+ alias_method :to_hash, :to_h
115
+
106
116
  # Get or set a payload
107
117
  #
108
118
  # @overload
@@ -1,5 +1,5 @@
1
1
  module ROM
2
2
  module Core
3
- VERSION = '4.0.2'.freeze
3
+ VERSION = '4.1.0'.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.2
4
+ version: 4.1.0
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-11-02 00:00:00.000000000 Z
11
+ date: 2017-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-inflector
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: dry-container
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,20 +100,6 @@ dependencies:
72
100
  - - ">="
73
101
  - !ruby/object:Gem::Version
74
102
  version: 0.12.1
75
- - !ruby/object:Gem::Dependency
76
- name: dry-core
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '0.3'
82
- type: :runtime
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.3'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: dry-initializer
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -106,20 +120,14 @@ dependencies:
106
120
  requirements:
107
121
  - - "~>"
108
122
  - !ruby/object:Gem::Version
109
- version: '1.0'
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: 1.0.2
123
+ version: '1.1'
113
124
  type: :runtime
114
125
  prerelease: false
115
126
  version_requirements: !ruby/object:Gem::Requirement
116
127
  requirements:
117
128
  - - "~>"
118
129
  - !ruby/object:Gem::Version
119
- version: '1.0'
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: 1.0.2
130
+ version: '1.1'
123
131
  - !ruby/object:Gem::Dependency
124
132
  name: rake
125
133
  requirement: !ruby/object:Gem::Requirement
@@ -226,6 +234,7 @@ files:
226
234
  - lib/rom/memory/commands.rb
227
235
  - lib/rom/memory/dataset.rb
228
236
  - lib/rom/memory/gateway.rb
237
+ - lib/rom/memory/mapper_compiler.rb
229
238
  - lib/rom/memory/relation.rb
230
239
  - lib/rom/memory/schema.rb
231
240
  - lib/rom/memory/storage.rb
@@ -235,6 +244,7 @@ files:
235
244
  - lib/rom/plugin_base.rb
236
245
  - lib/rom/plugin_registry.rb
237
246
  - lib/rom/plugins/command/schema.rb
247
+ - lib/rom/plugins/command/timestamps.rb
238
248
  - lib/rom/plugins/relation/instrumentation.rb
239
249
  - lib/rom/plugins/relation/registry_reader.rb
240
250
  - lib/rom/plugins/schema/timestamps.rb
@@ -268,6 +278,7 @@ files:
268
278
  - lib/rom/setup/finalize/finalize_mappers.rb
269
279
  - lib/rom/setup/finalize/finalize_relations.rb
270
280
  - lib/rom/support/configurable.rb
281
+ - lib/rom/support/inflector.rb
271
282
  - lib/rom/support/memoizable.rb
272
283
  - lib/rom/support/notifications.rb
273
284
  - lib/rom/transaction.rb