rom 0.2.0 → 0.3.0

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