activerecord 7.1.5.1 → 7.2.2.1

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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +645 -2329
  3. data/README.rdoc +15 -15
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +1 -1
  6. data/lib/active_record/associations/alias_tracker.rb +25 -19
  7. data/lib/active_record/associations/association.rb +15 -8
  8. data/lib/active_record/associations/belongs_to_association.rb +14 -7
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/belongs_to.rb +1 -0
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  12. data/lib/active_record/associations/builder/has_many.rb +3 -4
  13. data/lib/active_record/associations/builder/has_one.rb +3 -4
  14. data/lib/active_record/associations/collection_association.rb +7 -1
  15. data/lib/active_record/associations/collection_proxy.rb +14 -1
  16. data/lib/active_record/associations/errors.rb +265 -0
  17. data/lib/active_record/associations/has_many_association.rb +1 -1
  18. data/lib/active_record/associations/has_many_through_association.rb +7 -1
  19. data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
  20. data/lib/active_record/associations/nested_error.rb +47 -0
  21. data/lib/active_record/associations/preloader/association.rb +2 -1
  22. data/lib/active_record/associations/preloader/branch.rb +7 -1
  23. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  24. data/lib/active_record/associations/singular_association.rb +6 -0
  25. data/lib/active_record/associations/through_association.rb +1 -1
  26. data/lib/active_record/associations.rb +59 -292
  27. data/lib/active_record/attribute_assignment.rb +0 -2
  28. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  29. data/lib/active_record/attribute_methods/primary_key.rb +23 -55
  30. data/lib/active_record/attribute_methods/read.rb +1 -13
  31. data/lib/active_record/attribute_methods/serialization.rb +4 -24
  32. data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -6
  33. data/lib/active_record/attribute_methods.rb +54 -63
  34. data/lib/active_record/attributes.rb +61 -47
  35. data/lib/active_record/autosave_association.rb +12 -29
  36. data/lib/active_record/base.rb +2 -3
  37. data/lib/active_record/callbacks.rb +1 -1
  38. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
  39. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
  40. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +270 -65
  41. data/lib/active_record/connection_adapters/abstract/database_statements.rb +34 -17
  42. data/lib/active_record/connection_adapters/abstract/query_cache.rb +189 -74
  43. data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
  44. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  45. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +15 -6
  46. data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
  47. data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -44
  48. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +40 -10
  49. data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
  50. data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
  51. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +6 -0
  52. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +16 -15
  53. data/lib/active_record/connection_adapters/mysql2_adapter.rb +5 -23
  54. data/lib/active_record/connection_adapters/pool_config.rb +7 -6
  55. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
  56. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  57. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  58. data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
  59. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
  60. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -11
  61. data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -24
  62. data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
  63. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  64. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
  65. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
  66. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  67. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  68. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  69. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
  70. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +125 -75
  71. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
  72. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -48
  73. data/lib/active_record/connection_adapters.rb +121 -0
  74. data/lib/active_record/connection_handling.rb +56 -41
  75. data/lib/active_record/core.rb +85 -37
  76. data/lib/active_record/counter_cache.rb +18 -9
  77. data/lib/active_record/database_configurations/connection_url_resolver.rb +7 -2
  78. data/lib/active_record/database_configurations/database_config.rb +19 -4
  79. data/lib/active_record/database_configurations/hash_config.rb +38 -34
  80. data/lib/active_record/database_configurations/url_config.rb +20 -1
  81. data/lib/active_record/database_configurations.rb +1 -1
  82. data/lib/active_record/delegated_type.rb +24 -0
  83. data/lib/active_record/dynamic_matchers.rb +2 -2
  84. data/lib/active_record/encryption/encryptable_record.rb +3 -3
  85. data/lib/active_record/encryption/encrypted_attribute_type.rb +24 -4
  86. data/lib/active_record/encryption/encryptor.rb +18 -3
  87. data/lib/active_record/encryption/key_provider.rb +1 -1
  88. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  89. data/lib/active_record/encryption/message_serializer.rb +4 -0
  90. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  91. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  92. data/lib/active_record/enum.rb +18 -1
  93. data/lib/active_record/errors.rb +46 -20
  94. data/lib/active_record/explain.rb +13 -24
  95. data/lib/active_record/fixtures.rb +37 -31
  96. data/lib/active_record/future_result.rb +8 -4
  97. data/lib/active_record/gem_version.rb +2 -2
  98. data/lib/active_record/inheritance.rb +4 -2
  99. data/lib/active_record/insert_all.rb +18 -15
  100. data/lib/active_record/integration.rb +4 -1
  101. data/lib/active_record/internal_metadata.rb +48 -34
  102. data/lib/active_record/locking/optimistic.rb +7 -6
  103. data/lib/active_record/log_subscriber.rb +0 -21
  104. data/lib/active_record/message_pack.rb +1 -1
  105. data/lib/active_record/migration/command_recorder.rb +2 -3
  106. data/lib/active_record/migration/compatibility.rb +5 -3
  107. data/lib/active_record/migration/default_strategy.rb +4 -5
  108. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  109. data/lib/active_record/migration.rb +85 -76
  110. data/lib/active_record/model_schema.rb +31 -68
  111. data/lib/active_record/nested_attributes.rb +11 -3
  112. data/lib/active_record/normalization.rb +3 -7
  113. data/lib/active_record/persistence.rb +30 -352
  114. data/lib/active_record/query_cache.rb +19 -8
  115. data/lib/active_record/query_logs.rb +15 -0
  116. data/lib/active_record/querying.rb +21 -9
  117. data/lib/active_record/railtie.rb +37 -55
  118. data/lib/active_record/railties/controller_runtime.rb +13 -4
  119. data/lib/active_record/railties/databases.rake +40 -43
  120. data/lib/active_record/reflection.rb +98 -36
  121. data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
  122. data/lib/active_record/relation/batches.rb +14 -8
  123. data/lib/active_record/relation/calculations.rb +96 -63
  124. data/lib/active_record/relation/delegation.rb +8 -11
  125. data/lib/active_record/relation/finder_methods.rb +16 -2
  126. data/lib/active_record/relation/merger.rb +4 -6
  127. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  128. data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
  129. data/lib/active_record/relation/predicate_builder.rb +3 -3
  130. data/lib/active_record/relation/query_methods.rb +224 -58
  131. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  132. data/lib/active_record/relation/spawn_methods.rb +2 -18
  133. data/lib/active_record/relation/where_clause.rb +7 -19
  134. data/lib/active_record/relation.rb +496 -72
  135. data/lib/active_record/result.rb +31 -44
  136. data/lib/active_record/runtime_registry.rb +39 -0
  137. data/lib/active_record/sanitization.rb +24 -19
  138. data/lib/active_record/schema.rb +8 -6
  139. data/lib/active_record/schema_dumper.rb +19 -9
  140. data/lib/active_record/schema_migration.rb +30 -14
  141. data/lib/active_record/scoping/named.rb +1 -0
  142. data/lib/active_record/signed_id.rb +20 -1
  143. data/lib/active_record/statement_cache.rb +7 -7
  144. data/lib/active_record/table_metadata.rb +1 -10
  145. data/lib/active_record/tasks/database_tasks.rb +69 -41
  146. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  147. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  148. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
  149. data/lib/active_record/test_fixtures.rb +86 -89
  150. data/lib/active_record/testing/query_assertions.rb +121 -0
  151. data/lib/active_record/timestamp.rb +2 -2
  152. data/lib/active_record/token_for.rb +22 -12
  153. data/lib/active_record/touch_later.rb +1 -1
  154. data/lib/active_record/transaction.rb +132 -0
  155. data/lib/active_record/transactions.rb +70 -14
  156. data/lib/active_record/translation.rb +0 -2
  157. data/lib/active_record/type/serialized.rb +1 -3
  158. data/lib/active_record/type_caster/connection.rb +4 -4
  159. data/lib/active_record/validations/associated.rb +9 -3
  160. data/lib/active_record/validations/uniqueness.rb +15 -10
  161. data/lib/active_record/validations.rb +4 -1
  162. data/lib/active_record.rb +148 -39
  163. data/lib/arel/alias_predication.rb +1 -1
  164. data/lib/arel/collectors/bind.rb +2 -0
  165. data/lib/arel/collectors/composite.rb +7 -0
  166. data/lib/arel/collectors/sql_string.rb +1 -1
  167. data/lib/arel/collectors/substitute_binds.rb +1 -1
  168. data/lib/arel/nodes/binary.rb +0 -6
  169. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  170. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  171. data/lib/arel/nodes/node.rb +4 -3
  172. data/lib/arel/nodes/sql_literal.rb +7 -0
  173. data/lib/arel/nodes.rb +2 -2
  174. data/lib/arel/predications.rb +1 -1
  175. data/lib/arel/select_manager.rb +1 -1
  176. data/lib/arel/tree_manager.rb +3 -2
  177. data/lib/arel/update_manager.rb +2 -1
  178. data/lib/arel/visitors/dot.rb +1 -0
  179. data/lib/arel/visitors/mysql.rb +9 -4
  180. data/lib/arel/visitors/postgresql.rb +1 -12
  181. data/lib/arel/visitors/sqlite.rb +25 -0
  182. data/lib/arel/visitors/to_sql.rb +29 -16
  183. data/lib/arel.rb +7 -3
  184. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  185. metadata +16 -10
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_record/associations/nested_error"
4
+
3
5
  module ActiveRecord
