rom-core 4.0.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 (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