activerecord 7.1.5.1 → 7.2.0.beta1

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +515 -2445
  3. data/README.rdoc +15 -15
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +1 -1
  6. data/lib/active_record/associations/alias_tracker.rb +25 -19
  7. data/lib/active_record/associations/association.rb +9 -8
  8. data/lib/active_record/associations/belongs_to_association.rb +14 -7
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/belongs_to.rb +1 -0
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  12. data/lib/active_record/associations/builder/has_many.rb +3 -4
  13. data/lib/active_record/associations/builder/has_one.rb +3 -4
  14. data/lib/active_record/associations/collection_association.rb +6 -4
  15. data/lib/active_record/associations/collection_proxy.rb +14 -1
  16. data/lib/active_record/associations/has_many_association.rb +1 -1
  17. data/lib/active_record/associations/join_dependency/join_association.rb +29 -28
  18. data/lib/active_record/associations/join_dependency.rb +5 -5
  19. data/lib/active_record/associations/nested_error.rb +47 -0
  20. data/lib/active_record/associations/preloader/association.rb +2 -1
  21. data/lib/active_record/associations/preloader/branch.rb +7 -1
  22. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  23. data/lib/active_record/associations/singular_association.rb +6 -0
  24. data/lib/active_record/associations/through_association.rb +1 -1
  25. data/lib/active_record/associations.rb +33 -16
  26. data/lib/active_record/attribute_assignment.rb +1 -11
  27. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  28. data/lib/active_record/attribute_methods/dirty.rb +1 -1
  29. data/lib/active_record/attribute_methods/primary_key.rb +23 -55
  30. data/lib/active_record/attribute_methods/read.rb +4 -16
  31. data/lib/active_record/attribute_methods/serialization.rb +4 -24
  32. data/lib/active_record/attribute_methods/time_zone_conversion.rb +7 -10
  33. data/lib/active_record/attribute_methods/write.rb +3 -3
  34. data/lib/active_record/attribute_methods.rb +60 -71
  35. data/lib/active_record/attributes.rb +55 -42
  36. data/lib/active_record/autosave_association.rb +13 -32
  37. data/lib/active_record/base.rb +2 -3
  38. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
  39. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
  40. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +248 -65
  41. data/lib/active_record/connection_adapters/abstract/database_statements.rb +34 -17
  42. data/lib/active_record/connection_adapters/abstract/query_cache.rb +159 -74
  43. data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
  44. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
  45. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +14 -5
  46. data/lib/active_record/connection_adapters/abstract/transaction.rb +60 -57
  47. data/lib/active_record/connection_adapters/abstract_adapter.rb +18 -46
  48. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +32 -6
  49. data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
  50. data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
  51. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +7 -1
  52. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +11 -5
  53. data/lib/active_record/connection_adapters/mysql2_adapter.rb +5 -23
  54. data/lib/active_record/connection_adapters/pool_config.rb +7 -6
  55. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
  56. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  57. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  58. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  59. data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
  60. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
  61. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -13
  62. data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -21
  63. data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
  64. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  65. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
  66. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
  67. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  68. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  69. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  70. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
  71. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +107 -75
  72. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +12 -6
  73. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -48
  74. data/lib/active_record/connection_adapters.rb +121 -0
  75. data/lib/active_record/connection_handling.rb +56 -41
  76. data/lib/active_record/core.rb +53 -37
  77. data/lib/active_record/counter_cache.rb +18 -9
  78. data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
  79. data/lib/active_record/database_configurations/database_config.rb +15 -4
  80. data/lib/active_record/database_configurations/hash_config.rb +38 -34
  81. data/lib/active_record/database_configurations/url_config.rb +20 -1
  82. data/lib/active_record/database_configurations.rb +1 -1
  83. data/lib/active_record/delegated_type.rb +24 -0
  84. data/lib/active_record/dynamic_matchers.rb +2 -2
  85. data/lib/active_record/encryption/encryptable_record.rb +2 -2
  86. data/lib/active_record/encryption/encrypted_attribute_type.rb +22 -2
  87. data/lib/active_record/encryption/encryptor.rb +17 -2
  88. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  89. data/lib/active_record/encryption/message_serializer.rb +4 -0
  90. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  91. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  92. data/lib/active_record/encryption.rb +0 -2
  93. data/lib/active_record/enum.rb +10 -1
  94. data/lib/active_record/errors.rb +16 -11
  95. data/lib/active_record/explain.rb +13 -24
  96. data/lib/active_record/fixtures.rb +37 -31
  97. data/lib/active_record/future_result.rb +8 -4
  98. data/lib/active_record/gem_version.rb +3 -3
  99. data/lib/active_record/inheritance.rb +4 -2
  100. data/lib/active_record/insert_all.rb +18 -15
  101. data/lib/active_record/integration.rb +4 -1
  102. data/lib/active_record/internal_metadata.rb +48 -34
  103. data/lib/active_record/locking/optimistic.rb +7 -6
  104. data/lib/active_record/log_subscriber.rb +0 -21
  105. data/lib/active_record/marshalling.rb +1 -4
  106. data/lib/active_record/message_pack.rb +1 -1
  107. data/lib/active_record/migration/command_recorder.rb +2 -3
  108. data/lib/active_record/migration/compatibility.rb +5 -3
  109. data/lib/active_record/migration/default_strategy.rb +4 -5
  110. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  111. data/lib/active_record/migration.rb +85 -76
  112. data/lib/active_record/model_schema.rb +28 -68
  113. data/lib/active_record/nested_attributes.rb +13 -16
  114. data/lib/active_record/normalization.rb +3 -7
  115. data/lib/active_record/persistence.rb +30 -352
  116. data/lib/active_record/query_cache.rb +18 -6
  117. data/lib/active_record/query_logs.rb +15 -0
  118. data/lib/active_record/querying.rb +21 -9
  119. data/lib/active_record/railtie.rb +50 -62
  120. data/lib/active_record/railties/controller_runtime.rb +13 -4
  121. data/lib/active_record/railties/databases.rake +41 -44
  122. data/lib/active_record/reflection.rb +90 -35
  123. data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
  124. data/lib/active_record/relation/batches.rb +3 -3
  125. data/lib/active_record/relation/calculations.rb +94 -61
  126. data/lib/active_record/relation/delegation.rb +8 -11
  127. data/lib/active_record/relation/finder_methods.rb +16 -2
  128. data/lib/active_record/relation/merger.rb +4 -6
  129. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  130. data/lib/active_record/relation/predicate_builder.rb +3 -3
  131. data/lib/active_record/relation/query_methods.rb +196 -57
  132. data/lib/active_record/relation/record_fetch_warning.rb +3 -0
  133. data/lib/active_record/relation/spawn_methods.rb +2 -18
  134. data/lib/active_record/relation/where_clause.rb +7 -19
  135. data/lib/active_record/relation.rb +496 -72
  136. data/lib/active_record/result.rb +31 -44
  137. data/lib/active_record/runtime_registry.rb +39 -0
  138. data/lib/active_record/sanitization.rb +24 -19
  139. data/lib/active_record/schema.rb +8 -6
  140. data/lib/active_record/schema_dumper.rb +19 -9
  141. data/lib/active_record/schema_migration.rb +30 -14
  142. data/lib/active_record/signed_id.rb +11 -1
  143. data/lib/active_record/statement_cache.rb +7 -7
  144. data/lib/active_record/table_metadata.rb +1 -10
  145. data/lib/active_record/tasks/database_tasks.rb +76 -70
  146. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  147. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  148. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
  149. data/lib/active_record/test_fixtures.rb +81 -91
  150. data/lib/active_record/testing/query_assertions.rb +121 -0
  151. data/lib/active_record/timestamp.rb +1 -1
  152. data/lib/active_record/token_for.rb +22 -12
  153. data/lib/active_record/touch_later.rb +1 -1
  154. data/lib/active_record/transaction.rb +68 -0
  155. data/lib/active_record/transactions.rb +43 -14
  156. data/lib/active_record/translation.rb +0 -2
  157. data/lib/active_record/type/serialized.rb +1 -3
  158. data/lib/active_record/type_caster/connection.rb +4 -4
  159. data/lib/active_record/validations/associated.rb +9 -3
  160. data/lib/active_record/validations/uniqueness.rb +14 -10
  161. data/lib/active_record/validations.rb +4 -1
  162. data/lib/active_record.rb +149 -40
  163. data/lib/arel/alias_predication.rb +1 -1
  164. data/lib/arel/collectors/bind.rb +2 -0
  165. data/lib/arel/collectors/composite.rb +7 -0
  166. data/lib/arel/collectors/sql_string.rb +1 -1
  167. data/lib/arel/collectors/substitute_binds.rb +1 -1
  168. data/lib/arel/nodes/binary.rb +0 -6
  169. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  170. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  171. data/lib/arel/nodes/node.rb +4 -3
  172. data/lib/arel/nodes/sql_literal.rb +7 -0
  173. data/lib/arel/nodes.rb +2 -2
  174. data/lib/arel/predications.rb +1 -1
  175. data/lib/arel/select_manager.rb +1 -1
  176. data/lib/arel/tree_manager.rb +3 -2
  177. data/lib/arel/update_manager.rb +2 -1
  178. data/lib/arel/visitors/dot.rb +1 -0
  179. data/lib/arel/visitors/mysql.rb +9 -4
  180. data/lib/arel/visitors/postgresql.rb +1 -12
  181. data/lib/arel/visitors/to_sql.rb +29 -16
  182. data/lib/arel.rb +7 -3
  183. metadata +20 -15
