activerecord 7.2.3 → 8.0.4
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 +391 -958
- data/README.rdoc +1 -1
- data/lib/active_record/association_relation.rb +1 -0
- data/lib/active_record/associations/association.rb +34 -10
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/collection_association.rb +1 -1
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +3 -2
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +8 -3
- data/lib/active_record/associations.rb +34 -4
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_methods/primary_key.rb +4 -8
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +34 -25
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +6 -15
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +34 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +21 -40
- data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +50 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +84 -94
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -43
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +6 -12
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +59 -16
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +46 -96
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +80 -100
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +9 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +53 -12
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/connection_handling.rb +23 -1
- data/lib/active_record/core.rb +29 -14
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/database_configurations/hash_config.rb +16 -2
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +4 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
- data/lib/active_record/encryption/encryptor.rb +16 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/enum.rb +9 -22
- data/lib/active_record/errors.rb +13 -5
- data/lib/active_record/fixtures.rb +0 -2
- data/lib/active_record/future_result.rb +13 -9
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/insert_all.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/migration/command_recorder.rb +31 -11
- data/lib/active_record/migration/compatibility.rb +5 -2
- data/lib/active_record/migration.rb +38 -42
- data/lib/active_record/model_schema.rb +3 -4
- data/lib/active_record/nested_attributes.rb +4 -6
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_logs.rb +102 -50
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +8 -8
- data/lib/active_record/railtie.rb +2 -26
- data/lib/active_record/railties/databases.rake +11 -35
- data/lib/active_record/reflection.rb +18 -21
- data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
- data/lib/active_record/relation/batches.rb +132 -72
- data/lib/active_record/relation/calculations.rb +40 -39
- data/lib/active_record/relation/delegation.rb +25 -14
- data/lib/active_record/relation/finder_methods.rb +18 -18
- data/lib/active_record/relation/merger.rb +8 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +13 -0
- data/lib/active_record/relation/query_methods.rb +105 -61
- data/lib/active_record/relation/spawn_methods.rb +7 -7
- data/lib/active_record/relation.rb +79 -61
- data/lib/active_record/result.rb +66 -4
- data/lib/active_record/sanitization.rb +7 -6
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/statement_cache.rb +14 -14
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +69 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +2 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +12 -0
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/transactions.rb +5 -6
- data/lib/active_record/validations/uniqueness.rb +8 -8
- data/lib/active_record.rb +21 -48
- data/lib/arel/collectors/bind.rb +2 -2
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +2 -2
- data/lib/arel/nodes/binary.rb +1 -1
- data/lib/arel/nodes/node.rb +1 -1
- data/lib/arel/nodes/sql_literal.rb +1 -1
- data/lib/arel/table.rb +3 -7
- metadata +9 -10
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
data/lib/active_record/store.rb
CHANGED
|
@@ -25,8 +25,8 @@ module ActiveRecord
|
|
|
25
25
|
# You can set custom coder to encode/decode your serialized attributes to/from different formats.
|
|
26
26
|
# JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+.
|
|
27
27
|
#
|
|
28
|
-
# NOTE: If you are using structured database data types (e.g. PostgreSQL +hstore+/+json+,
|
|
29
|
-
# +json+) there is no need for the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store].
|
|
28
|
+
# NOTE: If you are using structured database data types (e.g. PostgreSQL +hstore+/+json+, MySQL 5.7+
|
|
29
|
+
# +json+, or SQLite 3.38+ +json+) there is no need for the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store].
|
|
30
30
|
# Simply use {.store_accessor}[rdoc-ref:ClassMethods#store_accessor] instead to generate
|
|
31
31
|
# the accessor methods. Be aware that these columns use a string keyed hash and do not allow access
|
|
32
32
|
# using a symbol.
|
|
@@ -217,7 +217,11 @@ module ActiveRecord
|
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
def store_accessor_for(store_attribute)
|
|
220
|
-
type_for_attribute(store_attribute).
|
|
220
|
+
type_for_attribute(store_attribute).tap do |type|
|
|
221
|
+
unless type.respond_to?(:accessor)
|
|
222
|
+
raise ConfigurationError, "the column '#{store_attribute}' has not been configured as a store. Please make sure the column is declared serializable via 'ActiveRecord.store' or, if your database supports it, use a structured column type like hstore or json."
|
|
223
|
+
end
|
|
224
|
+
end.accessor
|
|
221
225
|
end
|
|
222
226
|
|
|
223
227
|
class HashAccessor # :nodoc:
|
|
@@ -69,9 +69,7 @@ module ActiveRecord
|
|
|
69
69
|
|
|
70
70
|
def predicate_builder
|
|
71
71
|
if klass
|
|
72
|
-
|
|
73
|
-
predicate_builder.instance_variable_set(:@table, self)
|
|
74
|
-
predicate_builder
|
|
72
|
+
klass.predicate_builder.with(self)
|
|
75
73
|
else
|
|
76
74
|
PredicateBuilder.new(self)
|
|
77
75
|
end
|
|
@@ -45,7 +45,7 @@ module ActiveRecord
|
|
|
45
45
|
# Example:
|
|
46
46
|
# ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
|
|
47
47
|
# mysql2: ['--no-defaults', '--skip-add-drop-table'],
|
|
48
|
-
#
|
|
48
|
+
# postgresql: '--no-tablespaces'
|
|
49
49
|
# }
|
|
50
50
|
mattr_accessor :structure_dump_flags, instance_accessor: false
|
|
51
51
|
|
|
@@ -178,22 +178,9 @@ module ActiveRecord
|
|
|
178
178
|
dump_db_configs = []
|
|
179
179
|
|
|
180
180
|
each_current_configuration(env) do |db_config|
|
|
181
|
-
|
|
182
|
-
begin
|
|
183
|
-
database_initialized = migration_connection_pool.schema_migration.table_exists?
|
|
184
|
-
rescue ActiveRecord::NoDatabaseError
|
|
185
|
-
create(db_config)
|
|
186
|
-
retry
|
|
187
|
-
end
|
|
181
|
+
database_initialized = initialize_database(db_config)
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
if File.exist?(schema_dump_path(db_config))
|
|
191
|
-
load_schema(db_config, ActiveRecord.schema_format, nil)
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
seed = true
|
|
195
|
-
end
|
|
196
|
-
end
|
|
183
|
+
seed = true if database_initialized && db_config.seeds?
|
|
197
184
|
end
|
|
198
185
|
|
|
199
186
|
each_current_environment(env) do |environment|
|
|
@@ -253,12 +240,33 @@ module ActiveRecord
|
|
|
253
240
|
end
|
|
254
241
|
end
|
|
255
242
|
|
|
256
|
-
def
|
|
243
|
+
def migrate_all
|
|
244
|
+
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
|
245
|
+
db_configs.each { |db_config| initialize_database(db_config) }
|
|
246
|
+
|
|
247
|
+
if db_configs.size == 1 && db_configs.first.primary?
|
|
248
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(skip_initialize: true)
|
|
249
|
+
else
|
|
250
|
+
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
|
251
|
+
|
|
252
|
+
mapped_versions.sort.each do |version, db_configs|
|
|
253
|
+
db_configs.each do |db_config|
|
|
254
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do
|
|
255
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(version, skip_initialize: true)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def migrate(version = nil, skip_initialize: false)
|
|
257
263
|
scope = ENV["SCOPE"]
|
|
258
264
|
verbose_was, Migration.verbose = Migration.verbose, verbose?
|
|
259
265
|
|
|
260
266
|
check_target_version
|
|
261
267
|
|
|
268
|
+
initialize_database(migration_connection_pool.db_config) unless skip_initialize
|
|
269
|
+
|
|
262
270
|
migration_connection_pool.migration_context.migrate(target_version) do |migration|
|
|
263
271
|
if version.blank?
|
|
264
272
|
scope.blank? || scope == migration.scope
|
|
@@ -365,7 +373,8 @@ module ActiveRecord
|
|
|
365
373
|
database_adapter_for(db_config, *arguments).structure_load(filename, flags)
|
|
366
374
|
end
|
|
367
375
|
|
|
368
|
-
def load_schema(db_config, format =
|
|
376
|
+
def load_schema(db_config, format = db_config.schema_format, file = nil) # :nodoc:
|
|
377
|
+
format = format.to_sym
|
|
369
378
|
file ||= schema_dump_path(db_config, format)
|
|
370
379
|
return unless file
|
|
371
380
|
|
|
@@ -386,7 +395,7 @@ module ActiveRecord
|
|
|
386
395
|
Migration.verbose = verbose_was
|
|
387
396
|
end
|
|
388
397
|
|
|
389
|
-
def schema_up_to_date?(configuration,
|
|
398
|
+
def schema_up_to_date?(configuration, _ = nil, file = nil)
|
|
390
399
|
db_config = resolve_configuration(configuration)
|
|
391
400
|
|
|
392
401
|
file ||= schema_dump_path(db_config)
|
|
@@ -402,25 +411,32 @@ module ActiveRecord
|
|
|
402
411
|
end
|
|
403
412
|
end
|
|
404
413
|
|
|
405
|
-
def reconstruct_from_schema(db_config,
|
|
406
|
-
file ||= schema_dump_path(db_config,
|
|
414
|
+
def reconstruct_from_schema(db_config, file = nil) # :nodoc:
|
|
415
|
+
file ||= schema_dump_path(db_config, db_config.schema_format)
|
|
407
416
|
|
|
408
417
|
check_schema_file(file) if file
|
|
409
418
|
|
|
410
419
|
with_temporary_pool(db_config, clobber: true) do
|
|
411
|
-
if schema_up_to_date?(db_config,
|
|
420
|
+
if schema_up_to_date?(db_config, nil, file)
|
|
412
421
|
truncate_tables(db_config) unless ENV["SKIP_TEST_DATABASE_TRUNCATE"]
|
|
413
422
|
else
|
|
414
423
|
purge(db_config)
|
|
415
|
-
load_schema(db_config,
|
|
424
|
+
load_schema(db_config, db_config.schema_format, file)
|
|
416
425
|
end
|
|
417
426
|
rescue ActiveRecord::NoDatabaseError
|
|
418
427
|
create(db_config)
|
|
419
|
-
load_schema(db_config,
|
|
428
|
+
load_schema(db_config, db_config.schema_format, file)
|
|
420
429
|
end
|
|
421
430
|
end
|
|
422
431
|
|
|
423
|
-
def
|
|
432
|
+
def dump_all
|
|
433
|
+
with_temporary_pool_for_each do |pool|
|
|
434
|
+
db_config = pool.db_config
|
|
435
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def dump_schema(db_config, format = db_config.schema_format) # :nodoc:
|
|
424
440
|
return unless db_config.schema_dump
|
|
425
441
|
|
|
426
442
|
require "active_record/schema_dumper"
|
|
@@ -428,7 +444,7 @@ module ActiveRecord
|
|
|
428
444
|
return unless filename
|
|
429
445
|
|
|
430
446
|
FileUtils.mkdir_p(db_dir)
|
|
431
|
-
case format
|
|
447
|
+
case format.to_sym
|
|
432
448
|
when :ruby
|
|
433
449
|
File.open(filename, "w:utf-8") do |file|
|
|
434
450
|
ActiveRecord::SchemaDumper.dump(migration_connection_pool, file)
|
|
@@ -444,7 +460,7 @@ module ActiveRecord
|
|
|
444
460
|
end
|
|
445
461
|
end
|
|
446
462
|
|
|
447
|
-
def schema_dump_path(db_config, format =
|
|
463
|
+
def schema_dump_path(db_config, format = db_config.schema_format)
|
|
448
464
|
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
|
449
465
|
|
|
450
466
|
filename = db_config.schema_dump(format)
|
|
@@ -457,32 +473,16 @@ module ActiveRecord
|
|
|
457
473
|
end
|
|
458
474
|
end
|
|
459
475
|
|
|
460
|
-
def cache_dump_filename(
|
|
461
|
-
|
|
462
|
-
schema_cache_path ||
|
|
463
|
-
|
|
464
|
-
schema_cache_env ||
|
|
465
|
-
db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
|
|
466
|
-
else
|
|
467
|
-
ActiveRecord.deprecator.warn(<<~MSG.squish)
|
|
468
|
-
Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 8.0. Pass a
|
|
469
|
-
`ActiveRecord::DatabaseConfigurations::DatabaseConfig` object instead.
|
|
470
|
-
MSG
|
|
471
|
-
|
|
472
|
-
filename = if ActiveRecord::Base.configurations.primary?(db_config_or_name)
|
|
473
|
-
"schema_cache.yml"
|
|
474
|
-
else
|
|
475
|
-
"#{db_config_or_name}_schema_cache.yml"
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
schema_cache_path || schema_cache_env || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
|
479
|
-
end
|
|
476
|
+
def cache_dump_filename(db_config, schema_cache_path: nil)
|
|
477
|
+
schema_cache_path ||
|
|
478
|
+
db_config.schema_cache_path ||
|
|
479
|
+
db_config.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
|
|
480
480
|
end
|
|
481
481
|
|
|
482
|
-
def load_schema_current(format =
|
|
482
|
+
def load_schema_current(format = nil, file = nil, environment = env)
|
|
483
483
|
each_current_configuration(environment) do |db_config|
|
|
484
484
|
with_temporary_connection(db_config) do
|
|
485
|
-
load_schema(db_config, format, file)
|
|
485
|
+
load_schema(db_config, format || db_config.schema_format, file)
|
|
486
486
|
end
|
|
487
487
|
end
|
|
488
488
|
end
|
|
@@ -547,17 +547,6 @@ module ActiveRecord
|
|
|
547
547
|
end
|
|
548
548
|
|
|
549
549
|
private
|
|
550
|
-
def schema_cache_env
|
|
551
|
-
if ENV["SCHEMA_CACHE"]
|
|
552
|
-
ActiveRecord.deprecator.warn(<<~MSG.squish)
|
|
553
|
-
Setting `ENV["SCHEMA_CACHE"]` is deprecated and will be removed in Rails 8.0.
|
|
554
|
-
Configure the `:schema_cache_path` in the database configuration instead.
|
|
555
|
-
MSG
|
|
556
|
-
|
|
557
|
-
nil
|
|
558
|
-
end
|
|
559
|
-
end
|
|
560
|
-
|
|
561
550
|
def with_temporary_pool(db_config, clobber: false)
|
|
562
551
|
original_db_config = migration_class.connection_db_config
|
|
563
552
|
pool = migration_class.connection_handler.establish_connection(db_config, clobber: clobber)
|
|
@@ -667,6 +656,26 @@ module ActiveRecord
|
|
|
667
656
|
rescue ActiveRecord::NoDatabaseError
|
|
668
657
|
end
|
|
669
658
|
end
|
|
659
|
+
|
|
660
|
+
def initialize_database(db_config)
|
|
661
|
+
with_temporary_pool(db_config) do
|
|
662
|
+
begin
|
|
663
|
+
database_already_initialized = migration_connection_pool.schema_migration.table_exists?
|
|
664
|
+
rescue ActiveRecord::NoDatabaseError
|
|
665
|
+
create(db_config)
|
|
666
|
+
retry
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
unless database_already_initialized
|
|
670
|
+
schema_dump_path = schema_dump_path(db_config)
|
|
671
|
+
if schema_dump_path && File.exist?(schema_dump_path)
|
|
672
|
+
load_schema(db_config)
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
!database_already_initialized
|
|
677
|
+
end
|
|
678
|
+
end
|
|
670
679
|
end
|
|
671
680
|
end
|
|
672
681
|
end
|
|
@@ -78,8 +78,9 @@ module ActiveRecord
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def structure_load(filename, extra_flags)
|
|
81
|
-
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--output", File::NULL
|
|
81
|
+
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--output", File::NULL]
|
|
82
82
|
args.concat(Array(extra_flags)) if extra_flags
|
|
83
|
+
args.concat(["--file", filename])
|
|
83
84
|
args << db_config.database
|
|
84
85
|
run_cmd("psql", args, "loading")
|
|
85
86
|
end
|
|
@@ -50,9 +50,9 @@ module ActiveRecord
|
|
|
50
50
|
if ignore_tables.any?
|
|
51
51
|
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
|
52
52
|
condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
|
|
53
|
-
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
|
53
|
+
args << "SELECT sql || ';' FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
|
54
54
|
else
|
|
55
|
-
args << ".schema"
|
|
55
|
+
args << ".schema --nosys"
|
|
56
56
|
end
|
|
57
57
|
run_cmd("sqlite3", args, filename)
|
|
58
58
|
end
|
|
@@ -14,7 +14,7 @@ module ActiveRecord
|
|
|
14
14
|
ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
|
|
15
15
|
db_config._database = "#{db_config.database}-#{i}"
|
|
16
16
|
|
|
17
|
-
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config,
|
|
17
|
+
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, nil)
|
|
18
18
|
end
|
|
19
19
|
ensure
|
|
20
20
|
ActiveRecord::Base.establish_connection
|
|
@@ -137,12 +137,15 @@ module ActiveRecord
|
|
|
137
137
|
invalidate_already_loaded_fixtures
|
|
138
138
|
@loaded_fixtures = load_fixtures(config)
|
|
139
139
|
end
|
|
140
|
+
setup_asynchronous_queries_session
|
|
140
141
|
|
|
141
142
|
# Instantiate fixtures for every test if requested.
|
|
142
143
|
instantiate_fixtures if use_instantiated_fixtures
|
|
143
144
|
end
|
|
144
145
|
|
|
145
146
|
def teardown_fixtures
|
|
147
|
+
teardown_asynchronous_queries_session
|
|
148
|
+
|
|
146
149
|
# Rollback changes if a transaction is active.
|
|
147
150
|
if run_in_transaction?
|
|
148
151
|
teardown_transactional_fixtures
|
|
@@ -154,6 +157,14 @@ module ActiveRecord
|
|
|
154
157
|
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
|
155
158
|
end
|
|
156
159
|
|
|
160
|
+
def setup_asynchronous_queries_session
|
|
161
|
+
@_async_queries_session = ActiveRecord::Base.asynchronous_queries_tracker.start_session
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def teardown_asynchronous_queries_session
|
|
165
|
+
ActiveRecord::Base.asynchronous_queries_tracker.finalize_session(true) if @_async_queries_session
|
|
166
|
+
end
|
|
167
|
+
|
|
157
168
|
def invalidate_already_loaded_fixtures
|
|
158
169
|
@@already_loaded_fixtures.clear
|
|
159
170
|
end
|
|
@@ -190,6 +201,7 @@ module ActiveRecord
|
|
|
190
201
|
|
|
191
202
|
def teardown_transactional_fixtures
|
|
192
203
|
ActiveSupport::Notifications.unsubscribe(@connection_subscriber) if @connection_subscriber
|
|
204
|
+
|
|
193
205
|
unless @fixture_connection_pools.map(&:unpin_connection!).all?
|
|
194
206
|
# Something caused the transaction to be committed or rolled back
|
|
195
207
|
# We can no longer trust the database is in a clean state.
|
|
@@ -40,7 +40,7 @@ module ActiveRecord
|
|
|
40
40
|
# +nil+ if the token is invalid or the record was not found.
|
|
41
41
|
def find_by_token_for(purpose, token)
|
|
42
42
|
raise UnknownPrimaryKey.new(self) unless model.primary_key
|
|
43
|
-
model.token_definitions.fetch(purpose).resolve_token(token) { |id| find_by(model.primary_key => id) }
|
|
43
|
+
model.token_definitions.fetch(purpose).resolve_token(token) { |id| find_by(model.primary_key => [id]) }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# Finds a record using a given +token+ for a predefined +purpose+. Raises
|
|
@@ -219,12 +219,11 @@ module ActiveRecord
|
|
|
219
219
|
# database error will occur because the savepoint has already been
|
|
220
220
|
# automatically released. The following example demonstrates the problem:
|
|
221
221
|
#
|
|
222
|
-
# Model.
|
|
223
|
-
# Model.
|
|
224
|
-
# Model.lease_connection.create_table(...)
|
|
225
|
-
# end
|
|
226
|
-
#
|
|
227
|
-
# end
|
|
222
|
+
# Model.transaction do # BEGIN
|
|
223
|
+
# Model.transaction(requires_new: true) do # CREATE SAVEPOINT active_record_1
|
|
224
|
+
# Model.lease_connection.create_table(...) # active_record_1 now automatically released
|
|
225
|
+
# end # RELEASE SAVEPOINT active_record_1
|
|
226
|
+
# end # ^^^^ BOOM! database error!
|
|
228
227
|
#
|
|
229
228
|
# Note that "TRUNCATE" is also a MySQL DDL statement!
|
|
230
229
|
module ClassMethods
|
|
@@ -54,17 +54,17 @@ module ActiveRecord
|
|
|
54
54
|
private
|
|
55
55
|
# The check for an existing value should be run from a class that
|
|
56
56
|
# isn't abstract. This means working down from the current class
|
|
57
|
-
# (self), to the first non-abstract class.
|
|
58
|
-
# their subclasses, we have to build the hierarchy between self and
|
|
59
|
-
# the record's class.
|
|
57
|
+
# (self), to the first non-abstract class.
|
|
60
58
|
def find_finder_class_for(record)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
current_class = record.class
|
|
60
|
+
found_class = nil
|
|
61
|
+
loop do
|
|
62
|
+
found_class = current_class unless current_class.abstract_class?
|
|
63
|
+
break if current_class == @klass
|
|
64
|
+
current_class = current_class.superclass
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
found_class
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def validation_needed?(klass, record, attribute)
|
data/lib/active_record.rb
CHANGED
|
@@ -29,6 +29,7 @@ require "active_support/ordered_options"
|
|
|
29
29
|
require "active_model"
|
|
30
30
|
require "arel"
|
|
31
31
|
require "yaml"
|
|
32
|
+
require "zlib"
|
|
32
33
|
|
|
33
34
|
require "active_record/version"
|
|
34
35
|
require "active_record/deprecator"
|
|
@@ -196,6 +197,20 @@ module ActiveRecord
|
|
|
196
197
|
singleton_class.attr_accessor :schema_cache_ignored_tables
|
|
197
198
|
self.schema_cache_ignored_tables = []
|
|
198
199
|
|
|
200
|
+
# Checks to see if the +table_name+ is ignored by checking
|
|
201
|
+
# against the +schema_cache_ignored_tables+ option.
|
|
202
|
+
#
|
|
203
|
+
# ActiveRecord.schema_cache_ignored_table?(:developers)
|
|
204
|
+
#
|
|
205
|
+
def self.schema_cache_ignored_table?(table_name)
|
|
206
|
+
ActiveRecord.schema_cache_ignored_tables.any? do |ignored|
|
|
207
|
+
ignored === table_name
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
singleton_class.attr_accessor :database_cli
|
|
212
|
+
self.database_cli = { postgresql: "psql", mysql: %w[mysql mysql5], sqlite: "sqlite3" }
|
|
213
|
+
|
|
199
214
|
singleton_class.attr_reader :default_timezone
|
|
200
215
|
|
|
201
216
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
|
@@ -253,14 +268,6 @@ module ActiveRecord
|
|
|
253
268
|
singleton_class.attr_accessor :reading_role
|
|
254
269
|
self.reading_role = :reading
|
|
255
270
|
|
|
256
|
-
def self.legacy_connection_handling=(_)
|
|
257
|
-
raise ArgumentError, <<~MSG.squish
|
|
258
|
-
The `legacy_connection_handling` setter was deprecated in 7.0 and removed in 7.1,
|
|
259
|
-
but is still defined in your configuration. Please remove this call as it no longer
|
|
260
|
-
has any effect."
|
|
261
|
-
MSG
|
|
262
|
-
end
|
|
263
|
-
|
|
264
271
|
##
|
|
265
272
|
# :singleton-method: async_query_executor
|
|
266
273
|
# Sets the async_query_executor for an application. By default the thread pool executor
|
|
@@ -344,29 +351,6 @@ module ActiveRecord
|
|
|
344
351
|
singleton_class.attr_accessor :run_after_transaction_callbacks_in_order_defined
|
|
345
352
|
self.run_after_transaction_callbacks_in_order_defined = false
|
|
346
353
|
|
|
347
|
-
def self.commit_transaction_on_non_local_return
|
|
348
|
-
ActiveRecord.deprecator.warn <<-WARNING.squish
|
|
349
|
-
`Rails.application.config.active_record.commit_transaction_on_non_local_return`
|
|
350
|
-
is deprecated and will be removed in Rails 8.0.
|
|
351
|
-
WARNING
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
def self.commit_transaction_on_non_local_return=(value)
|
|
355
|
-
ActiveRecord.deprecator.warn <<-WARNING.squish
|
|
356
|
-
`Rails.application.config.active_record.commit_transaction_on_non_local_return`
|
|
357
|
-
is deprecated and will be removed in Rails 8.0.
|
|
358
|
-
WARNING
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
##
|
|
362
|
-
# :singleton-method: warn_on_records_fetched_greater_than
|
|
363
|
-
# Specify a threshold for the size of query result sets. If the number of
|
|
364
|
-
# records in the set exceeds the threshold, a warning is logged. This can
|
|
365
|
-
# be used to identify queries which load thousands of records and
|
|
366
|
-
# potentially cause memory bloat.
|
|
367
|
-
singleton_class.attr_accessor :warn_on_records_fetched_greater_than
|
|
368
|
-
self.warn_on_records_fetched_greater_than = false
|
|
369
|
-
|
|
370
354
|
singleton_class.attr_accessor :application_record_class
|
|
371
355
|
self.application_record_class = nil
|
|
372
356
|
|
|
@@ -384,7 +368,8 @@ module ActiveRecord
|
|
|
384
368
|
# specific) SQL statements. If :ruby, the schema is dumped as an
|
|
385
369
|
# ActiveRecord::Schema file which can be loaded into any database that
|
|
386
370
|
# supports migrations. Use :ruby if you want to have different database
|
|
387
|
-
# adapters for, e.g., your development and test environments.
|
|
371
|
+
# adapters for, e.g., your development and test environments. This can be
|
|
372
|
+
# overridden per-database in the database configuration.
|
|
388
373
|
singleton_class.attr_accessor :schema_format
|
|
389
374
|
self.schema_format = :ruby
|
|
390
375
|
|
|
@@ -444,20 +429,6 @@ module ActiveRecord
|
|
|
444
429
|
singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
|
|
445
430
|
self.verify_foreign_keys_for_fixtures = false
|
|
446
431
|
|
|
447
|
-
def self.allow_deprecated_singular_associations_name
|
|
448
|
-
ActiveRecord.deprecator.warn <<-WARNING.squish
|
|
449
|
-
`Rails.application.config.active_record.allow_deprecated_singular_associations_name`
|
|
450
|
-
is deprecated and will be removed in Rails 8.0.
|
|
451
|
-
WARNING
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
def self.allow_deprecated_singular_associations_name=(value)
|
|
455
|
-
ActiveRecord.deprecator.warn <<-WARNING.squish
|
|
456
|
-
`Rails.application.config.active_record.allow_deprecated_singular_associations_name`
|
|
457
|
-
is deprecated and will be removed in Rails 8.0.
|
|
458
|
-
WARNING
|
|
459
|
-
end
|
|
460
|
-
|
|
461
432
|
singleton_class.attr_accessor :query_transformers
|
|
462
433
|
self.query_transformers = []
|
|
463
434
|
|
|
@@ -578,8 +549,10 @@ module ActiveRecord
|
|
|
578
549
|
open_transactions = []
|
|
579
550
|
Base.connection_handler.each_connection_pool do |pool|
|
|
580
551
|
if active_connection = pool.active_connection
|
|
581
|
-
|
|
582
|
-
|
|
552
|
+
current_transaction = active_connection.current_transaction
|
|
553
|
+
|
|
554
|
+
if current_transaction.open? && current_transaction.joinable? && !current_transaction.state.invalidated?
|
|
555
|
+
open_transactions << current_transaction
|
|
583
556
|
end
|
|
584
557
|
end
|
|
585
558
|
end
|
data/lib/arel/collectors/bind.rb
CHANGED
|
@@ -13,12 +13,12 @@ module Arel # :nodoc: all
|
|
|
13
13
|
self
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def add_bind(bind, &
|
|
16
|
+
def add_bind(bind, &)
|
|
17
17
|
@binds << bind
|
|
18
18
|
self
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def add_binds(binds, proc_for_binds = nil)
|
|
21
|
+
def add_binds(binds, proc_for_binds = nil, &)
|
|
22
22
|
@binds.concat proc_for_binds ? binds.map(&proc_for_binds) : binds
|
|
23
23
|
self
|
|
24
24
|
end
|
|
@@ -15,12 +15,12 @@ module Arel # :nodoc: all
|
|
|
15
15
|
self
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def add_bind(bind)
|
|
18
|
+
def add_bind(bind, &)
|
|
19
19
|
bind = bind.value_for_database if bind.respond_to?(:value_for_database)
|
|
20
20
|
self << quoter.quote(bind)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def add_binds(binds, proc_for_binds = nil)
|
|
23
|
+
def add_binds(binds, proc_for_binds = nil, &)
|
|
24
24
|
self << binds.map { |bind| quoter.quote(bind) }.join(", ")
|
|
25
25
|
end
|
|
26
26
|
|
data/lib/arel/nodes/binary.rb
CHANGED
data/lib/arel/nodes/node.rb
CHANGED
data/lib/arel/table.rb
CHANGED
|
@@ -12,13 +12,9 @@ module Arel # :nodoc: all
|
|
|
12
12
|
attr_reader :table_alias
|
|
13
13
|
|
|
14
14
|
def initialize(name, as: nil, klass: nil, type_caster: klass&.type_caster)
|
|
15
|
-
|
|
16
|
-
case name
|
|
17
|
-
when Symbol then name.to_s
|
|
18
|
-
else
|
|
19
|
-
name
|
|
20
|
-
end
|
|
15
|
+
name = name.name if name.is_a?(Symbol)
|
|
21
16
|
|
|
17
|
+
@name = name
|
|
22
18
|
@klass = klass
|
|
23
19
|
@type_caster = type_caster
|
|
24
20
|
|
|
@@ -84,7 +80,7 @@ module Arel # :nodoc: all
|
|
|
84
80
|
end
|
|
85
81
|
|
|
86
82
|
def [](name, table = self)
|
|
87
|
-
name = name.
|
|
83
|
+
name = name.name if name.is_a?(Symbol)
|
|
88
84
|
name = @klass.attribute_aliases[name] || name if @klass
|
|
89
85
|
Attribute.new(table, name)
|
|
90
86
|
end
|