activerecord 7.0.8.7 → 7.2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +631 -1944
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +29 -29
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +16 -13
  7. data/lib/active_record/association_relation.rb +2 -2
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +35 -12
  10. data/lib/active_record/associations/association_scope.rb +16 -9
  11. data/lib/active_record/associations/belongs_to_association.rb +23 -8
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  13. data/lib/active_record/associations/builder/association.rb +3 -3
  14. data/lib/active_record/associations/builder/belongs_to.rb +22 -8
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  16. data/lib/active_record/associations/builder/has_many.rb +3 -4
  17. data/lib/active_record/associations/builder/has_one.rb +3 -4
  18. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  19. data/lib/active_record/associations/collection_association.rb +26 -14
  20. data/lib/active_record/associations/collection_proxy.rb +29 -11
  21. data/lib/active_record/associations/errors.rb +265 -0
  22. data/lib/active_record/associations/foreign_association.rb +10 -3
  23. data/lib/active_record/associations/has_many_association.rb +21 -14
  24. data/lib/active_record/associations/has_many_through_association.rb +17 -7
  25. data/lib/active_record/associations/has_one_association.rb +10 -3
  26. data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
  27. data/lib/active_record/associations/join_dependency.rb +10 -10
  28. data/lib/active_record/associations/nested_error.rb +47 -0
  29. data/lib/active_record/associations/preloader/association.rb +33 -8
  30. data/lib/active_record/associations/preloader/branch.rb +7 -1
  31. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  32. data/lib/active_record/associations/preloader.rb +13 -10
  33. data/lib/active_record/associations/singular_association.rb +7 -1
  34. data/lib/active_record/associations/through_association.rb +22 -11
  35. data/lib/active_record/associations.rb +354 -485
  36. data/lib/active_record/attribute_assignment.rb +0 -4
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  38. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  39. data/lib/active_record/attribute_methods/dirty.rb +53 -35
  40. data/lib/active_record/attribute_methods/primary_key.rb +45 -25
  41. data/lib/active_record/attribute_methods/query.rb +28 -16
  42. data/lib/active_record/attribute_methods/read.rb +8 -7
  43. data/lib/active_record/attribute_methods/serialization.rb +131 -32
  44. data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
  45. data/lib/active_record/attribute_methods/write.rb +6 -6
  46. data/lib/active_record/attribute_methods.rb +148 -33
  47. data/lib/active_record/attributes.rb +64 -50
  48. data/lib/active_record/autosave_association.rb +69 -37
  49. data/lib/active_record/base.rb +9 -5
  50. data/lib/active_record/callbacks.rb +11 -25
  51. data/lib/active_record/coders/column_serializer.rb +61 -0
  52. data/lib/active_record/coders/json.rb +1 -1
  53. data/lib/active_record/coders/yaml_column.rb +70 -42
  54. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +323 -88
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +217 -63
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +307 -129
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +510 -111
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +278 -125
  69. data/lib/active_record/connection_adapters/column.rb +9 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
  72. data/lib/active_record/connection_adapters/mysql/quoting.rb +53 -54
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  76. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
  77. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  78. data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
  79. data/lib/active_record/connection_adapters/pool_config.rb +20 -10
  80. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  87. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  89. data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
  90. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  91. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  92. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
  93. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  94. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +370 -63
  95. data/lib/active_record/connection_adapters/postgresql_adapter.rb +367 -201
  96. data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
  97. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  98. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
  99. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -46
  100. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  101. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
  102. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  103. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +50 -8
  104. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -110
  105. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  106. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  107. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  108. data/lib/active_record/connection_adapters.rb +124 -1
  109. data/lib/active_record/connection_handling.rb +96 -104
  110. data/lib/active_record/core.rb +251 -176
  111. data/lib/active_record/counter_cache.rb +68 -34
  112. data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
  113. data/lib/active_record/database_configurations/database_config.rb +26 -5
  114. data/lib/active_record/database_configurations/hash_config.rb +52 -34
  115. data/lib/active_record/database_configurations/url_config.rb +37 -12
  116. data/lib/active_record/database_configurations.rb +87 -34
  117. data/lib/active_record/delegated_type.rb +39 -10
  118. data/lib/active_record/deprecator.rb +7 -0
  119. data/lib/active_record/destroy_association_async_job.rb +3 -1
  120. data/lib/active_record/dynamic_matchers.rb +2 -2
  121. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  122. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  123. data/lib/active_record/encryption/config.rb +25 -1
  124. data/lib/active_record/encryption/configurable.rb +12 -19
  125. data/lib/active_record/encryption/context.rb +10 -3
  126. data/lib/active_record/encryption/contexts.rb +5 -1
  127. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  128. data/lib/active_record/encryption/encryptable_record.rb +45 -21
  129. data/lib/active_record/encryption/encrypted_attribute_type.rb +47 -12
  130. data/lib/active_record/encryption/encryptor.rb +18 -3
  131. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  132. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  133. data/lib/active_record/encryption/key_generator.rb +12 -1
  134. data/lib/active_record/encryption/key_provider.rb +1 -1
  135. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  136. data/lib/active_record/encryption/message_serializer.rb +6 -0
  137. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  138. data/lib/active_record/encryption/properties.rb +3 -3
  139. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  140. data/lib/active_record/encryption/scheme.rb +22 -21
  141. data/lib/active_record/encryption.rb +3 -0
  142. data/lib/active_record/enum.rb +129 -28
  143. data/lib/active_record/errors.rb +151 -31
  144. data/lib/active_record/explain.rb +21 -12
  145. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  146. data/lib/active_record/fixture_set/render_context.rb +2 -0
  147. data/lib/active_record/fixture_set/table_row.rb +29 -8
  148. data/lib/active_record/fixtures.rb +167 -97
  149. data/lib/active_record/future_result.rb +47 -8
  150. data/lib/active_record/gem_version.rb +4 -4
  151. data/lib/active_record/inheritance.rb +34 -18
  152. data/lib/active_record/insert_all.rb +72 -22
  153. data/lib/active_record/integration.rb +11 -8
  154. data/lib/active_record/internal_metadata.rb +124 -20
  155. data/lib/active_record/locking/optimistic.rb +8 -7
  156. data/lib/active_record/locking/pessimistic.rb +5 -2
  157. data/lib/active_record/log_subscriber.rb +18 -22
  158. data/lib/active_record/marshalling.rb +59 -0
  159. data/lib/active_record/message_pack.rb +124 -0
  160. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  161. data/lib/active_record/middleware/database_selector.rb +6 -8
  162. data/lib/active_record/middleware/shard_selector.rb +3 -1
  163. data/lib/active_record/migration/command_recorder.rb +106 -8
  164. data/lib/active_record/migration/compatibility.rb +147 -5
  165. data/lib/active_record/migration/default_strategy.rb +22 -0
  166. data/lib/active_record/migration/execution_strategy.rb +19 -0
  167. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  168. data/lib/active_record/migration.rb +234 -117
  169. data/lib/active_record/model_schema.rb +90 -102
  170. data/lib/active_record/nested_attributes.rb +48 -11
  171. data/lib/active_record/normalization.rb +163 -0
  172. data/lib/active_record/persistence.rb +168 -339
  173. data/lib/active_record/promise.rb +84 -0
  174. data/lib/active_record/query_cache.rb +18 -25
  175. data/lib/active_record/query_logs.rb +92 -52
  176. data/lib/active_record/query_logs_formatter.rb +41 -0
  177. data/lib/active_record/querying.rb +33 -8
  178. data/lib/active_record/railtie.rb +129 -85
  179. data/lib/active_record/railties/controller_runtime.rb +22 -7
  180. data/lib/active_record/railties/databases.rake +145 -154
  181. data/lib/active_record/railties/job_runtime.rb +23 -0
  182. data/lib/active_record/readonly_attributes.rb +32 -5
  183. data/lib/active_record/reflection.rb +267 -69
  184. data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
  185. data/lib/active_record/relation/batches.rb +198 -63
  186. data/lib/active_record/relation/calculations.rb +250 -93
  187. data/lib/active_record/relation/delegation.rb +30 -19
  188. data/lib/active_record/relation/finder_methods.rb +93 -18
  189. data/lib/active_record/relation/merger.rb +6 -6
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +18 -3
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  193. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  194. data/lib/active_record/relation/predicate_builder.rb +28 -16
  195. data/lib/active_record/relation/query_attribute.rb +2 -1
  196. data/lib/active_record/relation/query_methods.rb +576 -107
  197. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  198. data/lib/active_record/relation/spawn_methods.rb +5 -4
  199. data/lib/active_record/relation/where_clause.rb +7 -19
  200. data/lib/active_record/relation.rb +580 -90
  201. data/lib/active_record/result.rb +49 -48
  202. data/lib/active_record/runtime_registry.rb +63 -1
  203. data/lib/active_record/sanitization.rb +70 -25
  204. data/lib/active_record/schema.rb +8 -7
  205. data/lib/active_record/schema_dumper.rb +63 -14
  206. data/lib/active_record/schema_migration.rb +75 -24
  207. data/lib/active_record/scoping/default.rb +15 -5
  208. data/lib/active_record/scoping/named.rb +3 -2
  209. data/lib/active_record/scoping.rb +2 -1
  210. data/lib/active_record/secure_password.rb +60 -0
  211. data/lib/active_record/secure_token.rb +21 -3
  212. data/lib/active_record/signed_id.rb +27 -6
  213. data/lib/active_record/statement_cache.rb +7 -7
  214. data/lib/active_record/store.rb +8 -8
  215. data/lib/active_record/suppressor.rb +3 -1
  216. data/lib/active_record/table_metadata.rb +1 -1
  217. data/lib/active_record/tasks/database_tasks.rb +190 -118
  218. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  219. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  220. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  221. data/lib/active_record/test_fixtures.rb +170 -155
  222. data/lib/active_record/testing/query_assertions.rb +121 -0
  223. data/lib/active_record/timestamp.rb +31 -17
  224. data/lib/active_record/token_for.rb +123 -0
  225. data/lib/active_record/touch_later.rb +12 -7
  226. data/lib/active_record/transaction.rb +132 -0
  227. data/lib/active_record/transactions.rb +106 -24
  228. data/lib/active_record/translation.rb +0 -2
  229. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  230. data/lib/active_record/type/internal/timezone.rb +7 -2
  231. data/lib/active_record/type/serialized.rb +1 -3
  232. data/lib/active_record/type/time.rb +4 -0
  233. data/lib/active_record/type_caster/connection.rb +4 -4
  234. data/lib/active_record/validations/absence.rb +1 -1
  235. data/lib/active_record/validations/associated.rb +9 -3
  236. data/lib/active_record/validations/numericality.rb +5 -4
  237. data/lib/active_record/validations/presence.rb +5 -28
  238. data/lib/active_record/validations/uniqueness.rb +61 -11
  239. data/lib/active_record/validations.rb +12 -5
  240. data/lib/active_record/version.rb +1 -1
  241. data/lib/active_record.rb +247 -33
  242. data/lib/arel/alias_predication.rb +1 -1
  243. data/lib/arel/collectors/bind.rb +2 -0
  244. data/lib/arel/collectors/composite.rb +7 -0
  245. data/lib/arel/collectors/sql_string.rb +1 -1
  246. data/lib/arel/collectors/substitute_binds.rb +1 -1
  247. data/lib/arel/errors.rb +10 -0
  248. data/lib/arel/factory_methods.rb +4 -0
  249. data/lib/arel/nodes/binary.rb +6 -7
  250. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  251. data/lib/arel/nodes/cte.rb +36 -0
  252. data/lib/arel/nodes/fragments.rb +35 -0
  253. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  254. data/lib/arel/nodes/leading_join.rb +8 -0
  255. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  256. data/lib/arel/nodes/node.rb +115 -5
  257. data/lib/arel/nodes/sql_literal.rb +13 -0
  258. data/lib/arel/nodes/table_alias.rb +4 -0
  259. data/lib/arel/nodes.rb +6 -2
  260. data/lib/arel/predications.rb +3 -1
  261. data/lib/arel/select_manager.rb +1 -1
  262. data/lib/arel/table.rb +9 -5
  263. data/lib/arel/tree_manager.rb +8 -3
  264. data/lib/arel/update_manager.rb +2 -1
  265. data/lib/arel/visitors/dot.rb +1 -0
  266. data/lib/arel/visitors/mysql.rb +17 -5
  267. data/lib/arel/visitors/postgresql.rb +1 -12
  268. data/lib/arel/visitors/sqlite.rb +25 -0
  269. data/lib/arel/visitors/to_sql.rb +112 -34
  270. data/lib/arel/visitors/visitor.rb +2 -2
  271. data/lib/arel.rb +21 -3
  272. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  273. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  274. data/lib/rails/generators/active_record/migration.rb +3 -1
  275. data/lib/rails/generators/active_record/model/USAGE +113 -0
  276. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  277. metadata +54 -12
  278. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  279. data/lib/active_record/null_relation.rb +0 -63
