activerecord 6.1.7 → 7.0.0

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.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (238) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1055 -1125
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +0 -10
  7. data/lib/active_record/associations/association.rb +33 -17
  8. data/lib/active_record/associations/association_scope.rb +1 -3
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +8 -2
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_many.rb +3 -2
  15. data/lib/active_record/associations/builder/has_one.rb +2 -1
  16. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  17. data/lib/active_record/associations/collection_association.rb +18 -19
  18. data/lib/active_record/associations/collection_proxy.rb +8 -3
  19. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  20. data/lib/active_record/associations/has_many_association.rb +1 -1
  21. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  22. data/lib/active_record/associations/has_one_association.rb +10 -7
  23. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  24. data/lib/active_record/associations/join_dependency.rb +6 -2
  25. data/lib/active_record/associations/preloader/association.rb +186 -52
  26. data/lib/active_record/associations/preloader/batch.rb +48 -0
  27. data/lib/active_record/associations/preloader/branch.rb +147 -0
  28. data/lib/active_record/associations/preloader/through_association.rb +49 -13
  29. data/lib/active_record/associations/preloader.rb +39 -113
  30. data/lib/active_record/associations/singular_association.rb +8 -2
  31. data/lib/active_record/associations/through_association.rb +3 -3
  32. data/lib/active_record/associations.rb +90 -82
  33. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  34. data/lib/active_record/attribute_assignment.rb +1 -1
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  36. data/lib/active_record/attribute_methods/dirty.rb +49 -16
  37. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  38. data/lib/active_record/attribute_methods/query.rb +2 -2
  39. data/lib/active_record/attribute_methods/read.rb +7 -5
  40. data/lib/active_record/attribute_methods/serialization.rb +66 -12
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  42. data/lib/active_record/attribute_methods/write.rb +7 -10
  43. data/lib/active_record/attribute_methods.rb +13 -14
  44. data/lib/active_record/attributes.rb +24 -35
  45. data/lib/active_record/autosave_association.rb +6 -21
  46. data/lib/active_record/base.rb +19 -1
  47. data/lib/active_record/callbacks.rb +2 -2
  48. data/lib/active_record/coders/yaml_column.rb +2 -14
  49. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  52. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  53. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  54. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  55. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +34 -13
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +69 -18
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +35 -23
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
  66. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  67. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  68. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
  69. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
  70. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  71. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  72. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  73. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  77. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -50
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
  80. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  81. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  82. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +27 -16
  84. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
  85. data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
  86. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  87. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +15 -16
  88. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
  89. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
  90. data/lib/active_record/connection_adapters.rb +6 -5
  91. data/lib/active_record/connection_handling.rb +47 -53
  92. data/lib/active_record/core.rb +121 -139
  93. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  94. data/lib/active_record/database_configurations/database_config.rb +12 -9
  95. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  96. data/lib/active_record/database_configurations/url_config.rb +2 -2
  97. data/lib/active_record/database_configurations.rb +15 -32
  98. data/lib/active_record/delegated_type.rb +52 -11
  99. data/lib/active_record/destroy_association_async_job.rb +1 -1
  100. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  101. data/lib/active_record/dynamic_matchers.rb +1 -1
  102. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  103. data/lib/active_record/encryption/cipher.rb +53 -0
  104. data/lib/active_record/encryption/config.rb +44 -0
  105. data/lib/active_record/encryption/configurable.rb +61 -0
  106. data/lib/active_record/encryption/context.rb +35 -0
  107. data/lib/active_record/encryption/contexts.rb +72 -0
  108. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  109. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  110. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  111. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  112. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  113. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  114. data/lib/active_record/encryption/encryptor.rb +155 -0
  115. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  116. data/lib/active_record/encryption/errors.rb +15 -0
  117. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  118. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  119. data/lib/active_record/encryption/key.rb +28 -0
  120. data/lib/active_record/encryption/key_generator.rb +42 -0
  121. data/lib/active_record/encryption/key_provider.rb +46 -0
  122. data/lib/active_record/encryption/message.rb +33 -0
  123. data/lib/active_record/encryption/message_serializer.rb +90 -0
  124. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  125. data/lib/active_record/encryption/properties.rb +76 -0
  126. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  127. data/lib/active_record/encryption/scheme.rb +99 -0
  128. data/lib/active_record/encryption.rb +55 -0
  129. data/lib/active_record/enum.rb +49 -42
  130. data/lib/active_record/errors.rb +67 -4
  131. data/lib/active_record/explain_registry.rb +11 -6
  132. data/lib/active_record/fixture_set/file.rb +15 -1
  133. data/lib/active_record/fixture_set/table_row.rb +41 -6
  134. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  135. data/lib/active_record/fixtures.rb +17 -20
  136. data/lib/active_record/future_result.rb +139 -0
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +55 -17
  139. data/lib/active_record/insert_all.rb +80 -14
  140. data/lib/active_record/integration.rb +4 -3
  141. data/lib/active_record/internal_metadata.rb +1 -5
  142. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  143. data/lib/active_record/locking/optimistic.rb +10 -9
  144. data/lib/active_record/locking/pessimistic.rb +9 -3
  145. data/lib/active_record/log_subscriber.rb +14 -3
  146. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  147. data/lib/active_record/middleware/database_selector.rb +8 -3
  148. data/lib/active_record/middleware/shard_selector.rb +60 -0
  149. data/lib/active_record/migration/command_recorder.rb +4 -4
  150. data/lib/active_record/migration/compatibility.rb +89 -10
  151. data/lib/active_record/migration/join_table.rb +1 -1
  152. data/lib/active_record/migration.rb +110 -80
  153. data/lib/active_record/model_schema.rb +45 -58
  154. data/lib/active_record/nested_attributes.rb +13 -12
  155. data/lib/active_record/no_touching.rb +3 -3
  156. data/lib/active_record/null_relation.rb +2 -6
  157. data/lib/active_record/persistence.rb +219 -52
  158. data/lib/active_record/query_cache.rb +2 -2
  159. data/lib/active_record/query_logs.rb +138 -0
  160. data/lib/active_record/querying.rb +15 -5
  161. data/lib/active_record/railtie.rb +127 -17
  162. data/lib/active_record/railties/controller_runtime.rb +1 -1
  163. data/lib/active_record/railties/databases.rake +66 -129
  164. data/lib/active_record/readonly_attributes.rb +11 -0
  165. data/lib/active_record/reflection.rb +67 -50
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  167. data/lib/active_record/relation/batches.rb +3 -3
  168. data/lib/active_record/relation/calculations.rb +40 -36
  169. data/lib/active_record/relation/delegation.rb +6 -6
  170. data/lib/active_record/relation/finder_methods.rb +31 -35
  171. data/lib/active_record/relation/merger.rb +20 -13
  172. data/lib/active_record/relation/predicate_builder.rb +1 -6
  173. data/lib/active_record/relation/query_attribute.rb +5 -11
  174. data/lib/active_record/relation/query_methods.rb +235 -61
  175. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  176. data/lib/active_record/relation/spawn_methods.rb +2 -2
  177. data/lib/active_record/relation/where_clause.rb +10 -19
  178. data/lib/active_record/relation.rb +169 -84
  179. data/lib/active_record/result.rb +17 -7
  180. data/lib/active_record/runtime_registry.rb +9 -13
  181. data/lib/active_record/sanitization.rb +11 -7
  182. data/lib/active_record/schema_dumper.rb +10 -3
  183. data/lib/active_record/schema_migration.rb +4 -4
  184. data/lib/active_record/scoping/default.rb +61 -12
  185. data/lib/active_record/scoping/named.rb +3 -11
  186. data/lib/active_record/scoping.rb +64 -34
  187. data/lib/active_record/serialization.rb +1 -1
  188. data/lib/active_record/signed_id.rb +1 -1
  189. data/lib/active_record/store.rb +1 -6
  190. data/lib/active_record/suppressor.rb +11 -15
  191. data/lib/active_record/tasks/database_tasks.rb +116 -58
  192. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  193. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
  194. data/lib/active_record/test_databases.rb +1 -1
  195. data/lib/active_record/test_fixtures.rb +9 -13
  196. data/lib/active_record/timestamp.rb +3 -4
  197. data/lib/active_record/transactions.rb +9 -14
  198. data/lib/active_record/translation.rb +2 -2
  199. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  200. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  201. data/lib/active_record/type/internal/timezone.rb +2 -2
  202. data/lib/active_record/type/serialized.rb +1 -1
  203. data/lib/active_record/type/type_map.rb +17 -20
  204. data/lib/active_record/type.rb +1 -2
  205. data/lib/active_record/validations/associated.rb +1 -1
  206. data/lib/active_record/validations/uniqueness.rb +1 -1
  207. data/lib/active_record.rb +204 -28
  208. data/lib/arel/attributes/attribute.rb +0 -8
  209. data/lib/arel/crud.rb +28 -22
  210. data/lib/arel/delete_manager.rb +18 -4
  211. data/lib/arel/filter_predications.rb +9 -0
  212. data/lib/arel/insert_manager.rb +2 -3
  213. data/lib/arel/nodes/casted.rb +1 -1
  214. data/lib/arel/nodes/delete_statement.rb +12 -13
  215. data/lib/arel/nodes/filter.rb +10 -0
  216. data/lib/arel/nodes/function.rb +1 -0
  217. data/lib/arel/nodes/insert_statement.rb +2 -2
  218. data/lib/arel/nodes/select_core.rb +2 -2
  219. data/lib/arel/nodes/select_statement.rb +2 -2
  220. data/lib/arel/nodes/update_statement.rb +8 -3
  221. data/lib/arel/nodes.rb +1 -0
  222. data/lib/arel/predications.rb +11 -3
  223. data/lib/arel/select_manager.rb +10 -4
  224. data/lib/arel/table.rb +0 -1
  225. data/lib/arel/tree_manager.rb +0 -12
  226. data/lib/arel/update_manager.rb +18 -4
  227. data/lib/arel/visitors/dot.rb +80 -90
  228. data/lib/arel/visitors/mysql.rb +8 -2
  229. data/lib/arel/visitors/postgresql.rb +0 -10
  230. data/lib/arel/visitors/to_sql.rb +58 -2
  231. data/lib/arel.rb +2 -1
  232. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  233. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  234. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  235. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  236. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  237. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  238. metadata +58 -14
