rom 0.3.0 → 0.3.1

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: 721bf4200ba43797d78160490085ab5f545c4845
4
- data.tar.gz: b0931e08715301413a9f21ab95694dee5a1d1074
3
+ metadata.gz: 728df93bc1b41195f801808c3849bc5012575181
4
+ data.tar.gz: be8e7364087eb867e25f2c0347fde4f7eb0dd4db
5
5
  SHA512:
6
- metadata.gz: 829fd23000ae2dc4f88a05462285f34e47ce2aa288c14d93bd86385bc5ea8d4c281cfd579690f802911b644c49fc756a0fa37428a5429c8ce1427733c7dbbe51
7
- data.tar.gz: 6a4513c5fe5f436ada0045ce4a9b7933d5c2a6f6f58a546d013ec8f7e5dc9719dace3cfdb89b75fbc8769f22cb9fd988225eaae1f080d6e2c6cd94718dcc4782
6
+ metadata.gz: b72abeba04fcdfe33de4562a2d81aa1a0b6297dbbee46c9cbe45f13d4e06788c34af039cafb1b741e1a0e7ae6b865bc0f347823edf0735d57b54f57f3e1908ef
7
+ data.tar.gz: a14e740c4769a9cc6929bee634eaffdfed36d08e58c7c79aa136849387c6e8ed8cfda7bcb9f3e4f4d1ce2ca7e658fb5fc6a6fbaea8b8d2e6fb8f2f535d68cd22
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  env:
3
3
  - CODECLIMATE_REPO_TOKEN=f7c652b65a700fcf1032174afc5ea243b991e48bf73077cc34c148e1c800a2f7
4
- bundler_args: --without sql benchmarks
4
+ bundler_args: --without sql benchmarks console
5
5
  script: "bundle exec rake spec"
6
6
  rvm:
7
7
  - 2.0
