rom 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -3
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +13 -14
  5. data/{Changelog.md → CHANGELOG.md} +12 -3
  6. data/Gemfile +14 -10
  7. data/Gemfile.devtools +16 -16
  8. data/Guardfile +2 -5
  9. data/README.md +68 -56
  10. data/Rakefile +3 -3
  11. data/config/flay.yml +2 -2
  12. data/config/mutant.yml +2 -4
  13. data/config/rubocop.yml +30 -0
  14. data/lib/rom.rb +47 -9
  15. data/lib/rom/adapter.rb +52 -0
  16. data/lib/rom/adapter/memory.rb +70 -0
  17. data/lib/rom/boot.rb +158 -0
  18. data/lib/rom/boot/base_relation_dsl.rb +43 -0
  19. data/lib/rom/boot/dsl.rb +30 -0
  20. data/lib/rom/boot/mapper_dsl.rb +23 -0
  21. data/lib/rom/boot/relation_dsl.rb +23 -0
  22. data/lib/rom/boot/schema_dsl.rb +27 -0
  23. data/lib/rom/env.rb +48 -0
  24. data/lib/rom/header.rb +123 -0
  25. data/lib/rom/mapper.rb +38 -153
  26. data/lib/rom/mapper_builder.rb +85 -0
  27. data/lib/rom/model_builder.rb +58 -0
  28. data/lib/rom/ra.rb +196 -0
  29. data/lib/rom/ra/operation/group.rb +49 -0
  30. data/lib/rom/ra/operation/join.rb +41 -0
  31. data/lib/rom/ra/operation/wrap.rb +45 -0
  32. data/lib/rom/reader.rb +62 -0
  33. data/lib/rom/reader_builder.rb +28 -0
  34. data/lib/rom/relation.rb +41 -350
  35. data/lib/rom/relation_builder.rb +48 -0
  36. data/lib/rom/repository.rb +28 -53
  37. data/lib/rom/support/registry.rb +34 -0
  38. data/lib/rom/version.rb +3 -0
  39. data/rom.gemspec +12 -10
  40. data/spec/integration/adapters/extending_relations_spec.rb +43 -0
  41. data/spec/integration/mappers/definition_dsl_spec.rb +82 -0
  42. data/spec/integration/mappers/prefixing_attributes_spec.rb +42 -0
  43. data/spec/integration/mappers/renaming_attributes_spec.rb +138 -0
  44. data/spec/integration/ra/group_spec.rb +47 -0
  45. data/spec/integration/ra/join_spec.rb +24 -0
  46. data/spec/integration/ra/wrap_spec.rb +37 -0
  47. data/spec/integration/relations/reading_spec.rb +116 -0
  48. data/spec/integration/relations/registry_dsl_spec.rb +44 -0
  49. data/spec/integration/schema_spec.rb +29 -0
  50. data/spec/integration/setup_spec.rb +18 -0
  51. data/spec/shared/users_and_tasks.rb +34 -0
  52. data/spec/spec_helper.rb +14 -36
  53. data/spec/unit/rom/adapter_spec.rb +59 -0
  54. data/spec/unit/rom/header_spec.rb +58 -0
  55. data/spec/unit/rom/mapper_spec.rb +27 -0
  56. data/spec/unit/rom/ra/operation/group_spec.rb +55 -0
  57. data/spec/unit/rom/ra/operation/wrap_spec.rb +29 -0
  58. data/spec/unit/rom/relation_spec.rb +34 -0
  59. metadata +122 -190
  60. data/lib/rom/constants.rb +0 -16
  61. data/lib/rom/environment.rb +0 -105
  62. data/lib/rom/environment/builder.rb +0 -71
  63. data/lib/rom/mapper/attribute.rb +0 -108
  64. data/lib/rom/mapper/builder.rb +0 -58
  65. data/lib/rom/mapper/builder/definition.rb +0 -162
  66. data/lib/rom/mapper/header.rb +0 -103
  67. data/lib/rom/mapper/loader_builder.rb +0 -26
  68. data/lib/rom/schema.rb +0 -21
  69. data/lib/rom/schema/builder.rb +0 -59
  70. data/lib/rom/schema/definition.rb +0 -84
  71. data/lib/rom/schema/definition/relation.rb +0 -80
  72. data/lib/rom/schema/definition/relation/base.rb +0 -27
  73. data/lib/rom/session.rb +0 -111
  74. data/lib/rom/session/environment.rb +0 -67
  75. data/lib/rom/session/identity_map.rb +0 -43
  76. data/lib/rom/session/mapper.rb +0 -62
  77. data/lib/rom/session/relation.rb +0 -140
  78. data/lib/rom/session/state.rb +0 -59
  79. data/lib/rom/session/state/created.rb +0 -22
  80. data/lib/rom/session/state/deleted.rb +0 -25
  81. data/lib/rom/session/state/persisted.rb +0 -34
  82. data/lib/rom/session/state/transient.rb +0 -20
  83. data/lib/rom/session/state/updated.rb +0 -29
  84. data/lib/rom/session/tracker.rb +0 -62
  85. data/lib/rom/support/axiom/adapter.rb +0 -111
  86. data/lib/rom/support/axiom/adapter/data_objects.rb +0 -38
  87. data/lib/rom/support/axiom/adapter/memory.rb +0 -25
  88. data/lib/rom/support/axiom/adapter/postgres.rb +0 -19
  89. data/lib/rom/support/axiom/adapter/sqlite3.rb +0 -20
  90. data/lib/version.rb +0 -3
  91. data/spec/integration/environment_setup_spec.rb +0 -24
  92. data/spec/integration/grouped_mappers_spec.rb +0 -87
  93. data/spec/integration/join_and_group_spec.rb +0 -76
  94. data/spec/integration/join_and_wrap_spec.rb +0 -68
  95. data/spec/integration/mapping_embedded_relations_spec.rb +0 -73
  96. data/spec/integration/mapping_relations_spec.rb +0 -120
  97. data/spec/integration/schema_definition_spec.rb +0 -152
  98. data/spec/integration/session_spec.rb +0 -87
  99. data/spec/integration/wrapped_mappers_spec.rb +0 -73
  100. data/spec/shared/unit/environment_context.rb +0 -6
  101. data/spec/shared/unit/loader.rb +0 -11
  102. data/spec/shared/unit/loader_identity.rb +0 -13
  103. data/spec/shared/unit/mapper_context.rb +0 -11
  104. data/spec/shared/unit/relation_context.rb +0 -82
  105. data/spec/shared/unit/session_environment_context.rb +0 -11
  106. data/spec/shared/unit/session_relation_context.rb +0 -18
  107. data/spec/support/helper.rb +0 -34
  108. data/spec/support/ice_nine_config.rb +0 -10
  109. data/spec/support/test_mapper.rb +0 -110
  110. data/spec/unit/rom/environment/builder/mapping_spec.rb +0 -24
  111. data/spec/unit/rom/environment/builder/schema_spec.rb +0 -33
  112. data/spec/unit/rom/environment/class_methods/setup_spec.rb +0 -18
  113. data/spec/unit/rom/environment/repository_spec.rb +0 -21
  114. data/spec/unit/rom/mapper/attribute/embedded_collection/to_ast_spec.rb +0 -18
  115. data/spec/unit/rom/mapper/attribute/embedded_value/to_ast_spec.rb +0 -16
  116. data/spec/unit/rom/mapper/attribute/rename_spec.rb +0 -9
  117. data/spec/unit/rom/mapper/attribute/to_ast_spec.rb +0 -9
  118. data/spec/unit/rom/mapper/builder/class_methods/call_spec.rb +0 -61
  119. data/spec/unit/rom/mapper/class_methods/build_spec.rb +0 -55
  120. data/spec/unit/rom/mapper/dump_spec.rb +0 -11
  121. data/spec/unit/rom/mapper/group_spec.rb +0 -35
  122. data/spec/unit/rom/mapper/header/each_spec.rb +0 -26
  123. data/spec/unit/rom/mapper/header/element_reader_spec.rb +0 -21
  124. data/spec/unit/rom/mapper/header/group_spec.rb +0 -18
  125. data/spec/unit/rom/mapper/header/join_spec.rb +0 -14
  126. data/spec/unit/rom/mapper/header/keys_spec.rb +0 -29
  127. data/spec/unit/rom/mapper/header/project_spec.rb +0 -13
  128. data/spec/unit/rom/mapper/header/rename_spec.rb +0 -11
  129. data/spec/unit/rom/mapper/header/to_ast_spec.rb +0 -11
  130. data/spec/unit/rom/mapper/header/wrap_spec.rb +0 -18
  131. data/spec/unit/rom/mapper/identity_from_tuple_spec.rb +0 -11
  132. data/spec/unit/rom/mapper/identity_spec.rb +0 -11
  133. data/spec/unit/rom/mapper/join_spec.rb +0 -15
  134. data/spec/unit/rom/mapper/load_spec.rb +0 -11
  135. data/spec/unit/rom/mapper/new_object_spec.rb +0 -14
  136. data/spec/unit/rom/mapper/project_spec.rb +0 -11
  137. data/spec/unit/rom/mapper/rename_spec.rb +0 -16
  138. data/spec/unit/rom/mapper/wrap_spec.rb +0 -35
  139. data/spec/unit/rom/relation/delete_spec.rb +0 -15
  140. data/spec/unit/rom/relation/drop_spec.rb +0 -11
  141. data/spec/unit/rom/relation/each_spec.rb +0 -23
  142. data/spec/unit/rom/relation/first_spec.rb +0 -19
  143. data/spec/unit/rom/relation/group_spec.rb +0 -29
  144. data/spec/unit/rom/relation/inject_mapper_spec.rb +0 -17
  145. data/spec/unit/rom/relation/insert_spec.rb +0 -13
  146. data/spec/unit/rom/relation/last_spec.rb +0 -19
  147. data/spec/unit/rom/relation/one_spec.rb +0 -49
  148. data/spec/unit/rom/relation/rename_spec.rb +0 -21
  149. data/spec/unit/rom/relation/replace_spec.rb +0 -13
  150. data/spec/unit/rom/relation/restrict_spec.rb +0 -25
  151. data/spec/unit/rom/relation/sort_by_spec.rb +0 -25
  152. data/spec/unit/rom/relation/take_spec.rb +0 -11
  153. data/spec/unit/rom/relation/to_a_spec.rb +0 -20
  154. data/spec/unit/rom/relation/update_spec.rb +0 -25
  155. data/spec/unit/rom/relation/wrap_spec.rb +0 -29
  156. data/spec/unit/rom/repository/class_methods/build_spec.rb +0 -27
  157. data/spec/unit/rom/repository/element_reader_spec.rb +0 -21
  158. data/spec/unit/rom/repository/element_writer_spec.rb +0 -18
  159. data/spec/unit/rom/schema/builder/class_methods/build_spec.rb +0 -103
  160. data/spec/unit/rom/schema/element_reader_spec.rb +0 -15
  161. data/spec/unit/rom/session/class_methods/start_spec.rb +0 -23
  162. data/spec/unit/rom/session/clean_predicate_spec.rb +0 -21
  163. data/spec/unit/rom/session/environment/element_reader_spec.rb +0 -13
  164. data/spec/unit/rom/session/flush_spec.rb +0 -58
  165. data/spec/unit/rom/session/mapper/load_spec.rb +0 -47
  166. data/spec/unit/rom/session/relation/delete_spec.rb +0 -28
  167. data/spec/unit/rom/session/relation/dirty_predicate_spec.rb +0 -35
  168. data/spec/unit/rom/session/relation/identity_spec.rb +0 -11
  169. data/spec/unit/rom/session/relation/new_spec.rb +0 -50
  170. data/spec/unit/rom/session/relation/save_spec.rb +0 -50
  171. data/spec/unit/rom/session/relation/state_spec.rb +0 -23
  172. data/spec/unit/rom/session/relation/track_spec.rb +0 -23
  173. data/spec/unit/rom/session/relation/tracking_predicate_spec.rb +0 -23
  174. data/spec/unit/rom/session/relation/update_attributes_spec.rb +0 -45
  175. data/spec/unit/rom/session/state_spec.rb +0 -79
