activerecord 7.1.5.2 → 8.1.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 (244) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +567 -2443
  3. data/README.rdoc +16 -16
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +3 -2
  6. data/lib/active_record/associations/alias_tracker.rb +31 -23
  7. data/lib/active_record/associations/association.rb +43 -12
  8. data/lib/active_record/associations/belongs_to_association.rb +31 -8
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/association.rb +23 -11
  11. data/lib/active_record/associations/builder/belongs_to.rb +18 -4
  12. data/lib/active_record/associations/builder/collection_association.rb +7 -3
  13. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  14. data/lib/active_record/associations/builder/has_many.rb +3 -4
  15. data/lib/active_record/associations/builder/has_one.rb +3 -4
  16. data/lib/active_record/associations/builder/singular_association.rb +33 -5
  17. data/lib/active_record/associations/collection_association.rb +17 -9
  18. data/lib/active_record/associations/collection_proxy.rb +36 -5
  19. data/lib/active_record/associations/deprecation.rb +88 -0
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  21. data/lib/active_record/associations/errors.rb +268 -0
  22. data/lib/active_record/associations/has_many_association.rb +1 -1
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -3
  24. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  25. data/lib/active_record/associations/join_dependency.rb +4 -2
  26. data/lib/active_record/associations/nested_error.rb +47 -0
  27. data/lib/active_record/associations/preloader/association.rb +4 -3
  28. data/lib/active_record/associations/preloader/batch.rb +7 -1
  29. data/lib/active_record/associations/preloader/branch.rb +8 -1
  30. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  31. data/lib/active_record/associations/singular_association.rb +14 -3
  32. data/lib/active_record/associations/through_association.rb +1 -1
  33. data/lib/active_record/associations.rb +250 -315
  34. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  35. data/lib/active_record/attribute_assignment.rb +0 -2
  36. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  37. data/lib/active_record/attribute_methods/primary_key.rb +25 -61
  38. data/lib/active_record/attribute_methods/query.rb +34 -0
  39. data/lib/active_record/attribute_methods/read.rb +1 -13
  40. data/lib/active_record/attribute_methods/serialization.rb +20 -27
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +19 -20
  42. data/lib/active_record/attribute_methods.rb +71 -75
  43. data/lib/active_record/attributes.rb +96 -68
  44. data/lib/active_record/autosave_association.rb +93 -58
  45. data/lib/active_record/base.rb +5 -7
  46. data/lib/active_record/callbacks.rb +1 -1
  47. data/lib/active_record/coders/json.rb +14 -5
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +50 -126
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +52 -13
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +681 -135
  52. data/lib/active_record/connection_adapters/abstract/database_statements.rb +165 -86
  53. data/lib/active_record/connection_adapters/abstract/query_cache.rb +226 -78
  54. data/lib/active_record/connection_adapters/abstract/quoting.rb +79 -114
  55. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
  56. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -36
  57. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
  58. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +136 -34
  59. data/lib/active_record/connection_adapters/abstract/transaction.rb +163 -68
  60. data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -129
  61. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -63
  62. data/lib/active_record/connection_adapters/column.rb +17 -4
  63. data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -3
  64. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
  65. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -46
  68. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +97 -101
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +14 -33
  70. data/lib/active_record/connection_adapters/pool_config.rb +14 -13
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +98 -44
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
  74. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  75. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
  77. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  78. data/lib/active_record/connection_adapters/postgresql/quoting.rb +79 -68
  79. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  80. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
  81. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +44 -41
  82. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +69 -32
  83. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +155 -75
  84. data/lib/active_record/connection_adapters/postgresql_adapter.rb +104 -121
  85. data/lib/active_record/connection_adapters/schema_cache.rb +126 -133
  86. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  87. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +91 -95
  88. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -54
  89. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
  90. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  91. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +43 -2
  92. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -15
  93. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +231 -111
  94. data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
  95. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +40 -69
  96. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
  97. data/lib/active_record/connection_adapters.rb +66 -0
  98. data/lib/active_record/connection_handling.rb +88 -46
  99. data/lib/active_record/core.rb +142 -58
  100. data/lib/active_record/counter_cache.rb +52 -18
  101. data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
  102. data/lib/active_record/database_configurations/database_config.rb +28 -5
  103. data/lib/active_record/database_configurations/hash_config.rb +103 -41
  104. data/lib/active_record/database_configurations/url_config.rb +30 -1
  105. data/lib/active_record/database_configurations.rb +8 -4
  106. data/lib/active_record/delegated_type.rb +43 -19
  107. data/lib/active_record/dynamic_matchers.rb +56 -71
  108. data/lib/active_record/encryption/config.rb +3 -1
  109. data/lib/active_record/encryption/encryptable_record.rb +12 -12
  110. data/lib/active_record/encryption/encrypted_attribute_type.rb +35 -6
  111. data/lib/active_record/encryption/encryptor.rb +58 -22
  112. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  113. data/lib/active_record/encryption/key_provider.rb +1 -1
  114. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  115. data/lib/active_record/encryption/message_serializer.rb +4 -0
  116. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  117. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  118. data/lib/active_record/encryption/scheme.rb +9 -2
  119. data/lib/active_record/enum.rb +57 -36
  120. data/lib/active_record/errors.rb +76 -26
  121. data/lib/active_record/explain.rb +14 -25
  122. data/lib/active_record/explain_registry.rb +51 -2
  123. data/lib/active_record/filter_attribute_handler.rb +73 -0
  124. data/lib/active_record/fixture_set/table_row.rb +19 -2
  125. data/lib/active_record/fixtures.rb +39 -35
  126. data/lib/active_record/future_result.rb +21 -13
  127. data/lib/active_record/gem_version.rb +3 -3
  128. data/lib/active_record/inheritance.rb +5 -3
  129. data/lib/active_record/insert_all.rb +28 -20
  130. data/lib/active_record/integration.rb +4 -1
  131. data/lib/active_record/internal_metadata.rb +48 -34
  132. data/lib/active_record/locking/optimistic.rb +15 -7
  133. data/lib/active_record/locking/pessimistic.rb +5 -0
  134. data/lib/active_record/log_subscriber.rb +3 -34
  135. data/lib/active_record/message_pack.rb +1 -1
  136. data/lib/active_record/middleware/shard_selector.rb +34 -17
  137. data/lib/active_record/migration/command_recorder.rb +46 -14
  138. data/lib/active_record/migration/compatibility.rb +40 -25
  139. data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
  140. data/lib/active_record/migration/default_strategy.rb +4 -5
  141. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  142. data/lib/active_record/migration.rb +119 -103
  143. data/lib/active_record/model_schema.rb +66 -78
  144. data/lib/active_record/nested_attributes.rb +17 -9
  145. data/lib/active_record/persistence.rb +161 -454
  146. data/lib/active_record/query_cache.rb +33 -15
  147. data/lib/active_record/query_logs.rb +106 -39
  148. data/lib/active_record/query_logs_formatter.rb +17 -28
  149. data/lib/active_record/querying.rb +28 -16
  150. data/lib/active_record/railtie.rb +61 -74
  151. data/lib/active_record/railties/controller_runtime.rb +19 -5
  152. data/lib/active_record/railties/databases.rake +64 -78
  153. data/lib/active_record/railties/job_checkpoints.rb +15 -0
  154. data/lib/active_record/railties/job_runtime.rb +10 -11
  155. data/lib/active_record/reflection.rb +147 -53
  156. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  157. data/lib/active_record/relation/batches.rb +153 -73
  158. data/lib/active_record/relation/calculations.rb +146 -96
  159. data/lib/active_record/relation/delegation.rb +30 -23
  160. data/lib/active_record/relation/finder_methods.rb +64 -34
  161. data/lib/active_record/relation/merger.rb +12 -14
  162. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  163. data/lib/active_record/relation/predicate_builder/association_query_value.rb +19 -11
  164. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
  165. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  166. data/lib/active_record/relation/predicate_builder.rb +25 -10
  167. data/lib/active_record/relation/query_attribute.rb +4 -2
  168. data/lib/active_record/relation/query_methods.rb +351 -124
  169. data/lib/active_record/relation/spawn_methods.rb +9 -25
  170. data/lib/active_record/relation/where_clause.rb +17 -30
  171. data/lib/active_record/relation.rb +590 -124
  172. data/lib/active_record/result.rb +131 -59
  173. data/lib/active_record/runtime_registry.rb +44 -21
  174. data/lib/active_record/sanitization.rb +33 -25
  175. data/lib/active_record/schema.rb +8 -6
  176. data/lib/active_record/schema_dumper.rb +66 -31
  177. data/lib/active_record/schema_migration.rb +31 -14
  178. data/lib/active_record/scoping/named.rb +6 -2
  179. data/lib/active_record/scoping.rb +0 -1
  180. data/lib/active_record/secure_token.rb +3 -3
  181. data/lib/active_record/signed_id.rb +68 -20
  182. data/lib/active_record/statement_cache.rb +29 -25
  183. data/lib/active_record/store.rb +51 -22
  184. data/lib/active_record/structured_event_subscriber.rb +85 -0
  185. data/lib/active_record/table_metadata.rb +7 -33
  186. data/lib/active_record/tasks/abstract_tasks.rb +76 -0
  187. data/lib/active_record/tasks/database_tasks.rb +118 -90
  188. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -42
  189. data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -40
  190. data/lib/active_record/tasks/sqlite_database_tasks.rb +17 -28
  191. data/lib/active_record/test_databases.rb +14 -4
  192. data/lib/active_record/test_fixtures.rb +123 -89
  193. data/lib/active_record/testing/query_assertions.rb +127 -0
  194. data/lib/active_record/timestamp.rb +6 -4
  195. data/lib/active_record/token_for.rb +22 -12
  196. data/lib/active_record/touch_later.rb +1 -1
  197. data/lib/active_record/transaction.rb +129 -0
  198. data/lib/active_record/transactions.rb +97 -18
  199. data/lib/active_record/translation.rb +0 -2
  200. data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
  201. data/lib/active_record/type/internal/timezone.rb +7 -0
  202. data/lib/active_record/type/json.rb +15 -2
  203. data/lib/active_record/type/serialized.rb +12 -7
  204. data/lib/active_record/type/type_map.rb +1 -1
  205. data/lib/active_record/type_caster/connection.rb +5 -4
  206. data/lib/active_record/validations/associated.rb +10 -4
  207. data/lib/active_record/validations/uniqueness.rb +23 -18
  208. data/lib/active_record/validations.rb +4 -1
  209. data/lib/active_record.rb +203 -59
  210. data/lib/arel/alias_predication.rb +3 -1
  211. data/lib/arel/collectors/bind.rb +4 -2
  212. data/lib/arel/collectors/composite.rb +7 -0
  213. data/lib/arel/collectors/sql_string.rb +2 -2
  214. data/lib/arel/collectors/substitute_binds.rb +3 -3
  215. data/lib/arel/crud.rb +8 -11
  216. data/lib/arel/delete_manager.rb +5 -0
  217. data/lib/arel/nodes/binary.rb +1 -7
  218. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  219. data/lib/arel/nodes/count.rb +2 -2
  220. data/lib/arel/nodes/delete_statement.rb +4 -2
  221. data/lib/arel/nodes/function.rb +4 -10
  222. data/lib/arel/nodes/named_function.rb +2 -2
  223. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  224. data/lib/arel/nodes/node.rb +6 -5
  225. data/lib/arel/nodes/sql_literal.rb +8 -1
  226. data/lib/arel/nodes/update_statement.rb +4 -2
  227. data/lib/arel/nodes.rb +2 -4
  228. data/lib/arel/predications.rb +1 -1
  229. data/lib/arel/select_manager.rb +14 -5
  230. data/lib/arel/table.rb +3 -7
  231. data/lib/arel/tree_manager.rb +3 -2
  232. data/lib/arel/update_manager.rb +7 -1
  233. data/lib/arel/visitors/dot.rb +3 -3
  234. data/lib/arel/visitors/mysql.rb +9 -4
  235. data/lib/arel/visitors/postgresql.rb +56 -12
  236. data/lib/arel/visitors/sqlite.rb +80 -8
  237. data/lib/arel/visitors/to_sql.rb +34 -37
  238. data/lib/arel.rb +10 -4
  239. data/lib/rails/generators/active_record/application_record/USAGE +1 -1
  240. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  241. metadata +23 -14
  242. data/lib/active_record/explain_subscriber.rb +0 -34
  243. data/lib/active_record/normalization.rb +0 -167
  244. data/lib/active_record/relation/record_fetch_warning.rb +0 -49
