rom-repository 0.1.0 → 0.2.0.beta1
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/Gemfile +5 -0
- data/README.md +9 -16
- data/lib/rom-repository.rb +1 -18
- data/lib/rom/repository.rb +60 -0
- data/lib/rom/repository/header_builder.rb +6 -5
- data/lib/rom/repository/loading_proxy.rb +14 -5
- data/lib/rom/repository/loading_proxy/combine.rb +1 -1
- data/lib/rom/repository/loading_proxy/wrap.rb +1 -1
- data/lib/rom/repository/mapper_builder.rb +1 -1
- data/lib/rom/repository/struct_builder.rb +1 -1
- data/lib/rom/repository/version.rb +2 -6
- data/log/.gitkeep +0 -0
- data/rom-repository.gemspec +3 -3
- data/spec/integration/multi_adapter_spec.rb +9 -6
- data/spec/integration/repository_spec.rb +8 -4
- data/spec/shared/database.rb +5 -3
- data/spec/shared/relations.rb +3 -3
- data/spec/shared/repo.rb +5 -1
- data/spec/spec_helper.rb +1 -2
- data/spec/unit/loading_proxy_spec.rb +11 -2
- data/spec/unit/plugins/view_spec.rb +29 -0
- data/spec/unit/sql/relation_spec.rb +3 -3
- metadata +14 -36
- data/lib/rom/plugins/relation/sql/auto_combine.rb +0 -45
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +0 -48
- data/lib/rom/plugins/relation/sql/base_view.rb +0 -29
- data/lib/rom/plugins/relation/view.rb +0 -79
- data/lib/rom/plugins/relation/view/dsl.rb +0 -32
- data/lib/rom/repository/base.rb +0 -56
- data/lib/rom/repository/ext/relation.rb +0 -11
- data/lib/rom/repository/ext/relation/view_dsl.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2526fefe26c270b932eaf46aba937183488fafba
|
4
|
+
data.tar.gz: d867a97f3a2fad0abe56811ac3b3b4bfe477cc66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4959c0fcb0fe87446d84fa284f4732d1960ebdd7a424dbd97b51ec34e554648fd844cfe987749eecce37f2d9eca422550d42e723628493331080876568e5a3f5
|
7
|
+
data.tar.gz: a6912a4e51ad77c689b8b1e743f7f9fffeac88563264798745c4dc91cbeb61d0751aa5c65529ed829770431074535df2991e9faef5c9ebe4dc952a2e8b6f7753
|
data/Gemfile
CHANGED
@@ -2,12 +2,17 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
+
gem 'transproc', github: 'solnic/transproc', branch: 'master'
|
6
|
+
|
5
7
|
gem 'rom', github: 'rom-rb/rom', branch: 'master'
|
6
8
|
gem 'rom-sql', github: 'rom-rb/rom-sql', branch: 'master'
|
9
|
+
gem 'rom-support', github: 'rom-rb/rom-support', branch: 'master'
|
10
|
+
gem 'rom-mapper', github: 'rom-rb/rom-mapper', branch: 'master'
|
7
11
|
|
8
12
|
gem 'inflecto'
|
9
13
|
|
10
14
|
group :test do
|
15
|
+
gem 'anima', '~> 0.2.0'
|
11
16
|
gem 'rspec'
|
12
17
|
gem 'byebug', platforms: :mri
|
13
18
|
gem 'pg', platforms: [:mri, :rbx]
|
data/README.md
CHANGED
@@ -109,28 +109,21 @@ puts user_repo.with_tasks.to_a.inspect
|
|
109
109
|
# [#<ROM::Struct[User] id=1 name="Jane" tasks=[#<ROM::Struct[Task] id=2 user_id=1 title="Jane Task">]>, #<ROM::Struct[User] id=2 name="Joe" tasks=[#<ROM::Struct[Task] id=1 user_id=2 title="Joe Task">]>]
|
110
110
|
```
|
111
111
|
|
112
|
-
###
|
112
|
+
### Using Custom Model Types
|
113
113
|
|
114
|
-
|
115
|
-
|
114
|
+
To use a custom model type you simply use the standard `Relation#as` inteface
|
115
|
+
but you can pass a constant:
|
116
116
|
|
117
117
|
``` ruby
|
118
|
-
class
|
119
|
-
|
120
|
-
model UI::UserPresenter
|
121
|
-
end
|
118
|
+
class UserRepository < ROM::Repository::Base
|
119
|
+
relations :users, :tasks
|
122
120
|
|
123
|
-
|
121
|
+
def by_id(id)
|
122
|
+
users.by_id(id).as(User)
|
123
|
+
end
|
124
|
+
end
|
124
125
|
```
|
125
126
|
|
126
|
-
## Limitations
|
127
|
-
|
128
|
-
This is an early alpha and works only with rom-sql for now. There are a couple
|
129
|
-
improvements waiting to be done in the rom core and then rom-repository will receive
|
130
|
-
more love and features.
|
131
|
-
|
132
|
-
Stay tuned.
|
133
|
-
|
134
127
|
## License
|
135
128
|
|
136
129
|
See `LICENSE` file.
|
data/lib/rom-repository.rb
CHANGED
@@ -1,20 +1,3 @@
|
|
1
1
|
require 'rom'
|
2
2
|
|
3
|
-
require 'rom/
|
4
|
-
require 'rom/plugins/relation/key_inference'
|
5
|
-
|
6
|
-
require 'rom/plugins/relation/sql/base_view'
|
7
|
-
require 'rom/plugins/relation/sql/auto_combine'
|
8
|
-
require 'rom/plugins/relation/sql/auto_wrap'
|
9
|
-
|
10
|
-
require 'rom/repository/base'
|
11
|
-
|
12
|
-
if defined?(ROM::SQL)
|
13
|
-
class ROM::SQL::Relation < ROM::Relation
|
14
|
-
use :key_inference
|
15
|
-
use :view
|
16
|
-
use :base_view
|
17
|
-
use :auto_combine
|
18
|
-
use :auto_wrap
|
19
|
-
end
|
20
|
-
end
|
3
|
+
require 'rom/repository'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rom/support/deprecations'
|
2
|
+
require 'rom/support/options'
|
3
|
+
|
4
|
+
require 'rom/repository/mapper_builder'
|
5
|
+
require 'rom/repository/loading_proxy'
|
6
|
+
|
7
|
+
module ROM
|
8
|
+
class Repository
|
9
|
+
# Abstract repository class to inherit from
|
10
|
+
#
|
11
|
+
# TODO: rename this to Repository once deprecated Repository from rom core is gone
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
include Options
|
15
|
+
|
16
|
+
option :mapper_builder, reader: true, default: proc { MapperBuilder.new }
|
17
|
+
|
18
|
+
# Define which relations your repository is going to use
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# class MyRepo < ROM::Repository::Base
|
22
|
+
# relations :users, :tasks
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# my_repo = MyRepo.new(rom_env)
|
26
|
+
#
|
27
|
+
# my_repo.users
|
28
|
+
# my_repo.tasks
|
29
|
+
#
|
30
|
+
# @return [Array<Symbol>]
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def self.relations(*names)
|
34
|
+
if names.any?
|
35
|
+
attr_reader(*names)
|
36
|
+
@relations = names
|
37
|
+
else
|
38
|
+
@relations
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def initialize(env, options = {})
|
44
|
+
super
|
45
|
+
self.class.relations.each do |name|
|
46
|
+
proxy = LoadingProxy.new(
|
47
|
+
env.relation(name), name: name, mapper_builder: mapper_builder
|
48
|
+
)
|
49
|
+
instance_variable_set("@#{name}", proxy)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Base < Repository
|
54
|
+
def self.inherited(klass)
|
55
|
+
super
|
56
|
+
Deprecations.announce(self, 'inherit from Repository instead')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -3,7 +3,7 @@ require 'rom/header'
|
|
3
3
|
require 'rom/repository/struct_builder'
|
4
4
|
|
5
5
|
module ROM
|
6
|
-
class Repository
|
6
|
+
class Repository
|
7
7
|
# @api private
|
8
8
|
class HeaderBuilder
|
9
9
|
attr_reader :struct_builder
|
@@ -30,10 +30,11 @@ module ROM
|
|
30
30
|
def visit_relation(*args)
|
31
31
|
name, header, meta = args
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
model = meta.fetch(:model) do
|
34
|
+
struct_builder[meta.fetch(:base_name), header[1].map { |a| a[1] }]
|
35
|
+
end
|
36
|
+
|
37
|
+
options = [visit_header(header[1], meta), model: model]
|
37
38
|
|
38
39
|
if meta[:combine_type]
|
39
40
|
type = meta[:combine_type] == :many ? :array : :hash
|
@@ -5,7 +5,7 @@ require 'rom/repository/loading_proxy/combine'
|
|
5
5
|
require 'rom/repository/loading_proxy/wrap'
|
6
6
|
|
7
7
|
module ROM
|
8
|
-
class Repository
|
8
|
+
class Repository
|
9
9
|
# LoadingProxy decorates a relation and automatically generate mappers that
|
10
10
|
# will map raw tuples into structs
|
11
11
|
#
|
@@ -44,8 +44,12 @@ module ROM
|
|
44
44
|
#
|
45
45
|
# @api public
|
46
46
|
def map_with(*names)
|
47
|
-
|
48
|
-
|
47
|
+
if names.size == 1 && names[0].is_a?(Class)
|
48
|
+
with(meta: meta.merge(model: names[0]))
|
49
|
+
else
|
50
|
+
mappers = [mapper]+names.map { |name| relation.mappers[name] }
|
51
|
+
mappers.reduce(self) { |a, e| a >> e }
|
52
|
+
end
|
49
53
|
end
|
50
54
|
alias_method :as, :map_with
|
51
55
|
|
@@ -155,9 +159,9 @@ module ROM
|
|
155
159
|
# and ROM::Lazy is gone
|
156
160
|
#
|
157
161
|
# @api private
|
158
|
-
def method_missing(meth, *args)
|
162
|
+
def method_missing(meth, *args, &block)
|
159
163
|
if relation.respond_to?(meth)
|
160
|
-
result = relation.__send__(meth, *args)
|
164
|
+
result = relation.__send__(meth, *args, &block)
|
161
165
|
|
162
166
|
if result.kind_of?(Relation::Materializable) && !result.is_a?(Relation::Loaded)
|
163
167
|
__new__(result)
|
@@ -168,6 +172,11 @@ module ROM
|
|
168
172
|
super
|
169
173
|
end
|
170
174
|
end
|
175
|
+
|
176
|
+
# @api private
|
177
|
+
def respond_to_missing?(meth, _include_private = false)
|
178
|
+
relation.respond_to?(meth) || super
|
179
|
+
end
|
171
180
|
end
|
172
181
|
end
|
173
182
|
end
|
data/log/.gitkeep
ADDED
File without changes
|
data/rom-repository.gemspec
CHANGED
@@ -16,9 +16,9 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.license = 'MIT'
|
17
17
|
|
18
18
|
gem.add_runtime_dependency 'anima', '~> 0.2', '>= 0.2'
|
19
|
-
gem.add_runtime_dependency 'rom', '~> 0.
|
20
|
-
gem.add_runtime_dependency 'rom-support', '~> 0.
|
21
|
-
gem.add_runtime_dependency 'rom-mapper', '~> 0.
|
19
|
+
gem.add_runtime_dependency 'rom', '~> 1.0.0.beta1'
|
20
|
+
gem.add_runtime_dependency 'rom-support', '~> 1.0.0.beta1'
|
21
|
+
gem.add_runtime_dependency 'rom-mapper', '~> 0.3.beta1'
|
22
22
|
|
23
23
|
gem.add_development_dependency 'rake', '~> 10.3'
|
24
24
|
gem.add_development_dependency 'rspec', '~> 3.3'
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
RSpec.describe 'Repository with multi-adapters
|
3
|
+
RSpec.describe 'Repository with multi-adapters configuration' do
|
4
4
|
include_context 'database'
|
5
5
|
|
6
|
-
let(:
|
7
|
-
ROM.
|
6
|
+
let(:configuration) {
|
7
|
+
ROM::Configuration.new(default: [:sql, uri], memory: [:memory])
|
8
8
|
}
|
9
9
|
|
10
10
|
let(:users) { rom.relation(:sql_users) }
|
@@ -37,7 +37,7 @@ RSpec.describe 'Repository with multi-adapters setup' do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
class Repository < ROM::Repository
|
40
|
+
class Repository < ROM::Repository
|
41
41
|
relations :sql_users, :memory_tasks
|
42
42
|
|
43
43
|
def users_with_tasks(id)
|
@@ -46,8 +46,11 @@ RSpec.describe 'Repository with multi-adapters setup' do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
|
49
|
+
configuration.register_relation(Test::Users)
|
50
|
+
configuration.register_relation(Test::Tasks)
|
51
|
+
|
52
|
+
user_id = configuration.gateways[:default].dataset(:users).insert(name: 'Jane')
|
53
|
+
configuration.gateways[:memory].dataset(:tasks).insert(user_id: user_id, title: 'Jane Task')
|
51
54
|
end
|
52
55
|
|
53
56
|
specify 'ᕕ⁞ ᵒ̌ 〜 ᵒ̌ ⁞ᕗ' do
|
@@ -5,7 +5,11 @@ RSpec.describe 'ROM repository' do
|
|
5
5
|
include_context 'structs'
|
6
6
|
|
7
7
|
it 'loads a single relation' do
|
8
|
-
expect(repo.all_users.to_a).to
|
8
|
+
expect(repo.all_users.to_a).to match_array([jane, joe])
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'loads a relation by an association' do
|
12
|
+
expect(repo.tasks_for_users(repo.all_users)).to match_array([jane_task, joe_task])
|
9
13
|
end
|
10
14
|
|
11
15
|
it 'loads a combine relation with one parent' do
|
@@ -17,15 +21,15 @@ RSpec.describe 'ROM repository' do
|
|
17
21
|
end
|
18
22
|
|
19
23
|
it 'loads a combined relation with many children' do
|
20
|
-
expect(repo.users_with_tasks.to_a).to
|
24
|
+
expect(repo.users_with_tasks.to_a).to match_array([jane_with_tasks, joe_with_tasks])
|
21
25
|
end
|
22
26
|
|
23
27
|
it 'loads a combined relation with one child' do
|
24
|
-
expect(repo.users_with_task.to_a).to
|
28
|
+
expect(repo.users_with_task.to_a).to match_array([jane_with_task, joe_with_task])
|
25
29
|
end
|
26
30
|
|
27
31
|
it 'loads a combined relation with one child restricted by given criteria' do
|
28
|
-
expect(repo.users_with_task_by_title('Joe Task').to_a).to
|
32
|
+
expect(repo.users_with_task_by_title('Joe Task').to_a).to match_array([
|
29
33
|
jane_without_task, joe_with_task
|
30
34
|
])
|
31
35
|
end
|
data/spec/shared/database.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
RSpec.shared_context 'database' do
|
2
|
-
let(:
|
3
|
-
let(:conn) {
|
4
|
-
let(:rom) {
|
2
|
+
let(:configuration) { ROM::Configuration.new(:sql, uri).use(:macros) }
|
3
|
+
let(:conn) { configuration.gateways[:default].connection }
|
4
|
+
let(:rom) { ROM.container(configuration) }
|
5
5
|
let(:uri) { 'postgres://localhost/rom_repository' }
|
6
6
|
|
7
7
|
before do
|
8
|
+
conn.loggers << LOGGER
|
9
|
+
|
8
10
|
[:tags, :tasks, :users].each { |table| conn.drop_table?(table) }
|
9
11
|
|
10
12
|
conn.create_table :users do
|
data/spec/shared/relations.rb
CHANGED
@@ -4,7 +4,7 @@ RSpec.shared_context 'relations' do
|
|
4
4
|
let(:tags) { rom.relation(:tags) }
|
5
5
|
|
6
6
|
before do
|
7
|
-
|
7
|
+
configuration.relation(:users) do
|
8
8
|
def all
|
9
9
|
select(:id, :name).order(:name, :id)
|
10
10
|
end
|
@@ -14,7 +14,7 @@ RSpec.shared_context 'relations' do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
configuration.relation(:tasks) do
|
18
18
|
def find(criteria)
|
19
19
|
where(criteria)
|
20
20
|
end
|
@@ -24,6 +24,6 @@ RSpec.shared_context 'relations' do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
configuration.relation(:tags)
|
28
28
|
end
|
29
29
|
end
|
data/spec/shared/repo.rb
CHANGED
@@ -2,7 +2,7 @@ RSpec.shared_context('repo') do
|
|
2
2
|
let(:repo) { repo_class.new(rom) }
|
3
3
|
|
4
4
|
let(:repo_class) do
|
5
|
-
Class.new(ROM::Repository
|
5
|
+
Class.new(ROM::Repository) do
|
6
6
|
relations :users, :tasks, :tags
|
7
7
|
|
8
8
|
def find_users(criteria)
|
@@ -13,6 +13,10 @@ RSpec.shared_context('repo') do
|
|
13
13
|
users.all
|
14
14
|
end
|
15
15
|
|
16
|
+
def tasks_for_users(users)
|
17
|
+
tasks.for_users(users)
|
18
|
+
end
|
19
|
+
|
16
20
|
def task_with_user
|
17
21
|
tasks.find(id: 2).combine_parents(one: users)
|
18
22
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -18,6 +18,7 @@ rescue LoadError
|
|
18
18
|
end
|
19
19
|
|
20
20
|
root = Pathname(__FILE__).dirname
|
21
|
+
LOGGER = Logger.new(File.open('./log/test.log', 'a'))
|
21
22
|
|
22
23
|
Dir[root.join('support/*.rb').to_s].each do |f|
|
23
24
|
require f
|
@@ -41,5 +42,3 @@ RSpec.configure do |config|
|
|
41
42
|
|
42
43
|
config.include(MapperRegistry)
|
43
44
|
end
|
44
|
-
|
45
|
-
ROM.use :auto_registration
|
@@ -31,9 +31,9 @@ RSpec.describe 'loading proxy' do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
describe '#map_with' do
|
34
|
+
describe '#map_with/#as' do
|
35
35
|
before do
|
36
|
-
|
36
|
+
configuration.mappers do
|
37
37
|
register :users, name_list: -> users { users.map(&:name) }
|
38
38
|
end
|
39
39
|
end
|
@@ -41,6 +41,15 @@ RSpec.describe 'loading proxy' do
|
|
41
41
|
it 'sends the relation through multiple mappers' do
|
42
42
|
expect(users.map_with(:name_list).to_a).to eql(%w(Jane Joe))
|
43
43
|
end
|
44
|
+
|
45
|
+
context 'setting custom model type' do
|
46
|
+
let(:user_type) { Class.new { include Anima.new(:id, :name) } }
|
47
|
+
let(:custom_users) { users.as(user_type) }
|
48
|
+
|
49
|
+
it 'instantiates custom model' do
|
50
|
+
expect(custom_users.where(name: 'Jane').one).to be_instance_of(user_type)
|
51
|
+
end
|
52
|
+
end
|
44
53
|
end
|
45
54
|
|
46
55
|
describe 'retrieving a single struct' do
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rom/memory'
|
2
|
+
|
3
|
+
RSpec.describe ROM::Plugins::Relation::View do
|
4
|
+
subject(:relation) { relation_class.new([]) }
|
5
|
+
|
6
|
+
let(:relation_class) do
|
7
|
+
Class.new(ROM::Memory::Relation) do
|
8
|
+
use :view
|
9
|
+
|
10
|
+
view(:base, [:id, :name]) do
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
view(:ids, [:id]) do
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#attributes' do
|
21
|
+
it 'returns base view attributes by default' do
|
22
|
+
expect(relation.attributes).to eql([:id, :name])
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns attributes for a configured view' do
|
26
|
+
expect(relation.ids.attributes).to eql([:id])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -15,7 +15,7 @@ RSpec.describe 'SQL Relation extensions' do
|
|
15
15
|
describe '.view' do
|
16
16
|
context 'using short syntax' do
|
17
17
|
before do
|
18
|
-
|
18
|
+
configuration.relation(:users) do
|
19
19
|
view(:by_id, [:name]) do |name|
|
20
20
|
where(name: name).select(:name)
|
21
21
|
end
|
@@ -27,7 +27,7 @@ RSpec.describe 'SQL Relation extensions' do
|
|
27
27
|
|
28
28
|
context 'with multi-block syntax' do
|
29
29
|
before do
|
30
|
-
|
30
|
+
configuration.relation(:users) do
|
31
31
|
view(:by_id) do
|
32
32
|
header [:name]
|
33
33
|
|
@@ -44,7 +44,7 @@ RSpec.describe 'SQL Relation extensions' do
|
|
44
44
|
context 'with multi-block when first block has args' do
|
45
45
|
it 'raises error' do
|
46
46
|
expect {
|
47
|
-
|
47
|
+
configuration.relation(:users) do
|
48
48
|
view(:by_id) { |args| }
|
49
49
|
end
|
50
50
|
}.to raise_error(ArgumentError)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-repository
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0.beta1
|
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-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anima
|
@@ -36,60 +36,42 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 0.9.0
|
39
|
+
version: 1.0.0.beta1
|
43
40
|
type: :runtime
|
44
41
|
prerelease: false
|
45
42
|
version_requirements: !ruby/object:Gem::Requirement
|
46
43
|
requirements:
|
47
44
|
- - "~>"
|
48
45
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 0.9.0
|
46
|
+
version: 1.0.0.beta1
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
48
|
name: rom-support
|
55
49
|
requirement: !ruby/object:Gem::Requirement
|
56
50
|
requirements:
|
57
51
|
- - "~>"
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
version:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 0.1.0
|
53
|
+
version: 1.0.0.beta1
|
63
54
|
type: :runtime
|
64
55
|
prerelease: false
|
65
56
|
version_requirements: !ruby/object:Gem::Requirement
|
66
57
|
requirements:
|
67
58
|
- - "~>"
|
68
59
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
70
|
-
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: 0.1.0
|
60
|
+
version: 1.0.0.beta1
|
73
61
|
- !ruby/object:Gem::Dependency
|
74
62
|
name: rom-mapper
|
75
63
|
requirement: !ruby/object:Gem::Requirement
|
76
64
|
requirements:
|
77
65
|
- - "~>"
|
78
66
|
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.2.0
|
67
|
+
version: 0.3.beta1
|
83
68
|
type: :runtime
|
84
69
|
prerelease: false
|
85
70
|
version_requirements: !ruby/object:Gem::Requirement
|
86
71
|
requirements:
|
87
72
|
- - "~>"
|
88
73
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: 0.2.0
|
74
|
+
version: 0.3.beta1
|
93
75
|
- !ruby/object:Gem::Dependency
|
94
76
|
name: rake
|
95
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,14 +116,7 @@ files:
|
|
134
116
|
- Rakefile
|
135
117
|
- lib/rom-repository.rb
|
136
118
|
- lib/rom/plugins/relation/key_inference.rb
|
137
|
-
- lib/rom/
|
138
|
-
- lib/rom/plugins/relation/sql/auto_wrap.rb
|
139
|
-
- lib/rom/plugins/relation/sql/base_view.rb
|
140
|
-
- lib/rom/plugins/relation/view.rb
|
141
|
-
- lib/rom/plugins/relation/view/dsl.rb
|
142
|
-
- lib/rom/repository/base.rb
|
143
|
-
- lib/rom/repository/ext/relation.rb
|
144
|
-
- lib/rom/repository/ext/relation/view_dsl.rb
|
119
|
+
- lib/rom/repository.rb
|
145
120
|
- lib/rom/repository/header_builder.rb
|
146
121
|
- lib/rom/repository/loading_proxy.rb
|
147
122
|
- lib/rom/repository/loading_proxy/combine.rb
|
@@ -150,6 +125,7 @@ files:
|
|
150
125
|
- lib/rom/repository/struct_builder.rb
|
151
126
|
- lib/rom/repository/version.rb
|
152
127
|
- lib/rom/struct.rb
|
128
|
+
- log/.gitkeep
|
153
129
|
- rom-repository.gemspec
|
154
130
|
- spec/integration/multi_adapter_spec.rb
|
155
131
|
- spec/integration/repository_spec.rb
|
@@ -162,6 +138,7 @@ files:
|
|
162
138
|
- spec/support/mapper_registry.rb
|
163
139
|
- spec/unit/header_builder_spec.rb
|
164
140
|
- spec/unit/loading_proxy_spec.rb
|
141
|
+
- spec/unit/plugins/view_spec.rb
|
165
142
|
- spec/unit/sql/relation_spec.rb
|
166
143
|
- spec/unit/struct_builder_spec.rb
|
167
144
|
homepage: http://rom-rb.org
|
@@ -179,9 +156,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
156
|
version: '0'
|
180
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
158
|
requirements:
|
182
|
-
- - "
|
159
|
+
- - ">"
|
183
160
|
- !ruby/object:Gem::Version
|
184
|
-
version:
|
161
|
+
version: 1.3.1
|
185
162
|
requirements: []
|
186
163
|
rubyforge_project:
|
187
164
|
rubygems_version: 2.4.5
|
@@ -189,3 +166,4 @@ signing_key:
|
|
189
166
|
specification_version: 4
|
190
167
|
summary: Repository for ROM with auto-mapping and relation extensions
|
191
168
|
test_files: []
|
169
|
+
has_rdoc:
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module Plugins
|
3
|
-
module Relation
|
4
|
-
module SQL
|
5
|
-
module AutoCombine
|
6
|
-
# @api private
|
7
|
-
def self.included(klass)
|
8
|
-
super
|
9
|
-
klass.class_eval do
|
10
|
-
include(InstanceInterface)
|
11
|
-
extend(ClassInterface)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module ClassInterface
|
16
|
-
def inherited(klass)
|
17
|
-
super
|
18
|
-
klass.auto_curry :for_combine
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module InstanceInterface
|
23
|
-
# Default methods for fetching combined relation
|
24
|
-
#
|
25
|
-
# This method is used by default by `combine`
|
26
|
-
#
|
27
|
-
# @return [SQL::Relation]
|
28
|
-
#
|
29
|
-
# @api private
|
30
|
-
def for_combine(keys, relation)
|
31
|
-
pk, fk = keys.to_a.flatten
|
32
|
-
where(fk => relation.map { |tuple| tuple[pk] })
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
ROM.plugins do
|
42
|
-
adapter :sql do
|
43
|
-
register :auto_combine, ROM::Plugins::Relation::SQL::AutoCombine, type: :relation
|
44
|
-
end
|
45
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module Plugins
|
3
|
-
module Relation
|
4
|
-
module SQL
|
5
|
-
module AutoWrap
|
6
|
-
# @api private
|
7
|
-
def self.included(klass)
|
8
|
-
super
|
9
|
-
klass.class_eval do
|
10
|
-
include(InstanceInterface)
|
11
|
-
extend(ClassInterface)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module ClassInterface
|
16
|
-
def inherited(klass)
|
17
|
-
super
|
18
|
-
klass.auto_curry :for_wrap
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module InstanceInterface
|
23
|
-
# Default methods for fetching wrapped relation
|
24
|
-
#
|
25
|
-
# This method is used by default by `wrap` and `wrap_parents`
|
26
|
-
#
|
27
|
-
# @return [SQL::Relation]
|
28
|
-
#
|
29
|
-
# @api private
|
30
|
-
def for_wrap(keys, name)
|
31
|
-
other = __registry__[name]
|
32
|
-
|
33
|
-
inner_join(name, keys)
|
34
|
-
.select(*qualified.header.columns)
|
35
|
-
.select_append(*other.prefix(other.name).qualified.header)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
ROM.plugins do
|
45
|
-
adapter :sql do
|
46
|
-
register :auto_wrap, ROM::Plugins::Relation::SQL::AutoWrap, type: :relation
|
47
|
-
end
|
48
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module Plugins
|
3
|
-
module Relation
|
4
|
-
module SQL
|
5
|
-
module BaseView
|
6
|
-
# @api private
|
7
|
-
def self.included(klass)
|
8
|
-
super
|
9
|
-
klass.class_eval do
|
10
|
-
def self.inherited(other)
|
11
|
-
super
|
12
|
-
other.view(:base) do
|
13
|
-
header { dataset.columns }
|
14
|
-
relation { select(*attributes(:base)).order(primary_key) }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
ROM.plugins do
|
26
|
-
adapter :sql do
|
27
|
-
register :base_view, ROM::Plugins::Relation::SQL::BaseView, type: :relation
|
28
|
-
end
|
29
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'rom/plugins/relation/view/dsl'
|
2
|
-
|
3
|
-
module ROM
|
4
|
-
module Plugins
|
5
|
-
module Relation
|
6
|
-
module View
|
7
|
-
def self.included(klass)
|
8
|
-
super
|
9
|
-
|
10
|
-
klass.class_eval do
|
11
|
-
extend ClassInterface
|
12
|
-
|
13
|
-
def self.attributes
|
14
|
-
@__attributes__ ||= {}
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Return column names that will be selected for this relation
|
20
|
-
#
|
21
|
-
# By default we use dataset columns but first we look at configured
|
22
|
-
# attributes by `view` DSL
|
23
|
-
#
|
24
|
-
# @return [Array<Symbol>]
|
25
|
-
#
|
26
|
-
# @api private
|
27
|
-
def attributes(view_name = name)
|
28
|
-
header = self.class.attributes
|
29
|
-
.fetch(view_name, self.class.attributes.fetch(:base))
|
30
|
-
|
31
|
-
if header.is_a?(Proc)
|
32
|
-
instance_exec(&header)
|
33
|
-
else
|
34
|
-
header
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
module ClassInterface
|
39
|
-
# Define a relation view with a specific header
|
40
|
-
#
|
41
|
-
# With headers defined all the mappers will be inferred automatically
|
42
|
-
#
|
43
|
-
# @example
|
44
|
-
# class Users < ROM::Relation[:sql]
|
45
|
-
# view(:by_name, [:id, :name]) do |name|
|
46
|
-
# where(name: name)
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# view(:listing, [:id, :name, :email]) do
|
50
|
-
# select(:id, :name, :email).order(:name)
|
51
|
-
# end
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# @api public
|
55
|
-
def view(*args, &block)
|
56
|
-
if args.size == 1 && block.arity > 0
|
57
|
-
raise ArgumentError, "header must be set as second argument"
|
58
|
-
end
|
59
|
-
|
60
|
-
name, names, relation_block =
|
61
|
-
if args.size == 1
|
62
|
-
DSL.new(*args, &block).call
|
63
|
-
else
|
64
|
-
[*args, block]
|
65
|
-
end
|
66
|
-
|
67
|
-
attributes[name] = names
|
68
|
-
|
69
|
-
define_method(name, &relation_block)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
ROM.plugins do
|
78
|
-
register :view, ROM::Plugins::Relation::View, type: :relation
|
79
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module Plugins
|
3
|
-
module Relation
|
4
|
-
module View
|
5
|
-
class DSL
|
6
|
-
attr_reader :name
|
7
|
-
|
8
|
-
attr_reader :attributes
|
9
|
-
|
10
|
-
attr_reader :relation_block
|
11
|
-
|
12
|
-
def initialize(name, &block)
|
13
|
-
@name = name
|
14
|
-
instance_eval(&block)
|
15
|
-
end
|
16
|
-
|
17
|
-
def header(*args, &block)
|
18
|
-
@attributes = args.size > 0 ? args.first : block
|
19
|
-
end
|
20
|
-
|
21
|
-
def relation(&block)
|
22
|
-
@relation_block = lambda(&block)
|
23
|
-
end
|
24
|
-
|
25
|
-
def call
|
26
|
-
[name, attributes, relation_block]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/lib/rom/repository/base.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'rom/support/options'
|
2
|
-
|
3
|
-
require 'rom/repository/ext/relation'
|
4
|
-
|
5
|
-
require 'rom/repository/mapper_builder'
|
6
|
-
require 'rom/repository/loading_proxy'
|
7
|
-
|
8
|
-
module ROM
|
9
|
-
class Repository < Gateway
|
10
|
-
# Abstract repository class to inherit from
|
11
|
-
#
|
12
|
-
# TODO: rename this to Repository once deprecated Repository from rom core is gone
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
class Base # :trollface:
|
16
|
-
include Options
|
17
|
-
|
18
|
-
option :mapper_builder, reader: true, default: proc { MapperBuilder.new }
|
19
|
-
|
20
|
-
# Define which relations your repository is going to use
|
21
|
-
#
|
22
|
-
# @example
|
23
|
-
# class MyRepo < ROM::Repository::Base
|
24
|
-
# relations :users, :tasks
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# my_repo = MyRepo.new(rom_env)
|
28
|
-
#
|
29
|
-
# my_repo.users
|
30
|
-
# my_repo.tasks
|
31
|
-
#
|
32
|
-
# @return [Array<Symbol>]
|
33
|
-
#
|
34
|
-
# @api public
|
35
|
-
def self.relations(*names)
|
36
|
-
if names.any?
|
37
|
-
attr_reader(*names)
|
38
|
-
@relations = names
|
39
|
-
else
|
40
|
-
@relations
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# @api private
|
45
|
-
def initialize(env, options = {})
|
46
|
-
super
|
47
|
-
self.class.relations.each do |name|
|
48
|
-
proxy = LoadingProxy.new(
|
49
|
-
env.relation(name), name: name, mapper_builder: mapper_builder
|
50
|
-
)
|
51
|
-
instance_variable_set("@#{name}", proxy)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module SQL
|
3
|
-
class Relation < ROM::Relation
|
4
|
-
# View DSL evaluator
|
5
|
-
#
|
6
|
-
# @api private
|
7
|
-
class ViewDSL
|
8
|
-
attr_reader :name
|
9
|
-
|
10
|
-
attr_reader :attributes
|
11
|
-
|
12
|
-
attr_reader :relation_block
|
13
|
-
|
14
|
-
def initialize(name, &block)
|
15
|
-
@name = name
|
16
|
-
instance_eval(&block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def header(attributes)
|
20
|
-
@attributes = attributes
|
21
|
-
end
|
22
|
-
|
23
|
-
def relation(&block)
|
24
|
-
@relation_block = lambda(&block)
|
25
|
-
end
|
26
|
-
|
27
|
-
def call
|
28
|
-
[name, attributes, relation_block]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|