data/lib/active_record.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2022 David Heinemeier Hansson
4
+ # Copyright (c) David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -25,14 +25,17 @@
25
25
 
26
26
  require "active_support"
27
27
  require "active_support/rails"
28
+ require "active_support/ordered_options"
28
29
  require "active_model"
29
30
  require "arel"
30
31
  require "yaml"
31
32
 
32
33
  require "active_record/version"
34
+ require "active_record/deprecator"
33
35
  require "active_model/attribute_set"
34
36
  require "active_record/errors"
35
37
 
38
+ # :include: ../README.rdoc
36
39
  module ActiveRecord
37
40
  extend ActiveSupport::Autoload
38
41
 
@@ -47,18 +50,22 @@ module ActiveRecord
47
50
  autoload :Encryption
48
51
  autoload :Enum
49
52
  autoload :Explain
53
+ autoload :FixtureSet, "active_record/fixtures"
50
54
  autoload :Inheritance
51
55
  autoload :Integration
52
56
  autoload :InternalMetadata
57
+ autoload :LogSubscriber
58
+ autoload :Marshalling
53
59
  autoload :Migration
54
60
  autoload :Migrator, "active_record/migration"
55
61
  autoload :ModelSchema
56
62
  autoload :NestedAttributes
57
63
  autoload :NoTouching