@@ -10,15 +10,16 @@ module ActiveRecord
10
10
  :first_or_create, :first_or_create!, :first_or_initialize,
11
11
  :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
12
12
  :create_or_find_by, :create_or_find_by!,
13
- :destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
13
+ :destroy, :destroy_all, :delete, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
14
14
  :find_each, :find_in_batches, :in_batches,
15
15
  :select, :reselect, :order, :regroup, :in_order_of, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
16
16
  :where, :rewhere, :invert_where, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
17
17
  :and, :or, :annotate, :optimizer_hints, :extending,
18
18
  :having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
19
19
  :count, :average, :minimum, :maximum, :sum, :calculate,
20
- :pluck, :pick, :ids, :async_ids, :strict_loading, :excluding, :without, :with,
20
+ :pluck, :pick, :ids, :async_ids, :strict_loading, :excluding, :without, :with, :with_recursive,
21
21
  :async_count, :async_average, :async_minimum, :async_maximum, :async_sum, :async_pluck, :async_pick,
22
+ :insert, :insert_all, :insert!, :insert_all!, :upsert, :upsert_all
22
23
  ].freeze # :nodoc:
23
24
  delegate(*QUERYING_METHODS, to: :all)
24
25
 
@@ -47,19 +48,26 @@ module ActiveRecord
47
48
  #
