activerecord 7.1.0.beta1 → 7.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +85 -4
- data/lib/active_record/associations/collection_association.rb +1 -3
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations.rb +110 -110
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +20 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
- data/lib/active_record/connection_adapters/pool_manager.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +0 -16
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -5
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -8
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +25 -29
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -6
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +4 -4
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +49 -4
- data/lib/active_record/core.rb +7 -9
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +1 -1
- data/lib/active_record/errors.rb +19 -0
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +8 -8
- data/lib/active_record/nested_attributes.rb +0 -5
- data/lib/active_record/normalization.rb +2 -1
- data/lib/active_record/persistence.rb +1 -1
- data/lib/active_record/querying.rb +2 -2
- data/lib/active_record/railtie.rb +1 -1
- data/lib/active_record/reflection.rb +10 -16
- data/lib/active_record/relation/calculations.rb +8 -8
- data/lib/active_record/relation/finder_methods.rb +3 -12
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
- data/lib/active_record/schema_dumper.rb +9 -4
- data/lib/active_record/tasks/sqlite_database_tasks.rb +1 -0
- metadata +9 -9
@@ -126,6 +126,7 @@ module ActiveRecord
|
|
126
126
|
|
127
127
|
@config[:strict] = ConnectionAdapters::SQLite3Adapter.strict_strings_by_default unless @config.key?(:strict)
|
128
128
|
@connection_parameters = @config.merge(database: @config[:database].to_s, results_as_hash: true)
|
129
|
+
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
129
130
|
end
|
130
131
|
|
131
132
|
def database_exists?
|
@@ -180,6 +181,10 @@ module ActiveRecord
|
|
180
181
|
database_version >= "3.8.3"
|
181
182
|
end
|
182
183
|
|
184
|
+
def supports_insert_returning?
|
185
|
+
database_version >= "3.35.0"
|
186
|
+
end
|
187
|
+
|
183
188
|
def supports_insert_on_conflict?
|
184
189
|
database_version >= "3.24.0"
|
185
190
|
end
|
@@ -195,6 +200,10 @@ module ActiveRecord
|
|
195
200
|
@raw_connection && !@raw_connection.closed?
|
196
201
|
end
|
197
202
|
|
203
|
+
def return_value_after_insert?(column) # :nodoc:
|
204
|
+
column.auto_populated?
|
205
|
+
end
|
206
|
+
|
198
207
|
alias :reset! :reconnect!
|
199
208
|
|
200
209
|
# Disconnects from the database if already connected. Otherwise, this
|
@@ -393,6 +402,7 @@ module ActiveRecord
|
|
393
402
|
end
|
394
403
|
end
|
395
404
|
|
405
|
+
sql << " RETURNING #{insert.returning}" if insert.returning
|
396
406
|
sql
|
397
407
|
end
|
398
408
|
|
@@ -400,6 +410,10 @@ module ActiveRecord
|
|
400
410
|
@config.fetch(:flags, 0).anybits?(::SQLite3::Constants::Open::SHAREDCACHE)
|
401
411
|
end
|
402
412
|
|
413
|
+
def use_insert_returning?
|
414
|
+
@use_insert_returning
|
415
|
+
end
|
416
|
+
|
403
417
|
def get_database_version # :nodoc:
|
404
418
|
SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)", "SCHEMA"))
|
405
419
|
end
|
@@ -451,10 +465,10 @@ module ActiveRecord
|
|
451
465
|
when /^null$/i
|
452
466
|
nil
|
453
467
|
# Quoted types
|
454
|
-
when /^'(
|
468
|
+
when /^'([^|]*)'$/m
|
455
469
|
$1.gsub("''", "'")
|
456
470
|
# Quoted types
|
457
|
-
when /^"(
|
471
|
+
when /^"([^|]*)"$/m
|
458
472
|
$1.gsub('""', '"')
|
459
473
|
# Numeric types
|
460
474
|
when /\A-?\d+(\.\d*)?\z/
|
@@ -474,7 +488,7 @@ module ActiveRecord
|
|
474
488
|
end
|
475
489
|
|
476
490
|
def has_default_function?(default_value, default)
|
477
|
-
!default_value && %r{\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
|
491
|
+
!default_value && %r{\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP|\|\|}.match?(default)
|
478
492
|
end
|
479
493
|
|
480
494
|
# See: https://www.sqlite.org/lang_altertable.html
|
@@ -698,9 +712,40 @@ module ActiveRecord
|
|
698
712
|
end
|
699
713
|
|
700
714
|
def configure_connection
|
701
|
-
@
|
715
|
+
if @config[:timeout] && @config[:retries]
|
716
|
+
raise ArgumentError, "Cannot specify both timeout and retries arguments"
|
717
|
+
elsif @config[:timeout]
|
718
|
+
@raw_connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout]))
|
719
|
+
elsif @config[:retries]
|
720
|
+
retries = self.class.type_cast_config_to_integer(@config[:retries])
|
721
|
+
raw_connection.busy_handler do |count|
|
722
|
+
count <= retries
|
723
|
+
end
|
724
|
+
end
|
702
725
|
|
726
|
+
# Enforce foreign key constraints
|
727
|
+
# https://www.sqlite.org/pragma.html#pragma_foreign_keys
|
728
|
+
# https://www.sqlite.org/foreignkeys.html
|
703
729
|
raw_execute("PRAGMA foreign_keys = ON", "SCHEMA")
|
730
|
+
unless @memory_database
|
731
|
+
# Journal mode WAL allows for greater concurrency (many readers + one writer)
|
732
|
+
# https://www.sqlite.org/pragma.html#pragma_journal_mode
|
733
|
+
raw_execute("PRAGMA journal_mode = WAL", "SCHEMA")
|
734
|
+
# Set more relaxed level of database durability
|
735
|
+
# 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
|
736
|
+
# https://www.sqlite.org/pragma.html#pragma_synchronous
|
737
|
+
raw_execute("PRAGMA synchronous = NORMAL", "SCHEMA")
|
738
|
+
# Set the global memory map so all processes can share some data
|
739
|
+
# https://www.sqlite.org/pragma.html#pragma_mmap_size
|
740
|
+
# https://www.sqlite.org/mmap.html
|
741
|
+
raw_execute("PRAGMA mmap_size = #{128.megabytes}", "SCHEMA")
|
742
|
+
end
|
743
|
+
# Impose a limit on the WAL file to prevent unlimited growth
|
744
|
+
# https://www.sqlite.org/pragma.html#pragma_journal_size_limit
|
745
|
+
raw_execute("PRAGMA journal_size_limit = #{64.megabytes}", "SCHEMA")
|
746
|
+
# Set the local connection cache to 2000 pages
|
747
|
+
# https://www.sqlite.org/pragma.html#pragma_cache_size
|
748
|
+
raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
|
704
749
|
end
|
705
750
|
end
|
706
751
|
ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
|
data/lib/active_record/core.rb
CHANGED
@@ -344,11 +344,6 @@ module ActiveRecord
|
|
344
344
|
end
|
345
345
|
end
|
346
346
|
|
347
|
-
# Override the default class equality method to provide support for decorated models.
|
348
|
-
def ===(object) # :nodoc:
|
349
|
-
object.is_a?(self)
|
350
|
-
end
|
351
|
-
|
352
347
|
# Returns an instance of +Arel::Table+ loaded with the current table name.
|
353
348
|
def arel_table # :nodoc:
|
354
349
|
@arel_table ||= Arel::Table.new(table_name, klass: self)
|
@@ -615,7 +610,9 @@ module ActiveRecord
|
|
615
610
|
#
|
616
611
|
# user = User.first
|
617
612
|
# user.strict_loading! # => true
|
618
|
-
# user.
|
613
|
+
# user.address.city
|
614
|
+
# => ActiveRecord::StrictLoadingViolationError
|
615
|
+
# user.comments.to_a
|
619
616
|
# => ActiveRecord::StrictLoadingViolationError
|
620
617
|
#
|
621
618
|
# ==== Parameters
|
@@ -629,12 +626,13 @@ module ActiveRecord
|
|
629
626
|
#
|
630
627
|
# user = User.first
|
631
628
|
# user.strict_loading!(false) # => false
|
632
|
-
# user.
|
633
|
-
# => #<
|
629
|
+
# user.address.city # => "Tatooine"
|
630
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
634
631
|
#
|
635
632
|
# user.strict_loading!(mode: :n_plus_one_only)
|
636
633
|
# user.address.city # => "Tatooine"
|
637
|
-
# user.comments
|
634
|
+
# user.comments.to_a # => [#<Comment:0x00...]
|
635
|
+
# user.comments.first.ratings.to_a
|
638
636
|
# => ActiveRecord::StrictLoadingViolationError
|
639
637
|
def strict_loading!(value = true, mode: :all)
|
640
638
|
unless [:all, :n_plus_one_only].include?(mode)
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
14
14
|
klass = record.class
|
15
15
|
if klass.deterministic_encrypted_attributes&.include?(attribute)
|
16
16
|
encrypted_type = klass.type_for_attribute(attribute)
|
17
|
-
|
17
|
+
encrypted_type.previous_types.each do |type|
|
18
18
|
encrypted_value = type.serialize(value)
|
19
19
|
ActiveRecord::Encryption.without_encryption do
|
20
20
|
super(record, attribute, encrypted_value)
|
data/lib/active_record/errors.rb
CHANGED
@@ -483,6 +483,19 @@ module ActiveRecord
|
|
483
483
|
# TransactionRollbackError will be raised when a transaction is rolled
|
484
484
|
# back by the database due to a serialization failure or a deadlock.
|
485
485
|
#
|
486
|
+
# These exceptions should not be generally rescued in nested transaction
|
487
|
+
# blocks, because they have side-effects in the actual enclosing transaction
|
488
|
+
# and internal Active Record state. They can be rescued if you are above the
|
489
|
+
# root transaction block, though.
|
490
|
+
#
|
491
|
+
# In that case, beware of transactional tests, however, because they run test
|
492
|
+
# cases in their own umbrella transaction. If you absolutely need to handle
|
493
|
+
# these exceptions in tests please consider disabling transactional tests in
|
494
|
+
# the affected test class (<tt>self.use_transactional_tests = false</tt>).
|
495
|
+
#
|
496
|
+
# Due to the aforementioned side-effects, this exception should not be raised
|
497
|
+
# manually by users.
|
498
|
+
#
|
486
499
|
# See the following:
|
487
500
|
#
|
488
501
|
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
@@ -497,11 +510,17 @@ module ActiveRecord
|
|
497
510
|
|
498
511
|
# SerializationFailure will be raised when a transaction is rolled
|
499
512
|
# back by the database due to a serialization failure.
|
513
|
+
#
|
514
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
515
|
+
# its documentation to be aware of its caveats.
|
500
516
|
class SerializationFailure < TransactionRollbackError
|
501
517
|
end
|
502
518
|
|
503
519
|
# Deadlocked will be raised when a transaction is rolled
|
504
520
|
# back by the database when a deadlock is encountered.
|
521
|
+
#
|
522
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
523
|
+
# its documentation to be aware of its caveats.
|
505
524
|
class Deadlocked < TransactionRollbackError
|
506
525
|
end
|
507
526
|
|
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
# * add_foreign_key
|
13
13
|
# * add_check_constraint
|
14
14
|
# * add_exclusion_constraint
|
15
|
-
# *
|
15
|
+
# * add_unique_constraint
|
16
16
|
# * add_index
|
17
17
|
# * add_reference
|
18
18
|
# * add_timestamps
|
@@ -33,7 +33,7 @@ module ActiveRecord
|
|
33
33
|
# * remove_foreign_key (must supply a second table)
|
34
34
|
# * remove_check_constraint
|
35
35
|
# * remove_exclusion_constraint
|
36
|
-
# *
|
36
|
+
# * remove_unique_constraint
|
37
37
|
# * remove_index
|
38
38
|
# * remove_reference
|
39
39
|
# * remove_timestamps
|
@@ -53,7 +53,7 @@ module ActiveRecord
|
|
53
53
|
:change_column_comment, :change_table_comment,
|
54
54
|
:add_check_constraint, :remove_check_constraint,
|
55
55
|
:add_exclusion_constraint, :remove_exclusion_constraint,
|
56
|
-
:
|
56
|
+
:add_unique_constraint, :remove_unique_constraint,
|
57
57
|
:create_enum, :drop_enum, :rename_enum, :add_enum_value, :rename_enum_value,
|
58
58
|
]
|
59
59
|
include JoinTable
|
@@ -161,7 +161,7 @@ module ActiveRecord
|
|
161
161
|
add_foreign_key: :remove_foreign_key,
|
162
162
|
add_check_constraint: :remove_check_constraint,
|
163
163
|
add_exclusion_constraint: :remove_exclusion_constraint,
|
164
|
-
|
164
|
+
add_unique_constraint: :remove_unique_constraint,
|
165
165
|
enable_extension: :disable_extension,
|
166
166
|
create_enum: :drop_enum
|
167
167
|
}.each do |cmd, inv|
|
@@ -329,17 +329,17 @@ module ActiveRecord
|
|
329
329
|
super
|
330
330
|
end
|
331
331
|
|
332
|
-
def
|
332
|
+
def invert_add_unique_constraint(args)
|
333
333
|
options = args.dup.extract_options!
|
334
334
|
|
335
|
-
raise ActiveRecord::IrreversibleMigration, "
|
335
|
+
raise ActiveRecord::IrreversibleMigration, "add_unique_constraint is not reversible if given an using_index." if options[:using_index]
|
336
336
|
super
|
337
337
|
end
|
338
338
|
|
339
|
-
def
|
339
|
+
def invert_remove_unique_constraint(args)
|
340
340
|
_table, columns = args.dup.tap(&:extract_options!)
|
341
341
|
|
342
|
-
raise ActiveRecord::IrreversibleMigration, "
|
342
|
+
raise ActiveRecord::IrreversibleMigration, "remove_unique_constraint is only reversible if given an column_name." if columns.blank?
|
343
343
|
super
|
344
344
|
end
|
345
345
|
|
@@ -355,17 +355,12 @@ module ActiveRecord
|
|
355
355
|
options.update(attr_names.extract_options!)
|
356
356
|
options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
|
357
357
|
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
358
|
-
options[:class] = self
|
359
358
|
|
360
359
|
attr_names.each do |association_name|
|
361
360
|
if reflection = _reflect_on_association(association_name)
|
362
361
|
reflection.autosave = true
|
363
362
|
define_autosave_validation_callbacks(reflection)
|
364
363
|
|
365
|
-
if nested_attributes_options.dig(association_name.to_sym, :class) == self
|
366
|
-
raise ArgumentError, "Already declared #{association_name} as an accepts_nested_attributes association for this class."
|
367
|
-
end
|
368
|
-
|
369
364
|
nested_attributes_options = self.nested_attributes_options.dup
|
370
365
|
nested_attributes_options[association_name.to_sym] = options
|
371
366
|
self.nested_attributes_options = nested_attributes_options
|
@@ -51,7 +51,8 @@ module ActiveRecord # :nodoc:
|
|
51
51
|
#
|
52
52
|
# ==== Options
|
53
53
|
#
|
54
|
-
# * +:with+ -
|
54
|
+
# * +:with+ - Any callable object that accepts the attribute's value as
|
55
|
+
# its sole argument, and returns it normalized.
|
55
56
|
# * +:apply_to_nil+ - Whether to apply the normalization to +nil+ values.
|
56
57
|
# Defaults to +false+.
|
57
58
|
#
|
@@ -1272,7 +1272,7 @@ module ActiveRecord
|
|
1272
1272
|
def _raise_record_not_destroyed
|
1273
1273
|
@_association_destroy_exception ||= nil
|
1274
1274
|
key = self.class.primary_key
|
1275
|
-
raise @_association_destroy_exception || RecordNotDestroyed.new("Failed to destroy #{self.class} with #{key}=#{
|
1275
|
+
raise @_association_destroy_exception || RecordNotDestroyed.new("Failed to destroy #{self.class} with #{key}=#{id}", self)
|
1276
1276
|
ensure
|
1277
1277
|
@_association_destroy_exception = nil
|
1278
1278
|
end
|
@@ -51,7 +51,7 @@ module ActiveRecord
|
|
51
51
|
_load_from_sql(_query_by_sql(sql, binds, preparable: preparable), &block)
|
52
52
|
end
|
53
53
|
|
54
|
-
# Same as <tt>#find_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
54
|
+
# Same as <tt>#find_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
55
55
|
def async_find_by_sql(sql, binds = [], preparable: nil, &block)
|
56
56
|
_query_by_sql(sql, binds, preparable: preparable, async: true).then do |result|
|
57
57
|
_load_from_sql(result, &block)
|
@@ -102,7 +102,7 @@ module ActiveRecord
|
|
102
102
|
connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
|
103
103
|
end
|
104
104
|
|
105
|
-
# Same as <tt>#count_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
105
|
+
# Same as <tt>#count_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
106
106
|
def async_count_by_sql(sql)
|
107
107
|
connection.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
|
108
108
|
end
|
@@ -67,7 +67,7 @@ module ActiveRecord
|
|
67
67
|
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
|
68
68
|
console = ActiveSupport::Logger.new(STDERR)
|
69
69
|
console.level = Rails.logger.level
|
70
|
-
Rails.logger.
|
70
|
+
Rails.logger.broadcast_to(console)
|
71
71
|
end
|
72
72
|
ActiveRecord.verbose_query_logs = false
|
73
73
|
end
|
@@ -507,7 +507,7 @@ module ActiveRecord
|
|
507
507
|
derived_fk = derive_foreign_key(infer_from_inverse_of: infer_from_inverse_of)
|
508
508
|
|
509
509
|
if active_record.has_query_constraints?
|
510
|
-
derived_fk = derive_fk_query_constraints(
|
510
|
+
derived_fk = derive_fk_query_constraints(derived_fk)
|
511
511
|
end
|
512
512
|
|
513
513
|
derived_fk
|
@@ -770,13 +770,13 @@ module ActiveRecord
|
|
770
770
|
end
|
771
771
|
end
|
772
772
|
|
773
|
-
def derive_fk_query_constraints(
|
774
|
-
primary_query_constraints =
|
775
|
-
owner_pk =
|
773
|
+
def derive_fk_query_constraints(foreign_key)
|
774
|
+
primary_query_constraints = active_record.query_constraints_list
|
775
|
+
owner_pk = active_record.primary_key
|
776
776
|
|
777
777
|
if primary_query_constraints.size != 2
|
778
778
|
raise ArgumentError, <<~MSG.squish
|
779
|
-
The query constraints list on the `#{
|
779
|
+
The query constraints list on the `#{active_record}` model has more than 2
|
780
780
|
attributes. Active Record is unable to derive the query constraints
|
781
781
|
for the association. You need to explicitly define the query constraints
|
782
782
|
for this association.
|
@@ -785,19 +785,13 @@ module ActiveRecord
|
|
785
785
|
|
786
786
|
if !primary_query_constraints.include?(owner_pk)
|
787
787
|
raise ArgumentError, <<~MSG.squish
|
788
|
-
The query constraints on the `#{
|
788
|
+
The query constraints on the `#{active_record}` model does not include the primary
|
789
789
|
key so Active Record is unable to derive the foreign key constraints for
|
790
790
|
the association. You need to explicitly define the query constraints for this
|
791
791
|
association.
|
792
792
|
MSG
|
793
793
|
end
|
794
794
|
|
795
|
-
# The primary key and foreign key are both already in the query constraints
|
796
|
-
# so we don't want to derive the key. In this case we want a single key.
|
797
|
-
if primary_query_constraints.include?(owner_pk) && primary_query_constraints.include?(foreign_key)
|
798
|
-
return foreign_key
|
799
|
-
end
|
800
|
-
|
801
795
|
first_key, last_key = primary_query_constraints
|
802
796
|
|
803
797
|
if first_key == owner_pk
|
@@ -807,7 +801,7 @@ module ActiveRecord
|
|
807
801
|
else
|
808
802
|
raise ArgumentError, <<~MSG.squish
|
809
803
|
Active Record couldn't correctly interpret the query constraints
|
810
|
-
for the `#{
|
804
|
+
for the `#{active_record}` model. The query constraints on `#{active_record}` are
|
811
805
|
`#{primary_query_constraints}` and the foreign key is `#{foreign_key}`.
|
812
806
|
You need to explicitly set the query constraints for this association.
|
813
807
|
MSG
|
@@ -862,10 +856,10 @@ module ActiveRecord
|
|
862
856
|
|
863
857
|
# klass option is necessary to support loading polymorphic associations
|
864
858
|
def association_primary_key(klass = nil)
|
865
|
-
if
|
866
|
-
(klass || self.klass).composite_query_constraints_list
|
867
|
-
elsif primary_key = options[:primary_key]
|
859
|
+
if primary_key = options[:primary_key]
|
868
860
|
@association_primary_key ||= -primary_key.to_s
|
861
|
+
elsif !polymorphic? && ((klass || self.klass).has_query_constraints? || options[:query_constraints])
|
862
|
+
(klass || self.klass).composite_query_constraints_list
|
869
863
|
elsif (klass || self.klass).composite_primary_key?
|
870
864
|
# If klass has composite primary key of shape [:<tenant_key>, :id], infer primary_key as :id
|
871
865
|
primary_key = (klass || self.klass).primary_key
|
@@ -93,7 +93,7 @@ module ActiveRecord
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
# Same as <tt>#count</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
96
|
+
# Same as <tt>#count</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
97
97
|
def async_count(column_name = nil)
|
98
98
|
async.count(column_name)
|
99
99
|
end
|
@@ -106,7 +106,7 @@ module ActiveRecord
|
|
106
106
|
calculate(:average, column_name)
|
107
107
|
end
|
108
108
|
|
109
|
-
# Same as <tt>#average</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
109
|
+
# Same as <tt>#average</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
110
110
|
def async_average(column_name)
|
111
111
|
async.average(column_name)
|
112
112
|
end
|
@@ -120,7 +120,7 @@ module ActiveRecord
|
|
120
120
|
calculate(:minimum, column_name)
|
121
121
|
end
|
122
122
|
|
123
|
-
# Same as <tt>#minimum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
123
|
+
# Same as <tt>#minimum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
124
124
|
def async_minimum(column_name)
|
125
125
|
async.minimum(column_name)
|
126
126
|
end
|
@@ -134,7 +134,7 @@ module ActiveRecord
|
|
134
134
|
calculate(:maximum, column_name)
|
135
135
|
end
|
136
136
|
|
137
|
-
# Same as <tt>#maximum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
137
|
+
# Same as <tt>#maximum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
138
138
|
def async_maximum(column_name)
|
139
139
|
async.maximum(column_name)
|
140
140
|
end
|
@@ -152,7 +152,7 @@ module ActiveRecord
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
-
# Same as <tt>#sum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
155
|
+
# Same as <tt>#sum</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
156
156
|
def async_sum(identity_or_column = nil)
|
157
157
|
async.sum(identity_or_column)
|
158
158
|
end
|
@@ -287,7 +287,7 @@ module ActiveRecord
|
|
287
287
|
end
|
288
288
|
end
|
289
289
|
|
290
|
-
# Same as <tt>#pluck</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
290
|
+
# Same as <tt>#pluck</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
291
291
|
def async_pluck(*column_names)
|
292
292
|
async.pluck(*column_names)
|
293
293
|
end
|
@@ -315,7 +315,7 @@ module ActiveRecord
|
|
315
315
|
limit(1).pluck(*column_names).then(&:first)
|
316
316
|
end
|
317
317
|
|
318
|
-
# Same as <tt>#pick</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
318
|
+
# Same as <tt>#pick</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
319
319
|
def async_pick(*column_names)
|
320
320
|
async.pick(*column_names)
|
321
321
|
end
|
@@ -358,7 +358,7 @@ module ActiveRecord
|
|
358
358
|
result.then { |result| type_cast_pluck_values(result, columns) }
|
359
359
|
end
|
360
360
|
|
361
|
-
# Same as <tt>#ids</tt> but perform the query asynchronously and returns an ActiveRecord::Promise
|
361
|
+
# Same as <tt>#ids</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
|
362
362
|
def async_ids
|
363
363
|
async.ids
|
364
364
|
end
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
# Person.find("1") # returns the object for ID = 1
|
17
17
|
# Person.find("31-sarah") # returns the object for ID = 31
|
18
18
|
# Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
|
19
|
-
# Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
|
19
|
+
# Person.find([7, 17]) # returns an array for objects with IDs in (7, 17), or with composite primary key [7, 17]
|
20
20
|
# Person.find([1]) # returns an array for the object with ID = 1
|
21
21
|
# Person.where("administrator = 1").order("created_on DESC").find(1)
|
22
22
|
#
|
@@ -527,12 +527,7 @@ module ActiveRecord
|
|
527
527
|
def find_some(ids)
|
528
528
|
return find_some_ordered(ids) unless order_values.present?
|
529
529
|
|
530
|
-
relation =
|
531
|
-
ids.map { |values_set| where(primary_key.zip(values_set).to_h) }.inject(&:or)
|
532
|
-
else
|
533
|
-
where(primary_key => ids)
|
534
|
-
end
|
535
|
-
|
530
|
+
relation = where(primary_key => ids)
|
536
531
|
relation = relation.select(table[primary_key]) unless select_values.empty?
|
537
532
|
result = relation.to_a
|
538
533
|
|
@@ -559,11 +554,7 @@ module ActiveRecord
|
|
559
554
|
ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
|
560
555
|
|
561
556
|
relation = except(:limit, :offset)
|
562
|
-
relation =
|
563
|
-
ids.map { |values_set| relation.where(primary_key.zip(values_set).to_h) }.inject(&:or)
|
564
|
-
else
|
565
|
-
relation.where(primary_key => ids)
|
566
|
-
end
|
557
|
+
relation = relation.where(primary_key => ids)
|
567
558
|
relation = relation.select(table[primary_key]) unless select_values.empty?
|
568
559
|
result = relation.records
|
569
560
|
|
@@ -34,19 +34,17 @@ module ActiveRecord
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def klass(value)
|
37
|
-
|
38
|
-
when Base
|
37
|
+
if value.is_a?(Base)
|
39
38
|
value.class
|
40
|
-
|
39
|
+
elsif value.is_a?(Relation)
|
41
40
|
value.klass
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
44
|
def convert_to_id(value)
|
46
|
-
|
47
|
-
when Base
|
45
|
+
if value.is_a?(Base)
|
48
46
|
value._read_attribute(primary_key(value))
|
49
|
-
|
47
|
+
elsif value.is_a?(Relation)
|
50
48
|
value.select(primary_key(value))
|
51
49
|
else
|
52
50
|
value
|
@@ -57,6 +57,7 @@ module ActiveRecord
|
|
57
57
|
|
58
58
|
def dump(stream)
|
59
59
|
header(stream)
|
60
|
+
schemas(stream)
|
60
61
|
extensions(stream)
|
61
62
|
types(stream)
|
62
63
|
tables(stream)
|
@@ -119,6 +120,10 @@ module ActiveRecord
|
|
119
120
|
def types(stream)
|
120
121
|
end
|
121
122
|
|
123
|
+
# schemas are only supported by PostgreSQL
|
124
|
+
def schemas(stream)
|
125
|
+
end
|
126
|
+
|
122
127
|
def tables(stream)
|
123
128
|
sorted_tables = @connection.tables.sort
|
124
129
|
|
@@ -188,7 +193,7 @@ module ActiveRecord
|
|
188
193
|
indexes_in_create(table, tbl)
|
189
194
|
check_constraints_in_create(table, tbl) if @connection.supports_check_constraints?
|
190
195
|
exclusion_constraints_in_create(table, tbl) if @connection.supports_exclusion_constraints?
|
191
|
-
|
196
|
+
unique_constraints_in_create(table, tbl) if @connection.supports_unique_constraints?
|
192
197
|
|
193
198
|
tbl.puts " end"
|
194
199
|
tbl.puts
|
@@ -224,10 +229,10 @@ module ActiveRecord
|
|
224
229
|
indexes = indexes.reject { |index| exclusion_constraint_names.include?(index.name) }
|
225
230
|
end
|
226
231
|
|
227
|
-
if @connection.
|
228
|
-
|
232
|
+
if @connection.supports_unique_constraints? && (unique_constraints = @connection.unique_constraints(table)).any?
|
233
|
+
unique_constraint_names = unique_constraints.collect(&:name)
|
229
234
|
|
230
|
-
indexes = indexes.reject { |index|
|
235
|
+
indexes = indexes.reject { |index| unique_constraint_names.include?(index.name) }
|
231
236
|
end
|
232
237
|
|
233
238
|
index_statements = indexes.map do |index|
|
@@ -23,6 +23,7 @@ module ActiveRecord
|
|
23
23
|
db_path = db_config.database
|
24
24
|
file = File.absolute_path?(db_path) ? db_path : File.join(root, db_path)
|
25
25
|
FileUtils.rm(file)
|
26
|
+
FileUtils.rm_f(["#{file}-shm", "#{file}-wal"])
|
26
27
|
rescue Errno::ENOENT => error
|
27
28
|
raise NoDatabaseError.new(error.message)
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.1.0.
|
4
|
+
version: 7.1.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.1.0.
|
19
|
+
version: 7.1.0.rc2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.1.0.
|
26
|
+
version: 7.1.0.rc2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 7.1.0.
|
33
|
+
version: 7.1.0.rc2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 7.1.0.
|
40
|
+
version: 7.1.0.rc2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: timeout
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -469,10 +469,10 @@ licenses:
|
|
469
469
|
- MIT
|
470
470
|
metadata:
|
471
471
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
472
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.1.0.
|
473
|
-
documentation_uri: https://api.rubyonrails.org/v7.1.0.
|
472
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.1.0.rc2/activerecord/CHANGELOG.md
|
473
|
+
documentation_uri: https://api.rubyonrails.org/v7.1.0.rc2/
|
474
474
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
475
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.1.0.
|
475
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.1.0.rc2/activerecord
|
476
476
|
rubygems_mfa_required: 'true'
|
477
477
|
post_install_message:
|
478
478
|
rdoc_options:
|