4
6
  # = Active Record Autosave Association
5
7
  #
@@ -315,7 +317,7 @@ module ActiveRecord
315
317
  def validate_single_association(reflection)
316
318
  association = association_instance_get(reflection.name)
317
319
  record = association && association.reader
318
- association_valid?(reflection, record) if record && (record.changed_for_autosave? || custom_validation_context?)
320
+ association_valid?(association, record) if record && (record.changed_for_autosave? || custom_validation_context?)
319
321
  end
320
322
 
321
323
  # Validate the associated records if <tt>:validate</tt> or
@@ -324,7 +326,7 @@ module ActiveRecord
324
326
  def validate_collection_association(reflection)
325
327
  if association = association_instance_get(reflection.name)
326
328
  if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
327
- records.each_with_index { |record, index| association_valid?(reflection, record, index) }
329
+ records.each { |record| association_valid?(association, record) }
328
330
  end
329
331
  end
330
332
  end
@@ -332,40 +334,25 @@ module ActiveRecord
332
334
  # Returns whether or not the association is valid and applies any errors to
333
335
  # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
334
336
  # enabled records if they're marked_for_destruction? or destroyed.
335
- def association_valid?(reflection, record, index = nil)
336
- return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
337
+ def association_valid?(association, record)
338
+ return true if record.destroyed? || (association.options[:autosave] && record.marked_for_destruction?)
337
339
 