data/lib/active_record.rb CHANGED
@@ -25,9 +25,12 @@
25
25
 
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
+ require "active_support/ordered_options"
29
+ require "active_support/core_ext/array/conversions"
28
30
  require "active_model"
29
31
  require "arel"
30
32
  require "yaml"
33
+ require "zlib"
31
34
 
32
35
  require "active_record/version"
33
36
  require "active_record/deprecator"
@@ -50,6 +53,7 @@ module ActiveRecord
50
53
  autoload :Enum
51
54
  autoload :Explain
52
55
  autoload :FixtureSet, "active_record/fixtures"
56
+ autoload :FilterAttributeHandler
53
57
  autoload :Inheritance
54
58
  autoload :Integration
55
59
  autoload :InternalMetadata
@@ -60,7 +64,6 @@ module ActiveRecord
60
64
  autoload :ModelSchema
61
65
  autoload :NestedAttributes
62
66
  autoload :NoTouching
63
- autoload :Normalization
64
67
  autoload :Persistence
65
68
  autoload :QueryCache
66
69
  autoload :QueryLogs
@@ -106,6 +109,7 @@ module ActiveRecord
106
109
  autoload :Result
107
110
  autoload :StatementCache
108
111
  autoload :TableMetadata
112
+ autoload :Transaction
109
113
  autoload :Type
