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
data/lib/rom/constants.rb DELETED
@@ -1,16 +0,0 @@
1
- module ROM
2
- # Raised when the returned tuples are unexpectedly empty
3
- NoTuplesError = Class.new(RuntimeError)
4
-
5
- # Raised when the returned tuples are unexpectedly too many
6
- ManyTuplesError = Class.new(RuntimeError)
7
-
8
- # Represent an undefined argument
9
- Undefined = Class.new.freeze
10
-
11
- # An empty frozen Hash useful for parameter default values
12
- EMPTY_HASH = {}.freeze
13
-
14
- # An empty frozen Array useful for parameter default values
15
- EMPTY_ARRAY = [].freeze
16
- end
@@ -1,105 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/environment/builder'
4
-
5
- module ROM
6
-
7
- # The environment configures repositories and loads schema with relations
8
- #
9
- class Environment
10
- # @api private
11
- attr_reader :repositories, :relations
12
-
13
- # Return schema registry
14
- #
15
- # @return [Schema]
16
- #
17
- # @api public
18
- attr_reader :schema
19
-
20
- # Return mapper registry
21
- #
22
- # @return [Hash]
23
- #
24
- # @api public
25
- attr_reader :mappers
26
-
27
- # @api private
28
- def initialize(repositories, schema, relations, mappers)
29
- @repositories = repositories
30
- @schema = schema
31
- @relations = relations
32
- @mappers = mappers
33
- end
34
-
35
- # Setup ROM environment
36
- #
37
- # @example
38
- #
39
- # env = ROM::Environment.setup(test: 'memory://test') do
40
- # schema do
41
- # base_relation(:users) do
42
- # repository :test
43
- #
44
- # attribute :id, Integer
45
- # attribute :name, String
46
- #
47
- # key :id
48
- # end
49
- # end
50
- #
51
- # mapping do
52
- # relation(:users) do
53
- # model User
54
- #
55
- # map :id, :name
56
- # end
57
- # end
58
- #
59
- # end
60
- #
61
- # @param [Environment, Hash<#to_sym, String>] config
62
- # an environment or a hash of adapter uri strings,
63
- # keyed by repository name
64
- #
65
- # @return [Environment::Builder]
66
- #
67
- # @api public
68
- def self.setup(config, &block)
69
- builder = Builder.call(config)
70
-
71
- if block
72
- builder.instance_eval(&block)
73
- builder.finalize
74
- else
75
- builder
76
- end
77
- end
78
-
79
- # Return registered relation
80
- #
81
- # @example
82
- #
83
- # env[:users]
84
- #
85
- # @param [Symbol] relation name
86
- #
87
- # @return [Relation]
88
- #
89
- # @api public
90
- def [](name)
91
- relations[name]
92
- end
93
-
94
- # The repository with the given +name+
95
- #
96
- # @return [Repository]
97
- #
98
- # @api public
99
- def repository(name)
100
- repositories[name]
101
- end
102
-
103
- end # Environment
104
-
105
- end # ROM
@@ -1,71 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'addressable/uri'
4
-
5
- require 'rom/environment'
6
- require 'rom/repository'
7
- require 'rom/schema/builder'
8
- require 'rom/mapper/builder'
9
-
10
- module ROM
11
-
12
- # The environment configures repositories and loads schema with relations
13
- #
14
- class Environment
15
-
16
- # Environment builder DSL
17
- #
18
- class Builder
19
- attr_reader :repositories, :relations, :mappers
20
-
21
- # @api private
22
- def self.call(config)
23
- repositories = config.each_with_object({}) { |(name, uri), hash|
24
- hash[name.to_sym] = Repository.build(name, Addressable::URI.parse(uri))
25
- }
26
-
27
- new(repositories)
28
- end
29
-
30
- # @api private
31
- def initialize(repositories)
32
- @repositories = repositories
33
- @relations = {}
34
- @schema = Schema::Builder.build(repositories)
35
- @mappers = Mapper::Builder.new(schema)
36
- end
37
-
38
- # @api private
39
- def schema(&block)
40
- @schema.call(&block) if block
41
- @schema
42
- end
43
-
44
- # @api private
45
- def mapping(&block)
46
- mappers.call(&block)
47
- end
48
-
49
- # @api private
50
- def [](name)
51
- relations[name]
52
- end
53
-
54
- # @api private
55
- def []=(name, relation)
56
- relations[name] = relation
57
- end
58
-
59
- # @api private
60
- def finalize
61
- mappers.each do |name, mapper|
62
- relations[name] = Relation.new(schema[name], mapper)
63
- end
64
-
65
- Environment.new(repositories, schema.finalize, relations, mappers.finalize)
66
- end
67
-
68
- end # Builder
69
-
70
- end # Environment
71
- end # ROM
@@ -1,108 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module ROM
4
- class Mapper
5
-
6
- # Represents a mapping attribute
7
- #
8
- # @private
9
- class Attribute
10
- include Adamantium, Concord::Public.new(:name, :options), Morpher::NodeHelpers
11
-
12
- class EmbeddedValue < Attribute
13
-
14
- # @api private
15
- def to_ast
16
- s(:key_transform, name, name, node)
17
- end
18
- memoize :to_ast
19
-
20
- # @api private
21
- def header
22
- options.fetch(:header)
23
- end
24
- memoize :header
25
-
26
- private
27
-
28
- # @api private
29
- def node
30
- options.fetch(:node)
31
- end
32
- memoize :node
33
- end
34
-
35
- class EmbeddedCollection < Attribute
36
-
37
- # @api private
38
- def to_ast
39
- s(:key_transform, name, name, s(:map, node))
40
- end
41
- memoize :to_ast
42
-
43
- # @api private
44
- def header
45
- options.fetch(:header)
46
- end
47
- memoize :header
48
-
49
- private
50
-
51
- # @api private
52
- def node
53
- options.fetch(:node)
54
- end
55
- memoize :node
56
- end
57
-
58
- # @api private
59
- def self.build(*args)
60
- input = args.first
61
-
62
- if input.kind_of?(self)
63
- input
64
- else
65
- name, options = args
66
- new(name, options || {})
67
- end
68
- end
69
-
70
- # @api private
71
- def to_ast
72
- s(:block, s(:key_fetch, tuple_key), s(:key_dump, name))
73
- end
74
- memoize :to_ast
75
-
76
- # @api private
77
- def key?
78
- options.fetch(:key, false)
79
- end
80
- memoize :key?
81
-
82
- # @api private
83
- def mapping
84
- { tuple_key => name }
85
- end
86
- memoize :mapping
87
-
88
- # @api private
89
- def tuple_key
90
- options[:from] || name
91
- end
92
- memoize :tuple_key
93
-
94
- # @api private
95
- def type
96
- options[:type] || Object
97
- end
98
- memoize :type
99
-
100
- # @api private
101
- def rename(new_name)
102
- self.class.new(new_name, options)
103
- end
104
-
105
- end # Attribute
106
-
107
- end # Mapper
108
- end # ROM
@@ -1,58 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/mapper/builder/definition'
4
-
5
- module ROM
6
- class Mapper
7
-
8
- # Builder DSL for ROM mappers
9
- #
10
- class Builder
11
- attr_reader :schema, :mappers
12
-
13
- # @api public
14
- def self.call(*args, &block)
15
- new(*args).call(&block)
16
- end
17
-
18
- # Initialize a new mapping instance
19
- #
20
- # @return [undefined]
21
- #
22
- # @api private
23
- def initialize(schema)
24
- @schema = schema
25
- @mappers = {}
26
- end
27
-
28
- # @api public
29
- def relation(name, &block)
30
- definition = Definition.build(schema[name].header, &block)
31
- mappers[name] = definition.mapper
32
- self
33
- end
34
-
35
- # @api private
36
- def call(&block)
37
- instance_eval(&block)
38
- end
39
-
40
- # @api private
41
- def finalize
42
- mappers.freeze
43
- end
44
-
45
- # @api private
46
- def each(&block)
47
- mappers.each(&block)
48
- end
49
-
50
- # @api private
51
- def [](name)
52
- mappers.fetch(name)
53
- end
54
-
55
- end # Builder
56
-
57
- end # Mapper
58
- end # ROM
@@ -1,162 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rom/mapper'
4
- require 'rom/mapper/attribute'
5
-
6
- module ROM
7
- class Mapper
8
- class Builder
9
-
10
- # Mapping definition DSL
11
- #
12
- # @private
13
- class Definition
14
- include Adamantium::Flat
15
-
16
- attr_reader :attributes
17
-
18
- LOADERS = [:instance_variables, :attribute_hash, :attribute_accessors].freeze
19
-
20
- # Build new mapping definition
21
- #
22
- # @api private
23
- def self.build(header, &block)
24
- new(header, &block)
25
- end
26
-
27
- # Initialize a new Definition instance
28
- #
29
- # @return [undefined]
30
- #
31
- # @api private
32
- def initialize(header, &block)
33
- @header = header
34
- @keys = header.keys.flat_map { |key_header| key_header.flat_map(&:name) }
35
- @attributes = []
36
- @loader = :load_instance_variables
37
-
38
- instance_eval(&block)
39
-
40
- build_mapper unless mapper
41
- end
42
-
43
- # @api private
44
- def attribute_names
45
- attributes.map(&:name)
46
- end
47
-
48
- # @api private
49
- def loader(name = Undefined)
50
- if name == Undefined
51
- @loader
52
- else
53
- unless LOADERS.include?(name)
54
- raise ArgumentError,
55
- "loader +#{name.inspect}+ is not known. Valid loaders are #{LOADERS.inspect}"
56
- end
57
-
58
- @loader = :"load_#{name}"
59
- end
60
- end
61
-
62
- # @api private
63
- def header
64
- @header.project(attributes.map(&:name))
65
- end
66
- memoize :header
67
-
68
- # Get or set mapper
69
- #
70
- # @example
71
- #
72
- # Mapping.build do
73
- # users do
74
- # mapper my_custom_mapper
75
- # end
76
- # end
77
- #
78
- # @param [Object]
79
- #
80
- # @return [Object]
81
- #
82
- # @api public
83
- def mapper(mapper = Undefined)
84
- if mapper == Undefined
85
- @mapper
86
- else
87
- @mapper = mapper
88
- end
89
- end
90
-
91
- # Get or set model for the mapper
92
- #
93
- # @example
94
- #
95
- # Mapping.build do
96
- # users do
97
- # model User
98
- # end
99
- # end
100
- #
101
- # @param [Class]
102
- #
103
- # @return [Class]
104
- #
105
- # @api public
106
- def model(model = Undefined)
107
- if model == Undefined
108
- @model
109
- else
110
- @model = model
111
- end
112
- end
113
-
114
- # Configure attribute mappings
115
- #
116
- # @example
117
- #
118
- # Mapping.build do
119
- # users do
120
- # map :id, :email
121
- # map :user_name, to: :name
122
- # end
123
- # end
124
- #
125
- # @params [Array<Symbol>,Symbol,Hash]
126
- #
127
- # @return [Definition]
128
- #
129
- # @api public
130
- def map(*args)
131
- if args.last.kind_of?(Hash)
132
- attributes.concat([build_attribute(*args)])
133
- else
134
- attributes.concat(args.map { |name| build_attribute(name) })
135
- end
136
- end
137
-
138
- private
139
-
140
- # Build default rom mapper
141
- #
142
- # @api private
143
- def build_mapper
144
- @mapper = Mapper.build(attributes, model: model, type: loader)
145
- end
146
-
147
- def build_attribute(name, options = {})
148
- header_name = options.fetch(:from, name)
149
-
150
- defaults = {
151
- key: @keys.include?(header_name),
152
- type: @header[header_name].type.primitive
153
- }
154
-
155
- Attribute.build(name, defaults.merge(options))
156
- end
157
-
158
- end # Definition
159
-
160
- end # DSL
161
- end # Mapper
162
- end # ROM