338
340
  context = validation_context if custom_validation_context?
339
341
 
340
342
  unless valid = record.valid?(context)
341
- if reflection.options[:autosave]
342
- indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord.index_nested_attribute_errors)
343
-
344
- record.errors.group_by_attribute.each { |attribute, errors|
345
- attribute = normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
346
-
347
- errors.each { |error|
348
- self.errors.import(
349
- error,
350
- attribute: attribute
351
- )
352
- }
343
+ if association.options[:autosave]
344
+ record.errors.each { |error|
345
+ self.errors.objects.append(
346
+ Associations::NestedError.new(association, error)
347
+ )
353
348
  }
354
349
  else
355
- errors.add(reflection.name)
350
+ errors.add(association.reflection.name)
356
351
  end
357
352
  end
358
353
  valid
359
354
  end
360
355
 
361
- def normalize_reflection_attribute(indexed_attribute, reflection, index, attribute)
362
- if indexed_attribute
363
- "#{reflection.name}[#{index}].#{attribute}"
364
- else
365
- "#{reflection.name}.#{attribute}"
366
- end
367
- end
368
-
369
356
  # Is used as an around_save callback to check while saving a collection
370
357
  # association whether or not the parent was a new record before saving.
371
358
  def around_save_collection_association
@@ -550,10 +537,6 @@ module ActiveRecord
550
537
  end
551
538
  end
552
539
 
553
- def custom_validation_context?
554
- validation_context && [:create, :update].exclude?(validation_context)
555
- end
556
-
557
540
  def _ensure_no_duplicate_errors
558
541
  errors.uniq!
559
542
  end
@@ -233,7 +233,7 @@ module ActiveRecord # :nodoc:
233
233
  #
234
234
  # Connections are usually created through
235
235
  # {ActiveRecord::Base.establish_connection}[rdoc-ref:ConnectionHandling#establish_connection] and retrieved
236
- # by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
236
+ # by ActiveRecord::Base.lease_connection. All classes inheriting from ActiveRecord::Base will use this
237
237
  # connection. But you can also set a class-specific connection. For example, if Course is an
238
238
  # ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
239
239
  # and Course and all of its subclasses will use this connection instead.
@@ -280,7 +280,7 @@ module ActiveRecord # :nodoc:
280
280
  # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
281
281
  # instances in the current object space.
282
282
  class Base
283
- extend ActiveModel::Naming
283
+ include ActiveModel::API
284
284
 
285
285
  extend ActiveSupport::Benchmarkable
286
286
  extend ActiveSupport::DescendantsTracker
@@ -304,7 +304,6 @@ module ActiveRecord # :nodoc:
304
304
  include Scoping
305
305
  include Sanitization
306
306
  include AttributeAssignment
307
- include ActiveModel::Conversion
308
307
  include Integration
309
308
  include Validations
310
309
  include CounterCache
@@ -418,7 +418,7 @@ module ActiveRecord
418
418
 
419
419
  def destroy # :nodoc:
420
420
  @_destroy_callback_already_called ||= false
421
- return if @_destroy_callback_already_called
421
+ return true if @_destroy_callback_already_called
422
422
  @_destroy_callback_already_called = true
423
423
  _run_destroy_callbacks { super }
424
424
  rescue RecordNotDestroyed => e
@@ -55,9 +55,6 @@ module ActiveRecord
55
55
  # about the model. The model needs to pass a connection specification name to the handler,
56
56
  # in order to look up the correct connection pool.
57
57
  class ConnectionHandler
58
- FINALIZER = lambda { |_| ActiveSupport::ForkTracker.check! }
59
- private_constant :FINALIZER
60
-
61
58
  class StringConnectionName # :nodoc:
62
59
  attr_reader :name
63
60
 
@@ -77,9 +74,6 @@ module ActiveRecord
77
74
  def initialize
78
75
  # These caches are keyed by pool_config.connection_name (PoolConfig#connection_name).
79
76
  @connection_name_to_pool_manager = Concurrent::Map.new(initial_capacity: 2)
80
-
81
- # Backup finalizer: if the forked child skipped Kernel#fork the early discard has not occurred
82
- ObjectSpace.define_finalizer self, FINALIZER
83
77
  end
84
78
 
85
79
  def prevent_writes # :nodoc:
@@ -94,22 +88,10 @@ module ActiveRecord
94
88
  connection_name_to_pool_manager.keys
95
89
  end
96
90
 
97
- def all_connection_pools
98
- ActiveRecord.deprecator.warn(<<-MSG.squish)
99
- The `all_connection_pools` method is deprecated in favor of `connection_pool_list`.
100
- Call `connection_pool_list(:all)` to get the same behavior as `all_connection_pools`.
101
- MSG
102
- connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs.map(&:pool) }
103
- end
104
-
105
- # Returns the pools for a connection handler and given role. If +:all+ is passed,
91
+ # Returns the pools for a connection handler and given role. If +:all+ is passed,
106
92
  # all pools belonging to the connection handler will be returned.