64
+ autoload :Normalization
58
65
  autoload :Persistence
59
66
  autoload :QueryCache
60
- autoload :Querying
61
67
  autoload :QueryLogs
68
+ autoload :Querying
62
69
  autoload :ReadonlyAttributes
63
70
  autoload :RecordInvalid, "active_record/validations"
64
71
  autoload :Reflection
@@ -68,6 +75,7 @@ module ActiveRecord
68
75
  autoload :SchemaDumper
69
76
  autoload :SchemaMigration
70
77
  autoload :Scoping
78
+ autoload :SecurePassword
71
79
  autoload :SecureToken
72
80
  autoload :Serialization
73
81
  autoload :SignedId
@@ -76,7 +84,9 @@ module ActiveRecord
76
84
  autoload :TestDatabases
77
85
  autoload :TestFixtures, "active_record/fixtures"
78
86
  autoload :Timestamp
87
+ autoload :TokenFor
79
88
  autoload :TouchLater
89
+ autoload :Transaction
80
90
  autoload :Transactions
81
91
  autoload :Translation
82
92
  autoload :Validations
@@ -93,7 +103,7 @@ module ActiveRecord
93
103
  autoload :DisableJoinsAssociationRelation
94
104
  autoload :FutureResult
95
105
  autoload :LegacyYamlAdapter
