rom 0.6.0 → 0.6.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile +1 -0
- data/README.md +1 -1
- data/lib/rom/command_registry.rb +90 -2
- data/lib/rom/commands/abstract.rb +1 -0
- data/lib/rom/commands/composite.rb +40 -1
- data/lib/rom/env.rb +12 -10
- data/lib/rom/support/options.rb +4 -0
- data/lib/rom/support/registry.rb +6 -2
- data/lib/rom/version.rb +1 -1
- data/rom.gemspec +0 -1
- data/spec/integration/commands/create_spec.rb +74 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/rom/commands_spec.rb +17 -0
- data/spec/unit/rom/env_spec.rb +9 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 865d4e2694bbdadfd473db6464100f268393559d
|
4
|
+
data.tar.gz: b676c75f27251e94c18c654213f27129a6be0651
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e89088463acbd0e5f6f90d599e9d6c8ab2fbc6ef35f9c6f5a12f41c68e5f2a2a471a710ccbc7172568faf750f0cd124abb79a0907b9d4bb9c9d12e3addbd72fa
|
7
|
+
data.tar.gz: f4a6d18309f9874329f7d3ec927ec10ea46bfb19e90d2c73fd5c09009c2735294a01eede5f858531fdeae52748ccc3e2b47c25880ddebae619e41862c02b3837
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## v0.6.1 2015-04-04
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Ability to auto-map command result via `rom.command(:rel_name).as(:mapper_name)` (solnic)
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
|
9
|
+
* gemspec no longer specifies required_ruby_version so that rom can be installed on jruby (solnic)
|
10
|
+
* Obsolete `Env#readers` was removed (splattael)
|
11
|
+
|
12
|
+
[Compare v0.6.0...v0.6.1](https://github.com/rom-rb/rom/compare/v0.6.0...v0.6.1)
|
13
|
+
|
1
14
|
## v0.6.0 2015-03-22
|
2
15
|
|
3
16
|
### Added
|
data/Gemfile
CHANGED
data/README.md
CHANGED
data/lib/rom/command_registry.rb
CHANGED
@@ -1,11 +1,33 @@
|
|
1
1
|
require 'rom/commands/result'
|
2
2
|
|
3
3
|
module ROM
|
4
|
-
#
|
4
|
+
# Specialized registry class for commands
|
5
5
|
#
|
6
6
|
# @api public
|
7
|
-
class CommandRegistry
|
7
|
+
class CommandRegistry
|
8
8
|
include Commands
|
9
|
+
include Options
|
10
|
+
|
11
|
+
# Internal command registry
|
12
|
+
#
|
13
|
+
# @return [Registry]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
attr_reader :registry
|
17
|
+
|
18
|
+
option :mappers, reader: true
|
19
|
+
option :mapper, reader: true
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def initialize(elements, options = {})
|
23
|
+
super
|
24
|
+
@registry =
|
25
|
+
if elements.is_a?(Registry)
|
26
|
+
elements
|
27
|
+
else
|
28
|
+
Registry.new(elements, self.class.name)
|
29
|
+
end
|
30
|
+
end
|
9
31
|
|
10
32
|
# Try to execute a command in a block
|
11
33
|
#
|
@@ -31,5 +53,71 @@ module ROM
|
|
31
53
|
rescue CommandError => e
|
32
54
|
Result::Failure.new(e)
|
33
55
|
end
|
56
|
+
|
57
|
+
# Return a command from the registry
|
58
|
+
#
|
59
|
+
# If mapper is set command will be turned into a composite command with
|
60
|
+
# auto-mapping
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# create_user = rom.command(:users)[:create]
|
64
|
+
# create_user[name: 'Jane']
|
65
|
+
#
|
66
|
+
# # with mapping, assuming :entity mapper is registered for :users relation
|
67
|
+
# create_user = rom.command(:users).as(:entity)[:create]
|
68
|
+
# create_user[name: 'Jane'] # => result is send through :entity mapper
|
69
|
+
#
|
70
|
+
# @param [Symbol] name The name of a registered command
|
71
|
+
#
|
72
|
+
# @return [Command,Command::Composite]
|
73
|
+
#
|
74
|
+
# @api public
|
75
|
+
def [](name)
|
76
|
+
command = registry[name]
|
77
|
+
mapper = options[:mapper]
|
78
|
+
|
79
|
+
if mapper
|
80
|
+
command.curry >> mapper
|
81
|
+
else
|
82
|
+
command
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Specify a mapper that should be used for commands from this registry
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
# entity_commands = rom.command(:users).as(:entity)
|
90
|
+
#
|
91
|
+
#
|
92
|
+
# @param [Symbol] mapper_name The name of a registered mapper
|
93
|
+
#
|
94
|
+
# @return [CommandRegistry]
|
95
|
+
#
|
96
|
+
# @api public
|
97
|
+
def as(mapper_name)
|
98
|
+
with(mapper: mappers[mapper_name])
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return new instance of this registry with updated options
|
102
|
+
#
|
103
|
+
# @return [CommandRegistry]
|
104
|
+
#
|
105
|
+
# @api private
|
106
|
+
def with(new_options)
|
107
|
+
self.class.new(registry, options.merge(new_options))
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# Allow retrieving commands using dot-notation
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
def method_missing(name, *)
|
116
|
+
if registry.key?(name)
|
117
|
+
self[name]
|
118
|
+
else
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
34
122
|
end
|
35
123
|
end
|
@@ -29,8 +29,19 @@ module ROM
|
|
29
29
|
#
|
30
30
|
# @api public
|
31
31
|
def call(*args)
|
32
|
-
|
32
|
+
response = left.call(*args)
|
33
|
+
|
34
|
+
if result == :one
|
35
|
+
if right.is_a?(Command) || right.is_a?(Commands::Composite)
|
36
|
+
right.call([response].first)
|
37
|
+
else
|
38
|
+
right.call([response]).first
|
39
|
+
end
|
40
|
+
else
|
41
|
+
right.call(response)
|
42
|
+
end
|
33
43
|
end
|
44
|
+
alias_method :[], :call
|
34
45
|
|
35
46
|
# Compose another composite command from self and other
|
36
47
|
#
|
@@ -42,6 +53,34 @@ module ROM
|
|
42
53
|
def >>(other)
|
43
54
|
self.class.new(self, other)
|
44
55
|
end
|
56
|
+
|
57
|
+
# @api private
|
58
|
+
def result
|
59
|
+
left.result
|
60
|
+
end
|
61
|
+
|
62
|
+
# @api private
|
63
|
+
def respond_to_missing?(name, include_private = false)
|
64
|
+
left.respond_to?(name) || super
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Allow calling methods on the left side object
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def method_missing(name, *args, &block)
|
73
|
+
if left.respond_to?(name)
|
74
|
+
response = left.__send__(name, *args, &block)
|
75
|
+
if response.is_a?(left.class)
|
76
|
+
self.class.new(response, right)
|
77
|
+
else
|
78
|
+
response
|
79
|
+
end
|
80
|
+
else
|
81
|
+
super
|
82
|
+
end
|
83
|
+
end
|
45
84
|
end
|
46
85
|
end
|
47
86
|
end
|
data/lib/rom/env.rb
CHANGED
@@ -17,11 +17,6 @@ module ROM
|
|
17
17
|
# @api public
|
18
18
|
attr_reader :relations
|
19
19
|
|
20
|
-
# @return [ReaderRegistry] reader registry
|
21
|
-
#
|
22
|
-
# @api public
|
23
|
-
attr_reader :readers
|
24
|
-
|
25
20
|
# @return [Registry] command registry
|
26
21
|
#
|
27
22
|
# @api public
|
@@ -33,12 +28,11 @@ module ROM
|
|
33
28
|
attr_reader :mappers
|
34
29
|
|
35
30
|
# @api private
|
36
|
-
def initialize(repositories, relations, mappers, commands
|
31
|
+
def initialize(repositories, relations, mappers, commands)
|
37
32
|
@repositories = repositories
|
38
33
|
@relations = relations
|
39
34
|
@mappers = mappers
|
40
35
|
@commands = commands
|
41
|
-
@readers = readers
|
42
36
|
freeze
|
43
37
|
end
|
44
38
|
|
@@ -69,7 +63,7 @@ module ROM
|
|
69
63
|
relations[name]
|
70
64
|
end
|
71
65
|
|
72
|
-
if mappers.
|
66
|
+
if mappers.key?(name)
|
73
67
|
relation.to_lazy(mappers: mappers[name])
|
74
68
|
else
|
75
69
|
relation.to_lazy
|
@@ -92,7 +86,7 @@ module ROM
|
|
92
86
|
#
|
93
87
|
# @api public
|
94
88
|
def read(name, &block)
|
95
|
-
warn <<-MSG
|
89
|
+
warn <<-MSG.gsub(/^\s+/, '')
|
96
90
|
#{self.class}#read is deprecated.
|
97
91
|
Please use `#{self.class}#relation(#{name.inspect})` instead.
|
98
92
|
For mapping append `.map_with(:your_mapper_name)`
|
@@ -105,11 +99,19 @@ module ROM
|
|
105
99
|
#
|
106
100
|
# @example
|
107
101
|
#
|
102
|
+
# # plain command returning tuples
|
108
103
|
# rom.command(:users).create
|
109
104
|
#
|
105
|
+
# # allow auto-mapping using registered mappers
|
106
|
+
# rom.command(:users).as(:entity)
|
107
|
+
#
|
110
108
|
# @api public
|
111
109
|
def command(name)
|
112
|
-
|
110
|
+
if mappers.key?(name)
|
111
|
+
commands[name].with(mappers: mappers[name])
|
112
|
+
else
|
113
|
+
commands[name]
|
114
|
+
end
|
113
115
|
end
|
114
116
|
end
|
115
117
|
end
|
data/lib/rom/support/options.rb
CHANGED
data/lib/rom/support/registry.rb
CHANGED
@@ -12,9 +12,9 @@ module ROM
|
|
12
12
|
|
13
13
|
attr_reader :elements, :name
|
14
14
|
|
15
|
-
def initialize(elements = {})
|
15
|
+
def initialize(elements = {}, name = self.class.name)
|
16
16
|
@elements = elements
|
17
|
-
@name =
|
17
|
+
@name = name
|
18
18
|
end
|
19
19
|
|
20
20
|
def each(&block)
|
@@ -22,6 +22,10 @@ module ROM
|
|
22
22
|
elements.each { |element| yield(element) }
|
23
23
|
end
|
24
24
|
|
25
|
+
def key?(name)
|
26
|
+
elements.key?(name)
|
27
|
+
end
|
28
|
+
|
25
29
|
def [](key)
|
26
30
|
elements.fetch(key) { raise ElementNotFoundError.new(key, name) }
|
27
31
|
end
|
data/lib/rom/version.rb
CHANGED
data/rom.gemspec
CHANGED
@@ -14,7 +14,6 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.files = `git ls-files`.split("\n").reject { |name| name.include?('benchmarks') }
|
15
15
|
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
16
16
|
gem.license = 'MIT'
|
17
|
-
gem.required_ruby_version = '~> 2.0'
|
18
17
|
|
19
18
|
gem.add_runtime_dependency 'transproc', '~> 0.1', '>= 0.1.2'
|
20
19
|
gem.add_runtime_dependency 'equalizer', '~> 0.0', '>= 0.0.9'
|
@@ -35,9 +35,33 @@ describe 'Commands / Create' do
|
|
35
35
|
result :one
|
36
36
|
|
37
37
|
def execute(user, task)
|
38
|
-
super(task.merge(name: user[:name]))
|
38
|
+
super(task.merge(name: user.to_h[:name]))
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
Test::User = Class.new do
|
43
|
+
include Anima.new(:name, :email)
|
44
|
+
end
|
45
|
+
|
46
|
+
Test::Task = Class.new do
|
47
|
+
include Anima.new(:name, :title)
|
48
|
+
end
|
49
|
+
|
50
|
+
class Test::UserMapper < ROM::Mapper
|
51
|
+
relation :users
|
52
|
+
register_as :entity
|
53
|
+
model Test::User
|
54
|
+
attribute :name
|
55
|
+
attribute :email
|
56
|
+
end
|
57
|
+
|
58
|
+
class Test::TaskMapper < ROM::Mapper
|
59
|
+
relation :tasks
|
60
|
+
register_as :entity
|
61
|
+
model Test::Task
|
62
|
+
attribute :name
|
63
|
+
attribute :title
|
64
|
+
end
|
41
65
|
end
|
42
66
|
|
43
67
|
it 'inserts user on successful validation' do
|
@@ -94,4 +118,53 @@ describe 'Commands / Create' do
|
|
94
118
|
}.to raise_error(ROM::InvalidOptionValueError)
|
95
119
|
end
|
96
120
|
end
|
121
|
+
|
122
|
+
describe 'sending result through a mapper' do
|
123
|
+
let(:attributes) do
|
124
|
+
{ name: 'Jane', email: 'jane@doe.org' }
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'uses registered mapper to process the result for :one result' do
|
128
|
+
command = rom.command(:users).as(:entity).create
|
129
|
+
result = command[attributes]
|
130
|
+
|
131
|
+
expect(result).to eql(Test::User.new(attributes))
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'with two composed commands respects the :result option' do
|
135
|
+
mapper_input = nil
|
136
|
+
|
137
|
+
mapper = proc do |tuples|
|
138
|
+
mapper_input = tuples
|
139
|
+
end
|
140
|
+
|
141
|
+
left = rom.command(:users).as(:entity).create.with(
|
142
|
+
name: 'Jane', email: 'jane@doe.org'
|
143
|
+
)
|
144
|
+
|
145
|
+
right = rom.command(:tasks).as(:entity).create.with(
|
146
|
+
title: 'Jane task'
|
147
|
+
)
|
148
|
+
|
149
|
+
command = left >> right >> mapper
|
150
|
+
|
151
|
+
result = command.call
|
152
|
+
|
153
|
+
task = Test::Task.new(name: 'Jane', title: 'Jane task')
|
154
|
+
|
155
|
+
expect(mapper_input).to eql([task])
|
156
|
+
expect(result).to eql(task)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'uses registered mapper to process the result for :many results' do
|
160
|
+
setup.commands(:users) do
|
161
|
+
define(:create_many, type: :create)
|
162
|
+
end
|
163
|
+
|
164
|
+
command = rom.command(:users).as(:entity).create_many
|
165
|
+
result = command[attributes]
|
166
|
+
|
167
|
+
expect(result).to eql([Test::User.new(attributes)])
|
168
|
+
end
|
169
|
+
end
|
97
170
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -160,6 +160,23 @@ describe 'Commands' do
|
|
160
160
|
expect(result).to eql(task_tuple)
|
161
161
|
expect(logs).to include(task_tuple)
|
162
162
|
end
|
163
|
+
|
164
|
+
it 'forwards methods to the left' do
|
165
|
+
user_input = { name: 'Jane' }
|
166
|
+
user_tuple = { user_id: 1, name: 'Jane' }
|
167
|
+
|
168
|
+
create_user = Class.new(ROM::Commands::Create) {
|
169
|
+
def execute(user_input)
|
170
|
+
relation.insert(user_input)
|
171
|
+
end
|
172
|
+
}.build(users)
|
173
|
+
|
174
|
+
command = create_user >> proc {}
|
175
|
+
|
176
|
+
expect(users).to receive(:insert).with(user_input).and_return(user_tuple)
|
177
|
+
|
178
|
+
command.with(user_input).call
|
179
|
+
end
|
163
180
|
end
|
164
181
|
|
165
182
|
describe 'access to exposed relations' do
|
data/spec/unit/rom/env_spec.rb
CHANGED
@@ -44,6 +44,15 @@ describe ROM::Env do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
describe '#read' do
|
48
|
+
it 'returns loaded relation and display a deprecation warning' do
|
49
|
+
expect {
|
50
|
+
result = rom.read(:users) { |r| r.by_name('Jane') }.as(:name_list)
|
51
|
+
expect(result.call).to match_array([{ name: 'Jane' }])
|
52
|
+
}.to output(/^ROM::Env#read is deprecated/).to_stderr
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
47
56
|
describe '#mappers' do
|
48
57
|
it 'returns mappers for all relations' do
|
49
58
|
expect(rom.mappers.users[:name_list]).to_not be(nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: transproc
|
@@ -248,9 +248,9 @@ require_paths:
|
|
248
248
|
- lib
|
249
249
|
required_ruby_version: !ruby/object:Gem::Requirement
|
250
250
|
requirements:
|
251
|
-
- - "
|
251
|
+
- - ">="
|
252
252
|
- !ruby/object:Gem::Version
|
253
|
-
version: '
|
253
|
+
version: '0'
|
254
254
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
255
255
|
requirements:
|
256
256
|
- - ">="
|