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,145 +0,0 @@
1
- require 'rom/pipeline'
2
- require 'rom/mapper_registry'
3
-
4
- require 'rom/relation/loaded'
5
- require 'rom/relation/composite'
6
- require 'rom/relation/graph'
7
- require 'rom/relation/materializable'
8
-
9
- module ROM
10
- class Relation
11
- # Lazy relation wraps canonical relation for data-pipelining
12
- #
13
- # @example
14
- # ROM.setup(:memory)
15
- #
16
- # class Users < ROM::Relation[:memory]
17
- # def by_name(name)
18
- # restrict(name: name)
19
- # end
20
- # end
21
- #
22
- # rom = ROM.finalize.env
23
- #
24
- # rom.relations.users << { name: 'Jane' }
25
- # rom.relations.users << { name: 'Joe' }
26
- #
27
- # mapper = proc { |users| users.map { |user| user[:name] } }
28
- # users = rom.relation(:users)
29
- #
30
- # (users.by_name >> mapper)['Jane'].inspect # => ["Jane"]
31
- #
32
- # @api public
33
- class Lazy
34
- include Equalizer.new(:relation, :options)
35
- include Options
36
- include Materializable
37
- include Pipeline
38
-
39
- option :mappers, reader: true, default: proc { MapperRegistry.new }
40
-
41
- # @return [Relation]
42
- #
43
- # @api private
44
- attr_reader :relation
45
-
46
- # Map of exposed relation methods
47
- #
48
- # @return [Hash<Symbol=>TrueClass>]
49
- #
50
- # @api private
51
- attr_reader :exposed_relations
52
-
53
- # @api private
54
- def initialize(relation, options = {})
55
- super
56
- @relation = relation
57
- @exposed_relations = @relation.exposed_relations
58
- end
59
-
60
- # Eager load other relation(s) for this relation
61
- #
62
- # @param [Array<Relation>] others The other relation(s) to eager load
63
- #
64
- # @return [Relation::Graph]
65
- #
66
- # @api public
67
- def combine(*others)
68
- Graph.build(self, others)
69
- end
70
-
71
- # Build a relation pipeline using registered mappers
72
- #
73
- # @example
74
- # rom.relation(:users).map_with(:json_serializer)
75
- #
76
- # @return [Relation::Composite]
77
- #
78
- # @api public
79
- def map_with(*names)
80
- [self, *names.map { |name| mappers[name] }]
81
- .reduce { |a, e| Composite.new(a, e) }
82
- end
83
- alias_method :as, :map_with
84
-
85
- # Load relation
86
- #
87
- # @return [Relation::Loaded]
88
- #
89
- # @api public
90
- def call
91
- Loaded.new(relation)
92
- end
93
-
94
- # @api private
95
- def respond_to_missing?(name, include_private = false)
96
- exposed_relations.include?(name) || super
97
- end
98
-
99
- # Return if this lazy relation is curried
100
- #
101
- # @return [false]
102
- #
103
- # @api private
104
- def curried?
105
- false
106
- end
107
-
108
- private
109
-
110
- # Forward methods to the underlaying relation
111
- #
112
- # Auto-curry relations when args size doesn't match arity
113
- #
114
- # @return [Lazy,Curried]
115
- #
116
- # @api private
117
- def method_missing(meth, *args, &block)
118
- if !exposed_relations.include?(meth) || (curried? && name != meth)
119
- super
120
- else
121
- arity = relation.method(meth).arity
122
-
123
- if arity < 0 || arity == args.size
124
- response = relation.__send__(meth, *args, &block)
125
-
126
- if response.is_a?(Relation)
127
- __new__(response)
128
- else
129
- response
130
- end
131
- else
132
- Curried.new(relation, name: meth, curry_args: args, arity: arity)
133
- end
134
- end
135
- end
136
-
137
- # Return new lazy relation with updated options
138
- #
139
- # @api private
140
- def __new__(relation, new_opts = {})
141
- Lazy.new(relation, options.merge(new_opts))
142
- end
143
- end
144
- end
145
- end
@@ -1,41 +0,0 @@
1
- require 'rom/support/enumerable_dataset'
2
-
3
- module ROM
4
- # A helper module that adds data-proxy behavior to an array-like object
5
- #
6
- # @see EnumerableDataset
7
- #
8
- # @api public
9
- module ArrayDataset
10
- extend DataProxy::ClassMethods
11
- include EnumerableDataset
12
-
13
- # Extends the class with data-proxy behavior
14
- #
15
- # @api private
16
- def self.included(klass)
17
- klass.class_eval do
18
- include Options
19
- include DataProxy
20
- end
21
- end
22
-
23
- forward(
24
- :*, :+, :-, :compact, :compact!, :flatten, :flatten!, :length, :pop,
25
- :reverse, :reverse!, :sample, :size, :shift, :shuffle, :shuffle!,
26
- :slice, :slice!, :sort!, :uniq, :uniq!, :unshift, :values_at
27
- )
28
-
29
- [
30
- :map!, :combination, :cycle, :delete_if, :keep_if, :permutation, :reject!,
31
- :select!, :sort_by!
32
- ].each do |method|
33
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
34
- def #{method}(*args, &block)
35
- return to_enum unless block
36
- self.class.new(data.send(:#{method}, *args, &block), options)
37
- end
38
- RUBY
39
- end
40
- end
41
- end
@@ -1,44 +0,0 @@
1
- module ROM
2
- # Internal support class for generating classes
3
- #
4
- # @private
5
- class ClassBuilder
6
- include Options
7
-
8
- option :name, type: String, reader: true
9
- option :parent, type: Class, reader: true, parent: Object
10
-
11
- # Generate a class based on options
12
- #
13
- # @example
14
- # builder = ROM::ClasBuilder.new(name: 'MyClass')
15
- #
16
- # klass = builder.call
17
- # klass.name # => "MyClass"
18
- #
19
- # @return [Class]
20
- #
21
- # @api private
22
- def call
23
- klass = Class.new(parent)
24
-
25
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
26
- def self.name
27
- #{name.inspect}
28
- end
29
-
30
- def self.inspect
31
- name
32
- end
33
-
34
- def self.to_s
35
- name
36
- end
37
- RUBY
38
-
39
- yield(klass) if block_given?
40
-
41
- klass
42
- end
43
- end
44
- end
@@ -1,56 +0,0 @@
1
- module ROM
2
- # Internal support module for class-level settings
3
- #
4
- # @private
5
- module ClassMacros
6
- # Specify what macros a class will use
7
- #
8
- # @example
9
- # class MyClass
10
- # extend ROM::ClassMacros
11
- #
12
- # defines :one, :two
13
- #
14
- # one 1
15
- # two 2
16
- # end
17
- #
18
- # class OtherClass < MyClass
19
- # two 'two'
20
- # end
21
- #
22
- # MyClass.one # => 1
23
- # MyClass.two # => 2
24
- #
25
- # OtherClass.one # => 1
26
- # OtherClass.two # => 'two'
27
- #
28
- # @api private
29
- def defines(*args)
30
- mod = Module.new
31
-
32
- args.each do |name|
33
- mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
34
- def #{name}(value = Undefined)
35
- if value == Undefined
36
- defined?(@#{name}) && @#{name}
37
- else
38
- @#{name} = value
39
- end
40
- end
41
- RUBY
42
- end
43
-
44
- delegates = args.map { |name| "klass.#{name}(#{name})" }.join("\n")
45
-
46
- mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
47
- def inherited(klass)
48
- super
49
- #{delegates}
50
- end
51
- RUBY
52
-
53
- extend(mod)
54
- end
55
- end
56
- end
@@ -1,102 +0,0 @@
1
- require 'equalizer'
2
-
3
- module ROM
4
- # Helper module for dataset classes
5
- #
6
- # It provides a constructor accepting data, header and an optional row_proc.
7
- # This module is used internally by EnumerableDataset and ArrayDataset.
8
- #
9
- # @private
10
- module DataProxy
11
- NON_FORWARDABLE = [
12
- :each, :to_a, :to_ary, :kind_of?, :instance_of?, :is_a?
13
- ].freeze
14
-
15
- # Wrapped data array
16
- #
17
- # @return [Object] Data object for the iterator
18
- #
19
- # @api private
20
- attr_reader :data
21
-
22
- # @return [Proc] tuple processing proc
23
- #
24
- # @api private
25
- attr_reader :row_proc
26
-
27
- # Extends the class with `forward` DSL and Equalizer using `data` attribute
28
- #
29
- # @see ClassMethods#forward
30
- #
31
- # @api private
32
- def self.included(klass)
33
- klass.class_eval do
34
- extend ClassMethods
35
-
36
- include Equalizer.new(:data)
37
-
38
- option :row_proc, reader: true, default: proc { |obj| obj.class.row_proc }
39
- end
40
- end
41
-
42
- # @api private
43
- def initialize(data, options = {})
44
- @data = data
45
- super(data, options)
46
- end
47
-
48
- # Iterate over data using row_proc
49
- #
50
- # @return [Enumerator] if block is not given
51
- #
52
- # @api private
53
- def each
54
- return to_enum unless block_given?
55
- data.each { |tuple| yield(row_proc[tuple]) }
56
- end
57
-
58
- module ClassMethods
59
- # Default no-op tuple proc
60
- #
61
- # @return [Proc]
62
- #
63
- # @api private
64
- def row_proc
65
- -> tuple { tuple }
66
- end
67
-
68
- # Forward provided methods to the underlaying data object
69
- #
70
- # @example
71
- #
72
- # class MyDataset
73
- # include DataProxy
74
- #
75
- # forward(:find_all, :map)
76
- # end
77
- #
78
- # @return [undefined]
79
- #
80
- # @api public
81
- def forward(*methods)
82
- # FIXME: we should probably raise if one of the non-forwardable methods
83
- # was provided
84
- (methods - NON_FORWARDABLE).each do |method_name|
85
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
86
- def #{method_name}(*args, &block)
87
- response = data.public_send(#{method_name.inspect}, *args, &block)
88
-
89
- if response.equal?(data)
90
- self
91
- elsif response.is_a?(data.class)
92
- self.class.new(response)
93
- else
94
- response
95
- end
96
- end
97
- RUBY
98
- end
99
- end
100
- end
101
- end
102
- end
@@ -1,36 +0,0 @@
1
- module ROM
2
- module Deprecations
3
- # @api private
4
- def deprecate(old_name, new_name, msg = nil)
5
- class_eval do
6
- define_method(old_name) do |*args, &block|
7
- ROM::Deprecations.announce "#{self.class}##{old_name} is", <<-MSG
8
- Please use #{self.class}##{new_name} instead.
9
- #{msg}
10
- MSG
11
- __send__(new_name, *args, &block)
12
- end
13
- end
14
- end
15
-
16
- def deprecate_class_method(old_name, new_name, msg = nil)
17
- class_eval do
18
- define_singleton_method(old_name) do |*args, &block|
19
- ROM::Deprecations.announce"#{self}.#{old_name} is", <<-MSG
20
- Please use #{self}.#{new_name} instead.
21
- #{msg}
22
- MSG
23
- __send__(new_name, *args, &block)
24
- end
25
- end
26
- end
27
-
28
- def self.announce(name, msg)
29
- warn <<-MSG.gsub(/^\s+/, '')
30
- #{name} deprecated and will be removed in 1.0.0.
31
- #{msg}
32
- #{caller.detect { |l| !l.include?('lib/rom')}}
33
- MSG
34
- end
35
- end
36
- end
@@ -1,65 +0,0 @@
1
- require 'rom/support/data_proxy'
2
-
3
- module ROM
4
- # A helper module that adds data-proxy behavior to an enumerable object
5
- #
6
- # This module is intended to be used by gateways
7
- #
8
- # Class that includes this module can define `row_proc` class method which
9
- # must return a proc-like object which will be used to process each element
10
- # in the enumerable
11
- #
12
- # @example
13
- # class MyDataset
14
- # include ROM::EnumerableDataset
15
- #
16
- # def self.row_proc
17
- # -> tuple { tuple.each_with_object({}) { |(k,v), h| h[k.to_sym] = v } }
18
- # end
19
- # end
20
- #
21
- # ds = MyDataset.new([{ 'name' => 'Jane' }, [:name])
22
- # ds.to_a # => { :name => 'Jane' }
23
- #
24
- # @api public
25
- module EnumerableDataset
26
- extend DataProxy::ClassMethods
27
- include Enumerable
28
-
29
- # Coerce a dataset to an array
30
- #
31
- # @return [Array]
32
- #
33
- # @api public
34
- alias_method :to_ary, :to_a
35
-
36
- # Included hook which extends a class with DataProxy behavior
37
- #
38
- # This module can also be included into other modules so we apply the
39
- # extension only for classes
40
- #
41
- # @api private
42
- def self.included(klass)
43
- return unless klass.is_a?(Class)
44
-
45
- klass.class_eval do
46
- include Options
47
- include DataProxy
48
- end
49
- end
50
-
51
- forward :take
52
-
53
- [
54
- :chunk, :collect, :collect_concat, :drop_while, :find_all, :flat_map,
55
- :grep, :map, :reject, :select, :sort, :sort_by, :take_while
56
- ].each do |method|
57
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
58
- def #{method}(*args, &block)
59
- return to_enum unless block
60
- self.class.new(super(*args, &block), options)
61
- end
62
- RUBY
63
- end
64
- end
65
- end