96
- autoload :NullRelation
106
+ autoload :Promise
97
107
  autoload :Relation
98
108
  autoload :Result
99
109
  autoload :StatementCache
@@ -101,17 +111,18 @@ module ActiveRecord
101
111
  autoload :Type
102
112
 
103
113
  autoload_under "relation" do
104
- autoload :QueryMethods
105
- autoload :FinderMethods
114
+ autoload :Batches
106
115
  autoload :Calculations
116
+ autoload :Delegation
117
+ autoload :FinderMethods
107
118
  autoload :PredicateBuilder
119
+ autoload :QueryMethods
108
120
  autoload :SpawnMethods
109
- autoload :Batches
110
- autoload :Delegation
111
121
  end
112
122
  end
113
123
 
114
124
  module Coders
125
+ autoload :ColumnSerializer, "active_record/coders/column_serializer"
115
126
  autoload :JSON, "active_record/coders/json"
116
127
  autoload :YAMLColumn, "active_record/coders/yaml_column"
117
128
  end
@@ -119,6 +130,8 @@ module ActiveRecord
119
130
  module AttributeMethods
120
131
  extend ActiveSupport::Autoload
121
132
 
133
+ autoload :CompositePrimaryKey
134
+
122
135
  eager_autoload do
123
136
  autoload :BeforeTypeCast
124
137
  autoload :Dirty
@@ -165,21 +178,24 @@ module ActiveRecord
165
178
  autoload :SQLiteDatabaseTasks, "active_record/tasks/sqlite_database_tasks"
166
179
  end
167
180
 
181
+ singleton_class.attr_accessor :disable_prepared_statements
182
+ self.disable_prepared_statements = false
183
+
184
+ ##
185
+ # :singleton-method: lazily_load_schema_cache
168
186
  # Lazily load the schema cache. This option will load the schema cache
169
- # when a connection is established rather than on boot. If set,
170
- # +config.active_record.use_schema_cache_dump+ will be set to false.
187
+ # when a connection is established rather than on boot.
171
188
  singleton_class.attr_accessor :lazily_load_schema_cache
172
189
  self.lazily_load_schema_cache = false
173
190
 
191
+ ##
192
+ # :singleton-method: schema_cache_ignored_tables
174
193
  # A list of tables or regex's to match tables to ignore when
175
194
  # dumping the schema cache. For example if this is set to +[/^_/]+
176
195
  # the schema cache will not dump tables named with an underscore.
177
196
  singleton_class.attr_accessor :schema_cache_ignored_tables
178
197
  self.schema_cache_ignored_tables = []
179
198
 
180
- singleton_class.attr_accessor :legacy_connection_handling
181
- self.legacy_connection_handling = true
182
-
183
199
  singleton_class.attr_reader :default_timezone
184
200
 
185
201
  # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
@@ -194,12 +210,59 @@ module ActiveRecord
194
210
 
195
211
  self.default_timezone = :utc
196
212
 