48
49
  # Note that building your own SQL query string from user input may expose your application to
49
50
  # injection attacks (https://guides.rubyonrails.org/security.html#sql-injection).
50
- def find_by_sql(sql, binds = [], preparable: nil, &block)
51
- _load_from_sql(_query_by_sql(sql, binds, preparable: preparable), &block)
51
+ def find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block)
52
+ result = with_connection do |c|
53
+ _query_by_sql(c, sql, binds, preparable: preparable, allow_retry: allow_retry)
54
+ end
55
+ _load_from_sql(result, &block)
52
56
  end
53
57
 
54
58
  # Same as <tt>#find_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
55
59
  def async_find_by_sql(sql, binds = [], preparable: nil, &block)
56
- _query_by_sql(sql, binds, preparable: preparable, async: true).then do |result|
60
+ result = with_connection do |c|
61
+ _query_by_sql(c, sql, binds, preparable: preparable, async: true)
62
+ end
63
+
64
+ result.then do |result|
57
65
  _load_from_sql(result, &block)
58
66
  end
59
67
  end
60
68
 
61
- def _query_by_sql(sql, binds = [], preparable: nil, async: false) # :nodoc:
62
- connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable, async: async)
69
+ def _query_by_sql(connection, sql, binds = [], preparable: nil, async: false, allow_retry: false) # :nodoc:
70
+ connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable, async: async, allow_retry: allow_retry)
63
71
  end
64
72
 
65
73
  def _load_from_sql(result_set, &block) # :nodoc:
@@ -99,12 +107,16 @@ module ActiveRecord
99
107
  #
100
108
  # * +sql+ - An SQL statement which should return a count query from the database, see the example above.
101
109
  def count_by_sql(sql)
