rom-repository 0.1.0 → 0.2.0.beta1

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: 69a0d338b66452b9d5434b08129f04c7ce0a260a
4
- data.tar.gz: 98e1038b529b861828284565d6e7fa59f3da5fbc
3
+ metadata.gz: 2526fefe26c270b932eaf46aba937183488fafba
4
+ data.tar.gz: d867a97f3a2fad0abe56811ac3b3b4bfe477cc66
5
5
  SHA512:
6
- metadata.gz: 0bde95e0e0fda272e1737e6eda953896f8fb5f3ce9a52620bcf41b469ef0f796dd05e11d2f05d6ed1fc1fd81004bb87fe7f2685e1151bc9414735f3d19c9b527
7
- data.tar.gz: b1b0a57585cc0cd60dfd3be82fc51e75ccdfacca7d6cdfa580d2216d2fe1358d018e68838a25ed6fa13eb909fbf3544a578ad6e0981d6ebf731440b45cbf0c5d
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
- ### Decorating Structs
112
+ ### Using Custom Model Types
113
113
 
114
- Nothing is stopping you from decorating your structs using registered mappers and
115
- custom decorator models:
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 UserStructMapper < ROM::Mapper
119
- register_as :ui_presenter
120
- model UI::UserPresenter
121
- end
118
+ class UserRepository < ROM::Repository::Base
119
+ relations :users, :tasks
122
120
 
123
- user_repo.by_id(1).as(:ui_presenter)
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.
@@ -1,20 +1,3 @@
1
1
  require 'rom'
2
2
 
3
- require 'rom/plugins/relation/view'
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 < Gateway
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
- options = [
34
- visit_header(header[1], meta),
35
- model: struct_builder[meta.fetch(:base_name), header[1].map { |a| a[1] }]
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 < Gateway
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
- mappers = [mapper]+names.map { |name| relation.mappers[name] }
48
- mappers.reduce(self) { |a, e| a >> e }
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
@@ -1,5 +1,5 @@
1
1
  module ROM
2
- class Repository < Gateway
2
+ class Repository
3
3
  class LoadingProxy
4
4
  # Provides convenient methods for producing combined relations
5
5
  #
@@ -1,5 +1,5 @@
1
1
  module ROM
2
- class Repository < Gateway
2
+ class Repository
3
3
  class LoadingProxy
4
4
  # Provides convenient methods for producing wrapped relations
5
5
  #
@@ -1,7 +1,7 @@
1
1
  require 'rom/repository/header_builder'
2
2
 
3
3
  module ROM
4
- class Repository < Gateway
4
+ class Repository
5
5
  # @api private
6
6
  class MapperBuilder
7
7
  attr_reader :header_builder
@@ -3,7 +3,7 @@ require 'anima'
3
3
  require 'rom/struct'
4
4
 
5
5
  module ROM
6
- class Repository < Gateway
6
+ class Repository
7
7
  # @api private
8
8
  class StructBuilder
9
9
  attr_reader :registry
@@ -1,9 +1,5 @@
1
1
  module ROM
2
- # TODO: remove this once deprecated Repository is gone in rom core
3
- class Gateway
4
- end
5
-
6
- class Repository < Gateway
7
- VERSION = '0.1.0'.freeze
2
+ class Repository
3
+ VERSION = '0.2.0.beta1'.freeze
8
4
  end
9
5
  end
File without changes
@@ -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.9', '>= 0.9.0'
20
- gem.add_runtime_dependency 'rom-support', '~> 0.1', '>= 0.1.0'
21
- gem.add_runtime_dependency 'rom-mapper', '~> 0.2', '>= 0.2.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 setup' do
3
+ RSpec.describe 'Repository with multi-adapters configuration' do
4
4
  include_context 'database'
5
5
 
6
- let(:setup) {
7
- ROM.setup(default: [:sql, uri], memory: [:memory])
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::Base
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
- user_id = setup.gateways[:default].dataset(:users).insert(name: 'Jane')
50
- setup.gateways[:memory].dataset(:tasks).insert(user_id: user_id, title: 'Jane Task')
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 eql([jane, joe])
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 eql([jane_with_tasks, joe_with_tasks])
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 eql([jane_with_task, joe_with_task])
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 eql([
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
@@ -1,10 +1,12 @@
1
1
  RSpec.shared_context 'database' do
2
- let(:setup) { ROM.setup(:sql, uri) }
3
- let(:conn) { setup.gateways[:default].connection }
4
- let(:rom) { setup.finalize }
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
@@ -4,7 +4,7 @@ RSpec.shared_context 'relations' do
4
4
  let(:tags) { rom.relation(:tags) }
5
5
 
6
6
  before do
7
- setup.relation(:users) do
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
- setup.relation(:tasks) do
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
- setup.relation(:tags)
27
+ configuration.relation(:tags)
28
28
  end
29
29
  end
@@ -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::Base) do
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
@@ -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
- setup.mappers do
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
- setup.relation(:users) do
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
- setup.relation(:users) do
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
- setup.relation(:users) do
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.1.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-08-19 00:00:00.000000000 Z
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: '0.9'
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: '0.9'
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: '0.1'
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: '0.1'
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: '0.2'
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: '0.2'
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/plugins/relation/sql/auto_combine.rb
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: '0'
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
@@ -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,11 +0,0 @@
1
- require 'rom/relation/curried'
2
-
3
- module ROM
4
- class Relation
5
- class Curried
6
- def attributes(view_name = name)
7
- relation.attributes(view_name)
8
- end
9
- end
10
- end
11
- 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