213
+ ##
214
+ # :singleton-method: db_warnings_action
215
+ # The action to take when database query produces warning.
216
+ # Must be one of :ignore, :log, :raise, :report, or a custom proc.
217
+ # The default is :ignore.
218
+ singleton_class.attr_reader :db_warnings_action
219
+
220
+ def self.db_warnings_action=(action)
221
+ @db_warnings_action =
222
+ case action
223
+ when :ignore
224
+ nil
225
+ when :log
226
+ ->(warning) do
227
+ warning_message = "[#{warning.class}] #{warning.message}"
228
+ warning_message += " (#{warning.code})" if warning.code
229
+ ActiveRecord::Base.logger.warn(warning_message)
230
+ end
231
+ when :raise
232
+ ->(warning) { raise warning }
233
+ when :report
234
+ ->(warning) { Rails.error.report(warning, handled: true) }
235
+ when Proc
236
+ action
237
+ else
238
+ raise ArgumentError, "db_warnings_action must be one of :ignore, :log, :raise, :report, or a custom proc."
239
+ end
240
+ end
241
+
242
+ self.db_warnings_action = :ignore
243
+
244
+ ##
245
+ # :singleton-method: db_warnings_ignore
246
+ # Specify allowlist of database warnings.
247
+ singleton_class.attr_accessor :db_warnings_ignore
248
+ self.db_warnings_ignore = []
249
+
197
250
  singleton_class.attr_accessor :writing_role
198
251
  self.writing_role = :writing
199
252
 
200
253
  singleton_class.attr_accessor :reading_role
201
254
  self.reading_role = :reading
202
255
 
256
+ def self.legacy_connection_handling=(_)
257
+ raise ArgumentError, <<~MSG.squish
258
+ The `legacy_connection_handling` setter was deprecated in 7.0 and removed in 7.1,
259
+ but is still defined in your configuration. Please remove this call as it no longer
260
+ has any effect."
261
+ MSG
262
+ end
263
+
264
+ ##
265
+ # :singleton-method: async_query_executor
203
266
  # Sets the async_query_executor for an application. By default the thread pool executor
204
267
  # set to +nil+ which will not run queries in the background. Applications must configure
205
268
  # a thread pool executor to use this feature. Options are:
@@ -227,7 +290,7 @@ module ActiveRecord
227
290
  # with the global thread pool async query executor.
228
291
  def self.global_executor_concurrency=(global_executor_concurrency)
229
292
  if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
230
- raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
293
+ raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
231
294
  end
232
295
 
233
296
  @global_executor_concurrency = global_executor_concurrency
@@ -237,11 +300,22 @@ module ActiveRecord
237
300
  @global_executor_concurrency ||= nil
238
301
  end
239
302
 
303
+ @permanent_connection_checkout = true
304
+ singleton_class.attr_reader :permanent_connection_checkout
305
+
306
+ # Defines whether +ActiveRecord::Base.connection+ is allowed, deprecated, or entirely disallowed.
307
+ def self.permanent_connection_checkout=(value)
308
+ unless [true, :deprecated, :disallowed].include?(value)
309
+ raise ArgumentError, "permanent_connection_checkout must be one of: `true`, `:deprecated` or `:disallowed`"
310
+ end
311
+ @permanent_connection_checkout = value
312
+ end
313
+
240
314
  singleton_class.attr_accessor :index_nested_attribute_errors
241
315
  self.index_nested_attribute_errors = false
242
316
 
243
317
  ##
244
- # :singleton-method:
318
+ # :singleton-method: verbose_query_logs
245
319
  #
246
320
  # Specifies if the methods calling database queries should be logged below
247
321
  # their relevant queries. Defaults to false.
@@ -249,7 +323,7 @@ module ActiveRecord
249
323
  self.verbose_query_logs = false
250
324
 
251
325
  ##
252
- # :singleton-method:
326
+ # :singleton-method: queues
253
327
  #
254
328
  # Specifies the names of the queues used by background jobs.
255
329
  singleton_class.attr_accessor :queues
@@ -258,8 +332,34 @@ module ActiveRecord
258
332
  singleton_class.attr_accessor :maintain_test_schema
259
333
  self.maintain_test_schema = nil
260
334
 
335
+ singleton_class.attr_accessor :raise_on_assign_to_attr_readonly
336
+ self.raise_on_assign_to_attr_readonly = false
337
+
338
+ singleton_class.attr_accessor :belongs_to_required_validates_foreign_key
339
+ self.belongs_to_required_validates_foreign_key = true
340
+
341
+ singleton_class.attr_accessor :before_committed_on_all_records
342
+ self.before_committed_on_all_records = false
343
+
344
+ singleton_class.attr_accessor :run_after_transaction_callbacks_in_order_defined
345
+ self.run_after_transaction_callbacks_in_order_defined = false
346
+
347
+ def self.commit_transaction_on_non_local_return
348
+ ActiveRecord.deprecator.warn <<-WARNING.squish
349
+ `Rails.application.config.active_record.commit_transaction_on_non_local_return`
350
+ is deprecated and will be removed in Rails 8.0.
351
+ WARNING
352
+ end
353
+
354
+ def self.commit_transaction_on_non_local_return=(value)
355
+ ActiveRecord.deprecator.warn <<-WARNING.squish
356
+ `Rails.application.config.active_record.commit_transaction_on_non_local_return`
357
+ is deprecated and will be removed in Rails 8.0.
358
+ WARNING
359
+ end
360
+
261
361
  ##
