rom 0.8.1 → 0.9.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +5 -1
  4. data/lib/rom.rb +35 -16
  5. data/lib/rom/command.rb +1 -9
  6. data/lib/rom/commands/graph/class_interface.rb +2 -2
  7. data/lib/rom/constants.rb +0 -6
  8. data/lib/rom/{env.rb → container.rb} +3 -3
  9. data/lib/rom/environment.rb +238 -0
  10. data/lib/rom/environment_plugin.rb +17 -0
  11. data/lib/rom/environment_plugins/auto_registration.rb +17 -0
  12. data/lib/rom/global.rb +0 -203
  13. data/lib/rom/mapper_registry.rb +2 -0
  14. data/lib/rom/pipeline.rb +2 -0
  15. data/lib/rom/plugin.rb +4 -18
  16. data/lib/rom/plugin_base.rb +31 -0
  17. data/lib/rom/plugin_registry.rb +54 -17
  18. data/lib/rom/relation.rb +54 -11
  19. data/lib/rom/relation/class_interface.rb +14 -21
  20. data/lib/rom/relation/curried.rb +36 -2
  21. data/lib/rom/relation/graph.rb +7 -0
  22. data/lib/rom/relation_registry.rb +4 -0
  23. data/lib/rom/setup.rb +9 -8
  24. data/lib/rom/setup/finalize.rb +5 -5
  25. data/lib/rom/version.rb +1 -1
  26. data/rom.gemspec +2 -0
  27. data/spec/integration/commands/create_spec.rb +1 -1
  28. data/spec/integration/commands/update_spec.rb +1 -1
  29. data/spec/integration/mappers/unwrap_spec.rb +1 -1
  30. data/spec/spec_helper.rb +2 -0
  31. data/spec/unit/rom/{env_spec.rb → container_spec.rb} +5 -5
  32. data/spec/unit/rom/plugin_spec.rb +0 -8
  33. data/spec/unit/rom/relation/composite_spec.rb +2 -2
  34. data/spec/unit/rom/relation/curried_spec.rb +53 -0
  35. data/spec/unit/rom/relation/graph_spec.rb +4 -0
  36. data/spec/unit/rom/relation/lazy/combine_spec.rb +6 -6
  37. data/spec/unit/rom/relation/lazy_spec.rb +4 -8
  38. data/spec/unit/rom/relation_spec.rb +0 -14
  39. data/spec/unit/rom/setup_spec.rb +1 -1
  40. metadata +52 -35
  41. data/lib/rom/header.rb +0 -193
  42. data/lib/rom/header/attribute.rb +0 -184
  43. data/lib/rom/mapper.rb +0 -103
  44. data/lib/rom/mapper/attribute_dsl.rb +0 -477
  45. data/lib/rom/mapper/dsl.rb +0 -119
  46. data/lib/rom/mapper/model_dsl.rb +0 -55
  47. data/lib/rom/model_builder.rb +0 -101
  48. data/lib/rom/processor.rb +0 -28
  49. data/lib/rom/processor/transproc.rb +0 -388
  50. data/lib/rom/relation/lazy.rb +0 -145
  51. data/lib/rom/support/array_dataset.rb +0 -41
  52. data/lib/rom/support/class_builder.rb +0 -44
  53. data/lib/rom/support/class_macros.rb +0 -56
  54. data/lib/rom/support/data_proxy.rb +0 -102
  55. data/lib/rom/support/deprecations.rb +0 -36
  56. data/lib/rom/support/enumerable_dataset.rb +0 -65
  57. data/lib/rom/support/inflector.rb +0 -73
  58. data/lib/rom/support/options.rb +0 -195
  59. data/lib/rom/support/registry.rb +0 -43
  60. data/spec/unit/rom/header_spec.rb +0 -102
  61. data/spec/unit/rom/mapper/dsl_spec.rb +0 -467
  62. data/spec/unit/rom/mapper_spec.rb +0 -84
  63. data/spec/unit/rom/model_builder_spec.rb +0 -46
  64. data/spec/unit/rom/processor/transproc_spec.rb +0 -448
  65. data/spec/unit/rom/support/array_dataset_spec.rb +0 -61
  66. data/spec/unit/rom/support/class_builder_spec.rb +0 -42
  67. data/spec/unit/rom/support/enumerable_dataset_spec.rb +0 -17
  68. data/spec/unit/rom/support/inflector_spec.rb +0 -89
  69. data/spec/unit/rom/support/options_spec.rb +0 -119
