activerecord 7.1.5.1 → 8.0.2
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 +369 -2484
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +2 -1
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +43 -12
- data/lib/active_record/associations/belongs_to_association.rb +21 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +7 -6
- 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 +17 -9
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +4 -3
- 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 +14 -3
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +92 -295
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- 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/primary_key.rb +25 -61
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -18
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +63 -49
- data/lib/active_record/autosave_association.rb +92 -57
- 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 +48 -122
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +286 -77
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +119 -55
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +197 -76
- data/lib/active_record/connection_adapters/abstract/quoting.rb +66 -92
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +12 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -12
- data/lib/active_record/connection_adapters/abstract/transaction.rb +140 -67
- data/lib/active_record/connection_adapters/abstract_adapter.rb +85 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +71 -52
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +56 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +92 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +13 -31
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -41
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- 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/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +36 -20
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +75 -28
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +73 -113
- data/lib/active_record/connection_adapters/schema_cache.rb +124 -131
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +81 -97
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +29 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +35 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +183 -87
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +39 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +65 -0
- data/lib/active_record/connection_handling.rb +74 -37
- data/lib/active_record/core.rb +132 -51
- data/lib/active_record/counter_cache.rb +19 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +23 -4
- data/lib/active_record/database_configurations/hash_config.rb +46 -34
- 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 +41 -17
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +7 -7
- data/lib/active_record/encryption/encrypted_attribute_type.rb +33 -4
- data/lib/active_record/encryption/encryptor.rb +28 -6
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- 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 -1
- data/lib/active_record/enum.rb +20 -16
- data/lib/active_record/errors.rb +54 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -33
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +19 -16
- 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 +5 -32
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +33 -14
- data/lib/active_record/migration/compatibility.rb +8 -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 +104 -98
- data/lib/active_record/model_schema.rb +32 -70
- data/lib/active_record/nested_attributes.rb +15 -9
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +127 -451
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +104 -37
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +24 -12
- data/lib/active_record/railtie.rb +26 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +43 -61
- data/lib/active_record/reflection.rb +112 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +138 -72
- data/lib/active_record/relation/calculations.rb +122 -82
- data/lib/active_record/relation/delegation.rb +30 -22
- data/lib/active_record/relation/finder_methods.rb +32 -18
- data/lib/active_record/relation/merger.rb +12 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +10 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +16 -3
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +317 -101
- data/lib/active_record/relation/spawn_methods.rb +3 -19
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +561 -119
- data/lib/active_record/result.rb +95 -46
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +31 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +53 -20
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/signed_id.rb +24 -4
- data/lib/active_record/statement_cache.rb +19 -19
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +2 -13
- data/lib/active_record/tasks/database_tasks.rb +87 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -3
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +4 -3
- data/lib/active_record/test_fixtures.rb +98 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +2 -2
- 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 +72 -17
- 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 +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +138 -57
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +4 -2
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +2 -2
- data/lib/arel/collectors/substitute_binds.rb +3 -3
- data/lib/arel/nodes/binary.rb +1 -7
- 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 +5 -4
- data/lib/arel/nodes/sql_literal.rb +8 -1
- 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/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- 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 +29 -16
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +18 -16
- data/lib/active_record/relation/record_fetch_warning.rb +0 -49
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "set"
|
4
3
|
require "active_record/connection_adapters/sql_type_metadata"
|
5
4
|
require "active_record/connection_adapters/abstract/schema_dumper"
|
6
5
|
require "active_record/connection_adapters/abstract/schema_creation"
|
@@ -23,7 +22,7 @@ module ActiveRecord
|
|
23
22
|
# and +:limit+ options, etc.
|
24
23
|
#
|
25
24
|
# All the concrete database adapters follow the interface laid down in this class.
|
26
|
-
# {ActiveRecord::Base.
|
25
|
+
# {ActiveRecord::Base.lease_connection}[rdoc-ref:ConnectionHandling#lease_connection] returns an AbstractAdapter object, which
|
27
26
|
# you can use.
|
28
27
|
#
|
29
28
|
# Most of the methods in the adapter are useful during migrations. Most
|
@@ -49,8 +48,6 @@ module ActiveRecord
|
|
49
48
|
return if value.eql?(@pool)
|
50
49
|
@schema_cache = nil
|
51
50
|
@pool = value
|
52
|
-
|
53
|
-
@pool.schema_reflection.load!(self) if ActiveRecord.lazily_load_schema_cache
|
54
51
|
end
|
55
52
|
|
56
53
|
set_callback :checkin, :after, :enable_lazy_transactions!
|
@@ -136,7 +133,7 @@ module ActiveRecord
|
|
136
133
|
@logger = ActiveRecord::Base.logger
|
137
134
|
|
138
135
|
if deprecated_logger || deprecated_connection_options || deprecated_config
|
139
|
-
raise ArgumentError, "when initializing an
|
136
|
+
raise ArgumentError, "when initializing an Active Record adapter with a config hash, that should be the only argument"
|
140
137
|
end
|
141
138
|
else
|
142
139
|
# Soft-deprecated for now; we'll probably warn in future.
|
@@ -153,7 +150,6 @@ module ActiveRecord
|
|
153
150
|
end
|
154
151
|
|
155
152
|
@owner = nil
|
156
|
-
@instrumenter = ActiveSupport::Notifications.instrumenter
|
157
153
|
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
|
158
154
|
@idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
159
155
|
@visitor = arel_visitor
|
@@ -171,40 +167,29 @@ module ActiveRecord
|
|
171
167
|
@default_timezone = self.class.validate_default_timezone(@config[:default_timezone])
|
172
168
|
|
173
169
|
@raw_connection_dirty = false
|
170
|
+
@last_activity = nil
|
174
171
|
@verified = false
|
175
172
|
end
|
176
173
|
|
177
|
-
|
178
|
-
|
174
|
+
def inspect # :nodoc:
|
175
|
+
name_field = " name=#{pool.db_config.name.inspect}" unless pool.db_config.name == "primary"
|
176
|
+
shard_field = " shard=#{shard.inspect}" unless shard == :default
|
179
177
|
|
180
|
-
|
181
|
-
|
178
|
+
"#<#{self.class.name}:#{'%#016x' % (object_id << 1)} env_name=#{pool.db_config.env_name.inspect}#{name_field} role=#{role.inspect}#{shard_field}>"
|
179
|
+
end
|
182
180
|
|
183
181
|
def lock_thread=(lock_thread) # :nodoc:
|
184
182
|
@lock =
|
185
183
|
case lock_thread
|
186
184
|
when Thread
|
187
|
-
|
185
|
+
ActiveSupport::Concurrency::ThreadLoadInterlockAwareMonitor.new
|
188
186
|
when Fiber
|
189
|
-
|
187
|
+
ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
190
188
|
else
|
191
189
|
ActiveSupport::Concurrency::NullLock
|
192
190
|
end
|
193
191
|
end
|
194
192
|
|
195
|
-
EXCEPTION_NEVER = { Exception => :never }.freeze # :nodoc:
|
196
|
-
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze # :nodoc:
|
197
|
-
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
198
|
-
def with_instrumenter(instrumenter, &block) # :nodoc:
|
199
|
-
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
200
|
-
previous_instrumenter = @instrumenter
|
201
|
-
@instrumenter = instrumenter
|
202
|
-
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
203
|
-
ensure
|
204
|
-
@instrumenter = previous_instrumenter
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
193
|
def check_if_write_query(sql) # :nodoc:
|
209
194
|
if preventing_writes? && write_query?(sql)
|
210
195
|
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
@@ -215,14 +200,14 @@ module ActiveRecord
|
|
215
200
|
@config[:replica] || false
|
216
201
|
end
|
217
202
|
|
218
|
-
def use_metadata_table?
|
219
|
-
@config.fetch(:use_metadata_table, true)
|
220
|
-
end
|
221
|
-
|
222
203
|
def connection_retries
|
223
204
|
(@config[:connection_retries] || 1).to_i
|
224
205
|
end
|
225
206
|
|
207
|
+
def verify_timeout
|
208
|
+
(@config[:verify_timeout] || 2).to_i
|
209
|
+
end
|
210
|
+
|
226
211
|
def retry_deadline
|
227
212
|
if @config[:retry_deadline]
|
228
213
|
@config[:retry_deadline].to_f
|
@@ -241,25 +226,9 @@ module ActiveRecord
|
|
241
226
|
# the value of +current_preventing_writes+.
|
242
227
|
def preventing_writes?
|
243
228
|
return true if replica?
|
244
|
-
return false if
|
229
|
+
return false if connection_descriptor.nil?
|
245
230
|
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
def migrations_paths # :nodoc:
|
250
|
-
@config[:migrations_paths] || Migrator.migrations_paths
|
251
|
-
end
|
252
|
-
|
253
|
-
def migration_context # :nodoc:
|
254
|
-
MigrationContext.new(migrations_paths, schema_migration, internal_metadata)
|
255
|
-
end
|
256
|
-
|
257
|
-
def schema_migration # :nodoc:
|
258
|
-
SchemaMigration.new(self)
|
259
|
-
end
|
260
|
-
|
261
|
-
def internal_metadata # :nodoc:
|
262
|
-
InternalMetadata.new(self)
|
231
|
+
connection_descriptor.current_preventing_writes
|
263
232
|
end
|
264
233
|
|
265
234
|
def prepared_statements?
|
@@ -310,8 +279,8 @@ module ActiveRecord
|
|
310
279
|
@owner = ActiveSupport::IsolatedExecutionState.context
|
311
280
|
end
|
312
281
|
|
313
|
-
def
|
314
|
-
@pool.
|
282
|
+
def connection_descriptor # :nodoc:
|
283
|
+
@pool.connection_descriptor
|
315
284
|
end
|
316
285
|
|
317
286
|
# The role (e.g. +:writing+) for the current connection. In a
|
@@ -327,7 +296,7 @@ module ActiveRecord
|
|
327
296
|
end
|
328
297
|
|
329
298
|
def schema_cache
|
330
|
-
@schema_cache ||= BoundSchemaReflection.
|
299
|
+
@pool.schema_cache || (@schema_cache ||= BoundSchemaReflection.for_lone_connection(@pool.schema_reflection, self))
|
331
300
|
end
|
332
301
|
|
333
302
|
# this method must only be called while holding connection pool's mutex
|
@@ -365,6 +334,13 @@ module ActiveRecord
|
|
365
334
|
Process.clock_gettime(Process::CLOCK_MONOTONIC) - @idle_since
|
366
335
|
end
|
367
336
|
|
337
|
+
# Seconds since this connection last communicated with the server
|
338
|
+
def seconds_since_last_activity # :nodoc:
|
339
|
+
if @raw_connection && @last_activity
|
340
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) - @last_activity
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
368
344
|
def unprepared_statement
|
369
345
|
cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
|
370
346
|
yield
|
@@ -580,7 +556,7 @@ module ActiveRecord
|
|
580
556
|
end
|
581
557
|
|
582
558
|
def return_value_after_insert?(column) # :nodoc:
|
583
|
-
column.
|
559
|
+
column.auto_populated?
|
584
560
|
end
|
585
561
|
|
586
562
|
def async_enabled? # :nodoc:
|
@@ -597,23 +573,31 @@ module ActiveRecord
|
|
597
573
|
end
|
598
574
|
|
599
575
|
# This is meant to be implemented by the adapters that support custom enum types
|
600
|
-
def create_enum(
|
576
|
+
def create_enum(...) # :nodoc:
|
601
577
|
end
|
602
578
|
|
603
579
|
# This is meant to be implemented by the adapters that support custom enum types
|
604
|
-
def drop_enum(
|
580
|
+
def drop_enum(...) # :nodoc:
|
605
581
|
end
|
606
582
|
|
607
583
|
# This is meant to be implemented by the adapters that support custom enum types
|
608
|
-
def rename_enum(
|
584
|
+
def rename_enum(...) # :nodoc:
|
609
585
|
end
|
610
586
|
|
611
587
|
# This is meant to be implemented by the adapters that support custom enum types
|
612
|
-
def add_enum_value(
|
588
|
+
def add_enum_value(...) # :nodoc:
|
613
589
|
end
|
614
590
|
|
615
591
|
# This is meant to be implemented by the adapters that support custom enum types
|
616
|
-
def rename_enum_value(
|
592
|
+
def rename_enum_value(...) # :nodoc:
|
593
|
+
end
|
594
|
+
|
595
|
+
# This is meant to be implemented by the adapters that support virtual tables
|
596
|
+
def create_virtual_table(*) # :nodoc:
|
597
|
+
end
|
598
|
+
|
599
|
+
# This is meant to be implemented by the adapters that support virtual tables
|
600
|
+
def drop_virtual_table(*) # :nodoc:
|
617
601
|
end
|
618
602
|
|
619
603
|
def advisory_locks_enabled? # :nodoc:
|
@@ -651,15 +635,6 @@ module ActiveRecord
|
|
651
635
|
yield
|
652
636
|
end
|
653
637
|
|
654
|
-
# Override to check all foreign key constraints in a database.
|
655
|
-
def all_foreign_keys_valid?
|
656
|
-
check_all_foreign_keys_valid!
|
657
|
-
true
|
658
|
-
rescue ActiveRecord::StatementInvalid
|
659
|
-
false
|
660
|
-
end
|
661
|
-
deprecate :all_foreign_keys_valid?, deprecator: ActiveRecord.deprecator
|
662
|
-
|
663
638
|
# Override to check all foreign key constraints in a database.
|
664
639
|
# The adapter should raise a +ActiveRecord::StatementInvalid+ if foreign key
|
665
640
|
# constraints are not met.
|
@@ -668,6 +643,13 @@ module ActiveRecord
|
|
668
643
|
|
669
644
|
# CONNECTION MANAGEMENT ====================================
|
670
645
|
|
646
|
+
# Checks whether the connection to the database was established. This doesn't
|
647
|
+
# include checking whether the database is actually capable of responding, i.e.
|
648
|
+
# whether the connection is stale.
|
649
|
+
def connected?
|
650
|
+
!@raw_connection.nil?
|
651
|
+
end
|
652
|
+
|
671
653
|
# Checks whether the connection to the database is still active. This includes
|
672
654
|
# checking whether the database is actually capable of responding, i.e. whether
|
673
655
|
# the connection isn't stale.
|
@@ -686,11 +668,12 @@ module ActiveRecord
|
|
686
668
|
|
687
669
|
enable_lazy_transactions!
|
688
670
|
@raw_connection_dirty = false
|
671
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
689
672
|
@verified = true
|
690
673
|
|
691
674
|
reset_transaction(restore: restore_transactions) do
|
692
675
|
clear_cache!(new_connection: true)
|
693
|
-
|
676
|
+
attempt_configure_connection
|
694
677
|
end
|
695
678
|
rescue => original_exception
|
696
679
|
translated_exception = translate_exception_class(original_exception, nil, nil)
|
@@ -705,6 +688,7 @@ module ActiveRecord
|
|
705
688
|
end
|
706
689
|
end
|
707
690
|
|
691
|
+
@last_activity = nil
|
708
692
|
@verified = false
|
709
693
|
|
710
694
|
raise translated_exception
|
@@ -742,7 +726,7 @@ module ActiveRecord
|
|
742
726
|
def reset!
|
743
727
|
clear_cache!(new_connection: true)
|
744
728
|
reset_transaction
|
745
|
-
|
729
|
+
attempt_configure_connection
|
746
730
|
end
|
747
731
|
|
748
732
|
# Removes the connection from the pool and disconnect it.
|
@@ -778,7 +762,8 @@ module ActiveRecord
|
|
778
762
|
if @unconfigured_connection
|
779
763
|
@raw_connection = @unconfigured_connection
|
780
764
|
@unconfigured_connection = nil
|
781
|
-
|
765
|
+
attempt_configure_connection
|
766
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
782
767
|
@verified = true
|
783
768
|
return
|
784
769
|
end
|
@@ -867,7 +852,7 @@ module ActiveRecord
|
|
867
852
|
end
|
868
853
|
|
869
854
|
def database_version # :nodoc:
|
870
|
-
|
855
|
+
pool.server_version(self)
|
871
856
|
end
|
872
857
|
|
873
858
|
def check_version # :nodoc:
|
@@ -878,7 +863,7 @@ module ActiveRecord
|
|
878
863
|
# numbered migration that has been executed, or 0 if no schema
|
879
864
|
# information is present / the database is empty.
|
880
865
|
def schema_version
|
881
|
-
migration_context.current_version
|
866
|
+
pool.migration_context.current_version
|
882
867
|
end
|
883
868
|
|
884
869
|
class << self
|
@@ -1008,6 +993,9 @@ module ActiveRecord
|
|
1008
993
|
if @verified
|
1009
994
|
# Cool, we're confident the connection's ready to use. (Note this might have
|
1010
995
|
# become true during the above #materialize_transactions.)
|
996
|
+
elsif (last_activity = seconds_since_last_activity) && last_activity < verify_timeout
|
997
|
+
# We haven't actually verified the connection since we acquired it, but it
|
998
|
+
# has been used very recently. We're going to assume it's still okay.
|
1011
999
|
elsif reconnectable
|
1012
1000
|
if allow_retry
|
1013
1001
|
# Not sure about the connection yet, but if anything goes wrong we can
|
@@ -1049,6 +1037,7 @@ module ActiveRecord
|
|
1049
1037
|
# Barring a known-retryable error inside the query (regardless of
|
1050
1038
|
# whether we were in a _position_ to retry it), we should infer that
|
1051
1039
|
# there's likely a real problem with the connection.
|
1040
|
+
@last_activity = nil
|
1052
1041
|
@verified = false
|
1053
1042
|
end
|
1054
1043
|
|
@@ -1063,11 +1052,13 @@ module ActiveRecord
|
|
1063
1052
|
# `with_raw_connection` block only when the block is guaranteed to
|
1064
1053
|
# exercise the raw connection.
|
1065
1054
|
def verified!
|
1055
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
1066
1056
|
@verified = true
|
1067
1057
|
end
|
1068
1058
|
|
1069
1059
|
def retryable_connection_error?(exception)
|
1070
|
-
exception.is_a?(ConnectionNotEstablished)
|
1060
|
+
(exception.is_a?(ConnectionNotEstablished) && !exception.is_a?(ConnectionNotDefined)) ||
|
1061
|
+
exception.is_a?(ConnectionFailed)
|
1071
1062
|
end
|
1072
1063
|
|
1073
1064
|
def invalidate_transaction(exception)
|
@@ -1128,37 +1119,37 @@ module ActiveRecord
|
|
1128
1119
|
end
|
1129
1120
|
end
|
1130
1121
|
|
1131
|
-
def translate_exception_class(
|
1132
|
-
|
1122
|
+
def translate_exception_class(native_error, sql, binds)
|
1123
|
+
return native_error if native_error.is_a?(ActiveRecordError)
|
1133
1124
|
|
1134
|
-
|
1135
|
-
|
1125
|
+
message = "#{native_error.class.name}: #{native_error.message}"
|
1126
|
+
|
1127
|
+
active_record_error = translate_exception(
|
1128
|
+
native_error, message: message, sql: sql, binds: binds
|
1136
1129
|
)
|
1137
|
-
|
1138
|
-
|
1130
|
+
active_record_error.set_backtrace(native_error.backtrace)
|
1131
|
+
active_record_error
|
1139
1132
|
end
|
1140
1133
|
|
1141
|
-
def log(sql, name = "SQL", binds = [], type_casted_binds = [],
|
1142
|
-
|
1134
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], async: false, &block) # :doc:
|
1135
|
+
instrumenter.instrument(
|
1143
1136
|
"sql.active_record",
|
1144
1137
|
sql: sql,
|
1145
1138
|
name: name,
|
1146
1139
|
binds: binds,
|
1147
1140
|
type_casted_binds: type_casted_binds,
|
1148
|
-
statement_name: statement_name,
|
1149
1141
|
async: async,
|
1150
1142
|
connection: self,
|
1143
|
+
transaction: current_transaction.user_transaction.presence,
|
1144
|
+
row_count: 0,
|
1151
1145
|
&block
|
1152
1146
|
)
|
1153
1147
|
rescue ActiveRecord::StatementInvalid => ex
|
1154
1148
|
raise ex.set_query(sql, binds)
|
1155
1149
|
end
|
1156
1150
|
|
1157
|
-
def
|
1158
|
-
|
1159
|
-
sql = transformer.call(sql, self)
|
1160
|
-
end
|
1161
|
-
sql
|
1151
|
+
def instrumenter # :nodoc:
|
1152
|
+
ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] ||= ActiveSupport::Notifications.instrumenter
|
1162
1153
|
end
|
1163
1154
|
|
1164
1155
|
def translate_exception(exception, message:, sql:, binds:)
|
@@ -1171,10 +1162,6 @@ module ActiveRecord
|
|
1171
1162
|
end
|
1172
1163
|
end
|
1173
1164
|
|
1174
|
-
def without_prepared_statement?(binds)
|
1175
|
-
!prepared_statements || binds.empty?
|
1176
|
-
end
|
1177
|
-
|
1178
1165
|
def column_for(table_name, column_name)
|
1179
1166
|
column_name = column_name.to_s
|
1180
1167
|
columns(table_name).detect { |c| c.name == column_name } ||
|
@@ -1211,7 +1198,7 @@ module ActiveRecord
|
|
1211
1198
|
#
|
1212
1199
|
# This is an internal hook to make possible connection adapters to build
|
1213
1200
|
# custom result objects with connection-specific data.
|
1214
|
-
def build_result(columns:, rows:, column_types:
|
1201
|
+
def build_result(columns:, rows:, column_types: nil)
|
1215
1202
|
ActiveRecord::Result.new(columns, rows, column_types)
|
1216
1203
|
end
|
1217
1204
|
|
@@ -1223,6 +1210,14 @@ module ActiveRecord
|
|
1223
1210
|
# Implementations may assume this method will only be called while
|
1224
1211
|
# holding @lock (or from #initialize).
|
1225
1212
|
def configure_connection
|
1213
|
+
check_version
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
def attempt_configure_connection
|
1217
|
+
configure_connection
|
1218
|
+
rescue
|
1219
|
+
disconnect!
|
1220
|
+
raise
|
1226
1221
|
end
|
1227
1222
|
|
1228
1223
|
def default_prepared_statements
|