110
114
 
111
115
  autoload_under "relation" do
@@ -128,6 +132,8 @@ module ActiveRecord
128
132
  module AttributeMethods
129
133
  extend ActiveSupport::Autoload
130
134
 
135
+ autoload :CompositePrimaryKey
136
+
131
137
  eager_autoload do
132
138
  autoload :BeforeTypeCast
133
139
  autoload :Dirty
@@ -169,7 +175,8 @@ module ActiveRecord
169
175
  extend ActiveSupport::Autoload
170
176
 
171
177
  autoload :DatabaseTasks
172
- autoload :MySQLDatabaseTasks, "active_record/tasks/mysql_database_tasks"
178
+ autoload :AbstractTasks, "active_record/tasks/abstract_tasks"
179
+ autoload :MySQLDatabaseTasks, "active_record/tasks/mysql_database_tasks"
173
180
  autoload :PostgreSQLDatabaseTasks, "active_record/tasks/postgresql_database_tasks"
174
181
  autoload :SQLiteDatabaseTasks, "active_record/tasks/sqlite_database_tasks"
175
182
  end
@@ -177,18 +184,35 @@ module ActiveRecord
177
184
  singleton_class.attr_accessor :disable_prepared_statements
178
185
  self.disable_prepared_statements = false
179
186
 
187
+ ##
188
+ # :singleton-method: lazily_load_schema_cache
180
189
  # Lazily load the schema cache. This option will load the schema cache
181
- # when a connection is established rather than on boot. If set,
182
- # +config.active_record.use_schema_cache_dump+ will be set to false.
190
+ # when a connection is established rather than on boot.
183
191
  singleton_class.attr_accessor :lazily_load_schema_cache
184
192
  self.lazily_load_schema_cache = false
185
193
 
