rom-core 4.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +603 -0
  3. data/LICENSE +20 -0
  4. data/README.md +18 -0
  5. data/lib/rom-core.rb +1 -0
  6. data/lib/rom/array_dataset.rb +44 -0
  7. data/lib/rom/association_set.rb +16 -0
  8. data/lib/rom/associations/abstract.rb +135 -0
  9. data/lib/rom/associations/definitions.rb +5 -0
  10. data/lib/rom/associations/definitions/abstract.rb +116 -0
  11. data/lib/rom/associations/definitions/many_to_many.rb +24 -0
  12. data/lib/rom/associations/definitions/many_to_one.rb +11 -0
  13. data/lib/rom/associations/definitions/one_to_many.rb +11 -0
  14. data/lib/rom/associations/definitions/one_to_one.rb +11 -0
  15. data/lib/rom/associations/definitions/one_to_one_through.rb +11 -0
  16. data/lib/rom/associations/many_to_many.rb +81 -0
  17. data/lib/rom/associations/many_to_one.rb +37 -0
  18. data/lib/rom/associations/one_to_many.rb +37 -0
  19. data/lib/rom/associations/one_to_one.rb +8 -0
  20. data/lib/rom/associations/one_to_one_through.rb +8 -0
  21. data/lib/rom/associations/through_identifier.rb +39 -0
  22. data/lib/rom/auto_curry.rb +55 -0
  23. data/lib/rom/cache.rb +46 -0
  24. data/lib/rom/command.rb +488 -0
  25. data/lib/rom/command_compiler.rb +239 -0
  26. data/lib/rom/command_proxy.rb +24 -0
  27. data/lib/rom/command_registry.rb +141 -0
  28. data/lib/rom/commands.rb +3 -0
  29. data/lib/rom/commands/class_interface.rb +270 -0
  30. data/lib/rom/commands/composite.rb +53 -0
  31. data/lib/rom/commands/create.rb +13 -0
  32. data/lib/rom/commands/delete.rb +14 -0
  33. data/lib/rom/commands/graph.rb +88 -0
  34. data/lib/rom/commands/graph/class_interface.rb +62 -0
  35. data/lib/rom/commands/graph/input_evaluator.rb +62 -0
  36. data/lib/rom/commands/lazy.rb +99 -0
  37. data/lib/rom/commands/lazy/create.rb +23 -0
  38. data/lib/rom/commands/lazy/delete.rb +27 -0
  39. data/lib/rom/commands/lazy/update.rb +34 -0
  40. data/lib/rom/commands/result.rb +96 -0
  41. data/lib/rom/commands/update.rb +14 -0
  42. data/lib/rom/configuration.rb +114 -0
  43. data/lib/rom/configuration_dsl.rb +87 -0
  44. data/lib/rom/configuration_dsl/command.rb +41 -0
  45. data/lib/rom/configuration_dsl/command_dsl.rb +35 -0
  46. data/lib/rom/configuration_dsl/relation.rb +26 -0
  47. data/lib/rom/configuration_plugin.rb +17 -0
  48. data/lib/rom/constants.rb +64 -0
  49. data/lib/rom/container.rb +147 -0
  50. data/lib/rom/core.rb +46 -0
  51. data/lib/rom/create_container.rb +60 -0
  52. data/lib/rom/data_proxy.rb +94 -0
  53. data/lib/rom/enumerable_dataset.rb +68 -0
  54. data/lib/rom/environment.rb +70 -0
  55. data/lib/rom/gateway.rb +184 -0
  56. data/lib/rom/global.rb +58 -0
  57. data/lib/rom/global/plugin_dsl.rb +47 -0
  58. data/lib/rom/initializer.rb +64 -0
  59. data/lib/rom/lint/enumerable_dataset.rb +54 -0
  60. data/lib/rom/lint/gateway.rb +120 -0
  61. data/lib/rom/lint/linter.rb +78 -0
  62. data/lib/rom/lint/spec.rb +20 -0
  63. data/lib/rom/lint/test.rb +98 -0
  64. data/lib/rom/mapper_registry.rb +24 -0
  65. data/lib/rom/memory.rb +4 -0
  66. data/lib/rom/memory/associations.rb +4 -0
  67. data/lib/rom/memory/associations/many_to_many.rb +10 -0
  68. data/lib/rom/memory/associations/many_to_one.rb +10 -0
  69. data/lib/rom/memory/associations/one_to_many.rb +10 -0
  70. data/lib/rom/memory/associations/one_to_one.rb +10 -0
  71. data/lib/rom/memory/commands.rb +56 -0
  72. data/lib/rom/memory/dataset.rb +97 -0
  73. data/lib/rom/memory/gateway.rb +64 -0
  74. data/lib/rom/memory/relation.rb +62 -0
  75. data/lib/rom/memory/schema.rb +23 -0
  76. data/lib/rom/memory/storage.rb +59 -0
  77. data/lib/rom/memory/types.rb +9 -0
  78. data/lib/rom/pipeline.rb +105 -0
  79. data/lib/rom/plugin.rb +25 -0
  80. data/lib/rom/plugin_base.rb +45 -0
  81. data/lib/rom/plugin_registry.rb +197 -0
  82. data/lib/rom/plugins/command/schema.rb +37 -0
  83. data/lib/rom/plugins/configuration/configuration_dsl.rb +21 -0
  84. data/lib/rom/plugins/relation/instrumentation.rb +51 -0
  85. data/lib/rom/plugins/relation/registry_reader.rb +44 -0
  86. data/lib/rom/plugins/schema/timestamps.rb +58 -0
  87. data/lib/rom/registry.rb +71 -0
  88. data/lib/rom/relation.rb +548 -0
  89. data/lib/rom/relation/class_interface.rb +282 -0
  90. data/lib/rom/relation/commands.rb +23 -0
  91. data/lib/rom/relation/composite.rb +46 -0
  92. data/lib/rom/relation/curried.rb +103 -0
  93. data/lib/rom/relation/graph.rb +197 -0
  94. data/lib/rom/relation/loaded.rb +127 -0
  95. data/lib/rom/relation/materializable.rb +66 -0
  96. data/lib/rom/relation/name.rb +111 -0
  97. data/lib/rom/relation/view_dsl.rb +64 -0
  98. data/lib/rom/relation/wrap.rb +83 -0
  99. data/lib/rom/relation_registry.rb +10 -0
  100. data/lib/rom/schema.rb +437 -0
  101. data/lib/rom/schema/associations_dsl.rb +195 -0
  102. data/lib/rom/schema/attribute.rb +419 -0
  103. data/lib/rom/schema/dsl.rb +164 -0
  104. data/lib/rom/schema/inferrer.rb +66 -0
  105. data/lib/rom/schema_plugin.rb +27 -0
  106. data/lib/rom/setup.rb +68 -0
  107. data/lib/rom/setup/auto_registration.rb +74 -0
  108. data/lib/rom/setup/auto_registration_strategies/base.rb +16 -0
  109. data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +63 -0
  110. data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +20 -0
  111. data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +18 -0
  112. data/lib/rom/setup/finalize.rb +103 -0
  113. data/lib/rom/setup/finalize/finalize_commands.rb +60 -0
  114. data/lib/rom/setup/finalize/finalize_mappers.rb +56 -0
  115. data/lib/rom/setup/finalize/finalize_relations.rb +135 -0
  116. data/lib/rom/support/configurable.rb +85 -0
  117. data/lib/rom/support/memoizable.rb +58 -0
  118. data/lib/rom/support/notifications.rb +103 -0
  119. data/lib/rom/transaction.rb +24 -0
  120. data/lib/rom/types.rb +26 -0
  121. data/lib/rom/version.rb +5 -0
  122. metadata +289 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013-2017 rom-rb team
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ [gem]: https://rubygems.org/gems/rom-core
2
+ [gemnasium]: https://gemnasium.com/rom-rb/rom-core
3
+
4
+ # rom-core [![Gitter chat](https://badges.gitter.im/rom-rb/chat.svg)](https://gitter.im/rom-rb/chat)
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/rom-core.svg)][gem]
7
+ [![Dependency Status](https://gemnasium.com/rom-rb/rom-core.svg)][gemnasium]
8
+
9
+ Core API for rom-rb and its adapters and extensions.
10
+
11
+ Resources:
12
+
13
+ * [User documentation](http://rom-rb.org/learn/core)
14
+ * [API documentation](http://rubydoc.info/gems/rom-core)
15
+
16
+ ## License
17
+
18
+ See `LICENSE` file.
data/lib/rom-core.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rom/core'
@@ -0,0 +1,44 @@
1
+ require 'rom/initializer'
2
+ require 'rom/enumerable_dataset'
3
+
4
+ module ROM
5
+ # A helper module that adds data-proxy behavior to an array-like object
6
+ #
7
+ # @see EnumerableDataset
8
+ #
9
+ # @api public
10
+ module ArrayDataset
11
+ extend DataProxy::ClassMethods
12
+ include EnumerableDataset
13
+
14
+ # Extends the class with data-proxy behavior
15
+ #
16
+ # @api private
17
+ def self.included(klass)
18
+ klass.class_eval do
19
+ extend Initializer
20
+ include DataProxy
21
+
22
+ param :data
23
+ end
24
+ end
25
+
26
+ forward(
27
+ :*, :+, :-, :compact, :compact!, :flatten, :flatten!, :length, :pop,
28
+ :reverse, :reverse!, :sample, :size, :shift, :shuffle, :shuffle!,
29
+ :slice, :slice!, :sort!, :uniq, :uniq!, :unshift, :values_at
30
+ )
31
+
32
+ [
33
+ :map!, :combination, :cycle, :delete_if, :keep_if, :permutation, :reject!,
34
+ :select!, :sort_by!
35
+ ].each do |method|
36
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
37
+ def #{method}(*args, &block)
38
+ return to_enum unless block
39
+ self.class.new(data.send(:#{method}, *args, &block), options)
40
+ end
41
+ RUBY
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ require 'rom/registry'
2
+
3
+ module ROM
4
+ # @api public
5
+ class AssociationSet < ROM::Registry
6
+ # @api private
7
+ def initialize(*)
8
+ super
9
+ elements.values.each do |assoc|
10
+ if assoc.aliased? && !key?(assoc.name)
11
+ elements[assoc.name] = assoc
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,135 @@
1
+ require 'dry/core/constants'
2
+ require 'dry/core/class_attributes'
3
+
4
+ require 'rom/types'
5
+ require 'rom/initializer'
6
+ require 'rom/support/memoizable'
7
+
8
+ module ROM
9
+ module Associations
10
+ # Abstract association class
11
+ #
12
+ # @api public
13
+ class Abstract
14
+ extend Initializer
15
+
16
+ include Memoizable
17
+ include Dry::Equalizer(:definition, :source, :target)
18
+
19
+ # @!attribute [r] definition
20
+ # @return [ROM::Associations::Definition] Association configuration object
21
+ param :definition
22
+
23
+ # @!attribute [r] relations
24
+ # @return [ROM::RelationRegistry] Relation registry
25
+ option :relations, reader: true
26
+
27
+ # @!attribute [r] source
28
+ # @return [ROM::SQL::Relation] the source relation
29
+ option :source, reader: true
30
+
31
+ # @!attribute [r] target
32
+ # @return [ROM::SQL::Relation::Name] the target relation
33
+ option :target, reader: true
34
+
35
+ # @api public
36
+ def self.new(definition, relations)
37
+ super(
38
+ definition,
39
+ relations: relations,
40
+ source: relations[definition.source.relation],
41
+ target: relations[definition.target.relation]
42
+ )
43
+ end
44
+
45
+ # @api public
46
+ def aliased?
47
+ definition.aliased?
48
+ end
49
+
50
+ # @api public
51
+ def as
52
+ definition.as
53
+ end
54
+
55
+ # @api public
56
+ def name
57
+ definition.name
58
+ end
59
+
60
+ # @api public
61
+ def view
62
+ definition.view
63
+ end
64
+
65
+ # @api public
66
+ def foreign_key
67
+ definition.foreign_key
68
+ end
69
+
70
+ # @api public
71
+ def result
72
+ definition.result
73
+ end
74
+
75
+ # @api public
76
+ def override?
77
+ definition.override
78
+ end
79
+
80
+ # @api public
81
+ def key
82
+ as || name
83
+ end
84
+
85
+ # @api protected
86
+ def apply_view(schema, relation)
87
+ view_rel = relation.public_send(view)
88
+ schema.merge(view_rel.schema).uniq(&:key).(view_rel)
89
+ end
90
+
91
+ # @api public
92
+ def combine_keys
93
+ { source_key => target_key }
94
+ end
95
+
96
+ # @api private
97
+ def join_key_map
98
+ join_keys.to_a.flatten(1).map(&:key)
99
+ end
100
+
101
+ # @api private
102
+ def node
103
+ target.with(
104
+ name: target.name.as(key),
105
+ meta: { keys: combine_keys, combine_type: result, combine_name: key }
106
+ )
107
+ end
108
+
109
+ # @api private
110
+ def wrap
111
+ target.with(
112
+ name: target.name.as(key),
113
+ schema: target.schema.wrap,
114
+ meta: { wrap: true, combine_name: key }
115
+ )
116
+ end
117
+
118
+ # @api private
119
+ def prepare(target)
120
+ if override?
121
+ target.public_send(view)
122
+ else
123
+ call(target: target)
124
+ end
125
+ end
126
+
127
+ # @api private
128
+ def self_ref?
129
+ source.name.dataset == target.name.dataset
130
+ end
131
+
132
+ memoize :combine_keys, :join_key_map
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,5 @@
1
+ require 'rom/associations/definitions/many_to_many'
2
+ require 'rom/associations/definitions/many_to_one'
3
+ require 'rom/associations/definitions/one_to_many'
4
+ require 'rom/associations/definitions/one_to_one'
5
+ require 'rom/associations/definitions/one_to_one_through'
@@ -0,0 +1,116 @@
1
+ require 'dry/core/class_attributes'
2
+
3
+ require 'rom/constants'
4
+ require 'rom/types'
5
+ require 'rom/initializer'
6
+ require 'rom/relation/name'
7
+ require 'rom/associations/through_identifier'
8
+
9
+ module ROM
10
+ module Associations
11
+ module Definitions
12
+ # Abstract association definition object
13
+ #
14
+ # @api public
15
+ class Abstract
16
+ include Dry::Equalizer(:source, :target, :result)
17
+ extend Initializer
18
+ extend Dry::Core::ClassAttributes
19
+
20
+ defines :result
21
+
22
+ # @!attribute [r] source
23
+ # @return [Relation::Name] the source relation name
24
+ param :source
25
+
26
+ # @!attribute [r] target
27
+ # @return [Relation::Name] the target relation name
28
+ param :target
29
+
30
+ # @!attribute [r] relation
31
+ # @return [Symbol] an optional relation identifier for the target
32
+ option :relation, Types::Strict::Symbol, optional: true
33
+
34
+ # @!attribute [r] result
35
+ # @return [Symbol] either :one or :many
36
+ option :result, Types::Strict::Symbol, default: -> { self.class.result }
37
+
38
+ # @!attribute [r] name
39
+ # @return [Symbol] The name of an association
40
+ option :name, Types::Strict::Symbol, default: -> { target.to_sym }
41
+
42
+ # @!attribute [r] alias
43
+ # @return [Symbol] An optional association alias
44
+ option :as, Types::Strict::Symbol.optional, optional: true
45
+
46
+ # @!attribute [r] foreign_key
47
+ # @return [Symbol] an optional association alias name
48
+ option :foreign_key, Types::Optional::Strict::Symbol, optional: true
49
+
50
+ # @!attribute [r] view
51
+ # @return [Symbol] An optional view that should be used to extend assoc relation
52
+ option :view, optional: true
53
+
54
+ # @!attribute [r] override
55
+ # @return [TrueClass,FalseClass] Whether custom view should override default one or not
56
+ option :override, optional: true, default: -> { false }
57
+
58
+ # Instantiate a new association definition
59
+ #
60
+ # @param [Symbol] source The name of the source dataset
61
+ # @param [Symbol] target The name of the target dataset
62
+ # @param [Hash] options The option hash
63
+ # @option options [Symbol] :as The name of the association (defaults to target)
64
+ # @option options [Symbol] :relation The name of the target relation (defaults to target)
65
+ # @option options [Symbol] :foreign_key The name of a custom foreign key
66
+ # @option options [Symbol] :view The name of a custom relation view on the target's relation side
67
+ # @option options [TrueClass,FalseClass] :override Whether provided :view should override association's default view
68
+ #
69
+ # @api public
70
+ def self.new(source, target, opts = EMPTY_HASH)
71
+ source_name = Relation::Name[source]
72
+ target_name = resolve_target_name(target, opts)
73
+ options = process_options(target_name, Hash[opts])
74
+
75
+ super(source_name, target_name, options)
76
+ end
77
+
78
+ # @api private
79
+ def self.resolve_target_name(target, options)
80
+ dataset = target
81
+ relation = options.fetch(:relation, target)
82
+
83
+ Relation::Name[relation, dataset, options[:as]]
84
+ end
85
+
86
+ # @api private
87
+ def self.process_options(target, options)
88
+ through = options[:through]
89
+
90
+ if through
91
+ options[:through] = ThroughIdentifier[through, target.relation, options[:assoc]]
92
+ end
93
+
94
+ options[:name] = target.relation
95
+
96
+ options
97
+ end
98
+
99
+ # @api public
100
+ def override?
101
+ options[:override].equal?(true)
102
+ end
103
+
104
+ # @api public
105
+ def aliased?
106
+ options.key?(:as)
107
+ end
108
+
109
+ # @api public
110
+ def type
111
+ Dry::Core::Inflector.demodulize(self.class.name).to_sym
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,24 @@
1
+ require 'rom/types'
2
+ require 'rom/associations/definitions/abstract'
3
+
4
+ module ROM
5
+ module Associations
6
+ module Definitions
7
+ class ManyToMany < Abstract
8
+ result :many
9
+
10
+ option :through, reader: true
11
+
12
+ # @api private
13
+ def through_relation
14
+ through.relation
15
+ end
16
+
17
+ # @api private
18
+ def through_assoc_name
19
+ through.assoc_name
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'rom/associations/definitions/abstract'
2
+
3
+ module ROM
4
+ module Associations
5
+ module Definitions
6
+ class ManyToOne < Abstract
7
+ result :one
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rom/associations/definitions/abstract'
2
+
3
+ module ROM
4
+ module Associations
5
+ module Definitions
6
+ class OneToMany < Abstract
7
+ result :many
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rom/associations/definitions/abstract'
2
+
3
+ module ROM
4
+ module Associations
5
+ module Definitions
6
+ class OneToOne < Abstract
7
+ result :one
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rom/associations/definitions/abstract'
2
+
3
+ module ROM
4
+ module Associations
5
+ module Definitions
6
+ class OneToOneThrough < ManyToMany
7
+ result :one
8
+ end
9
+ end
10
+ end
11
+ end