262
- # :singleton-method:
362
+ # :singleton-method: warn_on_records_fetched_greater_than
263
363
  # Specify a threshold for the size of query result sets. If the number of
264
364
  # records in the set exceeds the threshold, a warning is logged. This can
265
365
  # be used to identify queries which load thousands of records and
@@ -271,14 +371,14 @@ module ActiveRecord
271
371
  self.application_record_class = nil
272
372
 
273
373
  ##
274
- # :singleton-method:
374
+ # :singleton-method: action_on_strict_loading_violation
275
375
  # Set the application to log or raise when an association violates strict loading.
276
376
  # Defaults to :raise.
277
377
  singleton_class.attr_accessor :action_on_strict_loading_violation
278
378
  self.action_on_strict_loading_violation = :raise
279
379
 
280
380
  ##
281
- # :singleton-method:
381
+ # :singleton-method: schema_format
282
382
  # Specifies the format to use when dumping the database schema with Rails'
283
383
  # Rakefile. If :sql, the schema is dumped as (potentially database-
284
384
  # specific) SQL statements. If :ruby, the schema is dumped as an
@@ -289,7 +389,7 @@ module ActiveRecord
289
389
  self.schema_format = :ruby
290
390
 
291
391
  ##
292
- # :singleton-method:
392
+ # :singleton-method: error_on_ignored_order
293
393
  # Specifies if an error should be raised if the query has an order being
294
394
  # ignored when doing batch queries. Useful in applications where the
295
395
  # scope being ignored is error-worthy, rather than a warning.
@@ -297,13 +397,27 @@ module ActiveRecord
297
397
  self.error_on_ignored_order = false
298
398
 
299
399
  ##
300
- # :singleton-method:
400
+ # :singleton-method: timestamped_migrations
301
401
  # Specify whether or not to use timestamps for migration versions
302
402
  singleton_class.attr_accessor :timestamped_migrations
303
403
  self.timestamped_migrations = true
304
404
 
305
405
  ##
306
- # :singleton-method:
406
+ # :singleton-method: validate_migration_timestamps
407
+ # Specify whether or not to validate migration timestamps. When set, an error
408
+ # will be raised if a timestamp is more than a day ahead of the timestamp
409
+ # associated with the current time. +timestamped_migrations+ must be set to true.
410
+ singleton_class.attr_accessor :validate_migration_timestamps
411
+ self.validate_migration_timestamps = false
412
+
413
+ ##
414
+ # :singleton-method: migration_strategy
415
+ # Specify strategy to use for executing migrations.
416
+ singleton_class.attr_accessor :migration_strategy
417
+ self.migration_strategy = Migration::DefaultStrategy
418
+
419
+ ##
420
+ # :singleton-method: dump_schema_after_migration
307
421
  # Specify whether schema dump should happen at the end of the
308
422
  # bin/rails db:migrate command. This is true by default, which is useful for the
309
423
  # development environment. This should ideally be false in the production
@@ -312,7 +426,7 @@ module ActiveRecord
312
426
  self.dump_schema_after_migration = true
313
427
 
314
428
  ##
315
- # :singleton-method:
429
+ # :singleton-method: dump_schemas
316
430
  # Specifies which database schemas to dump when calling db:schema:dump.
317
431
  # If the value is :schema_search_path (the default), any schemas listed in
318
432
  # schema_search_path are dumped. Use :all to dump all schemas regardless
@@ -322,14 +436,7 @@ module ActiveRecord
322
436
  self.dump_schemas = :schema_search_path
323
437
 
324
438
  ##
325
- # :singleton-method:
326
- # Show a warning when Rails couldn't parse your database.yml
327
- # for multiple databases.
328
- singleton_class.attr_accessor :suppress_multiple_database_warning
329
- self.suppress_multiple_database_warning = false
330
-
331
- ##
332
- # :singleton-method:
439
+ # :singleton-method: verify_foreign_keys_for_fixtures
333
440
  # If true, Rails will verify all foreign keys in the database after loading fixtures.
334
441
  # An error will be raised if there are any foreign key violations, indicating incorrectly
335
442
  # written fixtures.
@@ -337,18 +444,32 @@ module ActiveRecord
337
444
  singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
338
445
  self.verify_foreign_keys_for_fixtures = false
339
446
 
447
+ def self.allow_deprecated_singular_associations_name
448
+ ActiveRecord.deprecator.warn <<-WARNING.squish
449
+ `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
450
+ is deprecated and will be removed in Rails 8.0.
451
+ WARNING
452
+ end
453
+
454
+ def self.allow_deprecated_singular_associations_name=(value)
455
+ ActiveRecord.deprecator.warn <<-WARNING.squish
456
+ `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
457
+ is deprecated and will be removed in Rails 8.0.
458
+ WARNING
459
+ end
460
+
340
461
  singleton_class.attr_accessor :query_transformers