@@ -1,5 +1,8 @@
1
1
  require 'set'
2
2
 
3
+ require 'rom/support/auto_curry'
4
+ require 'rom/relation/curried'
5
+
3
6
  module ROM
4
7
  class Relation
5
8
  module ClassInterface
@@ -21,7 +24,7 @@ module ROM
21
24
  klass.class_eval do
22
25
  use :registry_reader
23
26
 
24
- defines :gateway, :dataset, :register_as, :exposed_relations
27
+ defines :gateway, :dataset, :register_as
25
28
 
26
29
  deprecate_class_method :repository, :gateway
27
30
  deprecate :repository, :gateway
@@ -29,7 +32,6 @@ module ROM
29
32
  gateway :default
30
33
 
31
34
  dataset(default_name)
32
- exposed_relations Set.new
33
35
 
34
36
  # Relation's dataset name
35
37
  #
@@ -40,16 +42,6 @@ module ROM
40
42
  # @api public
41
43
  attr_reader :name
42
44
 
43
- # A set with public method names that return "virtual" relations
44
- #
45
- # Only those methods are exposed directly on relations return by
46
- # Env#relation interface
47
- #
48
- # @return [Set]
49
- #
50
- # @api private
51
- attr_reader :exposed_relations
52
-
53
45
  # Set or get name under which a relation will be registered
54
46
  #
55
47
  # This defaults to `dataset` name
@@ -65,18 +57,14 @@ module ROM
65
57
  end
66
58
  end
67
59
 
68
- # Hook used to collect public method names
69
- #
70
- # @api private
71
- def self.method_added(name)
72
- super
73
- exposed_relations << name if public_instance_methods.include?(name)
60
+ def self.exposed_relations(*args)
61
+ Deprecations.announce("#{self}.exposed_relations", 'this method has no effect anymore')
62
+ Set.new
74
63
  end
75
64
 
76
65
  # @api private
77
66
  def initialize(dataset, options = {})
78
67
  @name = self.class.dataset
79
- @exposed_relations = self.class.exposed_relations
80
68
  super
81
69
  end
82
70
 
@@ -90,7 +78,7 @@ module ROM
90
78
  end
91
79
  end
92
80
 
93
- ROM.register_relation(klass)
81
+ klass.extend(AutoCurry)
94
82
  end
95
83
 
96
84
  # Return adapter-specific relation subclass
@@ -187,10 +175,15 @@ module ROM
187
175
  registry
188
176
  end
189
177
 
178
+ # @api private
179
+ def curried
180
+ Curried
181
+ end
182
+
190
183
  # Hook to finalize a relation after its instance was created
191
184
  #
192
185
  # @api private
193
- def finalize(_env, _relation)
186
+ def finalize(_container, _relation)
194
187
  # noop
195
188
  end
196
189
  end
@@ -1,12 +1,24 @@
1
- require 'rom/relation/lazy'
1
+ require 'rom/support/options'
2
+ require 'rom/relation/materializable'
2
3
 
3
4
  module ROM
4
5
  class Relation
5
- class Curried < Lazy
6
+ class Curried
7
+ include Options
8
+ include Materializable
9
+
6
10
  option :name, type: Symbol, reader: true
7
11
  option :arity, type: Integer, reader: true, default: -1
8
12
  option :curry_args, type: Array, reader: true, default: EMPTY_ARRAY
9
13
 