102
- connection.select_value(sanitize_sql(sql), "#{name} Count").to_i
110
+ with_connection do |c|
111
+ c.select_value(sanitize_sql(sql), "#{name} Count").to_i
112
+ end
103
113
  end
104
114
 
105
115
  # Same as <tt>#count_by_sql</tt> but perform the query asynchronously and returns an ActiveRecord::Promise.
106
116
  def async_count_by_sql(sql)
107
- connection.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
117
+ with_connection do |c|
118
+ c.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
119
+ end
108
120
  end
109
121
  end
110
122
  end
@@ -31,7 +31,6 @@ module ActiveRecord
31
31
  config.active_record.check_schema_cache_dump_version = true
32
32
  config.active_record.maintain_test_schema = true
33
33
  config.active_record.has_many_inversing = false
34
- config.active_record.sqlite3_production_warning = true
35
34
  config.active_record.query_log_tags_enabled = false
36
35
  config.active_record.query_log_tags = [ :application ]
37
36
  config.active_record.query_log_tags_format = :legacy
@@ -88,7 +87,9 @@ module ActiveRecord
88
87
 
89
88
  initializer "active_record.postgresql_time_zone_aware_types" do
90
89
  ActiveSupport.on_load(:active_record_postgresqladapter) do
91
- ActiveRecord::Base.time_zone_aware_types << :timestamptz
90
+ ActiveSupport.on_load(:active_record) do
91
+ ActiveRecord::Base.time_zone_aware_types << :timestamptz
92
+ end
92
93
  end
93
94
  end
94
95
 
@@ -133,49 +134,11 @@ To keep using the current cache store, you can turn off cache versioning entirel
133
134
  end
134
135
  end
135
136
 
136
- initializer "active_record.use_schema_cache_dump" do
137
- ActiveRecord::ConnectionAdapters::SchemaReflection.use_schema_cache_dump = config.active_record.use_schema_cache_dump
138
- end
139
-
140
- initializer "active_record.check_schema_cache_dump" do
141
- check_schema_cache_dump_version = config.active_record.check_schema_cache_dump_version
142
-
143
- ActiveRecord::ConnectionAdapters::SchemaReflection.check_schema_cache_dump_version = check_schema_cache_dump_version
144
-
145
- if config.active_record.use_schema_cache_dump && !config.active_record.lazily_load_schema_cache
146
- config.after_initialize do |app|
147
- ActiveSupport.on_load(:active_record) do
148
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
149
- next if db_config.nil?
150
-
151
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
152
- db_config.name,
153
- schema_cache_path: db_config.schema_cache_path
154
- )
155
-
156
- cache = ActiveRecord::ConnectionAdapters::SchemaCache._load_from(filename)
157
- next if cache.nil?
137
+ initializer "active_record.copy_schema_cache_config" do
138
+ active_record_config = config.active_record
158
139
 
159
- if check_schema_cache_dump_version
160
- current_version = begin
161
- ActiveRecord::Migrator.current_version
162
- rescue ActiveRecordError => error
163
- warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
164
- nil
165
- end
166
- next if current_version.nil?
167
-
168
- if cache.schema_version != current_version
169
- warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the schema cache file is #{cache.schema_version}."
170
- next
171
- end
172
- end
173
-
174
- Rails.logger.info("Using schema cache file #{filename}")
175
- connection_pool.schema_reflection.set_schema_cache(cache)
176
- end
177
- end
178
- end
140
+ ActiveRecord::ConnectionAdapters::SchemaReflection.use_schema_cache_dump = active_record_config.use_schema_cache_dump
141
+ ActiveRecord::ConnectionAdapters::SchemaReflection.check_schema_cache_dump_version = active_record_config.check_schema_cache_dump_version
179
142
  end
180
143
 
181
144
  initializer "active_record.define_attribute_methods" do |app|
@@ -198,7 +161,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
198
161
  # Additionally if `check_schema_cache_dump_version` is enabled (which is the default),
199
162
  # loading the schema cache dump trigger a database connection to compare the schema
200
163
  # versions.
201
- # This means the attribute methods will be lazily defined whent the model is accessed,
164
+ # This means the attribute methods will be lazily defined when the model is accessed,
202
165
  # likely as part of the first few requests or jobs. This isn't good for performance