341
462
  self.query_transformers = []
342
463
 
343
464
  ##
344
- # :singleton-method:
465
+ # :singleton-method: use_yaml_unsafe_load
345
466
  # Application configurable boolean that instructs the YAML Coder to use
346
467
  # an unsafe load if set to true.
347
468
  singleton_class.attr_accessor :use_yaml_unsafe_load
348
469
  self.use_yaml_unsafe_load = false
349
470
 
350
471
  ##
351
- # :singleton-method:
472
+ # :singleton-method: raise_int_wider_than_64bit
352
473
  # Application configurable boolean that denotes whether or not to raise
353
474
  # an exception when the PostgreSQLAdapter is provided with an integer that
354
475
  # is wider than signed 64bit representation
@@ -356,12 +477,55 @@ module ActiveRecord
356
477
  self.raise_int_wider_than_64bit = true
357
478
 
358
479
  ##
359
- # :singleton-method:
480
+ # :singleton-method: yaml_column_permitted_classes
360
481
  # Application configurable array that provides additional permitted classes
361
482
  # to Psych safe_load in the YAML Coder
362
483
  singleton_class.attr_accessor :yaml_column_permitted_classes
363
484
  self.yaml_column_permitted_classes = [Symbol]
364
485
 
486
+ ##
487
+ # :singleton-method: generate_secure_token_on
488
+ # Controls when to generate a value for <tt>has_secure_token</tt>
489
+ # declarations. Defaults to <tt>:create</tt>.
490
+ singleton_class.attr_accessor :generate_secure_token_on
491
+ self.generate_secure_token_on = :create
492
+
493
+ def self.marshalling_format_version
494
+ Marshalling.format_version
495
+ end
496
+
497
+ def self.marshalling_format_version=(value)
498
+ Marshalling.format_version = value
499
+ end
500
+
501
+ ##
502
+ # :singleton-method: protocol_adapters
503
+ # Provides a mapping between database protocols/DBMSs and the
504
+ # underlying database adapter to be used. This is used only by the
505
+ # <tt>DATABASE_URL</tt> environment variable.
506
+ #
507
+ # == Example
508
+ #
509
+ # DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
510
+ #
511
+ # The above URL specifies that MySQL is the desired protocol/DBMS, and the
512
+ # application configuration can then decide which adapter to use. For this example
513
+ # the default mapping is from <tt>mysql</tt> to <tt>mysql2</tt>, but <tt>:trilogy</tt>
514
+ # is also supported.
515
+ #
516
+ # ActiveRecord.protocol_adapters.mysql = "mysql2"
517
+ #
518
+ # The protocols names are arbitrary, and external database adapters can be
519
+ # registered and set here.
520
+ singleton_class.attr_accessor :protocol_adapters
521
+ self.protocol_adapters = ActiveSupport::InheritableOptions.new(
522
+ {
523
+ sqlite: "sqlite3",
524
+ mysql: "mysql2",
525
+ postgres: "postgresql",
526
+ }
527
+ )
528
+
365
529
  def self.eager_load!
366
530
  super
367
531
  ActiveRecord::Locking.eager_load!
@@ -371,6 +535,56 @@ module ActiveRecord
371
535
  ActiveRecord::ConnectionAdapters.eager_load!
372
536
  ActiveRecord::Encryption.eager_load!
373
537
  end
538
+
539
+ # Explicitly closes all database connections in all pools.
540
+ def self.disconnect_all!
541
+ ConnectionAdapters::PoolConfig.disconnect_all!
542
+ end
543
+
544
+ # Registers a block to be called after all the current transactions have been
545
+ # committed.
546
+ #
547
+ # If there is no currently open transaction, the block is called immediately.
548
+ #
549
+ # If there are multiple nested transactions, the block is called after the outermost one
550
+ # has been committed,
551
+ #
552
+ # If any of the currently open transactions is rolled back, the block is never called.
553
+ #
554
+ # If multiple transactions are open across multiple databases, the block will be invoked
555
+ # if and once all of them have been committed. But note that nesting transactions across
556
+ # two distinct databases is a sharding anti-pattern that comes with a world of hurts.
557
+ def self.after_all_transactions_commit(&block)
558
+ open_transactions = all_open_transactions
559
+
560
+ if open_transactions.empty?
561
+ yield
562
+ elsif open_transactions.size == 1
563
+ open_transactions.first.after_commit(&block)
564
+ else
565
+ count = open_transactions.size
566
+ callback = -> do
567
+ count -= 1
568
+ block.call if count.zero?
569
+ end
570
+ open_transactions.each do |t|
571
+ t.after_commit(&callback)
572
+ end
573
+ open_transactions = nil # rubocop:disable Lint/UselessAssignment avoid holding it in the closure
574
+ end
575
+ end
576
+
577
+ def self.all_open_transactions # :nodoc:
578
+ open_transactions = []
579
+ Base.connection_handler.each_connection_pool do |pool|
580
+ if active_connection = pool.active_connection
581
+ if active_connection.current_transaction.open? && active_connection.current_transaction.joinable?
582
+ open_transactions << active_connection.current_transaction
583
+ end
584
+ end
585
+ end
586
+ open_transactions
587
+ end
374
588
  end