107
93
  def connection_pool_list(role = nil)
108
- if role.nil?
109
- deprecation_for_pool_handling(__method__)
110
- role = ActiveRecord::Base.current_role
111
- connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs(role).map(&:pool) }
112
- elsif role == :all
94
+ if role.nil? || role == :all
113
95
  connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs.map(&:pool) }
114
96
  else
115
97
  connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs(role).map(&:pool) }
@@ -171,11 +153,6 @@ module ActiveRecord
171
153
  # Returns true if there are any active connections among the connection
172
154
  # pools that the ConnectionHandler is managing.
173
155
  def active_connections?(role = nil)
174
- if role.nil?
175
- deprecation_for_pool_handling(__method__)
176
- role = ActiveRecord::Base.current_role
177
- end
178
-
179
156
  each_connection_pool(role).any?(&:active_connection?)
180
157
  end
181
158
 
@@ -183,32 +160,20 @@ module ActiveRecord
183
160
  # and also returns connections to the pool cached by threads that are no
184
161
  # longer alive.
185
162
  def clear_active_connections!(role = nil)
186
- if role.nil?
187
- deprecation_for_pool_handling(__method__)
188
- role = ActiveRecord::Base.current_role
163
+ each_connection_pool(role).each do |pool|
164
+ pool.release_connection
165
+ pool.disable_query_cache!
189
166
  end