@@ -1,15 +1,30 @@
1
- # v0.3.0 2014-11-24
1
+ ## v0.3.1 2014-11-25
2
+
3
+ ### Added
4
+
5
+ * attributes for `group` mapping operation can be specified without options (solnic)
6
+ * attributes for `wrap` mapping operation can be specified without options (solnic)
7
+ * `Env` uses Equalizer (solnic)
8
+ * boot dsl methods return self (solnic)
9
+
10
+ ### Fixed
11
+
12
+ * when schema is missing booting will gracefuly skip building relations and mappers (solnic)
13
+ * in-memory join handles one-to-many and many-to-one correctly (solnic)
14
+
15
+ [Compare v0.3.0...v0.3.1](https://github.com/rom-rb/rom/compare/v0.3.0...v0.3.1)
16
+
17
+ ## v0.3.0 2014-11-24
2
18
 
3
19
  This version is a rewrite that introduces a new, simplified architecture based
4
20
  on a new adapter interface.
5
21
 
6
22
  [Compare v0.2.0...v0.3.0](https://github.com/rom-rb/rom/compare/v0.2.0...v0.3.0)
7
23
 
8
- # v0.2.0 2014-04-06
24
+ ## v0.2.0 2014-04-06
25
+
26
+ ### Added
9
27
 
10
- * [BREAKING] rom-relation, rom-mapper and rom-session were merged into rom project (solnic)
11
- * [BREAKING] changed mapping DSL (users do...end => relation(:users) do...end) (solnic)
12
- * [BREAKING] added :from option to mapping DSL which replaced :to (solnic)
13
28
  * [feature] added :rename option to schema attribute DSL (solnic)
14
29
  * [feature] added support for join, group, wrap, project and rename operations (solnic)
15
30
  * [feature] added support for setting domain object loading strategy (solnic)
@@ -17,25 +32,31 @@ on a new adapter interface.
17
32
  * [feature] added public interface for building mappers (see Mapper.build) (solnic)
18
33
  * [feature] added support for mapping embedded objects using wrap/group (solnic)
19
34
  * [feature] environment exposes mapper registry via Environment#mappers (solnic)
35
+
36
+ ### Changed
37
+
38
+ * [BREAKING] rom-relation, rom-mapper and rom-session were merged into rom project (solnic)
39
+ * [BREAKING] changed mapping DSL (users do...end => relation(:users) do...end) (solnic)
40
+ * [BREAKING] added :from option to mapping DSL which replaced :to (solnic)
20
41
  * [internal] mappers are now backed by [morpher](https://github.com/mbj/morpher) (solnic)
21
42
  * [internal] renaming and optimizing relations happens on the schema level now (solnic)
22
43
  * [internal] environment will raise if unknown relation is referenced via `Environment#[]` (solnic)
23
44
 
24
45
  [Compare v0.1.2...v0.2.0](https://github.com/rom-rb/rom/compare/v0.1.2...v0.2.0)
25
46
 
26
- # v0.1.2 2013-09-02
47
+ ## v0.1.2 2013-09-02
27
48
 
28
49
  * [updated] [rom-relation](https://github.com/rom-rb/rom-relation/blob/v0.1.2/Changelog.md#v012-2013-09-02)
29
50
 
30
51
  [Compare v0.1.1...v0.1.2](https://github.com/rom-rb/rom/compare/v0.1.1...v0.1.2)
31
52
 
32
- # v0.1.1 2013-08-30
53
+ ## v0.1.1 2013-08-30
33
54
 
34
55
  * [updated] [rom-relation](https://github.com/rom-rb/rom-relation/blob/v0.1.1/Changelog.md#v011-2013-08-30)
35
56
  * [updated] [rom-session](https://github.com/rom-rb/rom-session/blob/v0.1.1/Changelog.md#v011-2013-08-30)
36
57
 
37
58
  [Compare v0.1.0...v0.1.1](https://github.com/rom-rb/rom/compare/v0.1.0...v0.1.1)
38
59
 
39
- # v0.1.0 2013-08-23
60
+ ## v0.1.0 2013-08-23
40
61
 
41
62
  First public release
data/Gemfile CHANGED
@@ -2,6 +2,11 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ group :console do
6
+ gem 'pry'
7
+ gem 'pg'
8
+ end
9
+
5
10
  group :test do
6
11
  gem 'mutant'
7
12
  gem 'mutant-rspec'
@@ -11,6 +11,11 @@ module ROM
11
11
  class Dataset
12
12
  include Charlatan.new(:data)
13
13
 
14
+ def to_ary
15
+ data
16
+ end
17
+ alias_method :to_a, :to_ary
18
+
14
19
  def each(&block)
15
20
  return to_enum unless block
16
21
  data.each(&block)
@@ -8,6 +8,8 @@ module ROM
8
8
  #
9
9
  # @api public
10
10
  class Boot
11
+ include Equalizer.new(:repositories, :env)
12
+
11
13
  attr_reader :repositories, :adapter_relation_map, :env
12
14
 
13
15
  # @api private
@@ -36,6 +38,7 @@ module ROM
36
38
  # @api public
37
39
  def schema(&block)
38
40
  @schema = DSL.new(self).schema(&block)
41
+ self
39
42
  end
40
43
 
41
44
  # Relation definition DSL
@@ -51,6 +54,7 @@ module ROM
51
54
  # @api public
52
55
  def relation(name, &block)
53
56
  @relations.update(name => block)
57
+ self
54
58
  end
55
59
 
56
60
  # Mapper definition DSL
@@ -70,6 +74,7 @@ module ROM
70
74
  # @api public
71
75
  def mappers(&block)
72
76
  @mappers.concat(DSL.new(self).mappers(&block))
77
+ self
73
78
  end
74
79
 
75
80
  # Finalize the setup
@@ -122,6 +127,8 @@ module ROM
122
127
 
123
128
  # @api private
124
129
  def load_relations(schema)
130
+ return RelationRegistry.new unless adapter_relation_map.any?
131
+
125
132
  builder = RelationBuilder.new(schema)
126
133
 
127
134
  relations = @relations.each_with_object({}) do |(name, block), h|
@@ -144,13 +151,15 @@ module ROM
144
151
 
145
152
  # @api private
146
153
  def load_readers(relations)
154
+ return ReaderRegistry.new unless adapter_relation_map.any?
155
+
147
156
  reader_builder = ReaderBuilder.new(relations)
148
157
 
149
158
  readers = @mappers.each_with_object({}) do |(name, options, block), h|
150
159
  h[name] = reader_builder.call(name, options, &block)
151
160
  end
152
161
 
153
- RelationRegistry.new(readers)
162
+ ReaderRegistry.new(readers)
154
163
  end
155
164
 
156
165
  end
@@ -5,6 +5,7 @@ module ROM
5
5
  # @api public
6
6
  class Env
7
7
  include Adamantium::Flat
8
+ include Equalizer.new(:repositories, :schema, :relations, :mappers)
8
9
 
9
10
  attr_reader :repositories, :schema, :relations, :mappers
10
11
 
@@ -16,7 +16,7 @@ module ROM
16
16
  Header.coerce(attributes)
17
17
  end
18
18
 
19
- def attribute(name, options)
19
+ def attribute(name, options = {})
20
20
  attributes << [name, options]
21
21
  end
22
22
  end
@@ -20,15 +20,13 @@ module ROM
20
20
  def each(&block)
21
21
  return to_enum unless block
22
22
 
23
- join_map = right.each_with_object({}) { |tuple, h|
24
- other = left.detect { |t| (tuple.to_a & t.to_a).any? }
25
- (h[other] ||= []) << tuple if other
23
+ join_map = left.each_with_object({}) { |tuple, h|
24
+ others = right.find_all { |t| (tuple.to_a & t.to_a).any? }
25
+ (h[tuple] ||= []).concat(others)
26
26
  }
27
27
 
28
28
  tuples = left.map { |tuple|
29
- others = join_map[tuple]
30
- next unless others.any?
31
- others.map { |other| tuple.merge(other) }
29
+ join_map[tuple].map { |other| tuple.merge(other) }
32
30
  }.flatten
33
31
 
34
32
  tuples.each(&block)
@@ -3,6 +3,7 @@ module ROM
3
3
  # @api private
4
4
  class Registry
5
5
  include Enumerable
6
+ include Equalizer.new(:elements)
6
7
 
7
8
  attr_reader :elements
8
9
 
@@ -1,3 +1,3 @@
1
1
  module ROM
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.3.1'.freeze
3
3
  end
@@ -79,4 +79,161 @@ describe 'Mapper definition DSL' do
79
79
 
80
80
  end
81
81
 
82
+ describe 'grouped relation mapper' do
83
+ before do
84
+ setup.relation(:tasks)
85
+
86
+ setup.relation(:users) do
87
+ def with_tasks
88
+ in_memory { group(join(tasks), tasks: [:title, :priority]) }
89
+ end
90
+ end
91
+
92
+ setup.mappers do
93
+ define(:users) do
94
+ model name: 'User'
95
+
96
+ attribute :name
97
+ attribute :email
98
+ end
99
+ end
100
+ end
101
+
102
+ it 'allows defining grouped attributes via options hash' do
103
+ setup.mappers do
104
+ define(:with_tasks, parent: :users) do
105
+ model name: 'UserWithTasks'
106
+
107
+ attribute :name
108
+ attribute :email
109
+
110
+ group tasks: [:title, :priority]
111
+ end
112
+ end
113
+
114
+ rom = setup.finalize
115
+
116
+ UserWithTasks.send(:include, Equalizer.new(:name, :email, :tasks))
117
+
118
+ jane = rom.read(:users).with_tasks.to_a.last
119
+
120
+ expect(jane).to eql(
121
+ UserWithTasks.new(
122
+ name: 'Jane',
123
+ email: 'jane@doe.org',
124
+ tasks: [{ title: 'be cool', priority: 2 }]
125
+ )
126
+ )
127
+ end
128
+
129
+ it 'allows defining grouped attributes via block' do
130
+ setup.mappers do
131
+ define(:with_tasks, parent: :users) do
132
+ model name: 'UserWithTasks'
133
+
134
+ attribute :name
135
+ attribute :email
136
+
137
+ group :tasks do
138
+ attribute :title
139
+ attribute :priority
140
+ end
141
+ end
142
+ end
143
+
144
+ rom = setup.finalize
145
+
146
+ UserWithTasks.send(:include, Equalizer.new(:name, :email, :tasks))
147
+
148
+ jane = rom.read(:users).with_tasks.to_a.last
149
+
150
+ expect(jane).to eql(
151
+ UserWithTasks.new(
152
+ name: 'Jane',
153
+ email: 'jane@doe.org',
154
+ tasks: [{ title: 'be cool', priority: 2 }]
155
+ )
156
+ )
157
+ end
158
+
159
+ end
160
+
161
+ describe 'wrapped relation mapper' do
162
+ before do
163
+ setup.relation(:tasks) do
164
+ def with_user
165
+ in_memory { wrap(join(users), user: [:email]) }
166
+ end
167
+ end
168
+
169
+ setup.relation(:users)
170
+
171
+ setup.mappers do
172
+ define(:tasks) do
173
+ model name: 'Task'
174
+
175
+ attribute :title
176
+ attribute :priority
177
+ end
178
+ end
179
+ end
180
+
181
+ it 'allows defining wrapped attributes via options hash' do
182
+ setup.mappers do
183
+ define(:with_user, parent: :tasks) do
184
+ model name: 'TaskWithUser'
185
+
186
+ attribute :title
187
+ attribute :priority
188
+
189
+ wrap user: [:email]
190
+ end
191
+ end
192
+
193
+ rom = setup.finalize
194
+
195
+ TaskWithUser.send(:include, Equalizer.new(:title, :priority, :user))
196
+
197
+ jane = rom.read(:tasks).with_user.to_a.last
198
+
199
+ expect(jane).to eql(
200
+ TaskWithUser.new(
201
+ title: 'be cool',
202
+ priority: 2,
203
+ user: { email: 'jane@doe.org' }
204
+ )
205
+ )
206
+ end
207
+
208
+ it 'allows defining wrapped attributes via options block' do
209
+ setup.mappers do
210
+ define(:with_user, parent: :tasks) do
211
+ model name: 'TaskWithUser'
212
+
213
+ attribute :title
214
+ attribute :priority
215
+
216
+ wrap :user do
217
+ attribute :email
218
+ end
219
+ end
220
+ end
221
+
222
+ rom = setup.finalize
223
+
224
+ TaskWithUser.send(:include, Equalizer.new(:title, :priority, :user))
225
+
226
+ jane = rom.read(:tasks).with_user.to_a.last
227
+
228
+ expect(jane).to eql(
229
+ TaskWithUser.new(
230
+ title: 'be cool',
231
+ priority: 2,
232
+ user: { email: 'jane@doe.org' }
233
+ )
234
+ )
235
+ end
236
+
237
+ end
238
+
82
239
  end
@@ -3,13 +3,15 @@ require "spec_helper"
3
3
  describe 'Join operation' do
4
4
  include_context 'users and tasks'
5
5
 
6
- specify 'defining a joined relation' do
6
+ specify 'defining a joined one-to-many relation' do
7
7
  setup.relation(:users) do
8
8
  def with_tasks
9
9
  in_memory { join(tasks) }
10
10
  end
11
11
  end
12
12
 
13
+ setup.relation(:tasks)
14
+
13
15
  users = rom.relations.users
14
16
 
15
17
  expect(users.with_tasks.to_a).to eql(
@@ -21,4 +23,24 @@ describe 'Join operation' do
21
23
  )
22
24
  end
23
25
 
26
+ specify 'defining a joined many-to-one relation' do
27
+ setup.relation(:users)
28
+
29
+ setup.relation(:tasks) do
30
+ def with_user
31
+ in_memory { join(users) }
32
+ end
33
+ end
34
+
35
+ tasks = rom.relations.tasks
36
+
37
+ expect(tasks.with_user.to_a).to eql(
38
+ [
39
+ { title: 'be nice', priority: 1, name: 'Joe', email: 'joe@doe.org' },
40
+ { title: 'sleep well', priority: 2, name: 'Joe', email: 'joe@doe.org' },
41
+ { title: 'be cool', priority: 2, name: 'Jane', email: 'jane@doe.org' }
42
+ ]
43
+ )
44
+ end
45
+
24
46
  end
@@ -1,18 +1,33 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Setting up ROM' do
4
- include_context 'users and tasks'
4
+ context 'with existing schema' do
5
+ include_context 'users and tasks'
5
6
 
6
- let(:jane) { { name: 'Jane', email: 'jane@doe.org' } }
7
- let(:joe) { { name: 'Joe', email: 'joe@doe.org' } }
7
+ let(:jane) { { name: 'Jane', email: 'jane@doe.org' } }
8
+ let(:joe) { { name: 'Joe', email: 'joe@doe.org' } }
8
9
 
9
- it 'configures relations' do
10
- expect(rom.memory.users).to match_array([joe, jane])
10
+ it 'configures relations' do
11
+ expect(rom.memory.users).to match_array([joe, jane])
12
+ end
13
+
14
+ it 'raises on double-finalize' do
15
+ expect {
16
+ 2.times { setup.finalize }
17
+ }.to raise_error(ROM::EnvAlreadyFinalizedError)
18
+ end
11
19
  end
12
20
 
13
- it 'raises on double-finalize' do
14
- expect {
15
- 2.times { setup.finalize }
16
- }.to raise_error(ROM::EnvAlreadyFinalizedError)
21
+ context 'without schema' do
22
+ it 'builds empty registries if there is no schema' do
23
+ setup = ROM.setup(memory: 'memory://test')
24
+
25
+ setup.relation(:users)
26
+
27
+ rom = setup.finalize
28
+
29
+ expect(rom.relations).to eql(ROM::RelationRegistry.new)
30
+ expect(rom.mappers).to eql(ROM::ReaderRegistry.new)
31
+ end
17
32
  end
18
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-24 00:00:00.000000000 Z
12
+ date: 2014-11-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable