rom-core 4.0.0.beta2 → 4.0.0.beta3
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/CHANGELOG.md +2 -1
- data/lib/rom/attribute.rb +427 -0
- data/lib/rom/auto_curry.rb +1 -1
- data/lib/rom/command.rb +9 -0
- data/lib/rom/command_proxy.rb +10 -2
- data/lib/rom/constants.rb +8 -0
- data/lib/rom/core.rb +0 -2
- data/lib/rom/gateway.rb +0 -11
- data/lib/rom/plugins/command/schema.rb +2 -4
- data/lib/rom/relation/class_interface.rb +13 -2
- data/lib/rom/relation/combined.rb +10 -4
- data/lib/rom/relation/commands.rb +28 -8
- data/lib/rom/relation/composite.rb +1 -3
- data/lib/rom/relation/curried.rb +10 -14
- data/lib/rom/relation/graph.rb +8 -0
- data/lib/rom/relation/materializable.rb +0 -7
- data/lib/rom/relation/name.rb +2 -2
- data/lib/rom/relation/wrap.rb +8 -27
- data/lib/rom/relation.rb +78 -15
- data/lib/rom/schema/dsl.rb +4 -2
- data/lib/rom/schema/inferrer.rb +4 -1
- data/lib/rom/schema.rb +13 -12
- data/lib/rom/setup/finalize/finalize_mappers.rb +5 -4
- data/lib/rom/setup/finalize/finalize_relations.rb +7 -10
- data/lib/rom/support/notifications.rb +92 -0
- data/lib/rom/version.rb +1 -1
- metadata +10 -5
- data/lib/rom/plugins/configuration/configuration_dsl.rb +0 -21
- data/lib/rom/schema/attribute.rb +0 -419
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.
|
4
|
+
version: 4.0.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -59,6 +59,9 @@ dependencies:
|
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0.11'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 0.11.1
|
62
65
|
type: :runtime
|
63
66
|
prerelease: false
|
64
67
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -66,6 +69,9 @@ dependencies:
|
|
66
69
|
- - "~>"
|
67
70
|
- !ruby/object:Gem::Version
|
68
71
|
version: '0.11'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.11.1
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: dry-core
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,6 +168,7 @@ files:
|
|
162
168
|
- lib/rom/associations/one_to_one.rb
|
163
169
|
- lib/rom/associations/one_to_one_through.rb
|
164
170
|
- lib/rom/associations/through_identifier.rb
|
171
|
+
- lib/rom/attribute.rb
|
165
172
|
- lib/rom/auto_curry.rb
|
166
173
|
- lib/rom/cache.rb
|
167
174
|
- lib/rom/command.rb
|
@@ -222,7 +229,6 @@ files:
|
|
222
229
|
- lib/rom/plugin_base.rb
|
223
230
|
- lib/rom/plugin_registry.rb
|
224
231
|
- lib/rom/plugins/command/schema.rb
|
225
|
-
- lib/rom/plugins/configuration/configuration_dsl.rb
|
226
232
|
- lib/rom/plugins/relation/instrumentation.rb
|
227
233
|
- lib/rom/plugins/relation/registry_reader.rb
|
228
234
|
- lib/rom/plugins/schema/timestamps.rb
|
@@ -242,7 +248,6 @@ files:
|
|
242
248
|
- lib/rom/relation_registry.rb
|
243
249
|
- lib/rom/schema.rb
|
244
250
|
- lib/rom/schema/associations_dsl.rb
|
245
|
-
- lib/rom/schema/attribute.rb
|
246
251
|
- lib/rom/schema/dsl.rb
|
247
252
|
- lib/rom/schema/inferrer.rb
|
248
253
|
- lib/rom/schema_plugin.rb
|
@@ -282,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
287
|
version: 1.3.1
|
283
288
|
requirements: []
|
284
289
|
rubyforge_project:
|
285
|
-
rubygems_version: 2.6.
|
290
|
+
rubygems_version: 2.6.11
|
286
291
|
signing_key:
|
287
292
|
specification_version: 4
|
288
293
|
summary: Ruby Object Mapper
|
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'rom/configuration_dsl'
|
2
|
-
require 'dry/core/deprecations'
|
3
|
-
|
4
|
-
module ROM
|
5
|
-
module ConfigurationPlugins
|
6
|
-
# Provides macros for defining relations, mappers and commands
|
7
|
-
#
|
8
|
-
# @api public
|
9
|
-
module ConfigurationDSL
|
10
|
-
|
11
|
-
# @api private
|
12
|
-
def self.apply(configuration, options = {})
|
13
|
-
Dry::Core::Deprecations.announce(
|
14
|
-
:macros,
|
15
|
-
"Calling `use(:macros)` is no longer necessary. Macros are enabled by default.",
|
16
|
-
tag: :rom
|
17
|
-
)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/rom/schema/attribute.rb
DELETED
@@ -1,419 +0,0 @@
|
|
1
|
-
require 'dry/equalizer'
|
2
|
-
|
3
|
-
require 'rom/initializer'
|
4
|
-
require 'rom/support/memoizable'
|
5
|
-
|
6
|
-
module ROM
|
7
|
-
class Schema
|
8
|
-
# Schema attributes provide meta information about types and an API
|
9
|
-
# for additional operations. This class can be extended by adapters to provide
|
10
|
-
# database-specific features. In example rom-sql provides SQL::Attribute
|
11
|
-
# with more features like creating SQL expressions for queries.
|
12
|
-
#
|
13
|
-
# Schema attributes are accessible through canonical relation schemas and
|
14
|
-
# instance-level schemas.
|
15
|
-
#
|
16
|
-
# @api public
|
17
|
-
class Attribute
|
18
|
-
include Dry::Equalizer(:type, :options)
|
19
|
-
include Memoizable
|
20
|
-
|
21
|
-
extend Initializer
|
22
|
-
|
23
|
-
# @!attribute [r] type
|
24
|
-
# @return [Dry::Types::Definition, Dry::Types::Sum, Dry::Types::Constrained]
|
25
|
-
param :type
|
26
|
-
|
27
|
-
# @api private
|
28
|
-
def [](input)
|
29
|
-
type[input]
|
30
|
-
end
|
31
|
-
|
32
|
-
# Return true if this attribute type is a primary key
|
33
|
-
#
|
34
|
-
# @example
|
35
|
-
# class Users < ROM::Relation[:memory]
|
36
|
-
# schema do
|
37
|
-
# attribute :id, Types::Int
|
38
|
-
# attribute :name, Types::String
|
39
|
-
#
|
40
|
-
# primary_key :id
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
#
|
44
|
-
# Users.schema[:id].primary_key?
|
45
|
-
# # => true
|
46
|
-
#
|
47
|
-
# Users.schema[:name].primary_key?
|
48
|
-
# # => false
|
49
|
-
#
|
50
|
-
# @return [TrueClass,FalseClass]
|
51
|
-
#
|
52
|
-
# @api public
|
53
|
-
def primary_key?
|
54
|
-
meta[:primary_key].equal?(true)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Return true if this attribute type is a foreign key
|
58
|
-
#
|
59
|
-
# @example
|
60
|
-
# class Tasks < ROM::Relation[:memory]
|
61
|
-
# schema do
|
62
|
-
# attribute :id, Types::Int
|
63
|
-
# attribute :user_id, Types.ForeignKey(:users)
|
64
|
-
# end
|
65
|
-
# end
|
66
|
-
#
|
67
|
-
# Users.schema[:user_id].foreign_key?
|
68
|
-
# # => true
|
69
|
-
#
|
70
|
-
# Users.schema[:id].foreign_key?
|
71
|
-
# # => false
|
72
|
-
#
|
73
|
-
# @return [TrueClass,FalseClass]
|
74
|
-
#
|
75
|
-
# @api public
|
76
|
-
def foreign_key?
|
77
|
-
meta[:foreign_key].equal?(true)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Return true if this attribute type is a foreign key
|
81
|
-
#
|
82
|
-
# @example
|
83
|
-
# class Tasks < ROM::Relation[:memory]
|
84
|
-
# schema do
|
85
|
-
# attribute :user_id, Types::Int.meta(alias: :id)
|
86
|
-
# attribute :name, Types::String
|
87
|
-
# end
|
88
|
-
# end
|
89
|
-
#
|
90
|
-
# Users.schema[:user_id].aliased?
|
91
|
-
# # => true
|
92
|
-
#
|
93
|
-
# Users.schema[:name].aliased?
|
94
|
-
# # => false
|
95
|
-
#
|
96
|
-
# @return [TrueClass,FalseClass]
|
97
|
-
#
|
98
|
-
# @api public
|
99
|
-
def aliased?
|
100
|
-
!meta[:alias].nil?
|
101
|
-
end
|
102
|
-
|
103
|
-
# Return source relation of this attribute type
|
104
|
-
#
|
105
|
-
# @example
|
106
|
-
# class Tasks < ROM::Relation[:memory]
|
107
|
-
# schema do
|
108
|
-
# attribute :id, Types::Int
|
109
|
-
# attribute :user_id, Types.ForeignKey(:users)
|
110
|
-
# end
|
111
|
-
# end
|
112
|
-
#
|
113
|
-
# Users.schema[:id].source
|
114
|
-
# # => :tasks
|
115
|
-
#
|
116
|
-
# Users.schema[:user_id].source
|
117
|
-
# # => :tasks
|
118
|
-
#
|
119
|
-
# @return [Symbol, Relation::Name]
|
120
|
-
#
|
121
|
-
# @api public
|
122
|
-
def source
|
123
|
-
meta[:source]
|
124
|
-
end
|
125
|
-
|
126
|
-
# Return target relation of this attribute type
|
127
|
-
#
|
128
|
-
# @example
|
129
|
-
# class Tasks < ROM::Relation[:memory]
|
130
|
-
# schema do
|
131
|
-
# attribute :id, Types::Int
|
132
|
-
# attribute :user_id, Types.ForeignKey(:users)
|
133
|
-
# end
|
134
|
-
# end
|
135
|
-
#
|
136
|
-
# Users.schema[:id].target
|
137
|
-
# # => nil
|
138
|
-
#
|
139
|
-
# Users.schema[:user_id].target
|
140
|
-
# # => :users
|
141
|
-
#
|
142
|
-
# @return [NilClass, Symbol, Relation::Name]
|
143
|
-
#
|
144
|
-
# @api public
|
145
|
-
def target
|
146
|
-
meta[:target]
|
147
|
-
end
|
148
|
-
|
149
|
-
# Return the canonical name of this attribute name
|
150
|
-
#
|
151
|
-
# This *always* returns the name that is used in the datastore, even when
|
152
|
-
# an attribute is aliased
|
153
|
-
#
|
154
|
-
# @example
|
155
|
-
# class Tasks < ROM::Relation[:memory]
|
156
|
-
# schema do
|
157
|
-
# attribute :user_id, Types::Int.meta(alias: :id)
|
158
|
-
# attribute :name, Types::String
|
159
|
-
# end
|
160
|
-
# end
|
161
|
-
#
|
162
|
-
# Users.schema[:id].name
|
163
|
-
# # => :id
|
164
|
-
#
|
165
|
-
# Users.schema[:user_id].name
|
166
|
-
# # => :user_id
|
167
|
-
#
|
168
|
-
# @return [Symbol]
|
169
|
-
#
|
170
|
-
# @api public
|
171
|
-
def name
|
172
|
-
meta[:name]
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return tuple key
|
176
|
-
#
|
177
|
-
# When schemas are projected with aliased attributes, we need a simple access to tuple keys
|
178
|
-
#
|
179
|
-
# @example
|
180
|
-
# class Tasks < ROM::Relation[:memory]
|
181
|
-
# schema do
|
182
|
-
# attribute :user_id, Types::Int.meta(alias: :id)
|
183
|
-
# attribute :name, Types::String
|
184
|
-
# end
|
185
|
-
# end
|
186
|
-
#
|
187
|
-
# Users.schema[:id].key
|
188
|
-
# # :id
|
189
|
-
#
|
190
|
-
# Users.schema.project(Users.schema[:id].aliased(:user_id)).key
|
191
|
-
# # :user_id
|
192
|
-
#
|
193
|
-
# @return [Symbol]
|
194
|
-
#
|
195
|
-
# @api public
|
196
|
-
def key
|
197
|
-
meta[:alias] || name
|
198
|
-
end
|
199
|
-
|
200
|
-
# Return attribute's alias
|
201
|
-
#
|
202
|
-
# @example
|
203
|
-
# class Tasks < ROM::Relation[:memory]
|
204
|
-
# schema do
|
205
|
-
# attribute :user_id, Types::Int.meta(alias: :id)
|
206
|
-
# attribute :name, Types::String
|
207
|
-
# end
|
208
|
-
# end
|
209
|
-
#
|
210
|
-
# Users.schema[:user_id].alias
|
211
|
-
# # => :user_id
|
212
|
-
#
|
213
|
-
# Users.schema[:name].alias
|
214
|
-
# # => nil
|
215
|
-
#
|
216
|
-
# @return [NilClass,Symbol]
|
217
|
-
#
|
218
|
-
# @api public
|
219
|
-
def alias
|
220
|
-
meta[:alias]
|
221
|
-
end
|
222
|
-
|
223
|
-
# Return new attribute type with provided alias
|
224
|
-
#
|
225
|
-
# @example
|
226
|
-
# class Tasks < ROM::Relation[:memory]
|
227
|
-
# schema do
|
228
|
-
# attribute :user_id, Types::Int
|
229
|
-
# attribute :name, Types::String
|
230
|
-
# end
|
231
|
-
# end
|
232
|
-
#
|
233
|
-
# aliased_user_id = Users.schema[:user_id].aliased(:id)
|
234
|
-
#
|
235
|
-
# aliased_user_id.aliased?
|
236
|
-
# # => true
|
237
|
-
#
|
238
|
-
# aliased_user_id.name
|
239
|
-
# # => :user_id
|
240
|
-
#
|
241
|
-
# aliased_user_id.alias
|
242
|
-
# # => :id
|
243
|
-
#
|
244
|
-
# @param [Symbol] name The alias
|
245
|
-
#
|
246
|
-
# @return [Schema::Attribute]
|
247
|
-
#
|
248
|
-
# @api public
|
249
|
-
def aliased(name)
|
250
|
-
meta(alias: name)
|
251
|
-
end
|
252
|
-
alias_method :as, :aliased
|
253
|
-
|
254
|
-
# Return new attribute type with an alias using provided prefix
|
255
|
-
#
|
256
|
-
# @example
|
257
|
-
# class Users < ROM::Relation[:memory]
|
258
|
-
# schema do
|
259
|
-
# attribute :id, Types::Int
|
260
|
-
# attribute :name, Types::String
|
261
|
-
# end
|
262
|
-
# end
|
263
|
-
#
|
264
|
-
# prefixed_id = Users.schema[:id].prefixed
|
265
|
-
#
|
266
|
-
# prefixed_id.aliased?
|
267
|
-
# # => true
|
268
|
-
#
|
269
|
-
# prefixed_id.name
|
270
|
-
# # => :id
|
271
|
-
#
|
272
|
-
# prefixed_id.alias
|
273
|
-
# # => :users_id
|
274
|
-
#
|
275
|
-
# prefixed_id = Users.schema[:id].prefixed(:user)
|
276
|
-
#
|
277
|
-
# prefixed_id.alias
|
278
|
-
# # => :user_id
|
279
|
-
#
|
280
|
-
# @param [Symbol] prefix The prefix (defaults to source.dataset)
|
281
|
-
#
|
282
|
-
# @return [Schema::Attribute]
|
283
|
-
#
|
284
|
-
# @api public
|
285
|
-
def prefixed(prefix = source.dataset)
|
286
|
-
aliased(:"#{prefix}_#{name}")
|
287
|
-
end
|
288
|
-
|
289
|
-
# Return if the attribute type is from a wrapped relation
|
290
|
-
#
|
291
|
-
# Wrapped attributes are used when two schemas from different relations
|
292
|
-
# are merged together. This way we can identify them easily and handle
|
293
|
-
# correctly in places like auto-mapping.
|
294
|
-
#
|
295
|
-
# @api public
|
296
|
-
def wrapped?
|
297
|
-
meta[:wrapped].equal?(true)
|
298
|
-
end
|
299
|
-
|
300
|
-
# Return attribute type wrapped for the specified relation name
|
301
|
-
#
|
302
|
-
# @param [Symbol] name The name of the source relation (defaults to source.dataset)
|
303
|
-
#
|
304
|
-
# @return [Schema::Attribute]
|
305
|
-
#
|
306
|
-
# @api public
|
307
|
-
def wrapped(name = source.dataset)
|
308
|
-
prefixed(name).meta(wrapped: true)
|
309
|
-
end
|
310
|
-
|
311
|
-
# Return attribute type with additional meta information
|
312
|
-
#
|
313
|
-
# Return meta information hash if no opts are provided
|
314
|
-
#
|
315
|
-
# @param [Hash] opts The meta options
|
316
|
-
#
|
317
|
-
# @return [Schema::Attribute]
|
318
|
-
#
|
319
|
-
# @api public
|
320
|
-
def meta(opts = nil)
|
321
|
-
if opts
|
322
|
-
self.class.new(type.meta(opts))
|
323
|
-
else
|
324
|
-
type.meta
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
# Return string representation of the attribute type
|
329
|
-
#
|
330
|
-
# @return [String]
|
331
|
-
#
|
332
|
-
# @api public
|
333
|
-
def inspect
|
334
|
-
%(#<#{self.class}[#{type.name}] #{meta.map { |k, v| "#{k}=#{v.inspect}" }.join(' ')}>)
|
335
|
-
end
|
336
|
-
alias_method :pretty_inspect, :inspect
|
337
|
-
|
338
|
-
# Check if the attribute type is equal to another
|
339
|
-
#
|
340
|
-
# @param [Dry::Type, Schema::Attribute]
|
341
|
-
#
|
342
|
-
# @return [TrueClass,FalseClass]
|
343
|
-
#
|
344
|
-
# @api public
|
345
|
-
def eql?(other)
|
346
|
-
other.is_a?(self.class) ? super : type.eql?(other)
|
347
|
-
end
|
348
|
-
|
349
|
-
# Return if this attribute type has additional attribute type for reading
|
350
|
-
# tuple values
|
351
|
-
#
|
352
|
-
# @return [TrueClass, FalseClass]
|
353
|
-
#
|
354
|
-
# @api private
|
355
|
-
def read?
|
356
|
-
! meta[:read].nil?
|
357
|
-
end
|
358
|
-
|
359
|
-
# Return read type or self
|
360
|
-
#
|
361
|
-
# @return [Schema::Attribute]
|
362
|
-
#
|
363
|
-
# @api private
|
364
|
-
def to_read_type
|
365
|
-
read? ? meta[:read] : type
|
366
|
-
end
|
367
|
-
|
368
|
-
# @api private
|
369
|
-
def respond_to_missing?(name, include_private = false)
|
370
|
-
type.respond_to?(name) || super
|
371
|
-
end
|
372
|
-
|
373
|
-
# Return AST for the type
|
374
|
-
#
|
375
|
-
# @return [Array]
|
376
|
-
#
|
377
|
-
# @api public
|
378
|
-
def to_ast
|
379
|
-
[:attribute, [name, type.to_ast(meta: false), meta_ast]]
|
380
|
-
end
|
381
|
-
|
382
|
-
# Return AST for the read type
|
383
|
-
#
|
384
|
-
# @return [Array]
|
385
|
-
#
|
386
|
-
# @api public
|
387
|
-
def to_read_ast
|
388
|
-
[:attribute, [name, to_read_type.to_ast(meta: false), meta_ast]]
|
389
|
-
end
|
390
|
-
|
391
|
-
# @api private
|
392
|
-
def meta_ast
|
393
|
-
meta_keys = %i(wrapped alias primary_key)
|
394
|
-
ast = meta.select { |k, _| meta_keys.include?(k) }
|
395
|
-
ast[:source] = source.to_sym if source
|
396
|
-
ast
|
397
|
-
end
|
398
|
-
|
399
|
-
memoize :to_ast, :to_read_ast, :meta_ast
|
400
|
-
|
401
|
-
private
|
402
|
-
|
403
|
-
# @api private
|
404
|
-
def method_missing(meth, *args, &block)
|
405
|
-
if type.respond_to?(meth)
|
406
|
-
response = type.__send__(meth, *args, &block)
|
407
|
-
|
408
|
-
if response.is_a?(type.class)
|
409
|
-
self.class.new(type, options)
|
410
|
-
else
|
411
|
-
response
|
412
|
-
end
|
413
|
-
else
|
414
|
-
super
|
415
|
-
end
|
416
|
-
end
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|