activerecord 7.1.0.beta1 → 7.1.0.rc2
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 +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:
|