194
+ ##
195
+ # :singleton-method: schema_cache_ignored_tables
186
196
  # A list of tables or regex's to match tables to ignore when
187
197
  # dumping the schema cache. For example if this is set to +[/^_/]+
188
198
  # the schema cache will not dump tables named with an underscore.
189
199
  singleton_class.attr_accessor :schema_cache_ignored_tables
190
200
  self.schema_cache_ignored_tables = []
191
201
 
202
+ # Checks to see if the +table_name+ is ignored by checking
203
+ # against the +schema_cache_ignored_tables+ option.
204
+ #
205
+ # ActiveRecord.schema_cache_ignored_table?(:developers)
206
+ #
207
+ def self.schema_cache_ignored_table?(table_name)
208
+ ActiveRecord.schema_cache_ignored_tables.any? do |ignored|
209
+ ignored === table_name
210
+ end
211
+ end
212
+
213
+ singleton_class.attr_accessor :database_cli
214
+ self.database_cli = { postgresql: "psql", mysql: %w[mysql mysql5], sqlite: "sqlite3" }
215
+
192
216
  singleton_class.attr_reader :default_timezone
193
217
 
194
218
  # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
@@ -203,6 +227,8 @@ module ActiveRecord
203
227
 
204
228
  self.default_timezone = :utc
205
229
 
230
+ ##
231
+ # :singleton-method: db_warnings_action
206
232
  # The action to take when database query produces warning.
207
233
  # Must be one of :ignore, :log, :raise, :report, or a custom proc.
208
234
  # The default is :ignore.
@@ -232,7 +258,12 @@ module ActiveRecord
232
258
 
233
259
  self.db_warnings_action = :ignore
234
260
 
261
+ ##
262
+ # :singleton-method: db_warnings_ignore
235
263
  # Specify allowlist of database warnings.
264
+ # Can be a string, regular expression, or an error code from the database.
265
+ #
266
+ # ActiveRecord::Base.db_warnings_ignore = [/`SHOW WARNINGS` did not return the warnings/, "01000"]
236
267
  singleton_class.attr_accessor :db_warnings_ignore
237
268
  self.db_warnings_ignore = []
238
269
 
@@ -242,14 +273,8 @@ module ActiveRecord
242
273
  singleton_class.attr_accessor :reading_role
243
274
  self.reading_role = :reading
244
275
 
245
- def self.legacy_connection_handling=(_)
246
- raise ArgumentError, <<~MSG.squish
247
- The `legacy_connection_handling` setter was deprecated in 7.0 and removed in 7.1,
248
- but is still defined in your configuration. Please remove this call as it no longer
249
- has any effect."
250
- MSG
251
- end
252
-
276
+ ##
277
+ # :singleton-method: async_query_executor
253
278
  # Sets the async_query_executor for an application. By default the thread pool executor
254
279
  # set to +nil+ which will not run queries in the background. Applications must configure
255
280
  # a thread pool executor to use this feature. Options are:
@@ -266,6 +291,7 @@ module ActiveRecord
266
291
  def self.global_thread_pool_async_query_executor # :nodoc:
267
292
  concurrency = global_executor_concurrency || 4
268
293
  @global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
294
+ name: "ActiveRecord-global-async-query-executor",
269
295
  min_threads: 0,
270
296
  max_threads: concurrency,
271
297
  max_queue: concurrency * 4,
@@ -287,11 +313,22 @@ module ActiveRecord
287
313
  @global_executor_concurrency ||= nil
288
314
  end
289
315
 
316
+ @permanent_connection_checkout = true
317
+ singleton_class.attr_reader :permanent_connection_checkout
318
+
319
+ # Defines whether +ActiveRecord::Base.connection+ is allowed, deprecated, or entirely disallowed.
320
+ def self.permanent_connection_checkout=(value)
321
+ unless [true, :deprecated, :disallowed].include?(value)
322
+ raise ArgumentError, "permanent_connection_checkout must be one of: `true`, `:deprecated` or `:disallowed`"
323
+ end
324
+ @permanent_connection_checkout = value
325
+ end
326
+
290
327
  singleton_class.attr_accessor :index_nested_attribute_errors
291
328
  self.index_nested_attribute_errors = false
292
329
 
293
330
  ##
294
- # :singleton-method:
331
+ # :singleton-method: verbose_query_logs
295
332
  #
296
333
  # Specifies if the methods calling database queries should be logged below
297
334
  # their relevant queries. Defaults to false.
@@ -299,7 +336,7 @@ module ActiveRecord
299
336
  self.verbose_query_logs = false
300
337
 
301
338
  ##
302
- # :singleton-method:
339
+ # :singleton-method: queues
303
340
  #
304
341
  # Specifies the names of the queues used by background jobs.
305
342
  singleton_class.attr_accessor :queues
@@ -320,41 +357,33 @@ module ActiveRecord
320
357
  singleton_class.attr_accessor :run_after_transaction_callbacks_in_order_defined
321
358
  self.run_after_transaction_callbacks_in_order_defined = false
322
359
 