@@ -17,20 +17,7 @@ module ActiveRecord
17
17
  # Accepts a logger conforming to the interface of Log4r which is then
18
18
  # passed on to any new database connections made and which can be
19
19
  # retrieved on both a class and instance level by calling +logger+.
20
- mattr_accessor :logger, instance_writer: false
21
-
22
- ##
23
- # :singleton-method:
24
- #
25
- # Specifies if the methods calling database queries should be logged below
26
- # their relevant queries. Defaults to false.
27
- mattr_accessor :verbose_query_logs, instance_writer: false, default: false
28
-
29
- ##
30
- # :singleton-method:
31
- #
32
- # Specifies the names of the queues used by background jobs.
33
- mattr_accessor :queues, instance_accessor: false, default: {}
20
+ class_attribute :logger, instance_writer: false
34
21
 
35
22
  ##
36
23
  # :singleton-method:
@@ -72,80 +59,17 @@ module ActiveRecord
72
59
 
73
60
  ##
74
61
  # :singleton-method:
75
- # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
76
- # dates and times from the database. This is set to :utc by default.
77
- mattr_accessor :default_timezone, instance_writer: false, default: :utc
78
-
79
- ##
80
- # :singleton-method:
81
- # Specifies the format to use when dumping the database schema with Rails'
82
- # Rakefile. If :sql, the schema is dumped as (potentially database-
83
- # specific) SQL statements. If :ruby, the schema is dumped as an
84
- # ActiveRecord::Schema file which can be loaded into any database that
85
- # supports migrations. Use :ruby if you want to have different database
86
- # adapters for, e.g., your development and test environments.
87
- mattr_accessor :schema_format, instance_writer: false, default: :ruby
88
-
89
- ##
90
- # :singleton-method:
91
- # Specifies if an error should be raised if the query has an order being
92
- # ignored when doing batch queries. Useful in applications where the
93
- # scope being ignored is error-worthy, rather than a warning.
94
- mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
95
-
96
- ##
97
- # :singleton-method:
98
- # Specify whether or not to use timestamps for migration versions
99
- mattr_accessor :timestamped_migrations, instance_writer: false, default: true
100
-
101
- ##
102
- # :singleton-method:
103
- # Specify whether schema dump should happen at the end of the
104
- # db:migrate rails command. This is true by default, which is useful for the
105
- # development environment. This should ideally be false in the production
106
- # environment where dumping schema is rarely needed.
107
- mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
108
-
109
- ##
110
- # :singleton-method:
111
- # Specifies which database schemas to dump when calling db:schema:dump.
112
- # If the value is :schema_search_path (the default), any schemas listed in
113
- # schema_search_path are dumped. Use :all to dump all schemas regardless
114
- # of schema_search_path, or a string of comma separated schemas for a
115
- # custom list.
116
- mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
117
-
118
- ##
119
- # :singleton-method:
120
- # Specify a threshold for the size of query result sets. If the number of
121
- # records in the set exceeds the threshold, a warning is logged. This can
122
- # be used to identify queries which load thousands of records and
123
- # potentially cause memory bloat.
124
- mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
125
-
126
- ##
127
- # :singleton-method:
128
- # Show a warning when Rails couldn't parse your database.yml
129
- # for multiple databases.
130
- mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false
131
-
132
- mattr_accessor :maintain_test_schema, instance_accessor: false
62
+ # Force enumeration of all columns in SELECT statements.
63
+ # e.g. `SELECT first_name, last_name FROM ...` instead of `SELECT * FROM ...`
64
+ # This avoids +PreparedStatementCacheExpired+ errors when a column is added
65
+ # to the database while the app is running.
66
+ class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
133
67
 
