activerecord 6.1.4.6 → 7.0.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (240) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1188 -932
  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 +34 -27
  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 +187 -55
  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 +119 -90
  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 +8 -23
  46. data/lib/active_record/base.rb +19 -1
  47. data/lib/active_record/callbacks.rb +2 -2
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +38 -13
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +78 -22
  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 +38 -24
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +5 -1
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  69. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  70. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -12
  72. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  73. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  80. data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -50
  81. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  83. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  84. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  85. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +35 -19
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
  87. data/lib/active_record/connection_adapters/schema_cache.rb +29 -4
  88. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +27 -19
  89. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
  90. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +16 -14
  91. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +89 -30
  92. data/lib/active_record/connection_adapters.rb +6 -5
  93. data/lib/active_record/connection_handling.rb +47 -53
  94. data/lib/active_record/core.rb +122 -132
  95. data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -1
  96. data/lib/active_record/database_configurations/database_config.rb +12 -9
  97. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  98. data/lib/active_record/database_configurations/url_config.rb +2 -2
  99. data/lib/active_record/database_configurations.rb +16 -32
  100. data/lib/active_record/delegated_type.rb +52 -11
  101. data/lib/active_record/destroy_association_async_job.rb +1 -1
  102. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  103. data/lib/active_record/dynamic_matchers.rb +1 -1
  104. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  105. data/lib/active_record/encryption/cipher.rb +53 -0
  106. data/lib/active_record/encryption/config.rb +44 -0
  107. data/lib/active_record/encryption/configurable.rb +61 -0
  108. data/lib/active_record/encryption/context.rb +35 -0
  109. data/lib/active_record/encryption/contexts.rb +72 -0
  110. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  111. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  112. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  113. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  114. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  115. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  116. data/lib/active_record/encryption/encryptor.rb +155 -0
  117. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  118. data/lib/active_record/encryption/errors.rb +15 -0
  119. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  120. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  121. data/lib/active_record/encryption/key.rb +28 -0
  122. data/lib/active_record/encryption/key_generator.rb +42 -0
  123. data/lib/active_record/encryption/key_provider.rb +46 -0
  124. data/lib/active_record/encryption/message.rb +33 -0
  125. data/lib/active_record/encryption/message_serializer.rb +90 -0
  126. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  127. data/lib/active_record/encryption/properties.rb +76 -0
  128. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  129. data/lib/active_record/encryption/scheme.rb +99 -0
  130. data/lib/active_record/encryption.rb +55 -0
  131. data/lib/active_record/enum.rb +49 -42
  132. data/lib/active_record/errors.rb +67 -4
  133. data/lib/active_record/explain_registry.rb +11 -6
  134. data/lib/active_record/fixture_set/file.rb +15 -1
  135. data/lib/active_record/fixture_set/table_row.rb +41 -6
  136. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  137. data/lib/active_record/fixtures.rb +17 -20
  138. data/lib/active_record/future_result.rb +139 -0
  139. data/lib/active_record/gem_version.rb +4 -4
  140. data/lib/active_record/inheritance.rb +55 -17
  141. data/lib/active_record/insert_all.rb +80 -14
  142. data/lib/active_record/integration.rb +4 -3
  143. data/lib/active_record/internal_metadata.rb +3 -5
  144. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  145. data/lib/active_record/locking/optimistic.rb +10 -9
  146. data/lib/active_record/locking/pessimistic.rb +9 -3
  147. data/lib/active_record/log_subscriber.rb +14 -3
  148. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  149. data/lib/active_record/middleware/database_selector.rb +8 -3
  150. data/lib/active_record/middleware/shard_selector.rb +60 -0
  151. data/lib/active_record/migration/command_recorder.rb +4 -4
  152. data/lib/active_record/migration/compatibility.rb +107 -3
  153. data/lib/active_record/migration/join_table.rb +1 -1
  154. data/lib/active_record/migration.rb +109 -79
  155. data/lib/active_record/model_schema.rb +45 -58
  156. data/lib/active_record/nested_attributes.rb +13 -12
  157. data/lib/active_record/no_touching.rb +3 -3
  158. data/lib/active_record/null_relation.rb +2 -6
  159. data/lib/active_record/persistence.rb +219 -52
  160. data/lib/active_record/query_cache.rb +2 -2
  161. data/lib/active_record/query_logs.rb +138 -0
  162. data/lib/active_record/querying.rb +15 -5
  163. data/lib/active_record/railtie.rb +127 -17
  164. data/lib/active_record/railties/controller_runtime.rb +1 -1
  165. data/lib/active_record/railties/databases.rake +66 -129
  166. data/lib/active_record/readonly_attributes.rb +11 -0
  167. data/lib/active_record/reflection.rb +67 -50
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  169. data/lib/active_record/relation/batches.rb +3 -3
  170. data/lib/active_record/relation/calculations.rb +43 -38
  171. data/lib/active_record/relation/delegation.rb +7 -7
  172. data/lib/active_record/relation/finder_methods.rb +31 -35
  173. data/lib/active_record/relation/merger.rb +20 -13
  174. data/lib/active_record/relation/predicate_builder.rb +1 -6
  175. data/lib/active_record/relation/query_attribute.rb +5 -11
  176. data/lib/active_record/relation/query_methods.rb +249 -61
  177. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  178. data/lib/active_record/relation/spawn_methods.rb +2 -2
  179. data/lib/active_record/relation/where_clause.rb +10 -19
  180. data/lib/active_record/relation.rb +184 -84
  181. data/lib/active_record/result.rb +17 -7
  182. data/lib/active_record/runtime_registry.rb +9 -13
  183. data/lib/active_record/sanitization.rb +11 -7
  184. data/lib/active_record/schema.rb +38 -23
  185. data/lib/active_record/schema_dumper.rb +25 -19
  186. data/lib/active_record/schema_migration.rb +4 -4
  187. data/lib/active_record/scoping/default.rb +61 -12
  188. data/lib/active_record/scoping/named.rb +3 -11
  189. data/lib/active_record/scoping.rb +64 -34
  190. data/lib/active_record/serialization.rb +1 -1
  191. data/lib/active_record/signed_id.rb +1 -1
  192. data/lib/active_record/suppressor.rb +11 -15
  193. data/lib/active_record/tasks/database_tasks.rb +120 -58
  194. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  195. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
  196. data/lib/active_record/test_databases.rb +1 -1
  197. data/lib/active_record/test_fixtures.rb +4 -4
  198. data/lib/active_record/timestamp.rb +3 -4
  199. data/lib/active_record/transactions.rb +9 -14
  200. data/lib/active_record/translation.rb +2 -2
  201. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  202. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  203. data/lib/active_record/type/internal/timezone.rb +2 -2
  204. data/lib/active_record/type/serialized.rb +1 -1
  205. data/lib/active_record/type/type_map.rb +17 -20
  206. data/lib/active_record/type.rb +1 -2
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/uniqueness.rb +1 -1
  209. data/lib/active_record.rb +204 -28
  210. data/lib/arel/attributes/attribute.rb +0 -8
  211. data/lib/arel/crud.rb +28 -22
  212. data/lib/arel/delete_manager.rb +18 -4
  213. data/lib/arel/filter_predications.rb +9 -0
  214. data/lib/arel/insert_manager.rb +2 -3
  215. data/lib/arel/nodes/casted.rb +1 -1
  216. data/lib/arel/nodes/delete_statement.rb +12 -13
  217. data/lib/arel/nodes/filter.rb +10 -0
  218. data/lib/arel/nodes/function.rb +1 -0
  219. data/lib/arel/nodes/insert_statement.rb +2 -2
  220. data/lib/arel/nodes/select_core.rb +2 -2
  221. data/lib/arel/nodes/select_statement.rb +2 -2
  222. data/lib/arel/nodes/update_statement.rb +8 -3
  223. data/lib/arel/nodes.rb +1 -0
  224. data/lib/arel/predications.rb +11 -3
  225. data/lib/arel/select_manager.rb +10 -4
  226. data/lib/arel/table.rb +0 -1
  227. data/lib/arel/tree_manager.rb +0 -12
  228. data/lib/arel/update_manager.rb +18 -4
  229. data/lib/arel/visitors/dot.rb +80 -90
  230. data/lib/arel/visitors/mysql.rb +8 -2
  231. data/lib/arel/visitors/postgresql.rb +0 -10
  232. data/lib/arel/visitors/to_sql.rb +58 -2
  233. data/lib/arel.rb +2 -1
  234. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  235. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  236. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  237. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  238. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  239. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  240. metadata +56 -11