203
166
  # but we unfortunately have to arbitrate between resiliency and performance, and chose
204
167
  # resiliency.
@@ -222,19 +185,25 @@ To keep using the current cache store, you can turn off cache versioning entirel
222
185
 
223
186
  initializer "active_record.warn_on_records_fetched_greater_than" do
224
187
  if config.active_record.warn_on_records_fetched_greater_than
188
+ ActiveRecord.deprecator.warn <<~MSG.squish
189
+ `config.active_record.warn_on_records_fetched_greater_than` is deprecated and will be
190
+ removed in Rails 7.3.
191
+ Please subscribe to `sql.active_record` notifications and access the row count field to
192
+ detect large result set sizes.
193
+ MSG
225
194
  ActiveSupport.on_load(:active_record) do
226
195
  require "active_record/relation/record_fetch_warning"
227
196
  end
228
197
  end
229
198
  end
230
199
 
231
- SQLITE3_PRODUCTION_WARN = "You are running SQLite in production, this is generally not recommended."\
232
- " You can disable this warning by setting \"config.active_record.sqlite3_production_warning=false\"."
233
- initializer "active_record.sqlite3_production_warning" do
234
- if config.active_record.sqlite3_production_warning && Rails.env.production?
235
- ActiveSupport.on_load(:active_record_sqlite3adapter) do
236
- Rails.logger.warn(SQLITE3_PRODUCTION_WARN)
237
- end
200
+ initializer "active_record.sqlite3_deprecated_warning" do
201
+ if config.active_record.key?(:sqlite3_production_warning)
202
+ config.active_record.delete(:sqlite3_production_warning)
203
+ ActiveRecord.deprecator.warn <<~MSG.squish
204
+ The `config.active_record.sqlite3_production_warning` configuration no longer has any effect
205
+ and can be safely removed.
206
+ MSG
238
207
  end
239
208
  end
240
209
 
@@ -248,6 +217,16 @@ To keep using the current cache store, you can turn off cache versioning entirel
248
217
  end
249
218
  end
250
219
 
220
+ initializer "active_record.postgresql_adapter_decode_dates" do
221
+ config.after_initialize do
222
+ if config.active_record.postgresql_adapter_decode_dates
223
+ ActiveSupport.on_load(:active_record_postgresqladapter) do
224
+ self.decode_dates = true
225
+ end
226
+ end
227
+ end
228
+ end
229
+
251
230
  initializer "active_record.set_configs" do |app|
252
231
  configs = app.config.active_record
253
232
 
@@ -262,7 +241,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
262
241
  end
263
242
 
264
243
  ActiveSupport.on_load(:active_record) do
265
- configs_used_in_other_initializers = configs.except(
244
+ # Configs used in other initializers
245
+ configs = configs.except(
266
246
  :migration_error,
267
247
  :database_selector,
268
248
  :database_resolver,
@@ -273,13 +253,13 @@ To keep using the current cache store, you can turn off cache versioning entirel
273
253
  :query_log_tags,
274
254
  :query_log_tags_format,
275
255
  :cache_query_log_tags,
276
- :sqlite3_production_warning,
277
256
  :sqlite3_adapter_strict_strings_by_default,
278
257
  :check_schema_cache_dump_version,
279
- :use_schema_cache_dump
258
+ :use_schema_cache_dump,
259
+ :postgresql_adapter_decode_dates,
280
260
  )
281
261
 
282
- configs_used_in_other_initializers.each do |k, v|
262
+ configs.each do |k, v|
283
263
  next if k == :encryption
284
264
  setter = "#{k}="
285
265
  # Some existing initializers might rely on Active Record configuration
@@ -377,19 +357,16 @@ To keep using the current cache store, you can turn off cache versioning entirel
377
357
  end
378
358
 
379
359
  initializer "active_record_encryption.configuration" do |app|
380
- ActiveSupport.on_load(:active_record_encryption) do
381
- ActiveRecord::Encryption.configure(
360
+ ActiveSupport.on_load(:active_record) do
361
+ ActiveRecord::Encryption.configure \
382
362
  primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
383
363
  deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
384
364
  key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
385
365
  **app.config.active_record.encryption
386
- )
387
366
 
388
367
  auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
389
368
  auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
390
- end
391
369
 
392
- ActiveSupport.on_load(:active_record) do
393
370
  # Support extended queries for deterministic attributes and validations
394
371
  if ActiveRecord::Encryption.config.extend_queries
395
372
  ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
@@ -414,7 +391,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
414
391
  pid: -> { Process.pid.to_s },
415
392
  socket: ->(context) { context[:connection].pool.db_config.socket },
416
393
  db_host: ->(context) { context[:connection].pool.db_config.host },
417
- database: ->(context) { context[:connection].pool.db_config.database }
394
+ database: ->(context) { context[:connection].pool.db_config.database },
395
+ source_location: -> { QueryLogs.query_source_location }
418
396
  )
