activerecord 7.1.5.1 → 7.2.0.beta1
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 +515 -2445
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +9 -8
- data/lib/active_record/associations/belongs_to_association.rb +14 -7
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/collection_association.rb +6 -4
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +29 -28
- data/lib/active_record/associations/join_dependency.rb +5 -5
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +2 -1
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +33 -16
- data/lib/active_record/attribute_assignment.rb +1 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +1 -1
- data/lib/active_record/attribute_methods/primary_key.rb +23 -55
- data/lib/active_record/attribute_methods/read.rb +4 -16
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -10
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +60 -71
- data/lib/active_record/attributes.rb +55 -42
- data/lib/active_record/autosave_association.rb +13 -32
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +248 -65
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +34 -17
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +159 -74
- data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/transaction.rb +60 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +18 -46
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +32 -6
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +7 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +11 -5
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +5 -23
- data/lib/active_record/connection_adapters/pool_config.rb +7 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -13
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -21
- data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +107 -75
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +12 -6
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -48
- data/lib/active_record/connection_adapters.rb +121 -0
- data/lib/active_record/connection_handling.rb +56 -41
- data/lib/active_record/core.rb +53 -37
- data/lib/active_record/counter_cache.rb +18 -9
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +15 -4
- data/lib/active_record/database_configurations/hash_config.rb +38 -34
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +24 -0
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +2 -2
- data/lib/active_record/encryption/encrypted_attribute_type.rb +22 -2
- data/lib/active_record/encryption/encryptor.rb +17 -2
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption.rb +0 -2
- data/lib/active_record/enum.rb +10 -1
- data/lib/active_record/errors.rb +16 -11
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -31
- data/lib/active_record/future_result.rb +8 -4
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +18 -15
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +7 -6
- data/lib/active_record/log_subscriber.rb +0 -21
- data/lib/active_record/marshalling.rb +1 -4
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +2 -3
- data/lib/active_record/migration/compatibility.rb +5 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +85 -76
- data/lib/active_record/model_schema.rb +28 -68
- data/lib/active_record/nested_attributes.rb +13 -16
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +30 -352
- data/lib/active_record/query_cache.rb +18 -6
- data/lib/active_record/query_logs.rb +15 -0
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +50 -62
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +41 -44
- data/lib/active_record/reflection.rb +90 -35
- data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +94 -61
- data/lib/active_record/relation/delegation.rb +8 -11
- data/lib/active_record/relation/finder_methods.rb +16 -2
- data/lib/active_record/relation/merger.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +196 -57
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -18
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +496 -72
- data/lib/active_record/result.rb +31 -44
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +24 -19
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +19 -9
- data/lib/active_record/schema_migration.rb +30 -14
- data/lib/active_record/signed_id.rb +11 -1
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/table_metadata.rb +1 -10
- data/lib/active_record/tasks/database_tasks.rb +76 -70
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
- data/lib/active_record/test_fixtures.rb +81 -91
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +1 -1
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +68 -0
- data/lib/active_record/transactions.rb +43 -14
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +14 -10
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +149 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/nodes/binary.rb +0 -6
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +4 -3
- data/lib/arel/nodes/sql_literal.rb +7 -0
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/to_sql.rb +29 -16
- data/lib/arel.rb +7 -3
- metadata +20 -15
data/lib/active_record.rb
CHANGED
@@ -25,6 +25,7 @@
|
|
25
25
|
|
26
26
|
require "active_support"
|
27
27
|
require "active_support/rails"
|
28
|
+
require "active_support/ordered_options"
|
28
29
|
require "active_model"
|
29
30
|
require "arel"
|
30
31
|
require "yaml"
|
@@ -85,6 +86,7 @@ module ActiveRecord
|
|
85
86
|
autoload :Timestamp
|
86
87
|
autoload :TokenFor
|
87
88
|
autoload :TouchLater
|
89
|
+
autoload :Transaction
|
88
90
|
autoload :Transactions
|
89
91
|
autoload :Translation
|
90
92
|
autoload :Validations
|
@@ -128,6 +130,8 @@ module ActiveRecord
|
|
128
130
|
module AttributeMethods
|
129
131
|
extend ActiveSupport::Autoload
|
130
132
|
|
133
|
+
autoload :CompositePrimaryKey
|
134
|
+
|
131
135
|
eager_autoload do
|
132
136
|
autoload :BeforeTypeCast
|
133
137
|
autoload :Dirty
|
@@ -177,12 +181,15 @@ module ActiveRecord
|
|
177
181
|
singleton_class.attr_accessor :disable_prepared_statements
|
178
182
|
self.disable_prepared_statements = false
|
179
183
|
|
184
|
+
##
|
185
|
+
# :singleton-method: lazily_load_schema_cache
|
180
186
|
# Lazily load the schema cache. This option will load the schema cache
|
181
|
-
# when a connection is established rather than on boot.
|
182
|
-
# +config.active_record.use_schema_cache_dump+ will be set to false.
|
187
|
+
# when a connection is established rather than on boot.
|
183
188
|
singleton_class.attr_accessor :lazily_load_schema_cache
|
184
189
|
self.lazily_load_schema_cache = false
|
185
190
|
|
191
|
+
##
|
192
|
+
# :singleton-method: schema_cache_ignored_tables
|
186
193
|
# A list of tables or regex's to match tables to ignore when
|
187
194
|
# dumping the schema cache. For example if this is set to +[/^_/]+
|
188
195
|
# the schema cache will not dump tables named with an underscore.
|
@@ -203,6 +210,8 @@ module ActiveRecord
|
|
203
210
|
|
204
211
|
self.default_timezone = :utc
|
205
212
|
|
213
|
+
##
|
214
|
+
# :singleton-method: db_warnings_action
|
206
215
|
# The action to take when database query produces warning.
|
207
216
|
# Must be one of :ignore, :log, :raise, :report, or a custom proc.
|
208
217
|
# The default is :ignore.
|
@@ -232,6 +241,8 @@ module ActiveRecord
|
|
232
241
|
|
233
242
|
self.db_warnings_action = :ignore
|
234
243
|
|
244
|
+
##
|
245
|
+
# :singleton-method: db_warnings_ignore
|
235
246
|
# Specify allowlist of database warnings.
|
236
247
|
singleton_class.attr_accessor :db_warnings_ignore
|
237
248
|
self.db_warnings_ignore = []
|
@@ -250,6 +261,8 @@ module ActiveRecord
|
|
250
261
|
MSG
|
251
262
|
end
|
252
263
|
|
264
|
+
##
|
265
|
+
# :singleton-method: async_query_executor
|
253
266
|
# Sets the async_query_executor for an application. By default the thread pool executor
|
254
267
|
# set to +nil+ which will not run queries in the background. Applications must configure
|
255
268
|
# a thread pool executor to use this feature. Options are:
|
@@ -277,7 +290,7 @@ module ActiveRecord
|
|
277
290
|
# with the global thread pool async query executor.
|
278
291
|
def self.global_executor_concurrency=(global_executor_concurrency)
|
279
292
|
if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
|
280
|
-
raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to
|
293
|
+
raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
|
281
294
|
end
|
282
295
|
|
283
296
|
@global_executor_concurrency = global_executor_concurrency
|
@@ -287,11 +300,22 @@ module ActiveRecord
|
|
287
300
|
@global_executor_concurrency ||= nil
|
288
301
|
end
|
289
302
|
|
303
|
+
@permanent_connection_checkout = true
|
304
|
+
singleton_class.attr_reader :permanent_connection_checkout
|
305
|
+
|
306
|
+
# Defines whether +ActiveRecord::Base.connection+ is allowed, deprecated, or entirely disallowed.
|
307
|
+
def self.permanent_connection_checkout=(value)
|
308
|
+
unless [true, :deprecated, :disallowed].include?(value)
|
309
|
+
raise ArgumentError, "permanent_connection_checkout must be one of: `true`, `:deprecated` or `:disallowed`"
|
310
|
+
end
|
311
|
+
@permanent_connection_checkout = value
|
312
|
+
end
|
313
|
+
|
290
314
|
singleton_class.attr_accessor :index_nested_attribute_errors
|
291
315
|
self.index_nested_attribute_errors = false
|
292
316
|
|
293
317
|
##
|
294
|
-
# :singleton-method:
|
318
|
+
# :singleton-method: verbose_query_logs
|
295
319
|
#
|
296
320
|
# Specifies if the methods calling database queries should be logged below
|
297
321
|
# their relevant queries. Defaults to false.
|
@@ -299,7 +323,7 @@ module ActiveRecord
|
|
299
323
|
self.verbose_query_logs = false
|
300
324
|
|
301
325
|
##
|
302
|
-
# :singleton-method:
|
326
|
+
# :singleton-method: queues
|
303
327
|
#
|
304
328
|
# Specifies the names of the queues used by background jobs.
|
305
329
|
singleton_class.attr_accessor :queues
|
@@ -320,11 +344,22 @@ module ActiveRecord
|
|
320
344
|
singleton_class.attr_accessor :run_after_transaction_callbacks_in_order_defined
|
321
345
|
self.run_after_transaction_callbacks_in_order_defined = false
|
322
346
|
|
323
|
-
|
324
|
-
|
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 7.3.
|
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 7.3.
|
358
|
+
WARNING
|
359
|
+
end
|
325
360
|
|
326
361
|
##
|
327
|
-
# :singleton-method:
|
362
|
+
# :singleton-method: warn_on_records_fetched_greater_than
|
328
363
|
# Specify a threshold for the size of query result sets. If the number of
|
329
364
|
# records in the set exceeds the threshold, a warning is logged. This can
|
330
365
|
# be used to identify queries which load thousands of records and
|
@@ -336,14 +371,14 @@ module ActiveRecord
|
|
336
371
|
self.application_record_class = nil
|
337
372
|
|
338
373
|
##
|
339
|
-
# :singleton-method:
|
374
|
+
# :singleton-method: action_on_strict_loading_violation
|
340
375
|
# Set the application to log or raise when an association violates strict loading.
|
341
376
|
# Defaults to :raise.
|
342
377
|
singleton_class.attr_accessor :action_on_strict_loading_violation
|
343
378
|
self.action_on_strict_loading_violation = :raise
|
344
379
|
|
345
380
|
##
|
346
|
-
# :singleton-method:
|
381
|
+
# :singleton-method: schema_format
|
347
382
|
# Specifies the format to use when dumping the database schema with Rails'
|
348
383
|
# Rakefile. If :sql, the schema is dumped as (potentially database-
|
349
384
|
# specific) SQL statements. If :ruby, the schema is dumped as an
|
@@ -354,7 +389,7 @@ module ActiveRecord
|
|
354
389
|
self.schema_format = :ruby
|
355
390
|
|
356
391
|
##
|
357
|
-
# :singleton-method:
|
392
|
+
# :singleton-method: error_on_ignored_order
|
358
393
|
# Specifies if an error should be raised if the query has an order being
|
359
394
|
# ignored when doing batch queries. Useful in applications where the
|
360
395
|
# scope being ignored is error-worthy, rather than a warning.
|
@@ -362,19 +397,27 @@ module ActiveRecord
|
|
362
397
|
self.error_on_ignored_order = false
|
363
398
|
|
364
399
|
##
|
365
|
-
# :singleton-method:
|
400
|
+
# :singleton-method: timestamped_migrations
|
366
401
|
# Specify whether or not to use timestamps for migration versions
|
367
402
|
singleton_class.attr_accessor :timestamped_migrations
|
368
403
|
self.timestamped_migrations = true
|
369
404
|
|
370
405
|
##
|
371
|
-
# :singleton-method:
|
406
|
+
# :singleton-method: validate_migration_timestamps
|
407
|
+
# Specify whether or not to validate migration timestamps. When set, an error
|
408
|
+
# will be raised if a timestamp is more than a day ahead of the timestamp
|
409
|
+
# associated with the current time. +timestamped_migrations+ must be set to true.
|
410
|
+
singleton_class.attr_accessor :validate_migration_timestamps
|
411
|
+
self.validate_migration_timestamps = false
|
412
|
+
|
413
|
+
##
|
414
|
+
# :singleton-method: migration_strategy
|
372
415
|
# Specify strategy to use for executing migrations.
|
373
416
|
singleton_class.attr_accessor :migration_strategy
|
374
417
|
self.migration_strategy = Migration::DefaultStrategy
|
375
418
|
|
376
419
|
##
|
377
|
-
# :singleton-method:
|
420
|
+
# :singleton-method: dump_schema_after_migration
|
378
421
|
# Specify whether schema dump should happen at the end of the
|
379
422
|
# bin/rails db:migrate command. This is true by default, which is useful for the
|
380
423
|
# development environment. This should ideally be false in the production
|
@@ -383,7 +426,7 @@ module ActiveRecord
|
|
383
426
|
self.dump_schema_after_migration = true
|
384
427
|
|
385
428
|
##
|
386
|
-
# :singleton-method:
|
429
|
+
# :singleton-method: dump_schemas
|
387
430
|
# Specifies which database schemas to dump when calling db:schema:dump.
|
388
431
|
# If the value is :schema_search_path (the default), any schemas listed in
|
389
432
|
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
@@ -392,22 +435,8 @@ module ActiveRecord
|
|
392
435
|
singleton_class.attr_accessor :dump_schemas
|
393
436
|
self.dump_schemas = :schema_search_path
|
394
437
|
|
395
|
-
def self.suppress_multiple_database_warning
|
396
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
397
|
-
config.active_record.suppress_multiple_database_warning is deprecated and will be removed in Rails 7.2.
|
398
|
-
It no longer has any effect and should be removed from the configuration file.
|
399
|
-
MSG
|
400
|
-
end
|
401
|
-
|
402
|
-
def self.suppress_multiple_database_warning=(value)
|
403
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
404
|
-
config.active_record.suppress_multiple_database_warning= is deprecated and will be removed in Rails 7.2.
|
405
|
-
It no longer has any effect and should be removed from the configuration file.
|
406
|
-
MSG
|
407
|
-
end
|
408
|
-
|
409
438
|
##
|
410
|
-
# :singleton-method:
|
439
|
+
# :singleton-method: verify_foreign_keys_for_fixtures
|
411
440
|
# If true, Rails will verify all foreign keys in the database after loading fixtures.
|
412
441
|
# An error will be raised if there are any foreign key violations, indicating incorrectly
|
413
442
|
# written fixtures.
|
@@ -415,25 +444,32 @@ module ActiveRecord
|
|
415
444
|
singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
|
416
445
|
self.verify_foreign_keys_for_fixtures = false
|
417
446
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
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 7.3.
|
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 7.3.
|
458
|
+
WARNING
|
459
|
+
end
|
424
460
|
|
425
461
|
singleton_class.attr_accessor :query_transformers
|
426
462
|
self.query_transformers = []
|
427
463
|
|
428
464
|
##
|
429
|
-
# :singleton-method:
|
465
|
+
# :singleton-method: use_yaml_unsafe_load
|
430
466
|
# Application configurable boolean that instructs the YAML Coder to use
|
431
467
|
# an unsafe load if set to true.
|
432
468
|
singleton_class.attr_accessor :use_yaml_unsafe_load
|
433
469
|
self.use_yaml_unsafe_load = false
|
434
470
|
|
435
471
|
##
|
436
|
-
# :singleton-method:
|
472
|
+
# :singleton-method: raise_int_wider_than_64bit
|
437
473
|
# Application configurable boolean that denotes whether or not to raise
|
438
474
|
# an exception when the PostgreSQLAdapter is provided with an integer that
|
439
475
|
# is wider than signed 64bit representation
|
@@ -441,14 +477,14 @@ module ActiveRecord
|
|
441
477
|
self.raise_int_wider_than_64bit = true
|
442
478
|
|
443
479
|
##
|
444
|
-
# :singleton-method:
|
480
|
+
# :singleton-method: yaml_column_permitted_classes
|
445
481
|
# Application configurable array that provides additional permitted classes
|
446
482
|
# to Psych safe_load in the YAML Coder
|
447
483
|
singleton_class.attr_accessor :yaml_column_permitted_classes
|
448
484
|
self.yaml_column_permitted_classes = [Symbol]
|
449
485
|
|
450
486
|
##
|
451
|
-
# :singleton-method:
|
487
|
+
# :singleton-method: generate_secure_token_on
|
452
488
|
# Controls when to generate a value for <tt>has_secure_token</tt>
|
453
489
|
# declarations. Defaults to <tt>:create</tt>.
|
454
490
|
singleton_class.attr_accessor :generate_secure_token_on
|
@@ -462,6 +498,34 @@ module ActiveRecord
|
|
462
498
|
Marshalling.format_version = value
|
463
499
|
end
|
464
500
|
|
501
|
+
##
|
502
|
+
# :singleton-method: protocol_adapters
|
503
|
+
# Provides a mapping between database protocols/DBMSs and the
|
504
|
+
# underlying database adapter to be used. This is used only by the
|
505
|
+
# <tt>DATABASE_URL</tt> environment variable.
|
506
|
+
#
|
507
|
+
# == Example
|
508
|
+
#
|
509
|
+
# DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
|
510
|
+
#
|
511
|
+
# The above URL specifies that MySQL is the desired protocol/DBMS, and the
|
512
|
+
# application configuration can then decide which adapter to use. For this example
|
513
|
+
# the default mapping is from <tt>mysql</tt> to <tt>mysql2</tt>, but <tt>:trilogy</tt>
|
514
|
+
# is also supported.
|
515
|
+
#
|
516
|
+
# ActiveRecord.protocol_adapters.mysql = "mysql2"
|
517
|
+
#
|
518
|
+
# The protocols names are arbitrary, and external database adapters can be
|
519
|
+
# registered and set here.
|
520
|
+
singleton_class.attr_accessor :protocol_adapters
|
521
|
+
self.protocol_adapters = ActiveSupport::InheritableOptions.new(
|
522
|
+
{
|
523
|
+
sqlite: "sqlite3",
|
524
|
+
mysql: "mysql2",
|
525
|
+
postgres: "postgresql",
|
526
|
+
}
|
527
|
+
)
|
528
|
+
|
465
529
|
def self.eager_load!
|
466
530
|
super
|
467
531
|
ActiveRecord::Locking.eager_load!
|
@@ -476,6 +540,51 @@ module ActiveRecord
|
|
476
540
|
def self.disconnect_all!
|
477
541
|
ConnectionAdapters::PoolConfig.disconnect_all!
|
478
542
|
end
|
543
|
+
|
544
|
+
# Registers a block to be called after all the current transactions have been
|
545
|
+
# committed.
|
546
|
+
#
|
547
|
+
# If there is no currently open transaction, the block is called immediately.
|
548
|
+
#
|
549
|
+
# If there are multiple nested transactions, the block is called after the outermost one
|
550
|
+
# has been committed,
|
551
|
+
#
|
552
|
+
# If any of the currently open transactions is rolled back, the block is never called.
|
553
|
+
#
|
554
|
+
# If multiple transactions are open across multiple databases, the block will be invoked
|
555
|
+
# if and once all of them have been committed. But note that nesting transactions across
|
556
|
+
# two distinct databases is a sharding anti-pattern that comes with a world of hurts.
|
557
|
+
def self.after_all_transactions_commit(&block)
|
558
|
+
open_transactions = all_open_transactions
|
559
|
+
|
560
|
+
if open_transactions.empty?
|
561
|
+
yield
|
562
|
+
elsif open_transactions.size == 1
|
563
|
+
open_transactions.first.after_commit(&block)
|
564
|
+
else
|
565
|
+
count = open_transactions.size
|
566
|
+
callback = -> do
|
567
|
+
count -= 1
|
568
|
+
block.call if count.zero?
|
569
|
+
end
|
570
|
+
open_transactions.each do |t|
|
571
|
+
t.after_commit(&callback)
|
572
|
+
end
|
573
|
+
open_transactions = nil # rubocop:disable Lint/UselessAssignment avoid holding it in the closure
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
def self.all_open_transactions # :nodoc:
|
578
|
+
open_transactions = []
|
579
|
+
Base.connection_handler.each_connection_pool do |pool|
|
580
|
+
if active_connection = pool.active_connection
|
581
|
+
if active_connection.current_transaction.open? && active_connection.current_transaction.joinable?
|
582
|
+
open_transactions << active_connection.current_transaction
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
open_transactions
|
587
|
+
end
|
479
588
|
end
|
480
589
|
|
481
590
|
ActiveSupport.on_load(:active_record) do
|
data/lib/arel/collectors/bind.rb
CHANGED
@@ -4,12 +4,19 @@ module Arel # :nodoc: all
|
|
4
4
|
module Collectors
|
5
5
|
class Composite
|
6
6
|
attr_accessor :preparable
|
7
|
+
attr_reader :retryable
|
7
8
|
|
8
9
|
def initialize(left, right)
|
9
10
|
@left = left
|
10
11
|
@right = right
|
11
12
|
end
|
12
13
|
|
14
|
+
def retryable=(retryable)
|
15
|
+
left.retryable = retryable
|
16
|
+
right.retryable = retryable
|
17
|
+
@retryable = retryable
|
18
|
+
end
|
19
|
+
|
13
20
|
def <<(str)
|
14
21
|
left << str
|
15
22
|
right << str
|
data/lib/arel/nodes/binary.rb
CHANGED
@@ -6,13 +6,17 @@ module Arel # :nodoc: all
|
|
6
6
|
attr_reader :sql_with_placeholders, :positional_binds, :named_binds
|
7
7
|
|
8
8
|
def initialize(sql_with_placeholders, positional_binds, named_binds)
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
has_positional = !(positional_binds.nil? || positional_binds.empty?)
|
10
|
+
has_named = !(named_binds.nil? || named_binds.empty?)
|
11
|
+
|
12
|
+
if has_positional
|
13
|
+
if has_named
|
14
|
+
raise BindError.new("cannot mix positional and named binds", sql_with_placeholders)
|
15
|
+
end
|
12
16
|
if positional_binds.size != (expected = sql_with_placeholders.count("?"))
|
13
17
|
raise BindError.new("wrong number of bind variables (#{positional_binds.size} for #{expected})", sql_with_placeholders)
|
14
18
|
end
|
15
|
-
elsif
|
19
|
+
elsif has_named
|
16
20
|
tokens_in_string = sql_with_placeholders.scan(/:(?<!::)([a-zA-Z]\w*)/).flatten.map(&:to_sym).uniq
|
17
21
|
tokens_in_hash = named_binds.keys.map(&:to_sym).uniq
|
18
22
|
|
@@ -26,7 +30,7 @@ module Arel # :nodoc: all
|
|
26
30
|
end
|
27
31
|
|
28
32
|
@sql_with_placeholders = sql_with_placeholders
|
29
|
-
if
|
33
|
+
if has_positional
|
30
34
|
@positional_binds = positional_binds
|
31
35
|
@named_binds = nil
|
32
36
|
else
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Arel # :nodoc: all
|
4
4
|
module Nodes
|
5
|
-
class
|
5
|
+
class Nary < Arel::Nodes::NodeExpression
|
6
6
|
attr_reader :children
|
7
7
|
|
8
8
|
def initialize(children)
|
@@ -23,7 +23,7 @@ module Arel # :nodoc: all
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def hash
|
26
|
-
children.hash
|
26
|
+
[self.class, children].hash
|
27
27
|
end
|
28
28
|
|
29
29
|
def eql?(other)
|
@@ -32,5 +32,8 @@ module Arel # :nodoc: all
|
|
32
32
|
end
|
33
33
|
alias :== :eql?
|
34
34
|
end
|
35
|
+
|
36
|
+
And = Class.new(Nary)
|
37
|
+
Or = Class.new(Nary)
|
35
38
|
end
|
36
39
|
end
|
data/lib/arel/nodes/node.rb
CHANGED
@@ -127,7 +127,7 @@ module Arel # :nodoc: all
|
|
127
127
|
# Factory method to create a Nodes::Grouping node that has an Nodes::Or
|
128
128
|
# node as a child.
|
129
129
|
def or(right)
|
130
|
-
Nodes::Grouping.new Nodes::Or.new(self, right)
|
130
|
+
Nodes::Grouping.new Nodes::Or.new([self, right])
|
131
131
|
end
|
132
132
|
|
133
133
|
###
|
@@ -147,8 +147,9 @@ module Arel # :nodoc: all
|
|
147
147
|
# Maybe we should just use `Table.engine`? :'(
|
148
148
|
def to_sql(engine = Table.engine)
|
149
149
|
collector = Arel::Collectors::SQLString.new
|
150
|
-
|
151
|
-
|
150
|
+
engine.with_connection do |connection|
|
151
|
+
connection.visitor.accept(self, collector).value
|
152
|
+
end
|
152
153
|
end
|
153
154
|
|
154
155
|
def fetch_attribute
|
@@ -8,6 +8,13 @@ module Arel # :nodoc: all
|
|
8
8
|
include Arel::AliasPredication
|
9
9
|
include Arel::OrderPredications
|
10
10
|
|
11
|
+
attr_reader :retryable
|
12
|
+
|
13
|
+
def initialize(string, retryable: false)
|
14
|
+
@retryable = retryable
|
15
|
+
super(string)
|
16
|
+
end
|
17
|
+
|
11
18
|
def encode_with(coder)
|
12
19
|
coder.scalar = self.to_s
|
13
20
|
end
|
data/lib/arel/nodes.rb
CHANGED
@@ -41,8 +41,8 @@ require "arel/nodes/matches"
|
|
41
41
|
require "arel/nodes/regexp"
|
42
42
|
require "arel/nodes/cte"
|
43
43
|
|
44
|
-
# nary
|
45
|
-
require "arel/nodes/
|
44
|
+
# nary (And and Or)
|
45
|
+
require "arel/nodes/nary"
|
46
46
|
|
47
47
|
# function
|
48
48
|
# FIXME: Function + Alias can be rewritten as a Function and Alias node.
|
data/lib/arel/predications.rb
CHANGED
@@ -232,7 +232,7 @@ module Arel # :nodoc: all
|
|
232
232
|
def grouping_any(method_id, others, *extras)
|
233
233
|
nodes = others.map { |expr| send(method_id, expr, *extras) }
|
234
234
|
Nodes::Grouping.new nodes.inject { |memo, node|
|
235
|
-
Nodes::Or.new(memo, node)
|
235
|
+
Nodes::Or.new([memo, node])
|
236
236
|
}
|
237
237
|
end
|
238
238
|
|
data/lib/arel/select_manager.rb
CHANGED
data/lib/arel/tree_manager.rb
CHANGED
@@ -52,8 +52,9 @@ module Arel # :nodoc: all
|
|
52
52
|
|
53
53
|
def to_sql(engine = Table.engine)
|
54
54
|
collector = Arel::Collectors::SQLString.new
|
55
|
-
|
56
|
-
|
55
|
+
engine.with_connection do |connection|
|
56
|
+
connection.visitor.accept(@ast, collector).value
|
57
|
+
end
|
57
58
|
end
|
58
59
|
|
59
60
|
def initialize_copy(other)
|
data/lib/arel/update_manager.rb
CHANGED
data/lib/arel/visitors/dot.rb
CHANGED
data/lib/arel/visitors/mysql.rb
CHANGED
@@ -27,7 +27,7 @@ module Arel # :nodoc: all
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def visit_Arel_Nodes_SelectCore(o, collector)
|
30
|
-
o.froms ||= Arel.sql("DUAL")
|
30
|
+
o.froms ||= Arel.sql("DUAL", retryable: true)
|
31
31
|
super
|
32
32
|
end
|
33
33
|
|
@@ -59,9 +59,14 @@ module Arel # :nodoc: all
|
|
59
59
|
infix_value o, collector, " NOT REGEXP "
|
60
60
|
end
|
61
61
|
|
62
|
-
# no-op
|
63
62
|
def visit_Arel_Nodes_NullsFirst(o, collector)
|
64
|
-
visit
|
63
|
+
visit(o.expr.expr, collector) << " IS NOT NULL, "
|
64
|
+
visit(o.expr, collector)
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_Arel_Nodes_NullsLast(o, collector)
|
68
|
+
visit(o.expr.expr, collector) << " IS NULL, "
|
69
|
+
visit(o.expr, collector)
|
65
70
|
end
|
66
71
|
|
67
72
|
def visit_Arel_Nodes_Cte(o, collector)
|
@@ -98,7 +103,7 @@ module Arel # :nodoc: all
|
|
98
103
|
Nodes::SelectStatement.new.tap do |stmt|
|
99
104
|
core = stmt.cores.last
|
100
105
|
core.froms = Nodes::Grouping.new(subselect).as("__active_record_temp")
|
101
|
-
core.projections = [Arel.sql(quote_column_name(key.name))]
|
106
|
+
core.projections = [Arel.sql(quote_column_name(key.name), retryable: true)]
|
102
107
|
end
|
103
108
|
end
|
104
109
|
end
|
@@ -63,7 +63,7 @@ module Arel # :nodoc: all
|
|
63
63
|
|
64
64
|
def visit_Arel_Nodes_Lateral(o, collector)
|
65
65
|
collector << "LATERAL "
|
66
|
-
grouping_parentheses o, collector
|
66
|
+
grouping_parentheses o.expr, collector
|
67
67
|
end
|
68
68
|
|
69
69
|
def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
|
@@ -83,17 +83,6 @@ module Arel # :nodoc: all
|
|
83
83
|
|
84
84
|
def bind_block; BIND_BLOCK; end
|
85
85
|
|
86
|
-
# Used by Lateral visitor to enclose select queries in parentheses
|
87
|
-
def grouping_parentheses(o, collector)
|
88
|
-
if o.expr.is_a? Nodes::SelectStatement
|
89
|
-
collector << "("
|
90
|
-
visit o.expr, collector
|
91
|
-
collector << ")"
|
92
|
-
else
|
93
|
-
visit o.expr, collector
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
86
|
# Utilized by GroupingSet, Cube & RollUp visitors to
|
98
87
|
# handle grouping aggregation semantics
|
99
88
|
def grouping_array_or_grouping_element(o, collector)
|