rom 0.4.2 → 0.5.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +81 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +12 -8
- data/Guardfile +17 -11
- data/README.md +7 -7
- data/Rakefile +29 -0
- data/lib/rom.rb +9 -66
- data/lib/rom/adapter.rb +45 -12
- data/lib/rom/adapter/memory.rb +0 -4
- data/lib/rom/adapter/memory/commands.rb +0 -10
- data/lib/rom/adapter/memory/dataset.rb +18 -6
- data/lib/rom/adapter/memory/storage.rb +0 -3
- data/lib/rom/command_registry.rb +24 -43
- data/lib/rom/commands.rb +5 -6
- data/lib/rom/commands/create.rb +5 -5
- data/lib/rom/commands/delete.rb +8 -6
- data/lib/rom/commands/result.rb +82 -0
- data/lib/rom/commands/update.rb +5 -4
- data/lib/rom/commands/with_options.rb +1 -4
- data/lib/rom/config.rb +70 -0
- data/lib/rom/env.rb +11 -3
- data/lib/rom/global.rb +107 -0
- data/lib/rom/header.rb +122 -89
- data/lib/rom/header/attribute.rb +148 -0
- data/lib/rom/mapper.rb +46 -67
- data/lib/rom/mapper_builder.rb +20 -73
- data/lib/rom/mapper_builder/mapper_dsl.rb +114 -0
- data/lib/rom/mapper_builder/model_dsl.rb +29 -0
- data/lib/rom/mapper_registry.rb +21 -0
- data/lib/rom/model_builder.rb +11 -17
- data/lib/rom/processor.rb +28 -0
- data/lib/rom/processor/transproc.rb +105 -0
- data/lib/rom/reader.rb +81 -21
- data/lib/rom/reader_builder.rb +14 -4
- data/lib/rom/relation.rb +19 -5
- data/lib/rom/relation_builder.rb +20 -6
- data/lib/rom/repository.rb +0 -2
- data/lib/rom/setup.rb +156 -0
- data/lib/rom/{boot → setup}/base_relation_dsl.rb +4 -8
- data/lib/rom/setup/command_dsl.rb +46 -0
- data/lib/rom/setup/finalize.rb +125 -0
- data/lib/rom/setup/mapper_dsl.rb +19 -0
- data/lib/rom/{boot → setup}/relation_dsl.rb +1 -4
- data/lib/rom/setup/schema_dsl.rb +33 -0
- data/lib/rom/support/registry.rb +10 -6
- data/lib/rom/version.rb +1 -1
- data/rom.gemspec +3 -1
- data/spec/integration/adapters/extending_relations_spec.rb +0 -2
- data/spec/integration/commands/create_spec.rb +2 -9
- data/spec/integration/commands/delete_spec.rb +4 -5
- data/spec/integration/commands/error_handling_spec.rb +4 -3
- data/spec/integration/commands/update_spec.rb +3 -8
- data/spec/integration/mappers/deep_embedded_spec.rb +52 -0
- data/spec/integration/mappers/definition_dsl_spec.rb +0 -118
- data/spec/integration/mappers/embedded_spec.rb +82 -0
- data/spec/integration/mappers/group_spec.rb +170 -0
- data/spec/integration/mappers/prefixing_attributes_spec.rb +2 -2
- data/spec/integration/mappers/renaming_attributes_spec.rb +8 -6
- data/spec/integration/mappers/symbolizing_attributes_spec.rb +80 -0
- data/spec/integration/mappers/wrap_spec.rb +162 -0
- data/spec/integration/multi_repo_spec.rb +64 -0
- data/spec/integration/relations/reading_spec.rb +12 -8
- data/spec/integration/relations/registry_dsl_spec.rb +1 -3
- data/spec/integration/schema_spec.rb +10 -0
- data/spec/integration/setup_spec.rb +57 -6
- data/spec/spec_helper.rb +2 -1
- data/spec/unit/config_spec.rb +60 -0
- data/spec/unit/rom/adapter/memory/dataset_spec.rb +52 -0
- data/spec/unit/rom/adapter_spec.rb +31 -11
- data/spec/unit/rom/header_spec.rb +60 -16
- data/spec/unit/rom/mapper_builder_spec.rb +311 -0
- data/spec/unit/rom/mapper_registry_spec.rb +25 -0
- data/spec/unit/rom/mapper_spec.rb +4 -5
- data/spec/unit/rom/model_builder_spec.rb +15 -13
- data/spec/unit/rom/processor/transproc_spec.rb +331 -0
- data/spec/unit/rom/reader_spec.rb +73 -0
- data/spec/unit/rom/registry_spec.rb +38 -0
- data/spec/unit/rom/relation_spec.rb +0 -1
- data/spec/unit/rom/setup_spec.rb +55 -0
- data/spec/unit/rom_spec.rb +14 -0
- metadata +62 -22
- data/Gemfile.devtools +0 -71
- data/lib/rom/boot.rb +0 -197
- data/lib/rom/boot/command_dsl.rb +0 -48
- data/lib/rom/boot/dsl.rb +0 -37
- data/lib/rom/boot/mapper_dsl.rb +0 -23
- data/lib/rom/boot/schema_dsl.rb +0 -27
- data/lib/rom/ra.rb +0 -172
- data/lib/rom/ra/operation/group.rb +0 -47
- data/lib/rom/ra/operation/join.rb +0 -39
- data/lib/rom/ra/operation/wrap.rb +0 -45
- data/lib/rom/transformer.rb +0 -77
- data/spec/integration/ra/group_spec.rb +0 -46
- data/spec/integration/ra/join_spec.rb +0 -50
- data/spec/integration/ra/wrap_spec.rb +0 -37
- data/spec/unit/rom/ra/operation/group_spec.rb +0 -55
- data/spec/unit/rom/ra/operation/wrap_spec.rb +0 -29
- data/spec/unit/rom/transformer_spec.rb +0 -41
data/lib/rom/boot/command_dsl.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'rom/mapper_builder'
|
2
|
-
|
3
|
-
module ROM
|
4
|
-
|
5
|
-
class CommandDSL
|
6
|
-
attr_reader :commands
|
7
|
-
|
8
|
-
class CommandDefinition
|
9
|
-
attr_reader :options
|
10
|
-
|
11
|
-
def initialize(options, &block)
|
12
|
-
@options = options
|
13
|
-
instance_exec(&block) if block
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_h
|
17
|
-
options
|
18
|
-
end
|
19
|
-
|
20
|
-
def type
|
21
|
-
options[:type]
|
22
|
-
end
|
23
|
-
|
24
|
-
def method_missing(name, *args, &block)
|
25
|
-
if args.size == 1
|
26
|
-
options[name] = args.first
|
27
|
-
else
|
28
|
-
super
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def initialize
|
34
|
-
@commands = {}
|
35
|
-
end
|
36
|
-
|
37
|
-
def call
|
38
|
-
commands
|
39
|
-
end
|
40
|
-
|
41
|
-
def define(name, options = {}, &block)
|
42
|
-
commands[name] = CommandDefinition.new(options, &block)
|
43
|
-
self
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
data/lib/rom/boot/dsl.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'rom/boot/schema_dsl'
|
2
|
-
require 'rom/boot/mapper_dsl'
|
3
|
-
require 'rom/boot/command_dsl'
|
4
|
-
|
5
|
-
module ROM
|
6
|
-
class Boot
|
7
|
-
|
8
|
-
class DSL
|
9
|
-
attr_reader :env
|
10
|
-
|
11
|
-
def initialize(env)
|
12
|
-
@env = env
|
13
|
-
@schema = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def schema(&block)
|
17
|
-
dsl = SchemaDSL.new(env, @schema)
|
18
|
-
dsl.instance_exec(&block)
|
19
|
-
dsl.call
|
20
|
-
end
|
21
|
-
|
22
|
-
def mappers(&block)
|
23
|
-
dsl = MapperDSL.new
|
24
|
-
dsl.instance_exec(&block)
|
25
|
-
dsl.call
|
26
|
-
end
|
27
|
-
|
28
|
-
def commands(&block)
|
29
|
-
dsl = CommandDSL.new
|
30
|
-
dsl.instance_exec(&block)
|
31
|
-
dsl.call
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
data/lib/rom/boot/mapper_dsl.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'rom/mapper_builder'
|
2
|
-
|
3
|
-
module ROM
|
4
|
-
|
5
|
-
class MapperDSL
|
6
|
-
attr_reader :mappers
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@mappers = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def call
|
13
|
-
mappers
|
14
|
-
end
|
15
|
-
|
16
|
-
def define(name, options = {}, &block)
|
17
|
-
mappers << [name, options, block]
|
18
|
-
self
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
data/lib/rom/boot/schema_dsl.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'rom/boot/base_relation_dsl'
|
2
|
-
|
3
|
-
module ROM
|
4
|
-
class Boot
|
5
|
-
|
6
|
-
class SchemaDSL
|
7
|
-
attr_reader :env, :schema
|
8
|
-
|
9
|
-
def initialize(env, schema = {})
|
10
|
-
@env = env
|
11
|
-
@schema = schema
|
12
|
-
end
|
13
|
-
|
14
|
-
def base_relation(name, &block)
|
15
|
-
dsl = BaseRelationDSL.new(env, name)
|
16
|
-
definition = dsl.call(&block)
|
17
|
-
(schema[dsl.repository] ||= []) << definition
|
18
|
-
end
|
19
|
-
|
20
|
-
def call
|
21
|
-
schema
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
data/lib/rom/ra.rb
DELETED
@@ -1,172 +0,0 @@
|
|
1
|
-
require 'rom/ra/operation/join'
|
2
|
-
require 'rom/ra/operation/group'
|
3
|
-
require 'rom/ra/operation/wrap'
|
4
|
-
|
5
|
-
module ROM
|
6
|
-
|
7
|
-
# Experimental DSL for in-memory relational operations
|
8
|
-
#
|
9
|
-
# @api private
|
10
|
-
module RA
|
11
|
-
|
12
|
-
# Join two relations in-memory using natural-join
|
13
|
-
#
|
14
|
-
# @example
|
15
|
-
#
|
16
|
-
# require 'rom'
|
17
|
-
# require 'rom/adapter/memory'
|
18
|
-
#
|
19
|
-
# setup = ROM.setup(memory: 'memory://localhost')
|
20
|
-
#
|
21
|
-
# setup.schema do
|
22
|
-
# base_relation(:users) do
|
23
|
-
# repository :memory
|
24
|
-
#
|
25
|
-
# attribute :user_id
|
26
|
-
# attribute :name
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# base_relation(:tasks) do
|
30
|
-
# repository :memory
|
31
|
-
#
|
32
|
-
# attribute :user_id
|
33
|
-
# attribute :title
|
34
|
-
# end
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# setup.relation(:tasks)
|
38
|
-
#
|
39
|
-
# setup.relation(:users) do
|
40
|
-
# def with_tasks
|
41
|
-
# in_memory { join(tasks) }
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# rom.relations.users.insert user_id: 1, name: 'Piotr'
|
46
|
-
# rom.relations.tasks.insert user_id: 1, title: 'Relax'
|
47
|
-
#
|
48
|
-
# rom.relations.users.with_tasks.to_a
|
49
|
-
# => [{:user_id=>1, :name=>"Piotr", :title=>"Relax"}]
|
50
|
-
#
|
51
|
-
# @api public
|
52
|
-
def join(*args)
|
53
|
-
left, right = args.size > 1 ? args : [self, args.first]
|
54
|
-
Operation::Join.new(left, right)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Groups two relations in-memory using group operation
|
58
|
-
#
|
59
|
-
# @example
|
60
|
-
#
|
61
|
-
# require 'rom'
|
62
|
-
# require 'rom/adapter/memory'
|
63
|
-
#
|
64
|
-
# setup = ROM.setup(memory: 'memory://localhost')
|
65
|
-
#
|
66
|
-
# setup.schema do
|
67
|
-
# base_relation(:users) do
|
68
|
-
# repository :memory
|
69
|
-
#
|
70
|
-
# attribute :user_id
|
71
|
-
# attribute :name
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# base_relation(:tasks) do
|
75
|
-
# repository :memory
|
76
|
-
#
|
77
|
-
# attribute :user_id
|
78
|
-
# attribute :title
|
79
|
-
# end
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# setup.relation(:tasks)
|
83
|
-
#
|
84
|
-
# setup.relation(:users) do
|
85
|
-
# def with_tasks
|
86
|
-
# in_memory { group(join(tasks), tasks: [:title]) }
|
87
|
-
# end
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
# rom.relations.users.insert user_id: 1, name: 'Piotr'
|
91
|
-
# rom.relations.tasks.insert user_id: 1, title: 'Work'
|
92
|
-
# rom.relations.tasks.insert user_id: 1, title: 'Relax'
|
93
|
-
#
|
94
|
-
# rom.relations.users.with_tasks.to_a
|
95
|
-
# => [{:user_id=>1, :name=>"Piotr", tasks: [{:title=>"Relax"}, {:title=>"Work"}]}]
|
96
|
-
#
|
97
|
-
# @api public
|
98
|
-
def group(*args)
|
99
|
-
ra_with_options(*args) { |relation, options|
|
100
|
-
Operation::Group.new(relation, options)
|
101
|
-
}
|
102
|
-
end
|
103
|
-
|
104
|
-
# Embed one relation in another in-memory using wrap operation
|
105
|
-
#
|
106
|
-
# @example
|
107
|
-
#
|
108
|
-
# require 'rom'
|
109
|
-
# require 'rom/adapter/memory'
|
110
|
-
#
|
111
|
-
# setup = ROM.setup(memory: 'memory://localhost')
|
112
|
-
#
|
113
|
-
# setup.schema do
|
114
|
-
# base_relation(:users) do
|
115
|
-
# repository :memory
|
116
|
-
#
|
117
|
-
# attribute :user_id
|
118
|
-
# attribute :name
|
119
|
-
# end
|
120
|
-
#
|
121
|
-
# base_relation(:addresses) do
|
122
|
-
# repository :memory
|
123
|
-
#
|
124
|
-
# attribute :user_id
|
125
|
-
# attribute :street
|
126
|
-
# attribute :zipcode
|
127
|
-
# attribute :city
|
128
|
-
# end
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# setup.relation(:addresses)
|
132
|
-
#
|
133
|
-
# setup.relation(:users) do
|
134
|
-
# def with_address
|
135
|
-
# in_memory { wrap(join(addresses), address: [:street, :zipcode, :city]) }
|
136
|
-
# end
|
137
|
-
# end
|
138
|
-
#
|
139
|
-
# rom = setup.finalize
|
140
|
-
#
|
141
|
-
# rom.relations.users.insert user_id: 1, name: 'Piotr'
|
142
|
-
# rom.relations.addresses.insert user_id: 1, street: 'Street 1', zipcode: '123', city: 'Kraków'
|
143
|
-
#
|
144
|
-
# rom.relations.users.with_address.to_a
|
145
|
-
# => [{:user_id=>1, :name=>"Piotr", :address=>{:street=>"Street 1", :zipcode=>"123", :city=>"Kraków"}}]
|
146
|
-
#
|
147
|
-
# @api public
|
148
|
-
def wrap(*args)
|
149
|
-
ra_with_options(*args) { |relation, options|
|
150
|
-
Operation::Wrap.new(relation, options)
|
151
|
-
}
|
152
|
-
end
|
153
|
-
|
154
|
-
private
|
155
|
-
|
156
|
-
# @api private
|
157
|
-
def ra_with_options(*args)
|
158
|
-
relation =
|
159
|
-
if args.size > 1
|
160
|
-
args.first
|
161
|
-
else
|
162
|
-
self
|
163
|
-
end
|
164
|
-
|
165
|
-
options = args.last
|
166
|
-
|
167
|
-
yield(relation, options)
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module RA
|
3
|
-
class Operation
|
4
|
-
|
5
|
-
class Group
|
6
|
-
# FIXME: only reading from a relation should be allowed here so this is
|
7
|
-
# obviously too much
|
8
|
-
include Charlatan.new(:relation)
|
9
|
-
|
10
|
-
include Enumerable
|
11
|
-
|
12
|
-
attr_reader :options, :header
|
13
|
-
|
14
|
-
def initialize(relation, options)
|
15
|
-
super
|
16
|
-
@options = options
|
17
|
-
@header = relation.header + options.keys - attribute_names
|
18
|
-
end
|
19
|
-
|
20
|
-
def each(&block)
|
21
|
-
return to_enum unless block
|
22
|
-
|
23
|
-
result = relation.each_with_object({}) do |tuple, grouped|
|
24
|
-
left = tuple.reject { |k,_| attribute_names.include?(k) }
|
25
|
-
right = tuple.reject { |k,_| !attribute_names.include?(k) }
|
26
|
-
|
27
|
-
grouped[left] ||= {}
|
28
|
-
grouped[left][key] ||= []
|
29
|
-
grouped[left][key] << right if right.values.any?
|
30
|
-
end
|
31
|
-
|
32
|
-
result.map { |k,v| k.merge(v) }.each(&block)
|
33
|
-
end
|
34
|
-
|
35
|
-
def key
|
36
|
-
options.keys.first
|
37
|
-
end
|
38
|
-
|
39
|
-
def attribute_names
|
40
|
-
options.values.first
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module RA
|
3
|
-
class Operation
|
4
|
-
|
5
|
-
class Join
|
6
|
-
include Charlatan.new(:left)
|
7
|
-
include Enumerable
|
8
|
-
|
9
|
-
attr_reader :right
|
10
|
-
|
11
|
-
def initialize(left, right)
|
12
|
-
super
|
13
|
-
@left, @right = left, right
|
14
|
-
end
|
15
|
-
|
16
|
-
def header
|
17
|
-
left.header + right.header
|
18
|
-
end
|
19
|
-
|
20
|
-
def each(&block)
|
21
|
-
return to_enum unless block
|
22
|
-
|
23
|
-
join_map = left.each_with_object({}) { |tuple, h|
|
24
|
-
others = right.find_all { |t| (tuple.to_a & t.to_a).any? }
|
25
|
-
(h[tuple] ||= []).concat(others)
|
26
|
-
}
|
27
|
-
|
28
|
-
tuples = left.map { |tuple|
|
29
|
-
join_map[tuple].map { |other| tuple.merge(other) }
|
30
|
-
}.flatten
|
31
|
-
|
32
|
-
tuples.each(&block)
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module ROM
|
2
|
-
module RA
|
3
|
-
class Operation
|
4
|
-
|
5
|
-
class Wrap
|
6
|
-
# FIXME: only reading from a relation should be allowed here so this is
|
7
|
-
# obviously too much
|
8
|
-
include Charlatan.new(:relation)
|
9
|
-
|
10
|
-
include Enumerable
|
11
|
-
|
12
|
-
attr_reader :options, :header
|
13
|
-
|
14
|
-
def initialize(relation, options)
|
15
|
-
super
|
16
|
-
@options = options
|
17
|
-
@header = relation.header + options.keys - attribute_names
|
18
|
-
end
|
19
|
-
|
20
|
-
def each(&block)
|
21
|
-
return to_enum unless block
|
22
|
-
|
23
|
-
results = relation.each_with_object([]) do |tuple, wrapped|
|
24
|
-
result = tuple.reject { |k,_| attribute_names.include?(k) }
|
25
|
-
result[key] = tuple.reject { |k,_| !attribute_names.include?(k) }
|
26
|
-
|
27
|
-
wrapped << result
|
28
|
-
end
|
29
|
-
|
30
|
-
results.each(&block)
|
31
|
-
end
|
32
|
-
|
33
|
-
def key
|
34
|
-
options.keys.first
|
35
|
-
end
|
36
|
-
|
37
|
-
def attribute_names
|
38
|
-
options.values.first
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|