419
397
  ActiveRecord.disable_prepared_statements = true
420
398
 
@@ -455,5 +433,15 @@ To keep using the current cache store, you can turn off cache versioning entirel
455
433
  end
456
434
  end
457
435
  end
436
+
437
+ initializer "active_record.attributes_for_inspect" do |app|
438
+ ActiveSupport.on_load(:active_record) do
439
+ if app.config.consider_all_requests_local
440
+ if app.config.active_record.attributes_for_inspect.nil?
441
+ ActiveRecord::Base.attributes_for_inspect = :all
442
+ end
443
+ end
444
+ end
445
+ end
458
446
  end
459
447
  end
@@ -11,7 +11,14 @@ module ActiveRecord
11
11
  module ClassMethods # :nodoc:
12
12
  def log_process_action(payload)
13
13
  messages, db_runtime = super, payload[:db_runtime]
14
- messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
14
+
15
+ if db_runtime
16
+ queries_count = payload[:queries_count] || 0
17
+ cached_queries_count = payload[:cached_queries_count] || 0
18
+ messages << ("ActiveRecord: %.1fms (%d %s, %d cached)" % [db_runtime.to_f, queries_count,
19
+ "query".pluralize(queries_count), cached_queries_count])
20
+ end
21
+
15
22
  messages
16
23
  end
17
24
  end
@@ -34,11 +41,11 @@ module ActiveRecord
34
41
 
35
42
  def cleanup_view_runtime
36
43
  if logger && logger.info?
37
- db_rt_before_render = ActiveRecord::RuntimeRegistry.reset
44
+ db_rt_before_render = ActiveRecord::RuntimeRegistry.reset_runtimes
38
45
  self.db_runtime = (db_runtime || 0) + db_rt_before_render
39
46
  runtime = super
40
47
  queries_rt = ActiveRecord::RuntimeRegistry.sql_runtime - ActiveRecord::RuntimeRegistry.async_sql_runtime
41
- db_rt_after_render = ActiveRecord::RuntimeRegistry.reset
48
+ db_rt_after_render = ActiveRecord::RuntimeRegistry.reset_runtimes
42
49
  self.db_runtime += db_rt_after_render
43
50
  runtime - queries_rt
44
51
  else
@@ -49,7 +56,9 @@ module ActiveRecord
49
56
  def append_info_to_payload(payload)
50
57
  super
51
58
 
52
- payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::RuntimeRegistry.reset
59
+ payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::RuntimeRegistry.reset_runtimes
60
+ payload[:queries_count] = ActiveRecord::RuntimeRegistry.reset_queries_count
61
+ payload[:cached_queries_count] = ActiveRecord::RuntimeRegistry.reset_cached_queries_count
53
62
  end
54
63
  end
55
64
  end
@@ -9,10 +9,10 @@ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
9
9
  db_namespace = namespace :db do
10
10
  desc "Set the environment value for the database"
11
11
  task "environment:set" => :load_config do
12
- connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
13
- raise ActiveRecord::EnvironmentStorageError unless connection.internal_metadata.enabled?
12
+ pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
13
+ raise ActiveRecord::EnvironmentStorageError unless pool.internal_metadata.enabled?
14
14
 
15
- connection.internal_metadata.create_table_and_set_flags(connection.migration_context.current_environment)
15
+ pool.internal_metadata.create_table_and_set_flags(pool.migration_context.current_environment)
16
16
  end
17
17
 
18
18
  task check_protected_environments: :load_config do
@@ -89,7 +89,7 @@ db_namespace = namespace :db do
89
89
  task migrate: :load_config do
90
90
  db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
91
91
 