134
68
  class_attribute :belongs_to_required_by_default, instance_accessor: false
135
69
 
136
- ##
137
- # :singleton-method:
138
- # Set the application to log or raise when an association violates strict loading.
139
- # Defaults to :raise.
140
- mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise
141
-
142
70
  class_attribute :strict_loading_by_default, instance_accessor: false, default: false
143
71
 
144
- mattr_accessor :writing_role, instance_accessor: false, default: :writing
145
-
146
- mattr_accessor :reading_role, instance_accessor: false, default: :reading
147
-
148
- mattr_accessor :has_many_inversing, instance_accessor: false, default: false
72
+ class_attribute :has_many_inversing, instance_accessor: false, default: false
149
73
 
150
74
  class_attribute :default_connection_handler, instance_writer: false
151
75
 
@@ -153,28 +77,31 @@ module ActiveRecord
153
77
 
154
78
  class_attribute :default_shard, instance_writer: false
155
79
 
156
- mattr_accessor :legacy_connection_handling, instance_writer: false, default: true
80
+ class_attribute :shard_selector, instance_accessor: false, default: nil
157
81
 
158
- # Application configurable boolean that instructs the YAML Coder to use
159
- # an unsafe load if set to true.
160
- mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
161
-
162
- # Application configurable array that provides additional permitted classes
163
- # to Psych safe_load in the YAML Coder
164
- mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: [Symbol]
82
+ def self.application_record_class? # :nodoc:
83
+ if ActiveRecord.application_record_class
84
+ self == ActiveRecord.application_record_class
85
+ else
86
+ if defined?(ApplicationRecord) && self == ApplicationRecord
87
+ true
88
+ end
89
+ end
90
+ end
165
91
 