@@ -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,20 +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
81
+
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
157
91
 
158
92
  self.filter_attributes = []
159
93
 
160
94
  def self.connection_handler
161
- Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
95
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
162
96
  end
163
97
 
164
98
  def self.connection_handler=(handler)
165
- Thread.current.thread_variable_set(:ar_connection_handler, handler)
99
+ ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
166
100
  end
167
101
 
168
102
  def self.connection_handlers
169
- unless legacy_connection_handling
103
+ if ActiveRecord.legacy_connection_handling
104
+ else
170
105
  raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
171
106
  end
172
107
 
@@ -174,13 +109,32 @@ module ActiveRecord
174
109
  end
175
110
 
176
111
  def self.connection_handlers=(handlers)
177
- unless legacy_connection_handling
178
- 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."
179
124
  end
180
125
 
181
126
  @@connection_handlers = handlers
182
127
  end
183
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
+
184
138
  # Returns the symbol representing the current connected role.
185
139
  #
186
140
  # ActiveRecord::Base.connected_to(role: :writing) do
@@ -191,12 +145,12 @@ module ActiveRecord
191
145
  # ActiveRecord::Base.current_role #=> :reading
192
146
  # end
193
147
  def self.current_role
194
- if ActiveRecord::Base.legacy_connection_handling
148
+ if ActiveRecord.legacy_connection_handling
195
149
  connection_handlers.key(connection_handler) || default_role