92
- if db_configs.size == 1 && db_configs.first.primary?
92
+ if db_configs.size == 1
93
93
  ActiveRecord::Tasks::DatabaseTasks.migrate
94
94
  else
95
95
  mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
@@ -135,7 +135,7 @@ db_namespace = namespace :db do
135
135
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
136
136
  desc "Migrate #{name} database for current environment"
137
137
  task name => :load_config do
138
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
138
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do
139
139
  ActiveRecord::Tasks::DatabaseTasks.migrate
140
140
  end
141
141
 
@@ -186,7 +186,7 @@ db_namespace = namespace :db do
186
186
 
187
187
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
188
188
 
189
- ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
189
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool.migration_context.run(
190
190
  :up,
191
191
  ActiveRecord::Tasks::DatabaseTasks.target_version
192
192
  )
@@ -199,9 +199,9 @@ db_namespace = namespace :db do
199
199
  task name => :load_config do
200
200
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
201
201
 
202
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
202
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do |pool|
203
203
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
204
- conn.migration_context.run(:up, ActiveRecord::Tasks::DatabaseTasks.target_version)
204
+ pool.migration_context.run(:up, ActiveRecord::Tasks::DatabaseTasks.target_version)
205
205
  end
206
206
 
207
207
  db_namespace["_dump:#{name}"].invoke
@@ -217,7 +217,7 @@ db_namespace = namespace :db do
217
217
 
218
218
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
219
219
 
220
- ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
220
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool.migration_context.run(
221
221
  :down,
222
222
  ActiveRecord::Tasks::DatabaseTasks.target_version
223
223
  )
@@ -230,9 +230,9 @@ db_namespace = namespace :db do
230
230
  task name => :load_config do
231
231
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
232
232
 
233
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
233
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do |pool|
234
234
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
235
- conn.migration_context.run(:down, ActiveRecord::Tasks::DatabaseTasks.target_version)
235
+ pool.migration_context.run(:down, ActiveRecord::Tasks::DatabaseTasks.target_version)
236
236
  end
237
237
 
238
238
  db_namespace["_dump:#{name}"].invoke
@@ -242,7 +242,7 @@ db_namespace = namespace :db do
242
242
 
243
243
  desc "Display status of migrations"
244
244
  task status: :load_config do
245
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do
245
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each do
246
246
  ActiveRecord::Tasks::DatabaseTasks.migrate_status
247
247
  end
248
248
  end
@@ -251,7 +251,7 @@ db_namespace = namespace :db do
251
251
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
252
252
  desc "Display status of migrations for #{name} database"
253
253
  task name => :load_config do
254
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do
254
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do
255
255
  ActiveRecord::Tasks::DatabaseTasks.migrate_status
256
256
  end
257
257
  end
@@ -265,8 +265,8 @@ db_namespace = namespace :db do
265
265
  task name => :load_config do
266
266
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
267
267
 
268
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
269
- conn.migration_context.rollback(step)
268
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do |pool|
269
+ pool.migration_context.rollback(step)
270
270
  end
271
271
 
272
272
  db_namespace["_dump:#{name}"].invoke
@@ -281,7 +281,7 @@ db_namespace = namespace :db do
281
281
 
282
282
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
283
283
 
284
- ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.rollback(step)
284
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool.migration_context.rollback(step)
285
285
 
286
286
  db_namespace["_dump"].invoke
287
287
  end
@@ -290,7 +290,7 @@ db_namespace = namespace :db do
290
290
  task forward: :load_config do
291
291
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
292
292
 
293
- ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.forward(step)
293
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool.migration_context.forward(step)
294
294
 
295
295
  db_namespace["_dump"].invoke
296
296
  end
@@ -321,9 +321,9 @@ db_namespace = namespace :db do
321
321
 
322
322
  desc "Retrieve the current schema version number"
323
323
  task version: :load_config do
324
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env) do |connection|
325
- puts "\ndatabase: #{connection.pool.db_config.database}\n"
326
- puts "Current version: #{connection.schema_version}"
324
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env) do |pool|
325
+ puts "\ndatabase: #{pool.db_config.database}\n"
326
+ puts "Current version: #{pool.migration_context.current_version}"
327
327
  puts
328
328
  end
329
329
  end