190
-
191
- each_connection_pool(role).each(&:release_connection)
192
167
  end
193
168
 
194
169
  # Clears the cache which maps classes.
195
170
  #
196
171
  # See ConnectionPool#clear_reloadable_connections! for details.
197
172
  def clear_reloadable_connections!(role = nil)
198
- if role.nil?
199
- deprecation_for_pool_handling(__method__)
200
- role = ActiveRecord::Base.current_role
201
- end
202
-
203
173
  each_connection_pool(role).each(&:clear_reloadable_connections!)
204
174
  end
205
175
 
206
176
  def clear_all_connections!(role = nil)
207
- if role.nil?
208
- deprecation_for_pool_handling(__method__)
209
- role = ActiveRecord::Base.current_role
210
- end
211
-
212
177
  each_connection_pool(role).each(&:disconnect!)
213
178
  end
214
179
 
@@ -216,11 +181,6 @@ module ActiveRecord
216
181
  #
217
182
  # See ConnectionPool#flush! for details.
218
183
  def flush_idle_connections!(role = nil)
219
- if role.nil?
220
- deprecation_for_pool_handling(__method__)
221
- role = ActiveRecord::Base.current_role
222
- end
223
-
224
184
  each_connection_pool(role).each(&:flush!)
225
185
  end
226
186
 
@@ -229,21 +189,8 @@ module ActiveRecord
229
189
  # opened and set as the active connection for the class it was defined
230
190
  # for (not necessarily the current class).
231
191
  def retrieve_connection(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard) # :nodoc:
232
- pool = retrieve_connection_pool(connection_name, role: role, shard: shard)
233
-
234
- unless pool
235
- if shard != ActiveRecord::Base.default_shard
236
- message = "No connection pool for '#{connection_name}' found for the '#{shard}' shard."
237
- elsif role != ActiveRecord::Base.default_role
238
- message = "No connection pool for '#{connection_name}' found for the '#{role}' role."
239
- else
240
- message = "No connection pool for '#{connection_name}' found."
241
- end
242
-
243
- raise ConnectionNotEstablished, message
244
- end
245
-
246
- pool.connection
192
+ pool = retrieve_connection_pool(connection_name, role: role, shard: shard, strict: true)
193
+ pool.lease_connection
247
194
  end
248
195
 
249
196
  # Returns true if a connection that's accessible to this class has
@@ -262,9 +209,22 @@ module ActiveRecord
262
209
  # Retrieving the connection pool happens a lot, so we cache it in @connection_name_to_pool_manager.
263
210
  # This makes retrieving the connection pool O(1) once the process is warm.
