rom-sql 3.6.4 → 3.7.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/CHANGELOG.md +17 -0
- data/README.md +1 -2
- data/lib/rom/plugins/relation/sql/auto_restrictions.rb +4 -1
- data/lib/rom/plugins/relation/sql/instrumentation.rb +6 -2
- data/lib/rom/plugins/relation/sql/postgres/explain.rb +1 -1
- data/lib/rom/plugins/relation/sql/postgres/full_text_search.rb +31 -12
- data/lib/rom/plugins/relation/sql/postgres/streaming.rb +6 -6
- data/lib/rom/sql/associations/many_to_many.rb +6 -3
- data/lib/rom/sql/associations/many_to_one.rb +3 -0
- data/lib/rom/sql/attribute.rb +22 -8
- data/lib/rom/sql/attribute_aliasing.rb +7 -6
- data/lib/rom/sql/commands/create.rb +4 -3
- data/lib/rom/sql/commands/update.rb +4 -3
- data/lib/rom/sql/dsl.rb +3 -1
- data/lib/rom/sql/extensions/active_support_notifications.rb +1 -1
- data/lib/rom/sql/extensions/postgres/type_builder.rb +7 -7
- data/lib/rom/sql/extensions/postgres/type_serializer.rb +2 -2
- data/lib/rom/sql/extensions/postgres/types/geometric.rb +12 -12
- data/lib/rom/sql/extensions/postgres/types/json.rb +9 -3
- data/lib/rom/sql/extensions/postgres/types/ltree.rb +106 -36
- data/lib/rom/sql/extensions/postgres/types/range.rb +18 -18
- data/lib/rom/sql/extensions/rails_log_subscriber.rb +4 -4
- data/lib/rom/sql/function.rb +37 -18
- data/lib/rom/sql/gateway.rb +8 -7
- data/lib/rom/sql/group_dsl.rb +7 -2
- data/lib/rom/sql/migration/inline_runner.rb +8 -2
- data/lib/rom/sql/migration/migrator.rb +5 -5
- data/lib/rom/sql/migration/recorder.rb +10 -4
- data/lib/rom/sql/migration/runner.rb +5 -4
- data/lib/rom/sql/migration/schema_diff.rb +15 -10
- data/lib/rom/sql/migration/writer.rb +8 -8
- data/lib/rom/sql/migration.rb +5 -5
- data/lib/rom/sql/order_dsl.rb +6 -2
- data/lib/rom/sql/plugin/associates.rb +21 -7
- data/lib/rom/sql/plugin/pagination.rb +2 -2
- data/lib/rom/sql/projection_dsl.rb +1 -1
- data/lib/rom/sql/relation/reading.rb +83 -71
- data/lib/rom/sql/relation/writing.rb +19 -13
- data/lib/rom/sql/relation.rb +74 -28
- data/lib/rom/sql/restriction_dsl.rb +6 -2
- data/lib/rom/sql/schema/attributes_inferrer.rb +2 -2
- data/lib/rom/sql/schema/dsl.rb +2 -2
- data/lib/rom/sql/schema/index_dsl.rb +5 -6
- data/lib/rom/sql/schema/inferrer.rb +23 -19
- data/lib/rom/sql/schema/type_builder.rb +19 -3
- data/lib/rom/sql/schema.rb +10 -10
- data/lib/rom/sql/tasks/migration_tasks.rake +4 -5
- data/lib/rom/sql/transaction.rb +1 -0
- data/lib/rom/sql/type_dsl.rb +7 -3
- data/lib/rom/sql/type_extensions.rb +4 -4
- data/lib/rom/sql/type_serializer.rb +2 -2
- data/lib/rom/sql/types.rb +2 -2
- data/lib/rom/sql/version.rb +1 -1
- data/lib/rom/types/values.rb +2 -4
- metadata +10 -19
@@ -13,7 +13,7 @@ module ROM
|
|
13
13
|
|
14
14
|
def call(changes)
|
15
15
|
changes.each { |diff| apply_schema(diff) }
|
16
|
-
changes.each { |diff| apply_constraints(diff) }
|
16
|
+
changes.each { |diff| apply_constraints(diff) } # rubocop:disable Style/CombinableLoops
|
17
17
|
|
18
18
|
self
|
19
19
|
end
|
@@ -54,6 +54,7 @@ module ROM
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
57
58
|
def alter_table(diff)
|
58
59
|
return if diff.meta?
|
59
60
|
|
@@ -68,9 +69,8 @@ module ROM
|
|
68
69
|
when SchemaDiff::AttributeChanged
|
69
70
|
if attribute.type_changed?
|
70
71
|
from, to = attribute.current.unwrap, attribute.target.unwrap
|
71
|
-
raise UnsupportedConversion
|
72
|
-
|
73
|
-
)
|
72
|
+
raise UnsupportedConversion,
|
73
|
+
"Don't know how to convert #{from.inspect} to #{to.inspect}"
|
74
74
|
end
|
75
75
|
|
76
76
|
if attribute.nullability_changed?
|
@@ -94,6 +94,7 @@ module ROM
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
97
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
97
98
|
|
98
99
|
def alter_foreign_keys(diff, foreign_key_changes)
|
99
100
|
return if foreign_key_changes.empty?
|
@@ -46,7 +46,6 @@ module ROM
|
|
46
46
|
end
|
47
47
|
|
48
48
|
class TableAltered < TableDiff
|
49
|
-
|
50
49
|
option :attribute_changes, default: -> { EMPTY_ARRAY }
|
51
50
|
|
52
51
|
option :index_changes, default: -> { EMPTY_ARRAY }
|
@@ -133,20 +132,22 @@ module ROM
|
|
133
132
|
end
|
134
133
|
|
135
134
|
class IndexAdded < IndexDiff
|
135
|
+
# rubocop:disable Metrics/AbcSize
|
136
136
|
def options
|
137
137
|
options = {}
|
138
|
-
options[:name] = index.name
|
138
|
+
options[:name] = index.name unless index.name.nil?
|
139
139
|
options[:unique] = true if index.unique?
|
140
|
-
options[:type] = index.type
|
141
|
-
options[:where] = index.predicate
|
140
|
+
options[:type] = index.type unless index.type.nil?
|
141
|
+
options[:where] = index.predicate unless index.predicate.nil?
|
142
142
|
options
|
143
143
|
end
|
144
|
+
# rubocop:enable Metrics/AbcSize
|
144
145
|
end
|
145
146
|
|
146
147
|
class IndexRemoved < IndexDiff
|
147
148
|
def options
|
148
149
|
options = {}
|
149
|
-
options[:name] = index.name
|
150
|
+
options[:name] = index.name unless index.name.nil?
|
150
151
|
options
|
151
152
|
end
|
152
153
|
end
|
@@ -177,6 +178,7 @@ module ROM
|
|
177
178
|
class ForeignKeyRemoved < ForeignKeyDiff
|
178
179
|
end
|
179
180
|
|
181
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength
|
180
182
|
def call(current, target)
|
181
183
|
if current.empty?
|
182
184
|
TableCreated.new(
|
@@ -203,21 +205,23 @@ module ROM
|
|
203
205
|
end
|
204
206
|
end
|
205
207
|
end
|
208
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength
|
206
209
|
|
210
|
+
# rubocop:disable Style/MultilineBlockChain
|
207
211
|
def compare_attributes(current, target)
|
208
212
|
changed_attributes = target.select { |name, attr|
|
209
213
|
current.key?(name) && !attributes_equal?(current[name], attr)
|
210
|
-
}.
|
211
|
-
|
212
|
-
}
|
213
|
-
added_attributes = target.select { |name, _| !current.key?(name) }
|
214
|
-
removed_attributes = current.select { |name, _| !target.key?(name) }
|
214
|
+
}.to_h { |name, target_attr| [name, [target_attr, current[name]]] }
|
215
|
+
added_attributes = target.reject { |name, _| current.key?(name) }
|
216
|
+
removed_attributes = current.reject { |name, _| target.key?(name) }
|
215
217
|
|
216
218
|
map_attributes(removed_attributes, AttributeRemoved) +
|
217
219
|
map_attributes(added_attributes, AttributeAdded) +
|
218
220
|
map_attributes(changed_attributes, AttributeChanged)
|
219
221
|
end
|
222
|
+
# rubocop:enable Style/MultilineBlockChain
|
220
223
|
|
224
|
+
# rubocop:disable Metrics/AbcSize
|
221
225
|
def compare_indexes(current, target)
|
222
226
|
added_indexes = target.indexes.reject { |idx|
|
223
227
|
current.indexes.any? { |curr_idx| curr_idx.attributes == idx.attributes }
|
@@ -229,6 +233,7 @@ module ROM
|
|
229
233
|
removed_indexes.map { |idx| IndexRemoved.new(idx) } +
|
230
234
|
added_indexes.map { |idx| IndexAdded.new(idx) }
|
231
235
|
end
|
236
|
+
# rubocop:enable Metrics/AbcSize
|
232
237
|
|
233
238
|
def compare_foreign_key_constraints(current, target)
|
234
239
|
target_fks = target.foreign_keys
|
@@ -7,8 +7,8 @@ module ROM
|
|
7
7
|
module Migration
|
8
8
|
# @api private
|
9
9
|
class Writer
|
10
|
-
MIGRATION_BEGIN = "ROM::SQL.migration do\n change do"
|
11
|
-
MIGRATION_END = "\n end\nend\n"
|
10
|
+
MIGRATION_BEGIN = "ROM::SQL.migration do\n change do"
|
11
|
+
MIGRATION_END = "\n end\nend\n"
|
12
12
|
|
13
13
|
attr_reader :yield_migration
|
14
14
|
|
@@ -36,11 +36,11 @@ module ROM
|
|
36
36
|
buffer << indent << op.to_s << ' '
|
37
37
|
write_arguments(buffer, args)
|
38
38
|
|
39
|
-
if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
39
|
+
next if nested.empty?
|
40
|
+
|
41
|
+
buffer << ' do'
|
42
|
+
write(nested, buffer, "#{indent} ")
|
43
|
+
buffer << indent << 'end'
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -61,7 +61,7 @@ module ROM
|
|
61
61
|
create_or_alter, args = op
|
62
62
|
table_name = args[0]
|
63
63
|
|
64
|
-
"#{create_or_alter.to_s.sub(
|
64
|
+
"#{create_or_alter.to_s.sub("_table", "")}_#{table_name}"
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
data/lib/rom/sql/migration.rb
CHANGED
@@ -54,12 +54,12 @@ module ROM
|
|
54
54
|
# @param [Symbol] gateway The gateway name, :default by default
|
55
55
|
#
|
56
56
|
# @api public
|
57
|
-
def migration(*args, &
|
57
|
+
def migration(*args, &)
|
58
58
|
if args.any?
|
59
59
|
container, gateway, * = args
|
60
|
-
with_gateway(container.gateways[gateway || :default]) { migration(&
|
60
|
+
with_gateway(container.gateways[gateway || :default]) { migration(&) }
|
61
61
|
else
|
62
|
-
current_gateway.migration(&
|
62
|
+
current_gateway.migration(&)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -121,8 +121,8 @@ module ROM
|
|
121
121
|
# @see ROM::SQL.migration
|
122
122
|
#
|
123
123
|
# @api public
|
124
|
-
def migration(&
|
125
|
-
migrator.migration(&
|
124
|
+
def migration(&)
|
125
|
+
migrator.migration(&)
|
126
126
|
end
|
127
127
|
|
128
128
|
# Run migrations
|
data/lib/rom/sql/order_dsl.rb
CHANGED
@@ -8,12 +8,16 @@ module ROM
|
|
8
8
|
class OrderDSL < DSL
|
9
9
|
private
|
10
10
|
|
11
|
+
def respond_to_missing?(_meth, _include_private = false)
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
11
15
|
# @api private
|
12
|
-
def method_missing(meth,
|
16
|
+
def method_missing(meth, ...)
|
13
17
|
if schema.key?(meth)
|
14
18
|
schema[meth]
|
15
19
|
else
|
16
|
-
::Sequel::VIRTUAL_ROW.__send__(meth.to_s.upcase,
|
20
|
+
::Sequel::VIRTUAL_ROW.__send__(meth.to_s.upcase, ...)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -10,7 +10,11 @@ module ROM
|
|
10
10
|
# @api private
|
11
11
|
module Associates
|
12
12
|
class AssociateOptions
|
13
|
-
attr_reader :name
|
13
|
+
attr_reader :name
|
14
|
+
|
15
|
+
attr_reader :assoc
|
16
|
+
|
17
|
+
attr_reader :opts
|
14
18
|
|
15
19
|
# @api private
|
16
20
|
def initialize(name, relation, opts)
|
@@ -37,7 +41,7 @@ module ROM
|
|
37
41
|
|
38
42
|
defines :associations
|
39
43
|
|
40
|
-
associations
|
44
|
+
associations({})
|
41
45
|
|
42
46
|
option :associations, default: -> { self.class.associations }
|
43
47
|
option :configured_associations, default: -> { EMPTY_ARRAY }
|
@@ -57,16 +61,17 @@ module ROM
|
|
57
61
|
|
58
62
|
associate_options = command.associations.map { |(name, opts)|
|
59
63
|
next if configured_assocs.include?(name)
|
64
|
+
|
60
65
|
AssociateOptions.new(name, relation, opts)
|
61
66
|
}.compact
|
62
67
|
|
63
68
|
before_hooks = associate_options.reject(&:after?).map(&:to_hash)
|
64
69
|
after_hooks = associate_options.select(&:after?).map(&:to_hash)
|
65
70
|
|
66
|
-
command
|
67
|
-
with(configured_associations: configured_assocs + associate_options.map(&:name))
|
68
|
-
before(*before_hooks)
|
69
|
-
after(*after_hooks)
|
71
|
+
command
|
72
|
+
.with(configured_associations: configured_assocs + associate_options.map(&:name))
|
73
|
+
.before(*before_hooks)
|
74
|
+
.after(*after_hooks)
|
70
75
|
end
|
71
76
|
|
72
77
|
# Set command to associate tuples with a parent tuple using provided keys
|
@@ -109,7 +114,15 @@ module ROM
|
|
109
114
|
# @return [Array<Hash>]
|
110
115
|
#
|
111
116
|
# @api public
|
112
|
-
|
117
|
+
#
|
118
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/AbcSize
|
119
|
+
def associate(
|
120
|
+
tuples,
|
121
|
+
curried_parent = nil,
|
122
|
+
assoc:,
|
123
|
+
keys:, # rubocop:disable Lint/UnusedMethodArgument
|
124
|
+
parent: curried_parent
|
125
|
+
)
|
113
126
|
result_type = result
|
114
127
|
|
115
128
|
output_tuples =
|
@@ -137,6 +150,7 @@ module ROM
|
|
137
150
|
|
138
151
|
result_type == :one ? output_tuples[0] : output_tuples
|
139
152
|
end
|
153
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/AbcSize
|
140
154
|
|
141
155
|
# Return a new command with the provided association
|
142
156
|
#
|
@@ -53,7 +53,7 @@ module ROM
|
|
53
53
|
# @api public
|
54
54
|
def prev_page
|
55
55
|
num = current_page - 1
|
56
|
-
num if num
|
56
|
+
num if num.positive?
|
57
57
|
end
|
58
58
|
|
59
59
|
# Return total number of tuples
|
@@ -100,7 +100,7 @@ module ROM
|
|
100
100
|
per_page = per_page.to_i
|
101
101
|
|
102
102
|
self.class.new(
|
103
|
-
dataset.offset((current_page-1)*per_page).limit(per_page),
|
103
|
+
dataset.offset((current_page - 1) * per_page).limit(per_page),
|
104
104
|
current_page: current_page, per_page: per_page
|
105
105
|
)
|
106
106
|
end
|
@@ -9,20 +9,22 @@ module ROM
|
|
9
9
|
# Query API for SQL::Relation
|
10
10
|
#
|
11
11
|
# @api public
|
12
|
+
#
|
13
|
+
# rubocop:disable Metrics/ModuleLength
|
12
14
|
module Reading
|
13
15
|
# Row-level lock modes
|
14
|
-
ROW_LOCK_MODES = Hash.new({ update:
|
16
|
+
ROW_LOCK_MODES = Hash.new({ update: 'FOR UPDATE' }).update(
|
15
17
|
# https://www.postgresql.org/docs/current/static/sql-select.html#SQL-FOR-UPDATE-SHARE
|
16
18
|
postgres: {
|
17
|
-
update: 'FOR UPDATE'
|
18
|
-
no_key_update: 'FOR NO KEY UPDATE'
|
19
|
-
share: 'FOR SHARE'
|
20
|
-
key_share: 'FOR KEY SHARE'
|
19
|
+
update: 'FOR UPDATE',
|
20
|
+
no_key_update: 'FOR NO KEY UPDATE',
|
21
|
+
share: 'FOR SHARE',
|
22
|
+
key_share: 'FOR KEY SHARE'
|
21
23
|
},
|
22
24
|
# https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
|
23
25
|
mysql: {
|
24
|
-
update: 'FOR UPDATE'
|
25
|
-
share: 'LOCK IN SHARE MODE'
|
26
|
+
update: 'FOR UPDATE',
|
27
|
+
share: 'LOCK IN SHARE MODE'
|
26
28
|
}
|
27
29
|
).freeze
|
28
30
|
|
@@ -140,11 +142,11 @@ module ROM
|
|
140
142
|
# from tuples
|
141
143
|
#
|
142
144
|
# @api public
|
143
|
-
def map(key = nil, &
|
145
|
+
def map(key = nil, &)
|
144
146
|
if key
|
145
|
-
dataset.map(key, &
|
147
|
+
dataset.map(key, &)
|
146
148
|
else
|
147
|
-
dataset.map(&
|
149
|
+
dataset.map(&)
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
@@ -235,8 +237,8 @@ module ROM
|
|
235
237
|
# @return [Relation]
|
236
238
|
#
|
237
239
|
# @api public
|
238
|
-
def select(
|
239
|
-
schema.project(
|
240
|
+
def select(...)
|
241
|
+
schema.project(...).(self)
|
240
242
|
end
|
241
243
|
alias_method :project, :select
|
242
244
|
|
@@ -247,8 +249,8 @@ module ROM
|
|
247
249
|
# @return [Relation]
|
248
250
|
#
|
249
251
|
# @api public
|
250
|
-
def select_append(
|
251
|
-
schema.merge(schema.canonical.project(
|
252
|
+
def select_append(...)
|
253
|
+
schema.merge(schema.canonical.project(...)).(self)
|
252
254
|
end
|
253
255
|
|
254
256
|
# Returns a copy of the relation with a SQL DISTINCT clause.
|
@@ -271,8 +273,8 @@ module ROM
|
|
271
273
|
# @return [Relation]
|
272
274
|
#
|
273
275
|
# @api public
|
274
|
-
def distinct(
|
275
|
-
new(dataset.__send__(__method__,
|
276
|
+
def distinct(...)
|
277
|
+
new(dataset.__send__(__method__, ...))
|
276
278
|
end
|
277
279
|
|
278
280
|
# Returns a result of SQL SUM clause.
|
@@ -359,9 +361,9 @@ module ROM
|
|
359
361
|
# @return [Relation]
|
360
362
|
#
|
361
363
|
# @api public
|
362
|
-
def where(*args, &
|
363
|
-
if
|
364
|
-
where(*args).where(schema.canonical.restriction(&
|
364
|
+
def where(*args, &)
|
365
|
+
if block_given?
|
366
|
+
where(*args).where(schema.canonical.restriction(&))
|
365
367
|
elsif args.size == 1 && args[0].is_a?(Hash)
|
366
368
|
new(dataset.where(coerce_conditions(args[0])))
|
367
369
|
elsif !args.empty?
|
@@ -381,8 +383,8 @@ module ROM
|
|
381
383
|
# @return [Relation]
|
382
384
|
#
|
383
385
|
# @api public
|
384
|
-
def exclude(
|
385
|
-
new(dataset.__send__(__method__,
|
386
|
+
def exclude(...)
|
387
|
+
new(dataset.__send__(__method__, ...))
|
386
388
|
end
|
387
389
|
|
388
390
|
# Restrict a relation to match grouping criteria
|
@@ -418,9 +420,9 @@ module ROM
|
|
418
420
|
# @return [Relation]
|
419
421
|
#
|
420
422
|
# @api public
|
421
|
-
def having(*args, &
|
422
|
-
if
|
423
|
-
new(dataset.having(*args, *schema.canonical.restriction(&
|
423
|
+
def having(*args, &)
|
424
|
+
if block_given?
|
425
|
+
new(dataset.having(*args, *schema.canonical.restriction(&)))
|
424
426
|
else
|
425
427
|
new(dataset.__send__(__method__, *args))
|
426
428
|
end
|
@@ -473,11 +475,11 @@ module ROM
|
|
473
475
|
# @return [Relation]
|
474
476
|
#
|
475
477
|
# @api public
|
476
|
-
def order(*args, &
|
477
|
-
if
|
478
|
-
new(dataset.order(*args, *schema.canonical.order(&
|
478
|
+
def order(*args, &)
|
479
|
+
if block_given?
|
480
|
+
new(dataset.order(*args, *schema.canonical.order(&)))
|
479
481
|
else
|
480
|
-
new(dataset.__send__(__method__, *args, &
|
482
|
+
new(dataset.__send__(__method__, *args, &))
|
481
483
|
end
|
482
484
|
end
|
483
485
|
|
@@ -501,8 +503,8 @@ module ROM
|
|
501
503
|
# @return [Relation]
|
502
504
|
#
|
503
505
|
# @api public
|
504
|
-
def reverse(
|
505
|
-
new(dataset.__send__(__method__,
|
506
|
+
def reverse(...)
|
507
|
+
new(dataset.__send__(__method__, ...))
|
506
508
|
end
|
507
509
|
|
508
510
|
# Limit a relation to a specific number of tuples
|
@@ -590,8 +592,8 @@ module ROM
|
|
590
592
|
# @return [Relation]
|
591
593
|
#
|
592
594
|
# @api public
|
593
|
-
def join(
|
594
|
-
__join__(__method__,
|
595
|
+
def join(...)
|
596
|
+
__join__(__method__, ...)
|
595
597
|
end
|
596
598
|
alias_method :inner_join, :join
|
597
599
|
|
@@ -640,8 +642,8 @@ module ROM
|
|
640
642
|
# @return [Relation]
|
641
643
|
#
|
642
644
|
# @api public
|
643
|
-
def left_join(
|
644
|
-
__join__(__method__,
|
645
|
+
def left_join(...)
|
646
|
+
__join__(__method__, ...)
|
645
647
|
end
|
646
648
|
|
647
649
|
# Join with another relation using RIGHT JOIN
|
@@ -689,8 +691,8 @@ module ROM
|
|
689
691
|
# @return [Relation]
|
690
692
|
#
|
691
693
|
# @api public
|
692
|
-
def right_join(
|
693
|
-
__join__(__method__,
|
694
|
+
def right_join(...)
|
695
|
+
__join__(__method__, ...)
|
694
696
|
end
|
695
697
|
|
696
698
|
# Group by specific columns
|
@@ -722,12 +724,12 @@ module ROM
|
|
722
724
|
# @return [Relation]
|
723
725
|
#
|
724
726
|
# @api public
|
725
|
-
def group(*args, &
|
726
|
-
if
|
727
|
-
if args.size
|
728
|
-
group(*args).group_append(&
|
727
|
+
def group(*args, &)
|
728
|
+
if block_given?
|
729
|
+
if args.size.positive?
|
730
|
+
group(*args).group_append(&)
|
729
731
|
else
|
730
|
-
new(dataset.__send__(__method__, *schema.canonical.group(&
|
732
|
+
new(dataset.__send__(__method__, *schema.canonical.group(&)))
|
731
733
|
end
|
732
734
|
else
|
733
735
|
new(dataset.__send__(__method__, *schema.canonical.project(*args)))
|
@@ -761,12 +763,12 @@ module ROM
|
|
761
763
|
# @return [Relation]
|
762
764
|
#
|
763
765
|
# @api public
|
764
|
-
def group_append(*args, &
|
765
|
-
if
|
766
|
-
if args.size
|
767
|
-
group_append(*args).group_append(&
|
766
|
+
def group_append(*args, &)
|
767
|
+
if block_given?
|
768
|
+
if args.size.positive?
|
769
|
+
group_append(*args).group_append(&)
|
768
770
|
else
|
769
|
-
new(dataset.group_append(*schema.canonical.group(&
|
771
|
+
new(dataset.group_append(*schema.canonical.group(&)))
|
770
772
|
end
|
771
773
|
else
|
772
774
|
new(dataset.group_append(*args))
|
@@ -784,8 +786,8 @@ module ROM
|
|
784
786
|
# @return [Relation]
|
785
787
|
#
|
786
788
|
# @api public
|
787
|
-
def group_and_count(
|
788
|
-
new(dataset.__send__(__method__,
|
789
|
+
def group_and_count(...)
|
790
|
+
new(dataset.__send__(__method__, ...))
|
789
791
|
end
|
790
792
|
|
791
793
|
# Select and group by specific columns
|
@@ -799,8 +801,8 @@ module ROM
|
|
799
801
|
# @return [Relation]
|
800
802
|
#
|
801
803
|
# @api public
|
802
|
-
def select_group(
|
803
|
-
new_schema = schema.project(
|
804
|
+
def select_group(...)
|
805
|
+
new_schema = schema.project(...)
|
804
806
|
new_schema.(self).group(*new_schema)
|
805
807
|
end
|
806
808
|
|
@@ -813,14 +815,17 @@ module ROM
|
|
813
815
|
# @param [Relation] relation Another relation
|
814
816
|
#
|
815
817
|
# @param [Hash] options Options for union
|
816
|
-
# @option options [Symbol] :alias
|
817
|
-
#
|
818
|
-
# @option options [
|
818
|
+
# @option options [Symbol] :alias
|
819
|
+
# Use the given value as the #from_self alias
|
820
|
+
# @option options [true, false] :all
|
821
|
+
# Set to true to use UNION ALL instead of UNION, so duplicate rows can occur
|
822
|
+
# @option options [true, false] :from_self
|
823
|
+
# Set to false to not wrap the returned dataset in a #from_self, use with care.
|
819
824
|
#
|
820
825
|
# @returRelation]
|
821
826
|
#
|
822
827
|
# @api public
|
823
|
-
def union(relation, options = EMPTY_HASH, &
|
828
|
+
def union(relation, options = EMPTY_HASH, &)
|
824
829
|
# We use the original relation name here if both relations have the
|
825
830
|
# same name. This makes it so if the user at some point references
|
826
831
|
# the relation directly by name later on things won't break in
|
@@ -830,7 +835,7 @@ module ROM
|
|
830
835
|
opts = { alias: alias_name.to_sym, **options }
|
831
836
|
|
832
837
|
new_schema = schema.qualified(opts[:alias])
|
833
|
-
new_schema.(new(dataset.__send__(__method__, relation.dataset, opts, &
|
838
|
+
new_schema.(new(dataset.__send__(__method__, relation.dataset, opts, &)))
|
834
839
|
end
|
835
840
|
|
836
841
|
# Checks whether a relation has at least one tuple
|
@@ -848,8 +853,8 @@ module ROM
|
|
848
853
|
# @return [TrueClass, FalseClass]
|
849
854
|
#
|
850
855
|
# @api public
|
851
|
-
def exist?(
|
852
|
-
!where(
|
856
|
+
def exist?(...)
|
857
|
+
!where(...).limit(1).count.zero?
|
853
858
|
end
|
854
859
|
|
855
860
|
# Return if a restricted relation has 0 tuples
|
@@ -905,12 +910,12 @@ module ROM
|
|
905
910
|
# @yieldparam relation [Array]
|
906
911
|
#
|
907
912
|
# @api public
|
908
|
-
def lock(**options, &
|
913
|
+
def lock(**options, &)
|
909
914
|
clause = lock_clause(**options)
|
910
915
|
|
911
|
-
if
|
916
|
+
if block_given?
|
912
917
|
transaction do
|
913
|
-
|
918
|
+
yield(dataset.lock_style(clause).to_a)
|
914
919
|
end
|
915
920
|
else
|
916
921
|
new(dataset.lock_style(clause))
|
@@ -1050,7 +1055,7 @@ module ROM
|
|
1050
1055
|
stmt << ' OF ' << Array(of).join(', ') if of
|
1051
1056
|
|
1052
1057
|
if skip_locked
|
1053
|
-
raise ArgumentError, 'SKIP LOCKED cannot be used with (NO)WAIT clause'
|
1058
|
+
raise ArgumentError, 'SKIP LOCKED cannot be used with (NO)WAIT clause' unless wait.nil?
|
1054
1059
|
|
1055
1060
|
stmt << ' SKIP LOCKED'
|
1056
1061
|
else
|
@@ -1068,6 +1073,8 @@ module ROM
|
|
1068
1073
|
# Apply input types to condition values
|
1069
1074
|
#
|
1070
1075
|
# @api private
|
1076
|
+
#
|
1077
|
+
# rubocop:disable Metrics/AbcSize
|
1071
1078
|
def coerce_conditions(conditions)
|
1072
1079
|
conditions.each_with_object({}) { |(k, v), h|
|
1073
1080
|
if k.is_a?(Symbol) && schema.canonical.key?(k)
|
@@ -1080,25 +1087,28 @@ module ROM
|
|
1080
1087
|
end
|
1081
1088
|
}
|
1082
1089
|
end
|
1090
|
+
# rubocop:enable Metrics/AbcSize
|
1083
1091
|
|
1084
1092
|
# Common join method used by other join methods
|
1085
1093
|
#
|
1086
1094
|
# @api private
|
1087
|
-
|
1095
|
+
#
|
1096
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
1097
|
+
def __join__(type, other, join_cond = EMPTY_HASH, opts = EMPTY_HASH, &)
|
1088
1098
|
if other.is_a?(Symbol) || other.is_a?(ROM::Relation::Name)
|
1089
|
-
if join_cond.equal?(EMPTY_HASH) && !
|
1099
|
+
if join_cond.equal?(EMPTY_HASH) && !block_given?
|
1090
1100
|
assoc = associations[other]
|
1091
1101
|
assoc.join(type, self)
|
1092
|
-
elsif
|
1093
|
-
__join__(type, other, JoinDSL.new(schema).(&
|
1102
|
+
elsif block_given?
|
1103
|
+
__join__(type, other, JoinDSL.new(schema).(&), opts)
|
1094
1104
|
else
|
1095
|
-
new(dataset.__send__(type, other.to_sym, join_cond, opts, &
|
1105
|
+
new(dataset.__send__(type, other.to_sym, join_cond, opts, &))
|
1096
1106
|
end
|
1097
|
-
elsif other.is_a?(Sequel::SQL::AliasedExpression)
|
1098
|
-
new(dataset.__send__(type, other, join_cond, opts, &
|
1107
|
+
elsif other.is_a?(::Sequel::SQL::AliasedExpression)
|
1108
|
+
new(dataset.__send__(type, other, join_cond, opts, &))
|
1099
1109
|
elsif other.respond_to?(:name) && other.name.is_a?(Relation::Name)
|
1100
|
-
if
|
1101
|
-
join_cond = JoinDSL.new(schema).(&
|
1110
|
+
if block_given?
|
1111
|
+
join_cond = JoinDSL.new(schema).(&)
|
1102
1112
|
|
1103
1113
|
if other.name.aliaz
|
1104
1114
|
join_opts = { table_alias: other.name.aliaz }
|
@@ -1111,10 +1121,12 @@ module ROM
|
|
1111
1121
|
associations[other.name.key].join(type, self, other)
|
1112
1122
|
end
|
1113
1123
|
else
|
1114
|
-
raise ArgumentError,
|
1124
|
+
raise ArgumentError,
|
1125
|
+
"+other+ must be either a symbol or a relation, #{other.class} given"
|
1115
1126
|
end
|
1116
1127
|
end
|
1117
1128
|
end
|
1129
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/ModuleLength
|
1118
1130
|
end
|
1119
1131
|
end
|
1120
1132
|
end
|