activerecord 7.0.0.alpha1 → 7.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +516 -10
- data/lib/active_record/associations/association.rb +2 -8
- data/lib/active_record/associations/builder/collection_association.rb +9 -2
- data/lib/active_record/associations/collection_association.rb +10 -2
- data/lib/active_record/associations/preloader/association.rb +68 -48
- data/lib/active_record/associations/preloader/batch.rb +3 -6
- data/lib/active_record/associations/preloader/through_association.rb +19 -9
- data/lib/active_record/associations/preloader.rb +14 -24
- data/lib/active_record/associations/through_association.rb +2 -2
- data/lib/active_record/associations.rb +16 -3
- data/lib/active_record/asynchronous_queries_tracker.rb +3 -0
- data/lib/active_record/attribute_methods/dirty.rb +9 -1
- data/lib/active_record/attribute_methods.rb +7 -5
- data/lib/active_record/autosave_association.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +6 -26
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +18 -5
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +33 -70
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -2
- data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -19
- data/lib/active_record/connection_adapters/abstract_adapter.rb +37 -8
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +23 -24
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/pool_config.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -44
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -4
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +48 -5
- data/lib/active_record/connection_adapters/schema_cache.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +15 -16
- data/lib/active_record/connection_handling.rb +31 -19
- data/lib/active_record/core.rb +13 -24
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +0 -9
- data/lib/active_record/database_configurations/hash_config.rb +40 -8
- data/lib/active_record/database_configurations.rb +2 -27
- data/lib/active_record/delegated_type.rb +19 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +1 -1
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +1 -2
- data/lib/active_record/encryption/message_serializer.rb +11 -1
- data/lib/active_record/encryption/scheme.rb +1 -1
- data/lib/active_record/enum.rb +8 -1
- data/lib/active_record/errors.rb +1 -1
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/fixture_set/table_row.rb +1 -1
- data/lib/active_record/fixtures.rb +1 -9
- data/lib/active_record/future_result.rb +2 -2
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/insert_all.rb +52 -15
- data/lib/active_record/integration.rb +3 -2
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/pessimistic.rb +9 -3
- data/lib/active_record/log_subscriber.rb +8 -1
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/model_schema.rb +1 -28
- data/lib/active_record/nested_attributes.rb +11 -10
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/persistence.rb +99 -21
- data/lib/active_record/query_logs.rb +18 -83
- data/lib/active_record/railtie.rb +11 -1
- data/lib/active_record/railties/databases.rake +4 -91
- data/lib/active_record/reflection.rb +22 -6
- data/lib/active_record/relation/calculations.rb +1 -10
- data/lib/active_record/relation/finder_methods.rb +0 -13
- data/lib/active_record/relation/query_methods.rb +5 -14
- data/lib/active_record/relation/record_fetch_warning.rb +5 -7
- data/lib/active_record/relation/where_clause.rb +2 -15
- data/lib/active_record/relation.rb +11 -13
- data/lib/active_record/result.rb +0 -5
- data/lib/active_record/runtime_registry.rb +10 -12
- data/lib/active_record/schema_dumper.rb +7 -0
- data/lib/active_record/scoping.rb +34 -22
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +18 -44
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -1
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/active_record.rb +41 -33
- data/lib/arel/crud.rb +12 -2
- data/lib/arel/delete_manager.rb +16 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/nodes/delete_statement.rb +5 -1
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/update_statement.rb +5 -1
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +10 -2
- data/lib/arel/update_manager.rb +16 -0
- data/lib/arel/visitors/mysql.rb +2 -1
- data/lib/arel/visitors/to_sql.rb +15 -0
- data/lib/arel.rb +1 -0
- metadata +17 -13
@@ -10,6 +10,7 @@ module ActiveRecord
|
|
10
10
|
included do
|
11
11
|
class_attribute :_reflections, instance_writer: false, default: {}
|
12
12
|
class_attribute :aggregate_reflections, instance_writer: false, default: {}
|
13
|
+
class_attribute :automatic_scope_inversing, instance_writer: false, default: false
|
13
14
|
end
|
14
15
|
|
15
16
|
class << self
|
@@ -234,6 +235,9 @@ module ActiveRecord
|
|
234
235
|
if has_inverse? && inverse_of.nil?
|
235
236
|
raise InverseOfAssociationNotFoundError.new(self)
|
236
237
|
end
|
238
|
+
if has_inverse? && inverse_of == self
|
239
|
+
raise InverseOfAssociationRecursiveError.new(self)
|
240
|
+
end
|
237
241
|
end
|
238
242
|
end
|
239
243
|
|
@@ -631,9 +635,10 @@ module ActiveRecord
|
|
631
635
|
# with the current reflection's klass name.
|
632
636
|
def valid_inverse_reflection?(reflection)
|
633
637
|
reflection &&
|
638
|
+
reflection != self &&
|
634
639
|
foreign_key == reflection.foreign_key &&
|
635
640
|
klass <= reflection.active_record &&
|
636
|
-
can_find_inverse_of_automatically?(reflection)
|
641
|
+
can_find_inverse_of_automatically?(reflection, true)
|
637
642
|
end
|
638
643
|
|
639
644
|
# Checks to see if the reflection doesn't have any options that prevent
|
@@ -642,14 +647,25 @@ module ActiveRecord
|
|
642
647
|
# have <tt>has_many</tt>, <tt>has_one</tt>, <tt>belongs_to</tt> associations.
|
643
648
|
# Third, we must not have options such as <tt>:foreign_key</tt>
|
644
649
|
# which prevent us from correctly guessing the inverse association.
|
645
|
-
|
646
|
-
# Anything with a scope can additionally ruin our attempt at finding an
|
647
|
-
# inverse, so we exclude reflections with scopes.
|
648
|
-
def can_find_inverse_of_automatically?(reflection)
|
650
|
+
def can_find_inverse_of_automatically?(reflection, inverse_reflection = false)
|
649
651
|
reflection.options[:inverse_of] != false &&
|
650
652
|
!reflection.options[:through] &&
|
651
653
|
!reflection.options[:foreign_key] &&
|
654
|
+
scope_allows_automatic_inverse_of?(reflection, inverse_reflection)
|
655
|
+
end
|
656
|
+
|
657
|
+
# Scopes on the potential inverse reflection prevent automatic
|
658
|
+
# <tt>inverse_of</tt>, since the scope could exclude the owner record
|
659
|
+
# we would inverse from. Scopes on the reflection itself allow for
|
660
|
+
# automatic <tt>inverse_of</tt> as long as
|
661
|
+
# <tt>config.active_record.automatic_scope_inversing<tt> is set to
|
662
|
+
# +true+ (the default for new applications).
|
663
|
+
def scope_allows_automatic_inverse_of?(reflection, inverse_reflection)
|
664
|
+
if inverse_reflection
|
652
665
|
!reflection.scope
|
666
|
+
else
|
667
|
+
!reflection.scope || reflection.klass.automatic_scope_inversing
|
668
|
+
end
|
653
669
|
end
|
654
670
|
|
655
671
|
def derive_class_name
|
@@ -736,7 +752,7 @@ module ActiveRecord
|
|
736
752
|
end
|
737
753
|
|
738
754
|
private
|
739
|
-
def can_find_inverse_of_automatically?(
|
755
|
+
def can_find_inverse_of_automatically?(*)
|
740
756
|
!polymorphic? && super
|
741
757
|
end
|
742
758
|
end
|
@@ -31,7 +31,7 @@ module ActiveRecord
|
|
31
31
|
#
|
32
32
|
# Article.group(:status, :category).count
|
33
33
|
# # => {["draft", "business"]=>10, ["draft", "technology"]=>4,
|
34
|
-
#
|
34
|
+
# # ["published", "business"]=>0, ["published", "technology"]=>2}
|
35
35
|
#
|
36
36
|
# If #count is used with {Relation#select}[rdoc-ref:QueryMethods#select], it will count the selected columns:
|
37
37
|
#
|
@@ -329,15 +329,6 @@ module ActiveRecord
|
|
329
329
|
group_fields = group_values
|
330
330
|
group_fields = group_fields.uniq if group_fields.size > 1
|
331
331
|
|
332
|
-
unless group_fields == group_values
|
333
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
334
|
-
`#{operation}` with group by duplicated fields does no longer affect to result in Rails 7.0.
|
335
|
-
To migrate to Rails 7.0's behavior, use `uniq!(:group)` to deduplicate group fields
|
336
|
-
(`#{klass.name&.tableize || klass.table_name}.uniq!(:group).#{operation}(#{column_name.inspect})`).
|
337
|
-
MSG
|
338
|
-
group_fields = group_values
|
339
|
-
end
|
340
|
-
|
341
332
|
if group_fields.size == 1 && group_fields.first.respond_to?(:to_sym)
|
342
333
|
association = klass._reflect_on_association(group_fields.first)
|
343
334
|
associated = association && association.belongs_to? # only count belongs_to associations
|
@@ -140,8 +140,6 @@ module ActiveRecord
|
|
140
140
|
# Person.first(3) # returns the first three objects fetched by SELECT * FROM people ORDER BY people.id LIMIT 3
|
141
141
|
#
|
142
142
|
def first(limit = nil)
|
143
|
-
check_reorder_deprecation unless loaded?
|
144
|
-
|
145
143
|
if limit
|
146
144
|
find_nth_with_limit(0, limit)
|
147
145
|
else
|
@@ -390,17 +388,6 @@ module ActiveRecord
|
|
390
388
|
end
|
391
389
|
|
392
390
|
private
|
393
|
-
def check_reorder_deprecation
|
394
|
-
if !order_values.empty? && order_values.all?(&:blank?)
|
395
|
-
blank_value = order_values.first
|
396
|
-
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
397
|
-
`.reorder(#{blank_value.inspect})` with `.first` / `.first!` no longer
|
398
|
-
takes non-deterministic result in Rails 7.0.
|
399
|
-
To continue taking non-deterministic result, use `.take` / `.take!` instead.
|
400
|
-
MSG
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
391
|
def construct_relation_for_exists(conditions)
|
405
392
|
conditions = sanitize_forbidden_attributes(conditions)
|
406
393
|
|
@@ -432,6 +432,7 @@ module ActiveRecord
|
|
432
432
|
references = column_references([column])
|
433
433
|
self.references_values |= references unless references.empty?
|
434
434
|
|
435
|
+
values = values.map { |value| type_caster.type_cast_for_database(column, value) }
|
435
436
|
column = order_column(column.to_s) if column.is_a?(Symbol)
|
436
437
|
|
437
438
|
spawn.order!(connection.field_ordered_value(column, values))
|
@@ -448,14 +449,14 @@ module ActiveRecord
|
|
448
449
|
# generates a query with 'ORDER BY id ASC, name ASC'.
|
449
450
|
def reorder(*args)
|
450
451
|
check_if_method_has_arguments!(__callee__, args) do
|
451
|
-
sanitize_order_arguments(args)
|
452
|
+
sanitize_order_arguments(args)
|
452
453
|
end
|
453
454
|
spawn.reorder!(*args)
|
454
455
|
end
|
455
456
|
|
456
457
|
# Same as #reorder but operates on relation in-place instead of copying.
|
457
458
|
def reorder!(*args) # :nodoc:
|
458
|
-
preprocess_order_args(args)
|
459
|
+
preprocess_order_args(args)
|
459
460
|
args.uniq!
|
460
461
|
self.reordering_value = true
|
461
462
|
self.order_values = args
|
@@ -1339,14 +1340,6 @@ module ActiveRecord
|
|
1339
1340
|
unless annotate_values.empty?
|
1340
1341
|
annotates = annotate_values
|
1341
1342
|
annotates = annotates.uniq if annotates.size > 1
|
1342
|
-
unless annotates == annotate_values
|
1343
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
1344
|
-
Duplicated query annotations are no longer shown in queries in Rails 7.0.
|
1345
|
-
To migrate to Rails 7.0's behavior, use `uniq!(:annotate)` to deduplicate query annotations
|
1346
|
-
(`#{klass.name&.tableize || klass.table_name}.uniq!(:annotate)`).
|
1347
|
-
MSG
|
1348
|
-
annotates = annotate_values
|
1349
|
-
end
|
1350
1343
|
arel.comment(*annotates)
|
1351
1344
|
end
|
1352
1345
|
|
@@ -1606,8 +1599,6 @@ module ActiveRecord
|
|
1606
1599
|
order_args.map! do |arg|
|
1607
1600
|
klass.sanitize_sql_for_order(arg)
|
1608
1601
|
end
|
1609
|
-
order_args.flatten!
|
1610
|
-
order_args.compact_blank!
|
1611
1602
|
end
|
1612
1603
|
|
1613
1604
|
def column_references(order_args)
|
@@ -1676,9 +1667,9 @@ module ActiveRecord
|
|
1676
1667
|
def check_if_method_has_arguments!(method_name, args, message = nil)
|
1677
1668
|
if args.blank?
|
1678
1669
|
raise ArgumentError, message || "The method .#{method_name}() must contain arguments."
|
1679
|
-
elsif block_given?
|
1680
|
-
yield args
|
1681
1670
|
else
|
1671
|
+
yield args if block_given?
|
1672
|
+
|
1682
1673
|
args.flatten!
|
1683
1674
|
args.compact_blank!
|
1684
1675
|
end
|
@@ -31,17 +31,15 @@ module ActiveRecord
|
|
31
31
|
end
|
32
32
|
# :startdoc:
|
33
33
|
|
34
|
-
|
35
|
-
extend
|
34
|
+
module QueryRegistry # :nodoc:
|
35
|
+
extend self
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
def initialize
|
40
|
-
@queries = []
|
37
|
+
def queries
|
38
|
+
ActiveSupport::IsolatedExecutionState[:active_record_query_registry] ||= []
|
41
39
|
end
|
42
40
|
|
43
41
|
def reset
|
44
|
-
|
42
|
+
queries.clear
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -163,21 +163,8 @@ module ActiveRecord
|
|
163
163
|
attr = extract_attribute(node) || begin
|
164
164
|
node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
|
165
165
|
end
|
166
|
-
|
167
|
-
|
168
|
-
ref = referenced_columns[attr]
|
169
|
-
next false unless ref
|
170
|
-
|
171
|
-
if equality_node?(node) && equality_node?(ref) || node == ref
|
172
|
-
true
|
173
|
-
else
|
174
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
175
|
-
Merging (#{node.to_sql}) and (#{ref.to_sql}) no longer maintain
|
176
|
-
both conditions, and will be replaced by the latter in Rails 7.0.
|
177
|
-
To migrate to Rails 7.0's behavior, use `relation.merge(other, rewhere: true)`.
|
178
|
-
MSG
|
179
|
-
false
|
180
|
-
end
|
166
|
+
|
167
|
+
attr && referenced_columns[attr]
|
181
168
|
end
|
182
169
|
end
|
183
170
|
|
@@ -11,7 +11,7 @@ module ActiveRecord
|
|
11
11
|
:reverse_order, :distinct, :create_with, :skip_query_cache]
|
12
12
|
|
13
13
|
CLAUSE_METHODS = [:where, :having, :from]
|
14
|
-
INVALID_METHODS_FOR_DELETE_ALL = [:distinct
|
14
|
+
INVALID_METHODS_FOR_DELETE_ALL = [:distinct]
|
15
15
|
|
16
16
|
VALUE_METHODS = MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS + CLAUSE_METHODS
|
17
17
|
|
@@ -41,11 +41,6 @@ module ActiveRecord
|
|
41
41
|
reset
|
42
42
|
end
|
43
43
|
|
44
|
-
def arel_attribute(name) # :nodoc:
|
45
|
-
table[name]
|
46
|
-
end
|
47
|
-
deprecate :arel_attribute
|
48
|
-
|
49
44
|
def bind_attribute(name, value) # :nodoc:
|
50
45
|
if reflection = klass._reflect_on_association(name)
|
51
46
|
name = reflection.foreign_key
|
@@ -295,14 +290,14 @@ module ActiveRecord
|
|
295
290
|
# Returns true if there is exactly one record.
|
296
291
|
def one?
|
297
292
|
return super if block_given?
|
298
|
-
return records.one? if
|
293
|
+
return records.one? if loaded?
|
299
294
|
limited_count == 1
|
300
295
|
end
|
301
296
|
|
302
297
|
# Returns true if there is more than one record.
|
303
298
|
def many?
|
304
299
|
return super if block_given?
|
305
|
-
return records.many? if
|
300
|
+
return records.many? if loaded?
|
306
301
|
limited_count > 1
|
307
302
|
end
|
308
303
|
|
@@ -394,7 +389,7 @@ module ActiveRecord
|
|
394
389
|
end
|
395
390
|
|
396
391
|
if timestamp
|
397
|
-
"#{size}-#{timestamp.utc.
|
392
|
+
"#{size}-#{timestamp.utc.to_formatted_s(cache_timestamp_format)}"
|
398
393
|
else
|
399
394
|
"#{size}"
|
400
395
|
end
|
@@ -485,8 +480,9 @@ module ActiveRecord
|
|
485
480
|
arel = eager_loading? ? apply_join_dependency.arel : build_arel
|
486
481
|
arel.source.left = table
|
487
482
|
|
488
|
-
|
489
|
-
|
483
|
+
group_values_arel_columns = arel_columns(group_values.uniq)
|
484
|
+
having_clause_ast = having_clause.ast unless having_clause.empty?
|
485
|
+
stmt = arel.compile_update(values, table[primary_key], having_clause_ast, group_values_arel_columns)
|
490
486
|
klass.connection.update(stmt, "#{klass} Update All").tap { reset }
|
491
487
|
end
|
492
488
|
|
@@ -615,7 +611,9 @@ module ActiveRecord
|
|
615
611
|
arel = eager_loading? ? apply_join_dependency.arel : build_arel
|
616
612
|
arel.source.left = table
|
617
613
|
|
618
|
-
|
614
|
+
group_values_arel_columns = arel_columns(group_values.uniq)
|
615
|
+
having_clause_ast = having_clause.ast unless having_clause.empty?
|
616
|
+
stmt = arel.compile_delete(table[primary_key], having_clause_ast, group_values_arel_columns)
|
619
617
|
|
620
618
|
klass.connection.delete(stmt, "#{klass} Delete All").tap { reset }
|
621
619
|
end
|
@@ -976,7 +974,7 @@ module ActiveRecord
|
|
976
974
|
end
|
977
975
|
|
978
976
|
def limited_count
|
979
|
-
@limited_count ||= limit(2).count
|
977
|
+
@limited_count ||= limit_value ? count : limit(2).count
|
980
978
|
end
|
981
979
|
end
|
982
980
|
end
|
data/lib/active_record/result.rb
CHANGED
@@ -1,22 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/per_thread_registry"
|
4
|
-
|
5
3
|
module ActiveRecord
|
6
4
|
# This is a thread locals registry for Active Record. For example:
|
7
5
|
#
|
8
|
-
# ActiveRecord::RuntimeRegistry.
|
9
|
-
#
|
10
|
-
# returns the connection handler local to the current thread.
|
6
|
+
# ActiveRecord::RuntimeRegistry.sql_runtime
|
11
7
|
#
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
extend ActiveSupport::PerThreadRegistry
|
8
|
+
# returns the connection handler local to the current unit of execution (either thread of fiber).
|
9
|
+
module RuntimeRegistry # :nodoc:
|
10
|
+
extend self
|
16
11
|
|
17
|
-
|
12
|
+
def sql_runtime
|
13
|
+
ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime]
|
14
|
+
end
|
18
15
|
|
19
|
-
def
|
20
|
-
|
16
|
+
def sql_runtime=(runtime)
|
17
|
+
ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime] = runtime
|
18
|
+
end
|
21
19
|
end
|
22
20
|
end
|
@@ -47,6 +47,7 @@ module ActiveRecord
|
|
47
47
|
def dump(stream)
|
48
48
|
header(stream)
|
49
49
|
extensions(stream)
|
50
|
+
types(stream)
|
50
51
|
tables(stream)
|
51
52
|
trailer(stream)
|
52
53
|
stream
|
@@ -99,6 +100,10 @@ HEADER
|
|
99
100
|
def extensions(stream)
|
100
101
|
end
|
101
102
|
|
103
|
+
# (enum) types are only supported by PostgreSQL
|
104
|
+
def types(stream)
|
105
|
+
end
|
106
|
+
|
102
107
|
def tables(stream)
|
103
108
|
sorted_tables = @connection.tables.sort
|
104
109
|
|
@@ -154,6 +159,7 @@ HEADER
|
|
154
159
|
columns.each do |column|
|
155
160
|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
|
156
161
|
next if column.name == pk
|
162
|
+
|
157
163
|
type, colspec = column_spec(column)
|
158
164
|
if type.is_a?(Symbol)
|
159
165
|
tbl.print " t.#{type} #{column.name.inspect}"
|
@@ -259,6 +265,7 @@ HEADER
|
|
259
265
|
|
260
266
|
parts << "on_update: #{foreign_key.on_update.inspect}" if foreign_key.on_update
|
261
267
|
parts << "on_delete: #{foreign_key.on_delete.inspect}" if foreign_key.on_delete
|
268
|
+
parts << "deferrable: #{foreign_key.deferrable.inspect}" if foreign_key.deferrable
|
262
269
|
|
263
270
|
" #{parts.join(', ')}"
|
264
271
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
module Scoping
|
@@ -57,8 +57,8 @@ module ActiveRecord
|
|
57
57
|
end
|
58
58
|
|
59
59
|
# This class stores the +:current_scope+ and +:ignore_default_scope+ values
|
60
|
-
# for different classes. The registry is stored as a thread
|
61
|
-
#
|
60
|
+
# for different classes. The registry is stored as either a thread or fiber
|
61
|
+
# local depending on the application configuration.
|
62
62
|
#
|
63
63
|
# This class allows you to store and get the scope values on different
|
64
64
|
# classes and different types of scopes. For example, if you are attempting
|
@@ -66,22 +66,22 @@ module ActiveRecord
|
|
66
66
|
# following code:
|
67
67
|
#
|
68
68
|
# registry = ActiveRecord::Scoping::ScopeRegistry
|
69
|
-
# registry.
|
69
|
+
# registry.set_current_scope(Board, some_new_scope)
|
70
70
|
#
|
71
71
|
# Now when you run:
|
72
72
|
#
|
73
|
-
# registry.
|
73
|
+
# registry.current_scope(Board)
|
74
74
|
#
|
75
|
-
# You will obtain whatever was defined in +some_new_scope+.
|
76
|
-
# and #set_value_for methods are delegated to the current ScopeRegistry
|
77
|
-
# object, so the above example code can also be called as:
|
78
|
-
#
|
79
|
-
# ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
|
80
|
-
# Board, some_new_scope)
|
75
|
+
# You will obtain whatever was defined in +some_new_scope+.
|
81
76
|
class ScopeRegistry # :nodoc:
|
82
|
-
|
77
|
+
class << self
|
78
|
+
delegate :current_scope, :set_current_scope, :ignore_default_scope, :set_ignore_default_scope,
|
79
|
+
:global_current_scope, :set_global_current_scope, to: :instance
|
83
80
|
|
84
|
-
|
81
|
+
def instance
|
82
|
+
ActiveSupport::IsolatedExecutionState[:active_record_scope_registry] ||= new
|
83
|
+
end
|
84
|
+
end
|
85
85
|
|
86
86
|
def initialize
|
87
87
|
@current_scope = {}
|
@@ -89,16 +89,28 @@ module ActiveRecord
|
|
89
89
|
@global_current_scope = {}
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
value_for(@#{type}, model, skip_inherited_scope)
|
96
|
-
end
|
92
|
+
def current_scope(model, skip_inherited_scope = false)
|
93
|
+
value_for(@current_scope, model, skip_inherited_scope)
|
94
|
+
end
|
97
95
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
96
|
+
def set_current_scope(model, value)
|
97
|
+
set_value_for(@current_scope, model, value)
|
98
|
+
end
|
99
|
+
|
100
|
+
def ignore_default_scope(model, skip_inherited_scope = false)
|
101
|
+
value_for(@ignore_default_scope, model, skip_inherited_scope)
|
102
|
+
end
|
103
|
+
|
104
|
+
def set_ignore_default_scope(model, value)
|
105
|
+
set_value_for(@ignore_default_scope, model, value)
|
106
|
+
end
|
107
|
+
|
108
|
+
def global_current_scope(model, skip_inherited_scope = false)
|
109
|
+
value_for(@global_current_scope, model, skip_inherited_scope)
|
110
|
+
end
|
111
|
+
|
112
|
+
def set_global_current_scope(model, value)
|
113
|
+
set_value_for(@global_current_scope, model, value)
|
102
114
|
end
|
103
115
|
|
104
116
|
private
|
@@ -30,32 +30,28 @@ module ActiveRecord
|
|
30
30
|
module Suppressor
|
31
31
|
extend ActiveSupport::Concern
|
32
32
|
|
33
|
+
class << self
|
34
|
+
def registry # :nodoc:
|
35
|
+
ActiveSupport::IsolatedExecutionState[:active_record_suppresor_registry] ||= {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
33
39
|
module ClassMethods
|
34
40
|
def suppress(&block)
|
35
|
-
previous_state =
|
36
|
-
|
41
|
+
previous_state = Suppressor.registry[name]
|
42
|
+
Suppressor.registry[name] = true
|
37
43
|
yield
|
38
44
|
ensure
|
39
|
-
|
45
|
+
Suppressor.registry[name] = previous_state
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
43
49
|
def save(**) # :nodoc:
|
44
|
-
|
50
|
+
Suppressor.registry[self.class.name] ? true : super
|
45
51
|
end
|
46
52
|
|
47
53
|
def save!(**) # :nodoc:
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
class SuppressorRegistry # :nodoc:
|
53
|
-
extend ActiveSupport::PerThreadRegistry
|
54
|
-
|
55
|
-
attr_reader :suppressed
|
56
|
-
|
57
|
-
def initialize
|
58
|
-
@suppressed = {}
|
54
|
+
Suppressor.registry[self.class.name] ? true : super
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -55,8 +55,7 @@ module ActiveRecord
|
|
55
55
|
|
56
56
|
extend self
|
57
57
|
|
58
|
-
attr_writer :
|
59
|
-
deprecate :current_config=
|
58
|
+
attr_writer :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
|
60
59
|
attr_accessor :database_configuration
|
61
60
|
|
62
61
|
LOCAL_HOSTS = ["127.0.0.1", "localhost"]
|
@@ -110,11 +109,6 @@ module ActiveRecord
|
|
110
109
|
@env ||= Rails.env
|
111
110
|
end
|
112
111
|
|
113
|
-
def spec
|
114
|
-
@spec ||= "primary"
|
115
|
-
end
|
116
|
-
deprecate spec: "please use name instead"
|
117
|
-
|
118
112
|
def name
|
119
113
|
@name ||= "primary"
|
120
114
|
end
|
@@ -123,18 +117,6 @@ module ActiveRecord
|
|
123
117
|
@seed_loader ||= Rails.application
|
124
118
|
end
|
125
119
|
|
126
|
-
def current_config(options = {})
|
127
|
-
if options.has_key?(:config)
|
128
|
-
@current_config = options[:config]
|
129
|
-
else
|
130
|
-
env_name = options[:env] || env
|
131
|
-
name = options[:spec] || "primary"
|
132
|
-
|
133
|
-
@current_config ||= configs_for(env_name: env_name, name: name)&.configuration_hash
|
134
|
-
end
|
135
|
-
end
|
136
|
-
deprecate :current_config
|
137
|
-
|
138
120
|
def create(configuration, *arguments)
|
139
121
|
db_config = resolve_configuration(configuration)
|
140
122
|
database_adapter_for(db_config, *arguments).create
|
@@ -216,10 +198,9 @@ module ActiveRecord
|
|
216
198
|
dump_schema(db_config, ActiveRecord.schema_format)
|
217
199
|
end
|
218
200
|
rescue ActiveRecord::NoDatabaseError
|
219
|
-
|
220
|
-
create_current(db_config.env_name, config_name)
|
201
|
+
create_current(db_config.env_name, db_config.name)
|
221
202
|
|
222
|
-
if File.exist?(
|
203
|
+
if File.exist?(schema_dump_path(db_config))
|
223
204
|
load_schema(
|
224
205
|
db_config,
|
225
206
|
ActiveRecord.schema_format,
|
@@ -378,7 +359,7 @@ module ActiveRecord
|
|
378
359
|
end
|
379
360
|
|
380
361
|
def load_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
381
|
-
file ||=
|
362
|
+
file ||= schema_dump_path(db_config, format)
|
382
363
|
|
383
364
|
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
384
365
|
check_schema_file(file)
|
@@ -399,16 +380,10 @@ module ActiveRecord
|
|
399
380
|
Migration.verbose = verbose_was
|
400
381
|
end
|
401
382
|
|
402
|
-
def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil
|
383
|
+
def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil)
|
403
384
|
db_config = resolve_configuration(configuration)
|
404
385
|
|
405
|
-
|
406
|
-
ActiveSupport::Deprecation.warn("`environment` and `name` will be removed as parameters in 7.0.0, you may now pass an ActiveRecord::DatabaseConfigurations::DatabaseConfig as `configuration` instead.")
|
407
|
-
end
|
408
|
-
|
409
|
-
name ||= db_config.name
|
410
|
-
|
411
|
-
file ||= dump_filename(name, format)
|
386
|
+
file ||= schema_dump_path(db_config)
|
412
387
|
|
413
388
|
return true unless File.exist?(file)
|
414
389
|
|
@@ -421,7 +396,7 @@ module ActiveRecord
|
|
421
396
|
end
|
422
397
|
|
423
398
|
def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
424
|
-
file ||=
|
399
|
+
file ||= schema_dump_path(db_config, format)
|
425
400
|
|
426
401
|
check_schema_file(file)
|
427
402
|
|
@@ -440,7 +415,7 @@ module ActiveRecord
|
|
440
415
|
|
441
416
|
def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
|
442
417
|
require "active_record/schema_dumper"
|
443
|
-
filename =
|
418
|
+
filename = schema_dump_path(db_config, format)
|
444
419
|
connection = ActiveRecord::Base.connection
|
445
420
|
|
446
421
|
FileUtils.mkdir_p(db_dir)
|
@@ -460,11 +435,6 @@ module ActiveRecord
|
|
460
435
|
end
|
461
436
|
end
|
462
437
|
|
463
|
-
def schema_file(format = ActiveRecord.schema_format)
|
464
|
-
File.join(db_dir, schema_file_type(format))
|
465
|
-
end
|
466
|
-
deprecate :schema_file
|
467
|
-
|
468
438
|
def schema_file_type(format = ActiveRecord.schema_format)
|
469
439
|
case format
|
470
440
|
when :ruby
|
@@ -473,15 +443,19 @@ module ActiveRecord
|
|
473
443
|
"structure.sql"
|
474
444
|
end
|
475
445
|
end
|
446
|
+
deprecate :schema_file_type
|
476
447
|
|
477
|
-
def
|
478
|
-
|
479
|
-
|
448
|
+
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
|
449
|
+
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
450
|
+
|
451
|
+
filename = db_config.schema_dump(format)
|
452
|
+
return unless filename
|
453
|
+
|
454
|
+
if File.dirname(filename) == ActiveRecord::Tasks::DatabaseTasks.db_dir
|
455
|
+
filename
|
480
456
|
else
|
481
|
-
|
457
|
+
File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
482
458
|
end
|
483
|
-
|
484
|
-
ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
485
459
|
end
|
486
460
|
|
487
461
|
def cache_dump_filename(db_config_name, schema_cache_path: nil)
|
@@ -57,8 +57,12 @@ module ActiveRecord
|
|
57
57
|
ActiveRecord.dump_schemas
|
58
58
|
end
|
59
59
|
|
60
|
-
args = ["--schema-only", "--no-privileges", "--no-owner"
|
60
|
+
args = ["--schema-only", "--no-privileges", "--no-owner"]
|
61
|
+
args << "--no-comment" if connection.database_version >= 110_000
|
62
|
+
args.concat(["--file", filename])
|
63
|
+
|
61
64
|
args.concat(Array(extra_flags)) if extra_flags
|
65
|
+
|
62
66
|
unless search_path.blank?
|
63
67
|
args += search_path.split(",").map do |part|
|
64
68
|
"--schema=#{part.strip}"
|