264
211
  # When a connection is established or removed, we invalidate the cache.
265
- def retrieve_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
266
- pool_config = get_pool_manager(connection_name)&.get_pool_config(role, shard)
267
- pool_config&.pool
212
+ def retrieve_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard, strict: false)
213
+ pool = get_pool_manager(connection_name)&.get_pool_config(role, shard)&.pool
214
+
215
+ if strict && !pool
216
+ if shard != ActiveRecord::Base.default_shard
217
+ message = "No connection pool for '#{connection_name}' found for the '#{shard}' shard."
218
+ elsif role != ActiveRecord::Base.default_role
219
+ message = "No connection pool for '#{connection_name}' found for the '#{role}' role."
220
+ else
221
+ message = "No connection pool for '#{connection_name}' found."
222
+ end
223
+
224
+ raise ConnectionNotEstablished, message
225
+ end
226
+
227
+ pool
268
228
  end
269
229
 
270
230
  private
@@ -284,23 +244,6 @@ module ActiveRecord
284
244
  connection_name_to_pool_manager.values
285
245
  end
286
246
 
287
- def deprecation_for_pool_handling(method)
288
- roles = []
289
- pool_managers.each do |pool_manager|
290
- roles << pool_manager.role_names
291
- end
292
-
293
- if roles.flatten.uniq.count > 1
294
- ActiveRecord.deprecator.warn(<<-MSG.squish)
295
- `#{method}` currently only applies to connection pools in the current
296
- role (`#{ActiveRecord::Base.current_role}`). In Rails 7.2, this method
297
- will apply to all known pools, regardless of role. To affect only those
298
- connections belonging to a specific role, pass the role name as an
299
- argument. To switch to the new behavior, pass `:all` as the role name.
300
- MSG
301
- end
302
- end
303
-
304
247
  def disconnect_pool_from_pool_manager(pool_manager, role, shard)
305
248
  pool_config = pool_manager.remove_pool_config(role, shard)
306
249
 
@@ -322,34 +265,8 @@ module ActiveRecord
322
265
  #
323
266
  def resolve_pool_config(config, connection_name, role, shard)
324
267
  db_config = Base.configurations.resolve(config)
325
-
268
+ db_config.validate!
326
269
  raise(AdapterNotSpecified, "database configuration does not specify adapter") unless db_config.adapter
327
-
328
- # Require the adapter itself and give useful feedback about
329
- # 1. Missing adapter gems and
330
- # 2. Adapter gems' missing dependencies.
331
- path_to_adapter = "active_record/connection_adapters/#{db_config.adapter}_adapter"
332
- begin
333
- require path_to_adapter
334
- rescue LoadError => e
335
- # We couldn't require the adapter itself. Raise an exception that
336
- # points out config typos and missing gems.
337
- if e.path == path_to_adapter
338
- # We can assume that a non-builtin adapter was specified, so it's
339
- # either misspelled or missing from Gemfile.
340
- raise LoadError, "Could not load the '#{db_config.adapter}' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
341
-
342
- # Bubbled up from the adapter require. Prefix the exception message
343
- # with some guidance about how to address it and reraise.
344
- else
345
- raise LoadError, "Error loading the '#{db_config.adapter}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
346
- end
347
- end
348
-
349
- unless ActiveRecord::Base.respond_to?(db_config.adapter_method)
350
- raise AdapterNotFound, "database configuration specifies nonexistent #{db_config.adapter} adapter"
351
- end
352
-
353
270
  ConnectionAdapters::PoolConfig.new(connection_name, db_config, role, shard)
354
271
  end
355
272
 
@@ -43,6 +43,7 @@ module ActiveRecord
43
43
  # Advise multi-threaded app servers to ignore this thread for
44
44
  # the purposes of fork safety warnings
45
45
  Thread.current.thread_variable_set(:fork_safe, true)
46
+ Thread.current.name = "AR Pool Reaper"
46
47
  running = true
47
48
  while running
48
49
  sleep t