rom 0.6.0.beta3 → 0.6.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.
@@ -101,8 +101,8 @@ describe ROM::Setup do
101
101
  expect(env.relations).to eql(ROM::RelationRegistry.new)
102
102
  end
103
103
 
104
- it 'builds empty readers' do
105
- expect(env.readers).to eql(ROM::ReaderRegistry.new)
104
+ it 'builds empty mappers' do
105
+ expect(env.mappers).to eql(ROM::Registry.new)
106
106
  end
107
107
 
108
108
  it 'builds empty commands' do
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.0.beta3
4
+ version: 0.6.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: 2015-03-03 00:00:00.000000000 Z
11
+ date: 2015-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: transproc
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.2
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.2
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: equalizer
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -152,8 +158,8 @@ files:
152
158
  - lib/rom/model_builder.rb
153
159
  - lib/rom/processor.rb
154
160
  - lib/rom/processor/transproc.rb
155
- - lib/rom/reader.rb
156
161
  - lib/rom/relation.rb
162
+ - lib/rom/relation/class_interface.rb
157
163
  - lib/rom/relation/composite.rb
158
164
  - lib/rom/relation/curried.rb
159
165
  - lib/rom/relation/lazy.rb
@@ -220,7 +226,6 @@ files:
220
226
  - spec/unit/rom/memory/storage_spec.rb
221
227
  - spec/unit/rom/model_builder_spec.rb
222
228
  - spec/unit/rom/processor/transproc_spec.rb
223
- - spec/unit/rom/reader_spec.rb
224
229
  - spec/unit/rom/registry_spec.rb
225
230
  - spec/unit/rom/relation/composite_spec.rb
226
231
  - spec/unit/rom/relation/lazy_spec.rb