166
92
  self.filter_attributes = []
167
93
 
168
94
  def self.connection_handler
169
- Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
95
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
170
96
  end
171
97
 
172
98
  def self.connection_handler=(handler)
173
- Thread.current.thread_variable_set(:ar_connection_handler, handler)
99
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
174
100
  end
175
101
 
176
102
  def self.connection_handlers
177
- unless legacy_connection_handling
103
+ if ActiveRecord.legacy_connection_handling
104
+ else
178
105
  raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
179
106
  end
180
107
 
@@ -182,13 +109,32 @@ module ActiveRecord
182
109
  end
183
110
 
184
111
  def self.connection_handlers=(handlers)
185
- unless legacy_connection_handling
186
- raise NotImplementedError, "The new connection handling does not setting support multiple connection handlers."
112
+ if ActiveRecord.legacy_connection_handling
113
+ ActiveSupport::Deprecation.warn(<<~MSG)
114
+ Using legacy connection handling is deprecated. Please set
115
+ `legacy_connection_handling` to `false` in your application.
116
+
117
+ The new connection handling does not support `connection_handlers`
118
+ getter and setter.
119
+
120
+ Read more about how to migrate at: https://guides.rubyonrails.org/active_record_multiple_databases.html#migrate-to-the-new-connection-handling
121
+ MSG
122
+ else
123
+ raise NotImplementedError, "The new connection handling does not support multiple connection handlers."
187
124
  end
