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 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