14
+ attr_reader :relation
15
+
16
+ # @api private
17
+ def initialize(relation, options = {})
18
+ @relation = relation
19
+ super
20
+ end
21
+
10
22
  # Load relation if args match the arity
11
23
  #
12
24
  # @return [Loaded,Lazy,Curried]
@@ -47,12 +59,34 @@ module ROM
47
59
  true
48
60
  end
49
61
 
62
+ # @api private
63
+ def respond_to_missing?(name, include_private = false)
64
+ super || relation.respond_to?(name)
65
+ end
66
+
50
67
  private
51
68
 
52
69
  # @api private
53
70
  def __new__(relation, new_opts = {})
54
71
  Curried.new(relation, options.merge(new_opts))
55
72
  end
73
+
74
+ # @api private
75
+ def method_missing(meth, *args, &block)
76
+ if relation.respond_to?(meth)
77
+ response = relation.__send__(meth, *args, &block)
78
+
79
+ super if response.is_a?(self.class)
80
+
81
+ if response.is_a?(Relation) || response.is_a?(Graph)
82
+ __new__(response)
83
+ else
84
+ response
85
+ end
86
+ else
87
+ super
88
+ end
89
+ end
56
90
  end
57
91
  end
58
92
  end
@@ -93,6 +93,13 @@ module ROM
93
93
 
94
94
  Loaded.new(self, [left, right])
95
95
  end
96
+
97
+ private
98
+
99
+ # @api private
100
+ def decorate?(other)
101
+ super || other.is_a?(Curried)
102
+ end
96
103
  end
97
104
  end
98
105
  end
@@ -0,0 +1,4 @@
1
+ module ROM
2
+ class RelationRegistry < Registry
3
+ end
4
+ end
data/lib/rom/setup.rb CHANGED
@@ -7,7 +7,7 @@ module ROM
7
7
  # @api public
8
8
  class Setup
9
9
  extend Deprecations
10
- include Equalizer.new(:gateways, :env)
10
+ include Equalizer.new(:gateways, :container)
11
11
 
12
12
  # @return [Hash] configured gateways
13
13
  #
@@ -39,10 +39,11 @@ module ROM
39
39
  # @api private
40
40
  attr_reader :command_classes
41
41
 
42
- # @return [Env] finalized env after setup phase is over
42
+ # @return [Conainer] finalized container after setup phase is over
43
43
  #
44
44
  # @api private
45
- attr_reader :env
45
+ attr_reader :container
46
+ alias_method :env, :container
46
47
 
47
48
  # @api private
48
49
  def initialize(gateways, default_adapter = nil)
@@ -51,21 +52,21 @@ module ROM
51
52
  @relation_classes = []
52
53
  @mapper_classes = []
53
54
  @command_classes = []
54
- @env = nil
55
+ @container = nil
55
56
  end
56
57
 
57
58
  # Finalize the setup
58
59
  #
59
- # @return [Env] frozen env with access to gateways, relations,
60
- # mappers and commands
60
+ # @return [Container] frozen container with access to gateways,
61
+ # relations, mappers and commands
61
62
  #
62
63
  # @api public
63
64
  def finalize
64
- raise EnvAlreadyFinalizedError if env
65
+ raise EnvAlreadyFinalizedError if container
65
66
  finalize = Finalize.new(
66
67
  gateways, relation_classes, mapper_classes, command_classes
67
68
  )
68
- @env = finalize.run!
69
+ @container = finalize.run!
69
70
  end
70
71
 
71
72
  # Return gateway identified by name
@@ -1,16 +1,16 @@
1
1
  require 'rom/relation'
2
- require 'rom/mapper'
3
2
  require 'rom/command'
4
3
 
5
4
  require 'rom/support/registry'
5
+ require 'rom/relation_registry'
6
6
  require 'rom/command_registry'
7
7
  require 'rom/mapper_registry'
8
8
 
9
- require 'rom/env'
9
+ require 'rom/container'
10
10
 
11
11
  module ROM