323
- singleton_class.attr_accessor :commit_transaction_on_non_local_return
324
- self.commit_transaction_on_non_local_return = false
325
-
326
- ##
327
- # :singleton-method:
328
- # Specify a threshold for the size of query result sets. If the number of
329
- # records in the set exceeds the threshold, a warning is logged. This can
330
- # be used to identify queries which load thousands of records and
331
- # potentially cause memory bloat.
332
- singleton_class.attr_accessor :warn_on_records_fetched_greater_than
333
- self.warn_on_records_fetched_greater_than = false
360
+ singleton_class.attr_accessor :raise_on_missing_required_finder_order_columns
361
+ self.run_after_transaction_callbacks_in_order_defined = false
334
362
 
335
363
  singleton_class.attr_accessor :application_record_class
336
364
  self.application_record_class = nil
337
365
 
338
366
  ##
339
- # :singleton-method:
367
+ # :singleton-method: action_on_strict_loading_violation
340
368
  # Set the application to log or raise when an association violates strict loading.
341
369
  # Defaults to :raise.
342
370
  singleton_class.attr_accessor :action_on_strict_loading_violation
343
371
  self.action_on_strict_loading_violation = :raise
344
372
 
345
373
  ##
346
- # :singleton-method:
374
+ # :singleton-method: schema_format
347
375
  # Specifies the format to use when dumping the database schema with Rails'
348
376
  # Rakefile. If :sql, the schema is dumped as (potentially database-
349
377
  # specific) SQL statements. If :ruby, the schema is dumped as an
350
378
  # ActiveRecord::Schema file which can be loaded into any database that
351
379
  # supports migrations. Use :ruby if you want to have different database
352
- # adapters for, e.g., your development and test environments.
380
+ # adapters for, e.g., your development and test environments. This can be
381
+ # overridden per-database in the database configuration.
353
382
  singleton_class.attr_accessor :schema_format
354
383
  self.schema_format = :ruby
355
384
 
356
385
  ##
357
- # :singleton-method:
386
+ # :singleton-method: error_on_ignored_order
358
387
  # Specifies if an error should be raised if the query has an order being
359
388
  # ignored when doing batch queries. Useful in applications where the
360
389
  # scope being ignored is error-worthy, rather than a warning.
@@ -362,19 +391,33 @@ module ActiveRecord
362
391
  self.error_on_ignored_order = false
363
392
 
364
393
  ##
365
- # :singleton-method:
394
+ # :singleton-method: timestamped_migrations
366
395
  # Specify whether or not to use timestamps for migration versions
367
396
  singleton_class.attr_accessor :timestamped_migrations
368
397
  self.timestamped_migrations = true
369
398
 
370
399
  ##
371
- # :singleton-method:
400
+ # :singleton-method: validate_migration_timestamps
401
+ # Specify whether or not to validate migration timestamps. When set, an error
402
+ # will be raised if a timestamp is more than a day ahead of the timestamp
403
+ # associated with the current time. +timestamped_migrations+ must be set to true.
404
+ singleton_class.attr_accessor :validate_migration_timestamps
405
+ self.validate_migration_timestamps = false
406
+
407
+ ##
408
+ # :singleton-method: migration_strategy
372
409
  # Specify strategy to use for executing migrations.
373
410
  singleton_class.attr_accessor :migration_strategy
374
411
  self.migration_strategy = Migration::DefaultStrategy
375
412
 
376
413
  ##
377
- # :singleton-method:
414
+ # :singleton-method: schema_versions_formatter
415
+ # Specify the formatter used by schema dumper to format versions information.
416
+ singleton_class.attr_accessor :schema_versions_formatter
417
+ self.schema_versions_formatter = Migration::DefaultSchemaVersionsFormatter
418
+
419
+ ##
420
+ # :singleton-method: dump_schema_after_migration
378
421
  # Specify whether schema dump should happen at the end of the
379
422
  # bin/rails db:migrate command. This is true by default, which is useful for the
380
423
  # development environment. This should ideally be false in the production
@@ -383,7 +426,7 @@ module ActiveRecord
383
426
  self.dump_schema_after_migration = true
384
427
 
385
428
  ##
386
- # :singleton-method:
429
+ # :singleton-method: dump_schemas
387
430
  # Specifies which database schemas to dump when calling db:schema:dump.
388
431
  # If the value is :schema_search_path (the default), any schemas listed in
389
432
  # schema_search_path are dumped. Use :all to dump all schemas regardless
@@ -392,22 +435,8 @@ module ActiveRecord
392
435
  singleton_class.attr_accessor :dump_schemas
393
436
  self.dump_schemas = :schema_search_path
394
437
 
395
- def self.suppress_multiple_database_warning
396
- ActiveRecord.deprecator.warn(<<-MSG.squish)
397
- config.active_record.suppress_multiple_database_warning is deprecated and will be removed in Rails 7.2.
398
- It no longer has any effect and should be removed from the configuration file.
399
- MSG
400
- end
401
-
402
- def self.suppress_multiple_database_warning=(value)
403
- ActiveRecord.deprecator.warn(<<-MSG.squish)
404
- config.active_record.suppress_multiple_database_warning= is deprecated and will be removed in Rails 7.2.
405
- It no longer has any effect and should be removed from the configuration file.
406
- MSG
407
- end
408
-
409
438
  ##
410
- # :singleton-method:
439
+ # :singleton-method: verify_foreign_keys_for_fixtures
411
440
  # If true, Rails will verify all foreign keys in the database after loading fixtures.
412
441
  # An error will be raised if there are any foreign key violations, indicating incorrectly
