rom 0.8.1 → 0.9.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.
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