@@ -344,8 +344,8 @@ db_namespace = namespace :db do
344
344
  task abort_if_pending_migrations: :load_config do
345
345
  pending_migrations = []
346
346
 
347
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
348
- pending_migrations << conn.migration_context.open.pending_migrations
347
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each do |pool|
348
+ pending_migrations << pool.migration_context.open.pending_migrations
349
349
  end
350
350
 
351
351
  pending_migrations = pending_migrations.flatten!
@@ -365,8 +365,8 @@ db_namespace = namespace :db do
365
365
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
366
366
  # desc "Raise an error if there are pending migrations for #{name} database"
367
367
  task name => :load_config do
368
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
369
- pending_migrations = conn.migration_context.open.pending_migrations
368
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: Rails.env, name: name) do |pool|
369
+ pending_migrations = pool.migration_context.open.pending_migrations
370
370
 
371
371
  if pending_migrations.any?
372
372
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
@@ -462,8 +462,8 @@ db_namespace = namespace :db do
462
462
  namespace :schema do
463
463
  desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
464
464
  task dump: :load_config do
465
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
466
- db_config = conn.pool.db_config
465
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each do |pool|
466
+ db_config = pool.db_config
467
467
  schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
468
468
  ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
469
469
  end
@@ -480,8 +480,8 @@ db_namespace = namespace :db do
480
480
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
481
481
  desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) for #{name} database"
482
482
  task name => :load_config do
483
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(name: name) do |conn|
484
- db_config = conn.pool.db_config
483
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(name: name) do |pool|
484
+ db_config = pool.db_config
485
485
  schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
486
486
  ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
487
487
  end
@@ -495,8 +495,8 @@ db_namespace = namespace :db do
495
495
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
496
496
  desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the #{name} database"
497
497
  task name => "db:test:purge:#{name}" do
498
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(name: name) do |conn|
499
- db_config = conn.pool.db_config
498
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(name: name) do |pool|
499
+ db_config = pool.db_config
500
500
  schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
501
501
  ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
502
502
  end
@@ -507,21 +507,18 @@ db_namespace = namespace :db do
507
507
  namespace :cache do
508
508
  desc "Create a db/schema_cache.yml file."
509
509
  task dump: :load_config do
510
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
511
- db_config = conn.pool.db_config
512
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.name, schema_cache_path: db_config.schema_cache_path)
510
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each do |pool|
511
+ db_config = pool.db_config
512
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config)
513
513
 
514
- ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(conn, filename)
514
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(pool, filename)
515
515
  end
516
516
  end
517
517
 
518
518
  desc "Clear a db/schema_cache.yml file."
519
519
  task clear: :load_config do
520
520
  ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
521
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
522
- db_config.name,
523
- schema_cache_path: db_config.schema_cache_path,
524
- )
521
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config)
525
522
  ActiveRecord::Tasks::DatabaseTasks.clear_schema_cache(
526
523
  filename,
527
524
  )
@@ -547,8 +544,8 @@ db_namespace = namespace :db do
547
544
  namespace :test do
548
545
  # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
549
546
  task load_schema: %w(db:test:purge) do
550
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test") do |conn|
551
- db_config = conn.pool.db_config
547
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test") do |pool|
548
+ db_config = pool.db_config
552
549
  ActiveRecord::Schema.verbose = false
553
550
  schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
554
551
  ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
@@ -573,8 +570,8 @@ db_namespace = namespace :db do
573
570
  # desc "Recreate the #{name} test database from an existent schema.rb file"
574
571
  namespace :load_schema do
575
572
  task name => "db:test:purge:#{name}" do
576
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test", name: name) do |conn|
577
- db_config = conn.pool.db_config
573
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test", name: name) do |pool|
574
+ db_config = pool.db_config
578
575
  ActiveRecord::Schema.verbose = false
579
576
  schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
580
577
  ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
@@ -585,8 +582,8 @@ db_namespace = namespace :db do
585
582
  # desc "Empty the #{name} test database"
586
583
  namespace :purge do
587
584
  task name => %w(load_config check_protected_environments) do
588
- ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test", name: name) do |conn|
589
- db_config = conn.pool.db_config
585
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test", name: name) do |pool|
586
+ db_config = pool.db_config
590
587
  ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
591
588
  end
592
589
  end