413
442
  # written fixtures.
@@ -415,25 +444,18 @@ module ActiveRecord
415
444
  singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
416
445
  self.verify_foreign_keys_for_fixtures = false
417
446
 
418
- ##
419
- # :singleton-method:
420
- # If true, Rails will continue allowing plural association names in where clauses on singular associations
421
- # This behavior will be removed in Rails 7.2.
422
- singleton_class.attr_accessor :allow_deprecated_singular_associations_name
423
- self.allow_deprecated_singular_associations_name = true
424
-
425
447
  singleton_class.attr_accessor :query_transformers
426
448
  self.query_transformers = []
427
449
 
428
450
  ##
429
- # :singleton-method:
451
+ # :singleton-method: use_yaml_unsafe_load
430
452
  # Application configurable boolean that instructs the YAML Coder to use
431
453
  # an unsafe load if set to true.
432
454
  singleton_class.attr_accessor :use_yaml_unsafe_load
433
455
  self.use_yaml_unsafe_load = false
434
456
 
435
457
  ##
436
- # :singleton-method:
458
+ # :singleton-method: raise_int_wider_than_64bit
437
459
  # Application configurable boolean that denotes whether or not to raise
438
460
  # an exception when the PostgreSQLAdapter is provided with an integer that
439
461
  # is wider than signed 64bit representation
@@ -441,19 +463,42 @@ module ActiveRecord
441
463
  self.raise_int_wider_than_64bit = true
442
464
 
443
465
  ##
444
- # :singleton-method:
466
+ # :singleton-method: yaml_column_permitted_classes
445
467
  # Application configurable array that provides additional permitted classes
446
468
  # to Psych safe_load in the YAML Coder
447
469
  singleton_class.attr_accessor :yaml_column_permitted_classes
448
470
  self.yaml_column_permitted_classes = [Symbol]
449
471
 
450
472
  ##
451
- # :singleton-method:
473
+ # :singleton-method: generate_secure_token_on
452
474
  # Controls when to generate a value for <tt>has_secure_token</tt>
453
475
  # declarations. Defaults to <tt>:create</tt>.
454
476
  singleton_class.attr_accessor :generate_secure_token_on
455
477
  self.generate_secure_token_on = :create
456
478
 
479
+ def self.deprecated_associations_options=(options)
480
+ raise ArgumentError, "deprecated_associations_options must be a hash" unless options.is_a?(Hash)
481
+
482
+ valid_keys = [:mode, :backtrace]
483
+
484
+ invalid_keys = options.keys - valid_keys
485
+ unless invalid_keys.empty?
486
+ inflected_key = invalid_keys.size == 1 ? "key" : "keys"
487
+ raise ArgumentError, "invalid deprecated_associations_options #{inflected_key} #{invalid_keys.map(&:inspect).to_sentence} (valid keys are #{valid_keys.map(&:inspect).to_sentence})"
488
+ end
489
+
490
+ options.each do |key, value|
491
+ ActiveRecord::Associations::Deprecation.send("#{key}=", value)
492
+ end
493
+ end
494
+
495
+ def self.deprecated_associations_options
496
+ {
497
+ mode: ActiveRecord::Associations::Deprecation.mode,
498
+ backtrace: ActiveRecord::Associations::Deprecation.backtrace
499
+ }
500
+ end
501
+
457
502
  def self.marshalling_format_version
458
503
  Marshalling.format_version
459
504
  end
@@ -462,6 +507,41 @@ module ActiveRecord
462
507
  Marshalling.format_version = value
463
508
  end
464
509
 
510
+ ##
511
+ # :singleton-method: protocol_adapters
512
+ # Provides a mapping between database protocols/DBMSs and the
513
+ # underlying database adapter to be used. This is used only by the
514
+ # <tt>DATABASE_URL</tt> environment variable.
515
+ #
516
+ # == Example
517
+ #
518
+ # DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
519
+ #
520
+ # The above URL specifies that MySQL is the desired protocol/DBMS, and the
521
+ # application configuration can then decide which adapter to use. For this example
522
+ # the default mapping is from <tt>mysql</tt> to <tt>mysql2</tt>, but <tt>:trilogy</tt>
523
+ # is also supported.
524
+ #
525
+ # ActiveRecord.protocol_adapters.mysql = "mysql2"
526
+ #
527
+ # The protocols names are arbitrary, and external database adapters can be
528
+ # registered and set here.
529
+ singleton_class.attr_accessor :protocol_adapters
530
+ self.protocol_adapters = ActiveSupport::InheritableOptions.new(
531
+ {
532
+ sqlite: "sqlite3",
533
+ mysql: "mysql2",
534
+ postgres: "postgresql",
535
+ }
536
+ )
537
+
538
+ ##
539
+ # :singleton-method: message_verifiers
540
+ #
541
+ # ActiveSupport::MessageVerifiers instance for Active Record. If you are using
542
+ # Rails, this will be set to +Rails.application.message_verifiers+.
543
+ singleton_class.attr_accessor :message_verifiers
544
+
465
545
  def self.eager_load!
466
546
  super
467
547
  ActiveRecord::Locking.eager_load!
@@ -476,6 +556,70 @@ module ActiveRecord
476
556
  def self.disconnect_all!
477
557
  ConnectionAdapters::PoolConfig.disconnect_all!