188
125
 
189
126
  @@connection_handlers = handlers
190
127
  end
191
128
 
129
+ def self.asynchronous_queries_session # :nodoc:
130
+ asynchronous_queries_tracker.current_session
131
+ end
132
+
133
+ def self.asynchronous_queries_tracker # :nodoc:
134
+ ActiveSupport::IsolatedExecutionState[:active_record_asynchronous_queries_tracker] ||= \
135
+ AsynchronousQueriesTracker.new
136
+ end
137
+
192
138
  # Returns the symbol representing the current connected role.
193
139
  #
194
140
  # ActiveRecord::Base.connected_to(role: :writing) do
@@ -199,12 +145,12 @@ module ActiveRecord
199
145
  # ActiveRecord::Base.current_role #=> :reading
200
146
  # end
201
147
  def self.current_role
202
- if ActiveRecord::Base.legacy_connection_handling
148
+ if ActiveRecord.legacy_connection_handling
203
149
  connection_handlers.key(connection_handler) || default_role
204
150
  else
205
151
  connected_to_stack.reverse_each do |hash|
206
152
  return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
207
- return hash[:role] if hash[:role] && hash[:klasses].include?(connection_classes)
153
+ return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
208
154
  end
209
155
 
210
156
  default_role
@@ -223,7 +169,7 @@ module ActiveRecord
223
169
  def self.current_shard
224
170
  connected_to_stack.reverse_each do |hash|
225
171
  return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
226
- return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_classes)
172
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
227
173
  end
228
174
 
229
175
  default_shard
@@ -240,12 +186,12 @@ module ActiveRecord
240
186
  # ActiveRecord::Base.current_preventing_writes #=> false
241
187
  # end
242
188
  def self.current_preventing_writes
243
- if legacy_connection_handling
189
+ if ActiveRecord.legacy_connection_handling
244
190
  connection_handler.prevent_writes
245
191
  else
246
192
  connected_to_stack.reverse_each do |hash|
247
193
  return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
248
- return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_classes)
194
+ return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
249
195
  end
250
196
 
251
197
  false
@@ -253,11 +199,11 @@ module ActiveRecord
253
199
  end
254
200
 
255
201
  def self.connected_to_stack # :nodoc:
256
- if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack)
202
+ if connected_to_stack = ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack]
257
203
  connected_to_stack
258
204
  else
259
205
  connected_to_stack = Concurrent::Array.new
260
- Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
206
+ ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
261
207
  connected_to_stack
262
208
  end
263
209
  end
@@ -266,7 +212,7 @@ module ActiveRecord
266
212
  @connection_class = b
267
213
  end
268
214
 
269
- def self.connection_class # :nodoc
215
+ def self.connection_class # :nodoc:
270
216
  @connection_class ||= false
271
217
  end
272
218
 
@@ -274,7 +220,7 @@ module ActiveRecord
274
220
  self.connection_class
275
221
  end
276
222
 
277
- def self.connection_classes # :nodoc:
223
+ def self.connection_class_for_self # :nodoc:
278
224
  klass = self
279
225
 
280
226
  until klass == Base
@@ -285,20 +231,12 @@ module ActiveRecord
285
231
  klass
286
232
  end
287
233
 