data/lib/rom/reader.rb DELETED
@@ -1,174 +0,0 @@
1
- module ROM
2
- # Exposes mapped tuples via enumerable interface
3
- #
4
- # See example for each method
5
- #
6
- # @api public
7
- class Reader
8
- include Enumerable
9
- include Equalizer.new(:path, :relation, :mapper)
10
-
11
- # Map relation to an array using a mapper
12
- #
13
- # @return [Array]
14
- #
15
- # @api public
16
- alias_method :to_ary, :to_a
17
-
18
- # @return [String] access path used to read a relation
19
- #
20
- # @api private
21
- attr_reader :path
22
-
23
- # @return [Relation] relation used by the reader
24
- #
25
- # @api private
26
- attr_reader :relation
27
-
28
- # @return [MapperRegistry] registry of mappers used by the reader
29
- #
30
- # @api private
31
- attr_reader :mappers
32
-
33
- # @return [Mapper] mapper to read the relation
34
- #
35
- # @api private
36
- attr_reader :mapper
37
-
38
- # Builds a reader instance for the provided relation
39
- #
40
- # @param [Symbol] name of the root relation
41
- # @param [Relation] relation that the reader will use
42
- # @param [MapperRegistry] mappers registry of mappers
43
- # @param [Array<Symbol>] method_names a list of method names exposed by the relation
44
- #
45
- # @return [Reader]
46
- #
47
- # @api private
48
- def self.build(name, relation, mappers, method_names = [])
49
- klass = build_class(relation, method_names)
50
- klass.new(name, relation, mappers)
51
- end
52
-
53
- # Build a reader subclass for the relation
54
- #
55
- # This method defines public methods on the class narrowing down data access
56
- # only to the methods exposed by a given relation
57
- #
58
- # @param [Relation] relation that the reader will use
59
- # @param [Array<Symbol>] method_names a list of method names exposed by the relation
60
- #
61
- # @return [Class]
62
- #
63
- # @api private
64
- def self.build_class(relation, method_names)
65
- klass_name = "#{Reader.name}[#{Inflector.camelize(relation.name)}]"
66
-
67
- ClassBuilder.new(name: klass_name, parent: Reader).call do |klass|
68
- method_names.each do |method_name|
69
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
70
- def #{method_name}(*args, &block)
71
- new_relation = relation.send(#{method_name.inspect}, *args, &block)
72
- self.class.new(
73
- new_path(#{method_name.to_s.inspect}), new_relation, mappers
74
- )
75
- end
76
- RUBY
77
- end
78
- end
79
- end
80
-
81
- # @api private
82
- def initialize(path, relation, mappers, mapper = nil)
83
- @path = path.to_s
84
- @relation = relation
85
- @mappers = mappers
86
- @mapper = mapper || mappers.by_path(@path)
87
- end
88
-
89
- # @api private
90
- def header
91
- mapper.header
92
- end
93
-
94
- # Yields tuples mapped to objects
95
- #
96
- # @example
97
- #
98
- # # accessing root relation
99
- # rom.read(:users).each { |user| # ... }
100
- #
101
- # # accessing virtual relations
102
- # rom.read(:users).adults.recent.active.each { |user| # ... }
103
- #
104
- # @api public
105
- def each
106
- mapper.call(relation).each { |tuple| yield(tuple) }
107
- end
108
-
109
- # Returns a single tuple from the relation if there is one.
110
- #
111
- # @raise [ROM::TupleCountMismatchError] if the relation contains more than
112
- # one tuple
113
- #
114
- # @api public
115
- def one
116
- if relation.count > 1
117
- raise(
118
- TupleCountMismatchError,
119
- 'The relation consists of more than one tuple'
120
- )
121
- else
122
- mapper.call(relation).first
123
- end
124
- end
125
-
126
- # Like [one], but additionally raises an error if the relation is empty.
127
- #
128
- # @raise [ROM::TupleCountMismatchError] if the relation does not contain
129
- # exactly one tuple
130
- #
131
- # @api public
132
- def one!
133
- one || raise(
134
- TupleCountMismatchError,
135
- 'The relation does not contain any tuples'
136
- )
137
- end
138
-
139
- # Map tuples using a specific mapper if name is provided
140
- #
141
- # Defaults to Enumerable#map behavior
142
- #
143
- # @example
144
- #
145
- # rom.read(:users).map(:my_mapper_name)
146
- # rom.read(:users).map { |user| ... }
147
- #
148
- # @return [Array,Reader]
149
- #
150
- # @api public
151
- def map(*args)
152
- if args.any?
153
- mappers[args[0]].call(relation)
154
- else
155
- super
156
- end
157
- end
158
-
159
- private
160
-
161
- # @api private
162
- def method_missing(name, *)
163
- raise(
164
- NoRelationError,
165
- "undefined relation #{name.inspect} within #{path.inspect}"
166
- )
167
- end
168
-
169
- # @api private
170
- def new_path(name)
171
- path.dup << ".#{name}"
172
- end
173
- end
174
- end
@@ -1,146 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ROM::Reader do
4
- subject(:reader) { ROM::Reader.new(name, relation, mappers) }
5
-
6
- let(:name) { :users }
7
- let(:relation) { [jane, joe] }
8
- let(:jane) { { name: 'Jane' } }
9
- let(:joe) { { name: 'Joe' } }
10
- let(:mappers) { ROM::MapperRegistry.new(users: mapper) }
11
- let(:mapper) { double('mapper', header: []) }
12
-
13
- describe '.build' do
14
- subject(:reader) do
15
- ROM::Reader.build(name, relation, mappers, [:all])
16
- end
17
-
18
- before do
19
- relation.instance_exec do
20
- def name
21
- 'users'
22
- end
23
-
24
- def all(*_args)
25
- find_all
26
- end
27
- end
28
- end
29
-
30
- it 'sets reader class name' do
31
- expect(reader.class.name).to eql("ROM::Reader[Users]")
32
- end
33
-
34
- it 'defines methods from relation' do
35
- block = proc {}
36
-
37
- user_id = 1
38
-
39
- expect(relation).to receive(:all)
40
- .with(user_id, &block)
41
- .and_return([joe])
42
-
43
- expect(mapper).to receive(:call)
44
- .with([joe])
45
- .and_return([joe])
46
-
47
- result = reader.all(user_id, &block)
48
-
49
- expect(result.path).to eql('users.all')
50
- expect(result.to_a).to eql([joe])
51
- end
52
-
53
- it 'raises error when relation does not respond to the method' do
54
- expect { reader.not_here }
55
- .to raise_error(ROM::NoRelationError, /not_here/)
56
- end
57
-
58
- it 'raises error when relation does not respond to the method with args' do
59
- expect { reader.find_by_id(1) }
60
- .to raise_error(ROM::NoRelationError, /find_by_id/)
61
- end
62
- end
63
-
64
- describe '#initialize' do
65
- it 'raises error when mapper cannot be found' do
66
- expect { ROM::Reader.new(:not_here, relation, mappers) }
67
- .to raise_error(ROM::MapperMissingError, /not_here/)
68
- end
69
- end
70
-
71
- describe '#each' do
72
- it 'yields mapped tuples from relations' do
73
- expect(mapper).to receive(:call)
74
- .with(relation)
75
- .and_return(relation)
76
-
77
- result = []
78
- reader.each { |user| result << user }
79
- expect(result).to eql([jane, joe])
80
- end
81
- end
82
-
83
- shared_examples_for 'one and one!' do |method|
84
- context 'with a single tuple' do
85
- let(:relation) { [jane] }
86
-
87
- it 'returns a single tuple' do
88
- expect(mapper).to receive(:call)
89
- .with(relation)
90
- .and_return(relation)
91
-
92
- expect(reader.public_send(method)).to eql(jane)
93
- end
94
- end
95
-
96
- context 'with more than one tuple' do
97
- it 'raises an error' do
98
- expect { reader.public_send(method) }
99
- .to raise_error(ROM::TupleCountMismatchError)
100
- end
101
- end
102
- end
103
-
104
- describe '#one' do
105
- it_should_behave_like 'one and one!', :one
106
-
107
- context 'without any tuple' do
108
- let(:relation) { [] }
109
-
110
- it 'returns nil' do
111
- expect(mapper).to receive(:call)
112
- .with(relation)
113
- .and_return(relation)
114
-
115
- expect(reader.one).to be_nil
116
- end
117
- end
118
- end
119
-
120
- describe '#one!' do
121
- it_should_behave_like 'one and one!', :one!
122
-
123
- context 'without any tuple' do
124
- let(:relation) { [] }
125
-
126
- it 'raises an error' do
127
- expect(mapper).to receive(:call)
128
- .with(relation)
129
- .and_return(relation)
130
-
131
- expect { reader.one! }.to raise_error(ROM::TupleCountMismatchError)
132
- end
133
- end
134
- end
135
-
136
- describe '#to_ary' do
137
- it 'casts relation to an array with loaded objects' do
138
- expect(mapper).to receive(:call)
139
- .with(relation)
140
- .and_return(relation)
141
-
142
- result = reader.to_ary
143
- expect(result).to eql(relation)
144
- end
145
- end
146
- end