196
150
  else
197
151
  connected_to_stack.reverse_each do |hash|
198
152
  return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
199
- 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)
200
154
  end
201
155
 
202
156
  default_role
@@ -215,7 +169,7 @@ module ActiveRecord
215
169
  def self.current_shard
216
170
  connected_to_stack.reverse_each do |hash|
217
171
  return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
218
- 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)
219
173
  end
220
174
 
221
175
  default_shard
@@ -232,12 +186,12 @@ module ActiveRecord
232
186
  # ActiveRecord::Base.current_preventing_writes #=> false
233
187
  # end
234
188
  def self.current_preventing_writes
235
- if legacy_connection_handling
189
+ if ActiveRecord.legacy_connection_handling
236
190
  connection_handler.prevent_writes
237
191
  else
238
192
  connected_to_stack.reverse_each do |hash|
239
193
  return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
240
- 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)
241
195
  end
242
196
 
243
197
  false
@@ -245,11 +199,11 @@ module ActiveRecord
245
199
  end
246
200
 
247
201
  def self.connected_to_stack # :nodoc:
248
- 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]
249
203
  connected_to_stack
250
204
  else
251
205
  connected_to_stack = Concurrent::Array.new
252
- Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
206
+ ActiveSupport::IsolatedExecutionState[:active_record_connected_to_stack] = connected_to_stack
253
207
  connected_to_stack
254
208
  end
255
209
  end
@@ -258,7 +212,7 @@ module ActiveRecord
258
212
  @connection_class = b
259
213
  end
260
214
 
261
- def self.connection_class # :nodoc
215
+ def self.connection_class # :nodoc:
262
216
  @connection_class ||= false
263
217
  end
264
218
 
@@ -266,7 +220,7 @@ module ActiveRecord
266
220
  self.connection_class
267
221
  end
268
222
 
269
- def self.connection_classes # :nodoc:
223
+ def self.connection_class_for_self # :nodoc:
270
224
  klass = self
271
225
 
272
226
  until klass == Base
@@ -277,20 +231,12 @@ module ActiveRecord
277
231
  klass
278
232
  end
279
233
 
280
- def self.allow_unsafe_raw_sql # :nodoc:
281
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 6.2")
282
- end
283
-
284
- def self.allow_unsafe_raw_sql=(value) # :nodoc:
285
- ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 6.2")
286
- end
287
-
288
234
  self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
289
- self.default_role = writing_role
235
+ self.default_role = ActiveRecord.writing_role
290
236
  self.default_shard = :default
291
237
 
292
238
  def self.strict_loading_violation!(owner:, reflection:) # :nodoc:
293
- case action_on_strict_loading_violation
239
+ case ActiveRecord.action_on_strict_loading_violation
294
240
  when :raise
295
241
  message = "`#{owner}` is marked for strict_loading. The `#{reflection.klass}` association named `:#{reflection.name}` cannot be lazily loaded."
296
242
  raise ActiveRecord::StrictLoadingViolationError.new(message)