375
589
 
376
590
  ActiveSupport.on_load(:active_record) do
@@ -3,7 +3,7 @@
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
+ Nodes::As.new self, Nodes::SqlLiteral.new(other, retryable: true)
7
7
  end
8
8
  end
9
9
  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
@@ -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,7 +5,7 @@ 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
@@ -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
data/lib/arel/errors.rb CHANGED
@@ -6,4 +6,14 @@ module Arel # :nodoc: all
6
6
 
7
7
  class EmptyJoinError < ArelError
8
8
  end
9
+
10
+ class BindError < ArelError
11
+ def initialize(message, sql = nil)
12
+ if sql
13
+ super("#{message} in: #{sql.inspect}")
14
+ else
15
+ super(message)
16
+ end
17
+ end
18
+ end
9
19
  end
@@ -45,5 +45,9 @@ module Arel # :nodoc: all
45
45
  def coalesce(*exprs)
46
46
  Nodes::NamedFunction.new "COALESCE", exprs
47
47
  end
48
+
49
+ def cast(name, type)
50
+ Nodes::NamedFunction.new "CAST", [name.as(type)]
51
+ end
48
52
  end
49
53
  end
@@ -39,6 +39,12 @@ module Arel # :nodoc: all
39
39
  end
40
40
  end
41
41
 
42
+ class As < Binary
43
+ def to_cte
44
+ Arel::Nodes::Cte.new(left.name, right)
45
+ end
46
+ end
47
+
42
48
  class Between < Binary; include FetchAttribute; end
43
49
 
44
50
  class GreaterThan < Binary
@@ -105,14 +111,7 @@ module Arel # :nodoc: all
105
111
  end
106
112
  end
107
113
 
108
- class Or < Binary
109
- def fetch_attribute(&block)
110
- left.fetch_attribute(&block) && right.fetch_attribute(&block)
111
- end
112
- end
113
-
114
114
  %w{
115
- As
116
115
  Assignment
117
116
  Join
118
117
  Union
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class BoundSqlLiteral < NodeExpression
6
+ attr_reader :sql_with_placeholders, :positional_binds, :named_binds
7
+
8
+ def initialize(sql_with_placeholders, positional_binds, named_binds)
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
16
+ if positional_binds.size != (expected = sql_with_placeholders.count("?"))
17
+ raise BindError.new("wrong number of bind variables (#{positional_binds.size} for #{expected})", sql_with_placeholders)
18
+ end
19
+ elsif has_named
20
+ tokens_in_string = sql_with_placeholders.scan(/:(?<!::)([a-zA-Z]\w*)/).flatten.map(&:to_sym).uniq
21
+ tokens_in_hash = named_binds.keys.map(&:to_sym).uniq
22
+
23
+ if !(missing = (tokens_in_string - tokens_in_hash)).empty?
24
+ if missing.size == 1
25
+ raise BindError.new("missing value for #{missing.first.inspect}", sql_with_placeholders)
26
+ else
27
+ raise BindError.new("missing values for #{missing.inspect}", sql_with_placeholders)
28
+ end
29
+ end
30
+ end
31
+
32
+ @sql_with_placeholders = sql_with_placeholders
33
+ if has_positional
34
+ @positional_binds = positional_binds
35
+ @named_binds = nil
36
+ else
37
+ @positional_binds = nil
38
+ @named_binds = named_binds
39
+ end
40
+ end
41
+
42
+ def hash
43
+ [self.class, sql_with_placeholders, positional_binds, named_binds].hash
44
+ end
45
+
46
+ def eql?(other)
47
+ self.class == other.class &&
48
+ sql_with_placeholders == other.sql_with_placeholders &&
49
+ positional_binds == other.positional_binds &&
50
+ named_binds == other.named_binds
51
+ end
52
+ alias :== :eql?
53
+
54
+ def +(other)
55
+ raise ArgumentError, "Expected Arel node" unless Arel.arel_node?(other)
56
+
57
+ Fragments.new([self, other])
58
+ end
59
+
60
+ def inspect
61
+ "#<#{self.class.name} #{sql_with_placeholders.inspect} #{(named_binds || positional_binds).inspect}>"
62
+ end
63
+ end
64
+ end
65
+ end