activerecord 7.1.3.4 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +652 -2032
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +15 -8
- data/lib/active_record/associations/belongs_to_association.rb +18 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/collection_association.rb +11 -5
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +3 -3
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -12
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +2 -1
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +62 -289
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +2 -2
- data/lib/active_record/attribute_methods/primary_key.rb +23 -55
- data/lib/active_record/attribute_methods/read.rb +4 -16
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +89 -58
- data/lib/active_record/attributes.rb +61 -47
- data/lib/active_record/autosave_association.rb +17 -31
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +270 -58
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +35 -18
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +190 -75
- data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +23 -10
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
- data/lib/active_record/connection_adapters/abstract_adapter.rb +38 -59
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +73 -19
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +16 -15
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +20 -32
- data/lib/active_record/connection_adapters/pool_config.rb +7 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +18 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +127 -77
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +32 -65
- data/lib/active_record/connection_adapters.rb +121 -0
- data/lib/active_record/connection_handling.rb +56 -41
- data/lib/active_record/core.rb +93 -40
- data/lib/active_record/counter_cache.rb +23 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +19 -4
- data/lib/active_record/database_configurations/hash_config.rb +44 -36
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +30 -6
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +3 -3
- data/lib/active_record/encryption/encrypted_attribute_type.rb +26 -6
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +8 -4
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +19 -2
- data/lib/active_record/errors.rb +46 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -31
- data/lib/active_record/future_result.rb +17 -4
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +18 -15
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/log_subscriber.rb +0 -21
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/message_pack.rb +2 -2
- data/lib/active_record/migration/command_recorder.rb +2 -3
- data/lib/active_record/migration/compatibility.rb +11 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +85 -76
- data/lib/active_record/model_schema.rb +38 -70
- data/lib/active_record/nested_attributes.rb +24 -5
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +32 -354
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +15 -0
- data/lib/active_record/query_logs_formatter.rb +1 -1
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +50 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +42 -45
- data/lib/active_record/reflection.rb +106 -38
- data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
- data/lib/active_record/relation/batches.rb +14 -8
- data/lib/active_record/relation/calculations.rb +96 -63
- data/lib/active_record/relation/delegation.rb +8 -11
- data/lib/active_record/relation/finder_methods.rb +16 -2
- data/lib/active_record/relation/merger.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +6 -1
- data/lib/active_record/relation/predicate_builder.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +245 -65
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -18
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +500 -66
- data/lib/active_record/result.rb +32 -45
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +24 -19
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +19 -9
- data/lib/active_record/schema_migration.rb +30 -14
- data/lib/active_record/scoping/named.rb +1 -0
- data/lib/active_record/signed_id.rb +20 -1
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/table_metadata.rb +1 -10
- data/lib/active_record/tasks/database_tasks.rb +98 -48
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
- data/lib/active_record/test_fixtures.rb +87 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +5 -3
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +70 -14
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +15 -10
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +150 -41
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/nodes/binary.rb +0 -6
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +4 -3
- data/lib/arel/nodes/sql_literal.rb +7 -0
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +31 -17
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +21 -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -70,6 +69,7 @@ module ActiveRecord
|
|
70
69
|
Rails.logger.broadcast_to(console)
|
71
70
|
end
|
72
71
|
ActiveRecord.verbose_query_logs = false
|
72
|
+
ActiveRecord::Base.attributes_for_inspect = :all
|
73
73
|
end
|
74
74
|
|
75
75
|
runner do
|
@@ -88,7 +88,9 @@ module ActiveRecord
|
|
88
88
|
|
89
89
|
initializer "active_record.postgresql_time_zone_aware_types" do
|
90
90
|
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
91
|
-
|
91
|
+
ActiveSupport.on_load(:active_record) do
|
92
|
+
ActiveRecord::Base.time_zone_aware_types << :timestamptz
|
93
|
+
end
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
@@ -133,48 +135,11 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
136
|
-
initializer "active_record.
|
137
|
-
|
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
|
-
|
150
|
-
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
|
151
|
-
db_config.name,
|
152
|
-
schema_cache_path: db_config.schema_cache_path
|
153
|
-
)
|
138
|
+
initializer "active_record.copy_schema_cache_config" do
|
139
|
+
active_record_config = config.active_record
|
154
140
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
if check_schema_cache_dump_version
|
159
|
-
current_version = begin
|
160
|
-
ActiveRecord::Migrator.current_version
|
161
|
-
rescue ActiveRecordError => error
|
162
|
-
warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
|
163
|
-
nil
|
164
|
-
end
|
165
|
-
next if current_version.nil?
|
166
|
-
|
167
|
-
if cache.schema_version != current_version
|
168
|
-
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}."
|
169
|
-
next
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
Rails.logger.info("Using schema cache file #{filename}")
|
174
|
-
connection_pool.schema_reflection.set_schema_cache(cache)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
141
|
+
ActiveRecord::ConnectionAdapters::SchemaReflection.use_schema_cache_dump = active_record_config.use_schema_cache_dump
|
142
|
+
ActiveRecord::ConnectionAdapters::SchemaReflection.check_schema_cache_dump_version = active_record_config.check_schema_cache_dump_version
|
178
143
|
end
|
179
144
|
|
180
145
|
initializer "active_record.define_attribute_methods" do |app|
|
@@ -197,7 +162,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
197
162
|
# Additionally if `check_schema_cache_dump_version` is enabled (which is the default),
|
198
163
|
# loading the schema cache dump trigger a database connection to compare the schema
|
199
164
|
# versions.
|
200
|
-
# This means the attribute methods will be lazily defined
|
165
|
+
# This means the attribute methods will be lazily defined when the model is accessed,
|
201
166
|
# likely as part of the first few requests or jobs. This isn't good for performance
|
202
167
|
# but we unfortunately have to arbitrate between resiliency and performance, and chose
|
203
168
|
# resiliency.
|
@@ -221,19 +186,25 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
221
186
|
|
222
187
|
initializer "active_record.warn_on_records_fetched_greater_than" do
|
223
188
|
if config.active_record.warn_on_records_fetched_greater_than
|
189
|
+
ActiveRecord.deprecator.warn <<~MSG.squish
|
190
|
+
`config.active_record.warn_on_records_fetched_greater_than` is deprecated and will be
|
191
|
+
removed in Rails 8.0.
|
192
|
+
Please subscribe to `sql.active_record` notifications and access the row count field to
|
193
|
+
detect large result set sizes.
|
194
|
+
MSG
|
224
195
|
ActiveSupport.on_load(:active_record) do
|
225
196
|
require "active_record/relation/record_fetch_warning"
|
226
197
|
end
|
227
198
|
end
|
228
199
|
end
|
229
200
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
201
|
+
initializer "active_record.sqlite3_deprecated_warning" do
|
202
|
+
if config.active_record.key?(:sqlite3_production_warning)
|
203
|
+
config.active_record.delete(:sqlite3_production_warning)
|
204
|
+
ActiveRecord.deprecator.warn <<~MSG.squish
|
205
|
+
The `config.active_record.sqlite3_production_warning` configuration no longer has any effect
|
206
|
+
and can be safely removed.
|
207
|
+
MSG
|
237
208
|
end
|
238
209
|
end
|
239
210
|
|
@@ -247,6 +218,16 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
247
218
|
end
|
248
219
|
end
|
249
220
|
|
221
|
+
initializer "active_record.postgresql_adapter_decode_dates" do
|
222
|
+
config.after_initialize do
|
223
|
+
if config.active_record.postgresql_adapter_decode_dates
|
224
|
+
ActiveSupport.on_load(:active_record_postgresqladapter) do
|
225
|
+
self.decode_dates = true
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
250
231
|
initializer "active_record.set_configs" do |app|
|
251
232
|
configs = app.config.active_record
|
252
233
|
|
@@ -261,8 +242,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
261
242
|
end
|
262
243
|
|
263
244
|
ActiveSupport.on_load(:active_record) do
|
264
|
-
|
265
|
-
configs = configs.except(
|
245
|
+
configs_used_in_other_initializers = 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
|
-
|
262
|
+
configs_used_in_other_initializers.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
|
@@ -332,6 +312,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
332
312
|
initializer "active_record.set_executor_hooks" do
|
333
313
|
ActiveRecord::QueryCache.install_executor_hooks
|
334
314
|
ActiveRecord::AsynchronousQueriesTracker.install_executor_hooks
|
315
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool.install_executor_hooks
|
335
316
|
end
|
336
317
|
|
337
318
|
initializer "active_record.add_watchable_files" do |app|
|
@@ -377,23 +358,23 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
377
358
|
end
|
378
359
|
|
379
360
|
initializer "active_record_encryption.configuration" do |app|
|
380
|
-
|
381
|
-
|
382
|
-
config.after_initialize do |app|
|
383
|
-
ActiveRecord::Encryption.configure \
|
361
|
+
ActiveSupport.on_load(:active_record_encryption) do
|
362
|
+
ActiveRecord::Encryption.configure(
|
384
363
|
primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
|
385
364
|
deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
|
386
365
|
key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
|
387
|
-
**config.active_record.encryption
|
366
|
+
**app.config.active_record.encryption
|
367
|
+
)
|
388
368
|
|
369
|
+
auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
|
389
370
|
auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
|
371
|
+
end
|
390
372
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
end
|
373
|
+
ActiveSupport.on_load(:active_record) do
|
374
|
+
# Support extended queries for deterministic attributes and validations
|
375
|
+
if ActiveRecord::Encryption.config.extend_queries
|
376
|
+
ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
|
377
|
+
ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
|
397
378
|
end
|
398
379
|
end
|
399
380
|
|
@@ -414,7 +395,8 @@ To keep using the current cache store, you can turn off cache versioning entirel
|
|
414
395
|
pid: -> { Process.pid.to_s },
|
415
396
|
socket: ->(context) { context[:connection].pool.db_config.socket },
|
416
397
|
db_host: ->(context) { context[:connection].pool.db_config.host },
|
417
|
-
database: ->(context) { context[:connection].pool.db_config.database }
|
398
|
+
database: ->(context) { context[:connection].pool.db_config.database },
|
399
|
+
source_location: -> { QueryLogs.query_source_location }
|
418
400
|
)
|
419
401
|
ActiveRecord.disable_prepared_statements = true
|
420
402
|
|
@@ -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
|
-
|
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.
|
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.
|
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.
|
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
|
-
|
13
|
-
raise ActiveRecord::EnvironmentStorageError unless
|
12
|
+
pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
|
13
|
+
raise ActiveRecord::EnvironmentStorageError unless pool.internal_metadata.enabled?
|
14
14
|
|
15
|
-
|
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,10 +89,10 @@ 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
|
92
|
+
if db_configs.size == 1 && db_configs.first.primary?
|
93
93
|
ActiveRecord::Tasks::DatabaseTasks.migrate
|
94
94
|
else
|
95
|
-
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
95
|
+
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
96
96
|
|
97
97
|
mapped_versions.sort.each do |version, db_configs|
|
98
98
|
db_configs.each do |db_config|
|
@@ -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.
|
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.
|
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.
|
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
|
-
|
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.
|
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.
|
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
|
-
|
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.
|
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.
|
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.
|
269
|
-
|
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.
|
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.
|
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.
|
325
|
-
puts "\ndatabase: #{
|
326
|
-
puts "Current 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.
|
348
|
-
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.
|
369
|
-
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.
|
466
|
-
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.
|
484
|
-
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.
|
499
|
-
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.
|
511
|
-
db_config =
|
512
|
-
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config
|
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(
|
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.
|
551
|
-
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.
|
577
|
-
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.
|
589
|
-
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
|