@@ -381,7 +327,32 @@ module ActiveRecord
381
327
  end
382
328
 
383
329
  def find_by!(*args) # :nodoc:
384
- 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
385
356
  end
386
357
 
387
358
  def initialize_generated_modules # :nodoc:
@@ -446,19 +417,10 @@ module ActiveRecord
446
417
  end
447
418
 
448
419
  # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
449
- #
450
- # class Post < ActiveRecord::Base
451
- # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
452
- # end
453
420
  def arel_table # :nodoc:
454
421
  @arel_table ||= Arel::Table.new(table_name, klass: self)
455
422
  end
456
423
 
457
- def arel_attribute(name, table = arel_table) # :nodoc:
458
- table[name]
459
- end
460
- deprecate :arel_attribute
461
-
462
424
  def predicate_builder # :nodoc:
463
425
  @predicate_builder ||= PredicateBuilder.new(table_metadata)
464
426
  end
@@ -467,10 +429,6 @@ module ActiveRecord
467
429
  TypeCaster::Map.new(self)
468
430
  end
469
431
 
470
- def _internal? # :nodoc:
471
- false
472
- end
473
-
474
432
  def cached_find_by_statement(key, &block) # :nodoc:
475
433
  cache = @find_by_statement_cache[connection.prepared_statements]
476
434
  cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
@@ -528,7 +486,7 @@ module ActiveRecord
528
486
  # post.init_with(coder)
529
487
  # post.title # => 'hello world'
530
488
  def init_with(coder, &block)
531
- coder = LegacyYamlAdapter.convert(self.class, coder)
489
+ coder = LegacyYamlAdapter.convert(coder)
532
490
  attributes = self.class.yaml_encoder.decode(coder)
533
491
  init_with_attributes(attributes, coder["new_record"], &block)
534
492
  end
@@ -630,6 +588,8 @@ module ActiveRecord
630
588
  # Delegates to id in order to allow two records of the same type and id to work with something like:
631
589
  # [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
632
590
  def hash
591
+ id = self.id
592
+
633
593
  if id
634
594
  self.class.hash ^ id.hash
635
595
  else
@@ -681,11 +641,37 @@ module ActiveRecord
681
641
  # if the record tries to lazily load an association.
682
642
  #
683
643
  # user = User.first
684
- # user.strict_loading!
685
- # user.comments.to_a
644
+ # user.strict_loading! # => true
645
+ # user.comments
686
646
  # => ActiveRecord::StrictLoadingViolationError
687
- def strict_loading!
688
- @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
689
675
  end
690
676
 
691
677
  # Marks this record as read only.
@@ -702,11 +688,11 @@ module ActiveRecord
702
688
  # We check defined?(@attributes) not to issue warnings if the object is
703
689
  # allocated but not initialized.
704
690
  inspection = if defined?(@attributes) && @attributes
705
- self.class.attribute_names.collect do |name|
691
+ self.class.attribute_names.filter_map do |name|
706
692
  if _has_attribute?(name)
707
693
  "#{name}: #{attribute_for_inspect(name)}"
708
694
  end
709
- end.compact.join(", ")
695
+ end.join(", ")
710
696
  else
711
697
  "not initialized"
712
698
  end
@@ -763,16 +749,20 @@ module ActiveRecord
763
749
  end
764
750
 
765
751
  def init_internals
766
- @primary_key = self.class.primary_key
767
752
  @readonly = false
768
753
  @previously_new_record = false
769
754
  @destroyed = false
770
755
  @marked_for_destruction = false
771
756
  @destroyed_by_association = nil
772
757
  @_start_transaction_state = nil
773
- @strict_loading = self.class.strict_loading_by_default
774
758
 
775
- 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
776
766
  end
777
767
 
778
768
  def initialize_internals_callback
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "uri"
3
4
  require "active_support/core_ext/enumerable"
5
+ require "active_support/core_ext/hash/reverse_merge"
4
6
 
5
7
  module ActiveRecord
6
8
  class DatabaseConfigurations
@@ -67,7 +69,7 @@ module ActiveRecord
67
69
  database: uri.opaque
68
70
  )
69
71
  else
70
- query_hash.merge(
72
+ query_hash.reverse_merge(
71
73
  adapter: @adapter,
72
74
  username: uri.user,
73
75
  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 6.2.0 in favor of DatabaseConfigurations#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