@@ -1,103 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/mapper/attribute'
4
-
5
- module ROM
6
- class Mapper
7
-
8
- # Mapper header wrapping axiom header and providing mapping information
9
- #
10
- # @private
11
- class Header
12
- include Enumerable, Concord.new(:attributes), Adamantium, Morpher::NodeHelpers
13
-
14
- # Build a header
15
- #
16
- # @api private
17
- def self.build(input)
18
- if input.is_a?(self)
19
- input
20
- else
21
- new(input.map { |args| Attribute.build(*args) })
22
- end
23
- end
24
-
25
- # Return attribute mapping
26
- #
27
- # @api private
28
- def mapping
29
- each_with_object({}) { |attribute, hash| hash.update(attribute.mapping) }
30
- end
31
- memoize :mapping
32
-
33
- # Return all key attributes
34
- #
35
- # @return [Array<Attribute>]
36
- #
37
- # @api public
38
- def keys
39
- select(&:key?)
40
- end
41
- memoize :keys
42
-
43
- def to_ast
44
- s(:hash_transform, *map(&:to_ast))
45
- end
46
- memoize :to_ast
47
-
48
- # Return attribute with the given name
49
- #
50
- # @return [Attribute]
51
- #
52
- # @api public
53
- def [](name)
54
- detect { |attribute| attribute.name == name } || raise(KeyError)
55
- end
56
-
57
- # Return attribute names
58
- #
59
- # @api private
60
- def attribute_names
61
- map(&:name)
62
- end
63
-
64
- # Iterate over attributes
65
- #
66
- # @api private
67
- def each(&block)
68
- return to_enum unless block_given?
69
- attributes.each(&block)
70
- self
71
- end
72
-
73
- # TODO: this should receive a hash with header objects already
74
- def wrap(other)
75
- new_attributes = other.map { |name, mapper| mapper.attribute(Attribute::EmbeddedValue, name) }
76
- self.class.new((attributes + new_attributes).uniq)
77
- end
78
-
79
- # TODO: this should receive a hash with header objects already
80
- def group(other)
81
- new_attributes = other.map { |name, mapper| mapper.attribute(Attribute::EmbeddedCollection, name) }
82
- self.class.new((attributes + new_attributes).uniq)
83
- end
84
-
85
- # @api private
86
- def join(other)
87
- self.class.new((attributes + other.attributes).uniq)
88
- end
89
-
90
- # @api private
91
- def project(names)
92
- self.class.new(select { |attribute| names.include?(attribute.tuple_key) })
93
- end
94
-
95
- # @api private
96
- def rename(names)
97
- self.class.new(map { |attribute| names[attribute.name] ? attribute.rename(names[attribute.name]) : attribute })
98
- end
99
-
100
- end # Header
101
-
102
- end # Mapper
103
- end # ROM
@@ -1,26 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module ROM
4
- class Mapper
5
-
6
- # Abstract loader class
7
- #
8
- # @private
9
- class LoaderBuilder
10
- extend Morpher::NodeHelpers
11
-
12
- def self.call(header, model, type)
13
- param =
14
- if type == :load_attribute_hash
15
- s(:param, model)
16
- else
17
- s(:param, model, *header.attribute_names)
18
- end
19
-
20
- Morpher.compile(s(:block, header.to_ast, s(type, param)))
21
- end
22
-
23
- end # Loader
24
-
25
- end # Mapper
26
- end # ROM
data/lib/rom/schema.rb DELETED
@@ -1,21 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module ROM
4
-
5
- # ROM's relation schema
6
- #
7
- class Schema
8
- include Concord.new(:relations), Adamantium::Flat
9
-
10
- # Return a relation identified by name
11
- #
12
- # @param [Symbol] name of the relation
13
- #
14
- # @return [Relation]
15
- def [](name)
16
- relations.fetch(name)
17
- end
18
-
19
- end # Schema
20
-
21
- end # ROM
@@ -1,59 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/schema'
4
- require 'rom/schema/definition'
5
-
6
- module ROM
7
- class Schema
8
-
9
- # Schema builder DSL
10
- #
11
- class Builder
12
- include Concord.new(:definition), Adamantium::Flat
13
-
14
- # Build a relation schema
15
- #
16
- # @example
17
- #
18
- # Schema.build do
19
- # base_relation :users do
20
- # repository :test
21
- # attribute :id, :name
22
- # end
23
- # end
24
- #
25
- # @return [Schema]
26
- #
27
- # @api public
28
- def self.build(repositories, &block)
29
- new(Definition.new(repositories, &block))
30
- end
31
-
32
- # Return defined relation identified by name
33
- #
34
- # @example
35
- #
36
- # schema[:users] # => #<Axiom::Relation::Base ..>
37
- #
38
- # @return [Axiom::Relation, Axiom::Relation::Base]
39
- #
40
- # @api public
41
- def [](name)
42
- definition[name]
43
- end
44
-
45
- # @api private
46
- def call(&block)
47
- definition.instance_eval(&block)
48
- self
49
- end
50
-
51
- # @api private
52
- def finalize
53
- Schema.new(definition.relations)
54
- end
55
-
56
- end # Builder
57
-
58
- end # Schema
59
- end # ROM
@@ -1,84 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/schema/definition/relation/base'
4
-
5
- module ROM
6
- class Schema
7
-
8
- # Builder object used by schema DSL to establish Axiom relations
9
- #
10
- # @private
11
- class Definition
12
- include Equalizer.new(:repositories, :relations)
13
-
14
- attr_reader :repositories, :relations
15
-
16
- # @api private
17
- def initialize(repositories, &block)
18
- @repositories = repositories
19
- @relations = {}
20
- instance_eval(&block) if block
21
- end
22
-
23
- # Build a base relation
24
- #
25
- # @example
26
- #
27
- # Schema.build do
28
- # base_relation :users do
29
- # # ...
30
- # end
31
- # end
32
- #
33
- # @return [Definition]
34
- #
35
- # @api private
36
- def base_relation(name, &block)
37
- builder = Relation::Base.new(relations, &block)
38
- repository = repositories.fetch(builder.repository)
39
-
40
- repository[name] = builder.call(name)
41
- relations[name] = repository[name]
42
- end
43
-
44
- # Build a relation
45
- #
46
- # @example
47
- #
48
- # Schema.build do
49
- # relation :users do
50
- # # ...
51
- # end
52
- # end
53
- #
54
- # @return [Definition]
55
- #
56
- # @api private
57
- def relation(name, &block)
58
- relations[name] = instance_eval(&block)
59
- end
60
-
61
- # Return relation identified by name
62
- #
63
- # @return [Axiom::Relation, Axiom::Relation::Base]
64
- #
65
- # @api private
66
- def [](name)
67
- relations[name]
68
- end
69
-
70
- private
71
-
72
- # Method missing hook
73
- #
74
- # @return [Axiom::Relation, Axiom::Relation::Base]
75
- #
76
- # @api private
77
- def method_missing(*args)
78
- self[args.first] || super
79
- end
80
-
81
- end # Definition
82
-
83
- end # Schema
84
- end # ROM
@@ -1,80 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module ROM
4
- class Schema
5
- class Definition
6
-
7
- # Builder object for Axiom relation
8
- #
9
- # @private
10
- class Relation
11
- include Equalizer.new(:header, :keys)
12
-
13
- attr_reader :registry
14
-
15
- # @api private
16
- def initialize(registry, &block)
17
- @registry = registry
18
- @header = []
19
- @keys = []
20
- @wrappings = []
21
- @groupings = []
22
- instance_eval(&block)
23
- end
24
-
25
- # @api private
26
- def call(name)
27
- relation = Axiom::Relation::Base.new(name, build_header)
28
-
29
- if @wrappings.any?
30
- @wrappings.each { |wrapping| relation = relation.wrap(wrapping) }
31
- end
32
-
33
- if @groupings.any?
34
- @groupings.each { |grouping| relation = relation.group(grouping) }
35
- end
36
-
37
- renames = @header.each_with_object({}) { |ary, mapping|
38
- mapping[ary.first] = ary.last[:rename] if ary.last[:rename]
39
- }
40
-
41
- relation.rename(renames).optimize
42
- end
43
-
44
- # @api private
45
- def attribute(name, type, options = {})
46
- @header << [name, type, options]
47
- end
48
-
49
- # @api private
50
- def wrap(wrapping)
51
- @wrappings << wrapping
52
- end
53
-
54
- # @api private
55
- def group(grouping)
56
- @groupings << grouping
57
- end
58
-
59
- # @api private
60
- def key(*attribute_names)
61
- @keys.concat(attribute_names)
62
- end
63
-
64
- private
65
-
66
- # @api private
67
- def method_missing(*args)
68
- registry[args.first] || super
69
- end
70
-
71
- # @api private
72
- def build_header
73
- Axiom::Relation::Header.coerce(@header, keys: @keys)
74
- end
75
-
76
- end # Relation
77
-
78
- end # Definition
79
- end # Schema
80
- end # ROM
@@ -1,27 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/schema/definition/relation'
4
-
5
- module ROM
6
- class Schema
7
- class Definition
8
- class Relation
9
-
10
- # Base relation builder object
11
- #
12
- class Base < self
13
-
14
- def repository(name = Undefined)
15
- if name == Undefined
16
- @repository
17
- else
18
- @repository = name
19
- end
20
- end
21
-
22
- end # Base
23
-
24
- end # Relation
25
- end # Definition
26
- end # Schema
27
- end # ROM
data/lib/rom/session.rb DELETED
@@ -1,111 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/session/environment'
4
- require 'rom/session/tracker'
5
- require 'rom/session/identity_map'
6
- require 'rom/session/relation'
7
- require 'rom/session/mapper'
8
-
9
- require 'rom/session/state'
10
- require 'rom/session/state/transient'
11
- require 'rom/session/state/persisted'
12
- require 'rom/session/state/created'
13
- require 'rom/session/state/updated'
14
- require 'rom/session/state/deleted'
15
-
16
- module ROM
17
-
18
- # Extended ROM::Environment with session support
19
- class Environment
20
-
21
- # Start a new session for this environment
22
- #
23
- # @example
24
- # env.session do |session|
25
- # # ...
26
- # end
27
- #
28
- # @see Session.start
29
- #
30
- # @api public
31
- def session(&block)
32
- Session.start(self, &block)
33
- end
34
- end
35
-
36
- # Session with IdentityMap and state-tracking functionality
37
- #
38
- # @example
39
- #
40
- # env.session do |session|
41
- # user = session[:users].new(id: 1, name: 'Jane')
42
- #
43
- # session[:users].save(user)
44
- #
45
- # session.flush
46
- # end
47
- #
48
- # @api public
49
- class Session
50
- include Concord.new(:environment)
51
-
52
- # Raised when an object is expected to be tracked and it's not
53
- #
54
- class ObjectNotTrackedError < StandardError
55
- def initialize(identity)
56
- super("Tracker doesn't include object with identity #{identity.inspect}")
57
- end
58
- end
59
-
60
- # Start a new session
61
- #
62
- # @example
63
- #
64
- # ROM::Session.start(env) do |session|
65
- # user = session[:users].new(name: 'Jane')
66
- # session[:users].save(user)
67
- # session[:users].flush
68
- # end
69
- #
70
- # @param [ROM::Environment] rom's environment
71
- #
72
- # @yieldparam [Session::Environment]
73
- #
74
- # @api public
75
- def self.start(environment)
76
- yield(new(Environment.build(environment)))
77
- end
78
-
79
- # Return a session relation identified by name
80
- #
81
- # @param [Symbol] relation name
82
- #
83
- # @return [Session::Relation]
84
- #
85
- # @api public
86
- def [](relation_name)
87
- environment[relation_name]
88
- end
89
-
90
- # Flush this session committing all the state changes
91
- #
92
- # @return [Session]
93
- #
94
- # @api public
95
- def flush
96
- environment.commit
97
- self
98
- end
99
-
100
- # Return if there are any pending state changes
101
- #
102
- # @return [Boolean]
103
- #
104
- # @api public
105
- def clean?
106
- environment.clean?
107
- end
108
-
109
- end # Session
110
-
111
- end # ROM