12
12
  class Setup
13
- # This giant builds an environment using defined classes for core parts of ROM
13
+ # This giant builds an container using defined classes for core parts of ROM
14
14
  #
15
15
  # It is used by the setup object after it's done gathering class definitions
16
16
  #
@@ -43,7 +43,7 @@ module ROM
43
43
  #
44
44
  # This creates relations, mappers and commands
45
45
  #
46
- # @return [Env]
46
+ # @return [Container]
47
47
  #
48
48
  # @api private
49
49
  def run!
@@ -53,7 +53,7 @@ module ROM
53
53
  mappers = load_mappers
54
54
  commands = load_commands(relations)
55
55
 
56
- Env.new(gateways, relations, mappers, commands)
56
+ Container.new(gateways, relations, mappers, commands)
57
57
  end
58
58
 
59
59
  private
data/lib/rom/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ROM
2
- VERSION = '0.8.1'.freeze
2
+ VERSION = '0.9.0.beta1'.freeze
3
3
  end
data/rom.gemspec CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_runtime_dependency 'transproc', '~> 0.3', '>= 0.3.0'
19
19
  gem.add_runtime_dependency 'equalizer', '~> 0.0', '>= 0.0.9'
20
+ gem.add_runtime_dependency 'rom-support', '~> 0.1', '>= 0.1.0'
21
+ gem.add_runtime_dependency 'rom-mapper', '~> 0.2', '>= 0.2.0'
20
22
 
21
23
  gem.add_development_dependency 'rake', '~> 10.3'
22
24
  gem.add_development_dependency 'rspec', '~> 3.3'
@@ -115,7 +115,7 @@ describe 'Commands / Create' do
115
115
  end
116
116
  end
117
117
  setup.finalize
118
- }.to raise_error(ROM::InvalidOptionValueError)
118
+ }.to raise_error(ROM::Options::InvalidOptionValueError)
119
119
  end
120
120
  end
121
121
 
@@ -97,7 +97,7 @@ describe 'Commands / Update' do
97
97
  end
98
98
  end
99
99
  setup.finalize
100
- }.to raise_error(ROM::InvalidOptionValueError)
100
+ }.to raise_error(ROM::Options::InvalidOptionValueError)
101
101
  end
102
102
  end
103
103
 
@@ -13,7 +13,7 @@ describe 'Mapper definition DSL' do
13
13
  tuple.merge(user: users.restrict(name: tuple[:name]).first)
14
14
  }
15
15
 
16
- self.class.new(tuples)
16
+ __new__(tuples)
17
17
  end
18
18
  end
19
19
 
data/spec/spec_helper.rb CHANGED
@@ -46,3 +46,5 @@ RSpec.configure do |config|
46
46
  ConstantLeakFinder.find(example)
47
47
  end
48
48
  end
49
+
50
+ ROM.use :auto_registration
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ROM::Env do
3
+ describe ROM::Container do
4
4
  include_context 'users and tasks'
5
5
 
6
6
  before do
@@ -64,9 +64,9 @@ describe ROM::Env do
64
64
  expect(by_name['Jane']).to match_array([{ name: 'Jane' }])
65
65
  end
66
66
 
67
- it 'returns lazy relation without mappers when mappers are not defined' do
68
- expect(rom.relation(:tasks)).to be_instance_of(ROM::Relation::Lazy)
69
- expect(rom.relation(:tasks).relation).to be(rom.relations.tasks)
67
+ it 'returns relation without mappers when mappers are not defined' do
68
+ expect(rom.relation(:tasks)).to be_kind_of(ROM::Relation)
69
+ expect(rom.relation(:tasks).mappers.elements).to be_empty
70
70
  end
71
71
  end
72
72
 