288
- def self.allow_unsafe_raw_sql # :nodoc:
289
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 7.0")
290
- end
291
-
292
- def self.allow_unsafe_raw_sql=(value) # :nodoc:
293
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 7.0")
294
- end
295
-
296
234
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
297
- self.default_role = writing_role
235
+ self.default_role = ActiveRecord.writing_role
298
236
  self.default_shard = :default
299
237
 
300
238
  def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
301
- case action_on_strict_loading_violation
239
+ case ActiveRecord.action_on_strict_loading_violation
302
240
  when :raise
303
241
  message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
304
242
  raise ActiveRecord::StrictLoadingViolationError.new(message)
@@ -389,7 +327,32 @@ module ActiveRecord
389
327
  end
390
328
 
391
329
  def find_by!(*args) # :nodoc:
392
- find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
330
+ find_by(*args) || where(*args).raise_record_not_found_exception!
331
+ end
332
+
333
+ %w(
334
+ reading_role writing_role legacy_connection_handling default_timezone index_nested_attribute_errors
335
+ verbose_query_logs queues warn_on_records_fetched_greater_than maintain_test_schema
336
+ application_record_class action_on_strict_loading_violation schema_format error_on_ignored_order
337
+ timestamped_migrations dump_schema_after_migration dump_schemas suppress_multiple_database_warning
338
+ ).each do |attr|
339
+ module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
340
+ def #{attr}
341
+ ActiveSupport::Deprecation.warn(<<~MSG)
342
+ ActiveRecord::Base.#{attr} is deprecated and will be removed in Rails 7.1.
343
+ Use `ActiveRecord.#{attr}` instead.
344
+ MSG
345
+ ActiveRecord.#{attr}
346
+ end
347
+
348
+ def #{attr}=(value)
349
+ ActiveSupport::Deprecation.warn(<<~MSG)
350
+ ActiveRecord::Base.#{attr}= is deprecated and will be removed in Rails 7.1.
351
+ Use `ActiveRecord.#{attr}=` instead.
352
+ MSG
353
+ ActiveRecord.#{attr} = value
354
+ end
355
+ RUBY
393
356
  end
394
357
 
395
358
  def initialize_generated_modules # :nodoc:
@@ -454,19 +417,10 @@ module ActiveRecord
454
417
  end
455
418
 
456
419
  # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
457
- #
458
- # class Post < ActiveRecord::Base
459
- # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
460
- # end
461
420
  def arel_table # :nodoc:
462
421
  @arel_table ||= Arel::Table.new(table_name, klass: self)
463
422
  end
464
423
 
465
- def arel_attribute(name, table = arel_table) # :nodoc:
466
- table[name]
467
- end
468
- deprecate :arel_attribute
469
-
470
424
  def predicate_builder # :nodoc:
471
425
  @predicate_builder ||= PredicateBuilder.new(table_metadata)
472
426
  end
@@ -475,10 +429,6 @@ module ActiveRecord
475
429
  TypeCaster::Map.new(self)
476
430
  end
477
431
 
478
- def _internal? # :nodoc:
479
- false
480
- end
481
-
482
432
  def cached_find_by_statement(key, &block) # :nodoc:
483
433
  cache = @find_by_statement_cache[connection.prepared_statements]
484
434
  cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
@@ -536,7 +486,7 @@ module ActiveRecord
536
486
  # post.init_with(coder)
537
487
  # post.title # => 'hello world'
538
488
  def init_with(coder, &block)
539
- coder = LegacyYamlAdapter.convert(self.class, coder)
489
+ coder = LegacyYamlAdapter.convert(coder)
540
490
  attributes = self.class.yaml_encoder.decode(coder)
541
491
  init_with_attributes(attributes, coder["new_record"], &block)
542
492
  end
@@ -638,6 +588,8 @@ module ActiveRecord
638
588
  # Delegates to id in order to allow two records of the same type and id to work with something like:
639
589
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
640
590
  def hash
591
+ id = self.id
592
+
641
593
  if id
642
594
  self.class.hash ^ id.hash
643
595
  else
@@ -689,11 +641,37 @@ module ActiveRecord
689
641
  # if the record tries to lazily load an association.
690
642
  #
691
643
  # user = User.first
