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