@@ -75,7 +75,7 @@ describe ROM::Env do
75
75
  expect {
76
76
  result = rom.read(:users) { |r| r.by_name('Jane') }.as(:name_list)
77
77
  expect(result.call).to match_array([{ name: 'Jane' }])
78
- }.to output(/^ROM::Env#read is deprecated/).to_stderr
78
+ }.to output(/^ROM::Container#read is deprecated/).to_stderr
79
79
  end
80
80
  end
81
81
 
@@ -9,10 +9,6 @@ describe "ROM::PluginRegistry" do
9
9
  Test::CommandPlugin = Module.new
10
10
  Test::MapperPlugin = Module.new
11
11
  Test::RelationPlugin = Module.new do
12
- def self.included(mod)
13
- mod.exposed_relations << :plugged_in
14
- end
15
-
16
12
  def plugged_in
17
13
  "a relation"
18
14
  end
@@ -73,10 +69,6 @@ describe "ROM::PluginRegistry" do
73
69
 
74
70
  it "allows definition of adapter restricted plugins" do
75
71
  Test::LazyPlugin = Module.new do
76
- def self.included(mod)
77
- mod.exposed_relations << :lazy?
78
- end
79
-
80
72
  def lazy?
81
73
  true
82
74
  end
@@ -25,7 +25,7 @@ describe ROM::Relation::Composite do
25
25
  relation = users >> name_list >> upcaser
26
26
  loaded = relation.call
27
27
 
28
- expect(loaded.source).to eql(users.relation)
28
+ expect(loaded.source).to eql(users)
29
29
  expect(loaded).to match_array(%w(JANE JOE))
30
30
  end
31
31
 
@@ -33,7 +33,7 @@ describe ROM::Relation::Composite do
33
33
  relation = users >> users.sorted
34
34
  loaded = relation.call
35
35
 
36
- expect(loaded.source).to eql(users.relation)
36
+ expect(loaded.source).to eql(users)
37
37
  expect(loaded).to match_array([
38
38
  { name: 'Jane', email: 'jane@doe.org' },
39
39
  { name: 'Joe', email: 'joe@doe.org' }
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ROM::Relation::Curried do
4
+ include_context 'users and tasks'
5
+
6
+ let(:users) { rom.relations.users }
7
+
8
+ before do
9
+ setup.relation(:users) do
10
+ def by_name(name)
11
+ restrict(name: name)
12
+ end
13
+
14
+ def find(criteria)
15
+ restrict(criteria)
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '#call' do
21
+ let(:relation) { users.by_name.('Jane') }
22
+
23
+ it 'materializes a relation' do
24
+ expect(relation).to match_array([
25
+ name: 'Jane', email: 'jane@doe.org'
26
+ ])
27
+ end
28
+
29
+ it 'returns a loaded relation' do
30
+ expect(relation.source).to eql(users.by_name('Jane'))
31
+ end
32
+ end
33
+
34
+ describe '#respond_to?' do
35
+ it 'returns true if wrapped relation responds to a method' do
36
+ expect(users.by_name).to respond_to(:dataset)
37
+ end
38
+
39
+ it 'returns false if wrapped relation does not respond to a method' do
40
+ expect(users.by_name).not_to respond_to(:not_here)
41
+ end
42
+ end
43
+
44
+ describe '#method_missing' do
45
+ it 'forwards to the relation' do
46
+ expect(users.by_name.dataset).to eql(users.dataset)
47
+ end
48
+
49
+ it 'does not forward to the relation when method is auto-curried' do
50
+ expect { users.by_name.find }.to raise_error(NoMethodError, /find/)
51
+ end
52
+ end
53
+ end
@@ -41,6 +41,10 @@ describe ROM::Relation::Graph do
41
41
  expect(graph.by_name('Jane')).to be_instance_of(ROM::Relation::Graph)
42
42
  end
43
43
 
44
+ it 'forwards methods to the root and decorates curried response' do
45
+ expect((users.combine(tasks.for_users)).by_name).to be_instance_of(ROM::Relation::Graph)
46
+ end
47
+
44
48
  it 'returns original response from the root' do
45
49
  expect(graph.mappers).to eql(users.mappers)
46
50
  end