692
- # user.strict_loading!
693
- # user.comments.to_a
644
+ # user.strict_loading! # => true
645
+ # user.comments
694
646
  # => ActiveRecord::StrictLoadingViolationError
695
- def strict_loading!
696
- @strict_loading = true
647
+ #
648
+ # === Parameters:
649
+ #
650
+ # * value - Boolean specifying whether to enable or disable strict loading.
651
+ # * mode - Symbol specifying strict loading mode. Defaults to :all. Using
652
+ # :n_plus_one_only mode will only raise an error if an association
653
+ # that will lead to an n plus one query is lazily loaded.
654
+ #
655
+ # === Example:
656
+ #
657
+ # user = User.first
658
+ # user.strict_loading!(false) # => false
659
+ # user.comments
660
+ # => #<ActiveRecord::Associations::CollectionProxy>
661
+ def strict_loading!(value = true, mode: :all)
662
+ unless [:all, :n_plus_one_only].include?(mode)
663
+ raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only]."
664
+ end
665
+
666
+ @strict_loading_mode = mode
667
+ @strict_loading = value
668
+ end
669
+
670
+ attr_reader :strict_loading_mode
671
+
672
+ # Returns +true+ if the record uses strict_loading with +:n_plus_one_only+ mode enabled.
673
+ def strict_loading_n_plus_one_only?
674
+ @strict_loading_mode == :n_plus_one_only
697
675
  end
698
676
 
699
677
  # Marks this record as read only.
@@ -710,11 +688,11 @@ module ActiveRecord
710
688
  # We check defined?(@attributes) not to issue warnings if the object is
711
689
  # allocated but not initialized.
712
690
  inspection = if defined?(@attributes) && @attributes
713
- self.class.attribute_names.collect do |name|
691
+ self.class.attribute_names.filter_map do |name|
714
692
  if _has_attribute?(name)
715
693
  "#{name}: #{attribute_for_inspect(name)}"
716
694
  end
717
- end.compact.join(", ")
695
+ end.join(", ")
718
696
  else
719
697
  "not initialized"
720
698
  end
@@ -771,16 +749,20 @@ module ActiveRecord
771
749
  end
772
750
 
773
751
  def init_internals
774
- @primary_key = self.class.primary_key
775
752
  @readonly = false
776
753
  @previously_new_record = false
777
754
  @destroyed = false
778
755
  @marked_for_destruction = false
779
756
  @destroyed_by_association = nil
780
757
  @_start_transaction_state = nil
781
- @strict_loading = self.class.strict_loading_by_default
782
758
 
783
- self.class.define_attribute_methods
759
+ klass = self.class
760
+
761
+ @primary_key = klass.primary_key
762
+ @strict_loading = klass.strict_loading_by_default
763
+ @strict_loading_mode = :all
764
+
765
+ klass.define_attribute_methods
784
766
  end
785
767
 
786
768
  def initialize_internals_callback
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  database: uri.opaque
69
69
  )
70
70
  else
