activerecord 7.1.5 → 7.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +515 -2440
  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