478
558
  end
559
+
560
+ # Registers a block to be called after all the current transactions have been
561
+ # committed.
562
+ #
563
+ # If there is no currently open transaction, the block is called immediately.
564
+ #
565
+ # If there are multiple nested transactions, the block is called after the outermost one
566
+ # has been committed,
567
+ #
568
+ # If any of the currently open transactions is rolled back, the block is never called.
569
+ #
570
+ # If multiple transactions are open across multiple databases, the block will be invoked
571
+ # if and once all of them have been committed. But note that nesting transactions across
572
+ # two distinct databases is a sharding anti-pattern that comes with a world of hurts.
573
+ def self.after_all_transactions_commit(&block)
574
+ open_transactions = all_open_transactions
575
+
576
+ if open_transactions.empty?
577
+ yield
578
+ elsif open_transactions.size == 1
579
+ open_transactions.first.after_commit(&block)
580
+ else
581
+ count = open_transactions.size
582
+ callback = -> do
583
+ count -= 1
584
+ block.call if count.zero?
585
+ end
586
+ open_transactions.each do |t|
587
+ t.after_commit(&callback)
588
+ end
589
+ open_transactions = nil # rubocop:disable Lint/UselessAssignment avoid holding it in the closure
590
+ end
591
+ end
592
+
593
+ def self.all_open_transactions # :nodoc:
594
+ open_transactions = []
595
+ Base.connection_handler.each_connection_pool do |pool|
596
+ if active_connection = pool.active_connection
597
+ current_transaction = active_connection.current_transaction
598
+
599
+ if current_transaction.open? && current_transaction.joinable?
600
+ open_transactions << current_transaction
601
+ end
602
+ end
603
+ end
604
+ open_transactions
605
+ end
606
+
607
+ def self.default_transaction_isolation_level=(isolation_level) # :nodoc:
608
+ ActiveSupport::IsolatedExecutionState[:active_record_transaction_isolation] = isolation_level
609
+ end
610
+
611
+ def self.default_transaction_isolation_level # :nodoc:
612
+ ActiveSupport::IsolatedExecutionState[:active_record_transaction_isolation]
613
+ end
614
+
615
+ # Sets a transaction isolation level for all connection pools within the block.
616
+ def self.with_transaction_isolation_level(isolation_level, &block)
617
+ original_level = self.default_transaction_isolation_level
618
+ self.default_transaction_isolation_level = isolation_level
619
+ yield
620
+ ensure
621
+ self.default_transaction_isolation_level = original_level
622
+ end
479
623
  end
480
624
 
481
625
  ActiveSupport.on_load(:active_record) do
@@ -3,7 +3,9 @@
3
3
  module Arel # :nodoc: all
4
4
  module AliasPredication
5
5
  def as(other)
6
- Nodes::As.new self, Nodes::SqlLiteral.new(other)
6
+ other = other.name if other.is_a?(Symbol)
7
+
8
+ Nodes::As.new self, Nodes::SqlLiteral.new(other, retryable: true)
7
9
  end
8
10
  end
9
11
  end
@@ -3,6 +3,8 @@
3
3
  module Arel # :nodoc: all
4
4
  module Collectors
5
5
  class Bind
6
+ attr_accessor :retryable
7
+
6
8
  def initialize
7
9
  @binds = []
8
10
  end
@@ -11,12 +13,12 @@ module Arel # :nodoc: all
11
13
  self
12
14
  end
13
15
 
14
- def add_bind(bind)
16
+ def add_bind(bind, &)
15
17
  @binds << bind
16
18
  self
17
19
  end
18
20
 
19
- def add_binds(binds, proc_for_binds = nil)
21
+ def add_binds(binds, proc_for_binds = nil, &)
20
22
  @binds.concat proc_for_binds ? binds.map(&proc_for_binds) : binds
21
23
  self
22
24
  end
@@ -4,12 +4,19 @@ module Arel # :nodoc: all
4
4
  module Collectors
5
5
  class Composite
6
6
  attr_accessor :preparable
7
+ attr_reader :retryable
7
8
 
8
9
  def initialize(left, right)
9
10
  @left = left
10
11
  @right = right
11
12
  end
12
13
 
14
+ def retryable=(retryable)
15
+ left.retryable = retryable
16
+ right.retryable = retryable
17
+ @retryable = retryable
18
+ end
19
+
13
20
  def <<(str)
14
21
  left << str
15
22
  right << str
@@ -5,14 +5,14 @@ require "arel/collectors/plain_string"
5
5
  module Arel # :nodoc: all
6
6
  module Collectors
7
7
  class SQLString < PlainString
8
- attr_accessor :preparable
8
+ attr_accessor :preparable, :retryable
9
9
 
10
10
  def initialize(*)
11
11
  super
12
12
  @bind_index = 1
13
13
  end
14
14
 
15
- def add_bind(bind)
15
+ def add_bind(bind, &)
16
16
  self << yield(@bind_index)
17
17
  @bind_index += 1
18
18
  self
@@ -3,7 +3,7 @@
3
3
  module Arel # :nodoc: all
4
4
  module Collectors
5
5
  class SubstituteBinds
6
- attr_accessor :preparable
6
+ attr_accessor :preparable, :retryable
7
7
 
8
8
  def initialize(quoter, delegate_collector)