71
- query_hash.merge(
71
+ query_hash.reverse_merge(
72
72
  adapter: @adapter,
73
73
  username: uri.user,
74
74
  password: uri.password,
@@ -15,15 +15,6 @@ module ActiveRecord
15
15
  @name = name
16
16
  end
17
17
 
18
- def spec_name
19
- @name
20
- end
21
- deprecate spec_name: "please use name instead"
22
-
23
- def config
24
- raise NotImplementedError
25
- end
26
-
27
18
  def adapter_method
28
19
  "#{adapter}_connection"
29
20
  end
@@ -48,6 +39,18 @@ module ActiveRecord
48
39
  raise NotImplementedError
49
40
  end
50
41
 
42
+ def min_threads
43
+ raise NotImplementedError
44
+ end
45
+
46
+ def max_threads
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def max_queue
51
+ raise NotImplementedError
52
+ end
53
+
51
54
  def checkout_timeout
52
55
  raise NotImplementedError
53
56
  end
@@ -26,16 +26,12 @@ module ActiveRecord
26
26
  # connections.
27
27
  class HashConfig < DatabaseConfig
28
28
  attr_reader :configuration_hash
29
+
29
30
  def initialize(env_name, name, configuration_hash)
30
31
  super(env_name, name)
31
32
  @configuration_hash = configuration_hash.symbolize_keys.freeze
32
33
  end
33
34
 
34
- def config
35
- ActiveSupport::Deprecation.warn("DatabaseConfig#config will be removed in 7.0.0 in favor of DatabaseConfig#configuration_hash which returns a hash with symbol keys")
36
- configuration_hash.stringify_keys
37
- end
38
-
39
35
  # Determines whether a database configuration is for a replica / readonly
40
36
  # connection. If the +replica+ key is present in the config, +replica?+ will
41
37
  # return +true+.
@@ -54,6 +50,10 @@ module ActiveRecord
54
50
  configuration_hash[:host]
55
51
  end
56
52
 
53
+ def socket # :nodoc:
54
+ configuration_hash[:socket]
55
+ end
56
+
57
57
  def database
58
58
  configuration_hash[:database]
59
59
  end
@@ -66,6 +66,18 @@ module ActiveRecord
66
66
  (configuration_hash[:pool] || 5).to_i
67
67
  end
68
68
 
69
+ def min_threads
70
+ (configuration_hash[:min_threads] || 0).to_i
71
+ end
72
+
73
+ def max_threads
74
+ (configuration_hash[:max_threads] || pool).to_i
75
+ end
76
+
77
+ def max_queue
78
+ max_threads * 4
79
+ end
80
+
69
81
  def checkout_timeout
70
82
  (configuration_hash[:checkout_timeout] || 5).to_f
71
83
  end
@@ -91,6 +103,52 @@ module ActiveRecord
91
103
  def schema_cache_path
92
104
  configuration_hash[:schema_cache_path]
93
105
  end
106
+
107
+ def default_schema_cache_path
108
+ "db/schema_cache.yml"
109
+ end
110
+
111
+ def lazy_schema_cache_path
112
+ schema_cache_path || default_schema_cache_path
113
+ end
114
+
115
+ def primary? # :nodoc:
116
+ Base.configurations.primary?(name)
117
+ end
118
+
119
+ # Determines whether to dump the schema/structure files and the
120
+ # filename that should be used.
121
+ #
122
+ # If +configuration_hash[:schema_dump]+ is set to +false+ or +nil+
123
+ # the schema will not be dumped.
124
+ #
125
+ # If the config option is set that will be used. Otherwise Rails
126
+ # will generate the filename from the database config name.
127
+ def schema_dump(format = ActiveRecord.schema_format)
128
+ if configuration_hash.key?(:schema_dump)
129
+ if config = configuration_hash[:schema_dump]
130
+ config
131
+ end
132
+ elsif primary?
133
+ schema_file_type(format)
134
+ else
135
+ "#{name}_#{schema_file_type(format)}"
136
+ end
137
+ end
138
+
139
+ def database_tasks? # :nodoc:
140
+ !replica? && !!configuration_hash.fetch(:database_tasks, true)
141
+ end
142
+
143
+ private
144
+ def schema_file_type(format)
145
+ case format
146
+ when :ruby
147
+ "schema.rb"
148
+ when :sql
149
+ "structure.sql"
150
+ end
151
+ end
94
152
  end
95
153
  end
96
154
  end
@@ -19,7 +19,7 @@ module ActiveRecord
19
19
  #
20
20
  # ==== Options
21
21
  #
22
- # * <tt>:env_name</tt> - The Rails environment, ie "development".
22
+ # * <tt>:env_name</tt> - The Rails environment, i.e. "development".
23
23
  # * <tt>:name</tt> - The db config name. In a standard two-tier
24
24
  # database configuration this will default to "primary". In a multiple
25
25
  # database three-tier database configuration this corresponds to the name
@@ -42,7 +42,7 @@ module ActiveRecord
42
42
  # Return a Hash that can be merged into the main config that represents
43
43
  # the passed in url
44
44
  def build_url_hash
45
- if url.nil? || %w(jdbc: http: https:).any? { |protocol| url.start_with?(protocol) }
45
+ if url.nil? || url.start_with?("jdbc:", "http:", "https:")
46
46
  { url: url }
47
47
  else
48
48
  ConnectionUrlResolver.new(url).to_hash