9
9
  @quoter = quoter
@@ -15,12 +15,12 @@ module Arel # :nodoc: all
15
15
  self
16
16
  end
17
17
 
18
- def add_bind(bind)
18
+ def add_bind(bind, &)
19
19
  bind = bind.value_for_database if bind.respond_to?(:value_for_database)
20
20
  self << quoter.quote(bind)
21
21
  end
22
22
 
23
- def add_binds(binds, proc_for_binds = nil)
23
+ def add_binds(binds, proc_for_binds = nil, &)
24
24
  self << binds.map { |bind| quoter.quote(bind) }.join(", ")
25
25
  end
26
26
 
data/lib/arel/crud.rb CHANGED
@@ -14,34 +14,31 @@ module Arel # :nodoc: all
14
14
  InsertManager.new
15
15
  end
16
16
 
17
- def compile_update(
18
- values,
19
- key = nil,
20
- having_clause = nil,
21
- group_values_columns = []
22
- )
17
+ def compile_update(values, key = nil)
23
18
  um = UpdateManager.new(source)
24
19
  um.set(values)
25
20
  um.take(limit)
26
21
  um.offset(offset)
27
22
  um.order(*orders)
28
23
  um.wheres = constraints
24
+ um.comment(comment)
29
25
  um.key = key
30
26
 
31
- um.group(group_values_columns) unless group_values_columns.empty?
32
- um.having(having_clause) unless having_clause.nil?
27
+ um.ast.groups = @ctx.groups
28
+ @ctx.havings.each { |h| um.having(h) }
33
29
  um
34
30
  end
35
31
 
36
- def compile_delete(key = nil, having_clause = nil, group_values_columns = [])
32
+ def compile_delete(key = nil)
37
33
  dm = DeleteManager.new(source)
38
34
  dm.take(limit)
39
35
  dm.offset(offset)
40
36
  dm.order(*orders)
41
37
  dm.wheres = constraints
38
+ dm.comment(comment)
42
39
  dm.key = key
43
- dm.group(group_values_columns) unless group_values_columns.empty?
44
- dm.having(having_clause) unless having_clause.nil?
40
+ dm.ast.groups = @ctx.groups
41
+ @ctx.havings.each { |h| dm.having(h) }
45
42
  dm
46
43
  end
47
44
  end
@@ -28,5 +28,10 @@ module Arel # :nodoc: all
28
28
  @ast.havings << expr
29
29
  self
30
30
  end
31
+
32
+ def comment(value)
33
+ @ast.comment = value
34
+ self
35
+ end
31
36
  end
32
37
  end
@@ -30,7 +30,7 @@ module Arel # :nodoc: all
30
30
  end
31
31
 
32
32
  module FetchAttribute
33
- def fetch_attribute
33
+ def fetch_attribute(&)
34
34
  if left.is_a?(Arel::Attributes::Attribute)
35
35
  yield left
36
36
  elsif right.is_a?(Arel::Attributes::Attribute)
@@ -111,12 +111,6 @@ module Arel # :nodoc: all
111
111
  end
112
112
  end
113
113
 
114
- class Or < Binary
115
- def fetch_attribute(&block)
116
- left.fetch_attribute(&block) && right.fetch_attribute(&block)
117
- end
118
- end
119
-
120
114
  %w{
121
115
  Assignment
122
116
  Join
@@ -6,13 +6,17 @@ module Arel # :nodoc: all
6
6
  attr_reader :sql_with_placeholders, :positional_binds, :named_binds
7
7
 
8
8
  def initialize(sql_with_placeholders, positional_binds, named_binds)
9
- if !positional_binds.empty? && !named_binds.empty?
10
- raise BindError.new("cannot mix positional and named binds", sql_with_placeholders)
11
- elsif !positional_binds.empty?
9
+ has_positional = !(positional_binds.nil? || positional_binds.empty?)
10
+ has_named = !(named_binds.nil? || named_binds.empty?)
11
+
12
+ if has_positional
13
+ if has_named
14
+ raise BindError.new("cannot mix positional and named binds", sql_with_placeholders)
15
+ end
12
16
  if positional_binds.size != (expected = sql_with_placeholders.count("?"))
13
17
  raise BindError.new("wrong number of bind variables (#{positional_binds.size} for #{expected})", sql_with_placeholders)
14
18
  end
15
- elsif !named_binds.empty?
19
+ elsif has_named
16
20
  tokens_in_string = sql_with_placeholders.scan(/:(?<!::)([a-zA-Z]\w*)/).flatten.map(&:to_sym).uniq
17
21
  tokens_in_hash = named_binds.keys.map(&:to_sym).uniq
18
22
 
@@ -26,7 +30,7 @@ module Arel # :nodoc: all
26
30
  end
27
31
 
28
32
  @sql_with_placeholders = sql_with_placeholders
29
- if !positional_binds.empty?
33
+ if has_positional
30
34
  @positional_binds = positional_binds
31
35
  @named_binds = nil
32
36
  else
@@ -3,8 +3,8 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class Count < Arel::Nodes::Function
6
- def initialize(expr, distinct = false, aliaz = nil)
7
- super(expr, aliaz)
6
+ def initialize(expr, distinct = false)
7
+ super(expr)
8
8
  @distinct = distinct
9
9
  end
10
10
  end