activerecord 7.2.4 → 8.1.4
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 +1013 -878
- data/README.rdoc +1 -1
- data/lib/active_record/association_relation.rb +2 -1
- data/lib/active_record/associations/association.rb +69 -27
- data/lib/active_record/associations/association_scope.rb +1 -1
- data/lib/active_record/associations/belongs_to_association.rb +2 -2
- data/lib/active_record/associations/builder/association.rb +23 -11
- data/lib/active_record/associations/builder/belongs_to.rb +36 -8
- data/lib/active_record/associations/builder/collection_association.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +1 -1
- data/lib/active_record/associations/builder/singular_association.rb +33 -5
- data/lib/active_record/associations/collection_association.rb +7 -3
- data/lib/active_record/associations/collection_proxy.rb +26 -4
- data/lib/active_record/associations/deprecation.rb +88 -0
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +3 -0
- data/lib/active_record/associations/foreign_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +3 -2
- data/lib/active_record/associations/has_one_association.rb +1 -0
- data/lib/active_record/associations/join_dependency.rb +3 -2
- data/lib/active_record/associations/preloader/association.rb +3 -3
- data/lib/active_record/associations/preloader/batch.rb +7 -1
- data/lib/active_record/associations/preloader/branch.rb +1 -0
- data/lib/active_record/associations/singular_association.rb +8 -3
- data/lib/active_record/associations.rb +192 -24
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_methods/primary_key.rb +4 -8
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/serialization.rb +18 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -14
- data/lib/active_record/attributes.rb +3 -0
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/base.rb +1 -2
- data/lib/active_record/callbacks.rb +1 -2
- data/lib/active_record/coders/column_serializer.rb +1 -1
- data/lib/active_record/coders/json.rb +16 -6
- data/lib/active_record/coders/yaml_column.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +35 -28
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +68 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +429 -93
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +148 -74
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +27 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +16 -25
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +32 -35
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +124 -34
- data/lib/active_record/connection_adapters/abstract/transaction.rb +40 -8
- data/lib/active_record/connection_adapters/abstract_adapter.rb +129 -63
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +132 -65
- data/lib/active_record/connection_adapters/column.rb +14 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +4 -4
- data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -66
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +89 -94
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +2 -10
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +79 -61
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +46 -3
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +21 -10
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +14 -33
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +71 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +156 -68
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +78 -105
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/column.rb +8 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +90 -98
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +27 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +15 -16
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +104 -37
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +41 -66
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +15 -18
- data/lib/active_record/connection_adapters.rb +1 -56
- data/lib/active_record/connection_handling.rb +25 -2
- data/lib/active_record/core.rb +33 -17
- data/lib/active_record/counter_cache.rb +35 -8
- data/lib/active_record/database_configurations/database_config.rb +9 -1
- data/lib/active_record/database_configurations/hash_config.rb +74 -9
- data/lib/active_record/database_configurations/url_config.rb +15 -3
- data/lib/active_record/database_configurations.rb +7 -3
- data/lib/active_record/delegated_type.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +5 -1
- data/lib/active_record/dynamic_matchers.rb +54 -69
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +8 -8
- data/lib/active_record/encryption/encrypted_attribute_type.rb +11 -2
- data/lib/active_record/encryption/encrypted_fixtures.rb +12 -7
- data/lib/active_record/encryption/encryptor.rb +28 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/scheme.rb +9 -2
- data/lib/active_record/enum.rb +33 -30
- data/lib/active_record/errors.rb +33 -9
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/explain_registry.rb +51 -2
- data/lib/active_record/filter_attribute_handler.rb +76 -0
- data/lib/active_record/fixtures.rb +2 -4
- data/lib/active_record/future_result.rb +15 -9
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +9 -4
- data/lib/active_record/insert_all.rb +14 -9
- data/lib/active_record/locking/optimistic.rb +8 -1
- data/lib/active_record/locking/pessimistic.rb +5 -0
- data/lib/active_record/log_subscriber.rb +31 -29
- data/lib/active_record/message_pack.rb +13 -0
- data/lib/active_record/middleware/shard_selector.rb +34 -17
- data/lib/active_record/migration/command_recorder.rb +56 -13
- data/lib/active_record/migration/compatibility.rb +37 -24
- data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
- data/lib/active_record/migration.rb +48 -42
- data/lib/active_record/model_schema.rb +40 -15
- data/lib/active_record/nested_attributes.rb +14 -12
- data/lib/active_record/persistence.rb +163 -133
- data/lib/active_record/query_cache.rb +22 -15
- data/lib/active_record/query_logs.rb +100 -52
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +35 -30
- data/lib/active_record/railties/controller_runtime.rb +11 -6
- data/lib/active_record/railties/databases.rake +26 -38
- data/lib/active_record/railties/job_checkpoints.rb +15 -0
- data/lib/active_record/railties/job_runtime.rb +10 -11
- data/lib/active_record/reflection.rb +54 -22
- data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
- data/lib/active_record/relation/batches.rb +147 -73
- data/lib/active_record/relation/calculations.rb +60 -43
- data/lib/active_record/relation/delegation.rb +25 -15
- data/lib/active_record/relation/finder_methods.rb +73 -43
- data/lib/active_record/relation/merger.rb +12 -10
- data/lib/active_record/relation/predicate_builder/array_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -9
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +23 -8
- data/lib/active_record/relation/query_attribute.rb +3 -1
- data/lib/active_record/relation/query_methods.rb +200 -96
- data/lib/active_record/relation/spawn_methods.rb +7 -7
- data/lib/active_record/relation/where_clause.rb +2 -9
- data/lib/active_record/relation.rb +127 -87
- data/lib/active_record/result.rb +109 -24
- data/lib/active_record/runtime_registry.rb +42 -58
- data/lib/active_record/sanitization.rb +9 -6
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +17 -10
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/signed_id.rb +44 -16
- data/lib/active_record/statement_cache.rb +24 -20
- data/lib/active_record/store.rb +53 -22
- data/lib/active_record/structured_event_subscriber.rb +85 -0
- data/lib/active_record/table_metadata.rb +6 -23
- data/lib/active_record/tasks/abstract_tasks.rb +83 -0
- data/lib/active_record/tasks/database_tasks.rb +85 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +4 -58
- data/lib/active_record/tasks/postgresql_database_tasks.rb +7 -40
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -28
- data/lib/active_record/test_databases.rb +18 -4
- data/lib/active_record/test_fixtures.rb +52 -6
- data/lib/active_record/testing/query_assertions.rb +8 -2
- data/lib/active_record/timestamp.rb +4 -2
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/transaction.rb +2 -5
- data/lib/active_record/transactions.rb +56 -32
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
- data/lib/active_record/type/internal/timezone.rb +7 -0
- data/lib/active_record/type/json.rb +13 -2
- data/lib/active_record/type/serialized.rb +16 -4
- data/lib/active_record/type/type_map.rb +1 -1
- data/lib/active_record/type_caster/connection.rb +2 -1
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +8 -8
- data/lib/active_record.rb +85 -50
- data/lib/arel/alias_predication.rb +2 -0
- data/lib/arel/collectors/bind.rb +2 -2
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +2 -2
- data/lib/arel/crud.rb +6 -11
- data/lib/arel/nodes/binary.rb +1 -1
- data/lib/arel/nodes/count.rb +2 -2
- data/lib/arel/nodes/function.rb +4 -10
- data/lib/arel/nodes/named_function.rb +2 -2
- data/lib/arel/nodes/node.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +1 -1
- data/lib/arel/nodes.rb +0 -2
- data/lib/arel/predications.rb +1 -3
- data/lib/arel/select_manager.rb +7 -2
- data/lib/arel/table.rb +3 -7
- data/lib/arel/visitors/dot.rb +0 -3
- data/lib/arel/visitors/postgresql.rb +55 -0
- data/lib/arel/visitors/sqlite.rb +55 -8
- data/lib/arel/visitors/to_sql.rb +4 -22
- data/lib/arel.rb +3 -1
- data/lib/rails/generators/active_record/application_record/USAGE +1 -1
- metadata +15 -12
- data/lib/active_record/explain_subscriber.rb +0 -34
- data/lib/active_record/normalization.rb +0 -163
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
|
@@ -1,11 +1,11 @@
|
|
|
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"
|
|
7
6
|
require "active_support/concurrency/null_lock"
|
|
8
7
|
require "active_support/concurrency/load_interlock_aware_monitor"
|
|
8
|
+
require "active_support/concurrency/thread_monitor"
|
|
9
9
|
require "arel/collectors/bind"
|
|
10
10
|
require "arel/collectors/composite"
|
|
11
11
|
require "arel/collectors/sql_string"
|
|
@@ -43,6 +43,7 @@ module ActiveRecord
|
|
|
43
43
|
|
|
44
44
|
attr_reader :pool
|
|
45
45
|
attr_reader :visitor, :owner, :logger, :lock
|
|
46
|
+
attr_reader :allow_preconnect # :nodoc:
|
|
46
47
|
attr_accessor :pinned # :nodoc:
|
|
47
48
|
alias :in_use? :owner
|
|
48
49
|
|
|
@@ -52,7 +53,11 @@ module ActiveRecord
|
|
|
52
53
|
@pool = value
|
|
53
54
|
end
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
def allow_preconnect=(value) # :nodoc:
|
|
57
|
+
@lock.synchronize do
|
|
58
|
+
@allow_preconnect = value
|
|
59
|
+
end
|
|
60
|
+
end
|
|
56
61
|
|
|
57
62
|
def self.type_cast_config_to_integer(config)
|
|
58
63
|
if config.is_a?(Integer)
|
|
@@ -121,7 +126,7 @@ module ActiveRecord
|
|
|
121
126
|
|
|
122
127
|
# Opens a database console session.
|
|
123
128
|
def self.dbconsole(config, options = {})
|
|
124
|
-
raise NotImplementedError
|
|
129
|
+
raise NotImplementedError.new("#{self} should define `dbconsole` that accepts a db config and options to implement connecting to the db console")
|
|
125
130
|
end
|
|
126
131
|
|
|
127
132
|
def initialize(config_or_deprecated_connection, deprecated_logger = nil, deprecated_connection_options = nil, deprecated_config = nil) # :nodoc:
|
|
@@ -129,6 +134,7 @@ module ActiveRecord
|
|
|
129
134
|
|
|
130
135
|
@raw_connection = nil
|
|
131
136
|
@unconfigured_connection = nil
|
|
137
|
+
@connected_since = nil
|
|
132
138
|
|
|
133
139
|
if config_or_deprecated_connection.is_a?(Hash)
|
|
134
140
|
@config = config_or_deprecated_connection.symbolize_keys
|
|
@@ -141,6 +147,7 @@ module ActiveRecord
|
|
|
141
147
|
# Soft-deprecated for now; we'll probably warn in future.
|
|
142
148
|
|
|
143
149
|
@unconfigured_connection = config_or_deprecated_connection
|
|
150
|
+
@connected_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
144
151
|
@logger = deprecated_logger || ActiveRecord::Base.logger
|
|
145
152
|
if deprecated_config
|
|
146
153
|
@config = (deprecated_config || {}).symbolize_keys
|
|
@@ -153,9 +160,9 @@ module ActiveRecord
|
|
|
153
160
|
|
|
154
161
|
@owner = nil
|
|
155
162
|
@pinned = false
|
|
156
|
-
@instrumenter = ActiveSupport::Notifications.instrumenter
|
|
157
163
|
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
|
|
158
164
|
@idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
165
|
+
@allow_preconnect = false
|
|
159
166
|
@visitor = arel_visitor
|
|
160
167
|
@statements = build_statement_pool
|
|
161
168
|
self.lock_thread = nil
|
|
@@ -173,6 +180,8 @@ module ActiveRecord
|
|
|
173
180
|
@raw_connection_dirty = false
|
|
174
181
|
@last_activity = nil
|
|
175
182
|
@verified = false
|
|
183
|
+
|
|
184
|
+
@pool_jitter = rand * max_jitter
|
|
176
185
|
end
|
|
177
186
|
|
|
178
187
|
def inspect # :nodoc:
|
|
@@ -186,31 +195,23 @@ module ActiveRecord
|
|
|
186
195
|
@lock =
|
|
187
196
|
case lock_thread
|
|
188
197
|
when Thread
|
|
189
|
-
ActiveSupport::Concurrency::
|
|
198
|
+
ActiveSupport::Concurrency::ThreadMonitor.new
|
|
190
199
|
when Fiber
|
|
191
|
-
|
|
200
|
+
::Monitor.new
|
|
192
201
|
else
|
|
193
202
|
ActiveSupport::Concurrency::NullLock
|
|
194
203
|
end
|
|
195
204
|
end
|
|
196
205
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def with_instrumenter(instrumenter, &block) # :nodoc:
|
|
201
|
-
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
|
202
|
-
previous_instrumenter = @instrumenter
|
|
203
|
-
@instrumenter = instrumenter
|
|
204
|
-
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
|
205
|
-
ensure
|
|
206
|
-
@instrumenter = previous_instrumenter
|
|
206
|
+
def ensure_writes_are_allowed(sql) # :nodoc:
|
|
207
|
+
if preventing_writes?
|
|
208
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
|
207
209
|
end
|
|
208
210
|
end
|
|
209
211
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
end
|
|
212
|
+
MAX_JITTER = 0.0..1.0 # :nodoc:
|
|
213
|
+
def max_jitter
|
|
214
|
+
(@config[:pool_jitter] || 0.2).to_f.clamp(MAX_JITTER)
|
|
214
215
|
end
|
|
215
216
|
|
|
216
217
|
def replica?
|
|
@@ -243,9 +244,9 @@ module ActiveRecord
|
|
|
243
244
|
# the value of +current_preventing_writes+.
|
|
244
245
|
def preventing_writes?
|
|
245
246
|
return true if replica?
|
|
246
|
-
return false if
|
|
247
|
+
return false if connection_descriptor.nil?
|
|
247
248
|
|
|
248
|
-
|
|
249
|
+
connection_descriptor.current_preventing_writes
|
|
249
250
|
end
|
|
250
251
|
|
|
251
252
|
def prepared_statements?
|
|
@@ -277,7 +278,11 @@ module ActiveRecord
|
|
|
277
278
|
end
|
|
278
279
|
|
|
279
280
|
def valid_type?(type) # :nodoc:
|
|
280
|
-
|
|
281
|
+
self.class.valid_type?(type)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def native_database_types # :nodoc:
|
|
285
|
+
self.class.native_database_types
|
|
281
286
|
end
|
|
282
287
|
|
|
283
288
|
# this method must only be called while holding connection pool's mutex
|
|
@@ -296,8 +301,8 @@ module ActiveRecord
|
|
|
296
301
|
@owner = ActiveSupport::IsolatedExecutionState.context
|
|
297
302
|
end
|
|
298
303
|
|
|
299
|
-
def
|
|
300
|
-
@pool.
|
|
304
|
+
def connection_descriptor # :nodoc:
|
|
305
|
+
@pool.connection_descriptor
|
|
301
306
|
end
|
|
302
307
|
|
|
303
308
|
# The role (e.g. +:writing+) for the current connection. In a
|
|
@@ -316,8 +321,12 @@ module ActiveRecord
|
|
|
316
321
|
@pool.schema_cache || (@schema_cache ||= BoundSchemaReflection.for_lone_connection(@pool.schema_reflection, self))
|
|
317
322
|
end
|
|
318
323
|
|
|
324
|
+
def pool_jitter(duration)
|
|
325
|
+
duration * (1.0 - @pool_jitter)
|
|
326
|
+
end
|
|
327
|
+
|
|
319
328
|
# this method must only be called while holding connection pool's mutex
|
|
320
|
-
def expire
|
|
329
|
+
def expire(update_idle = true) # :nodoc:
|
|
321
330
|
if in_use?
|
|
322
331
|
if @owner != ActiveSupport::IsolatedExecutionState.context
|
|
323
332
|
raise ActiveRecordError, "Cannot expire connection, " \
|
|
@@ -325,8 +334,12 @@ module ActiveRecord
|
|
|
325
334
|
"Current thread: #{ActiveSupport::IsolatedExecutionState.context}."
|
|
326
335
|
end
|
|
327
336
|
|
|
328
|
-
|
|
329
|
-
|
|
337
|
+
_run_checkin_callbacks do
|
|
338
|
+
@idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC) if update_idle
|
|
339
|
+
@owner = nil
|
|
340
|
+
enable_lazy_transactions!
|
|
341
|
+
unset_query_cache!
|
|
342
|
+
end
|
|
330
343
|
else
|
|
331
344
|
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
|
332
345
|
end
|
|
@@ -358,6 +371,21 @@ module ActiveRecord
|
|
|
358
371
|
end
|
|
359
372
|
end
|
|
360
373
|
|
|
374
|
+
# Seconds since this connection was established. nil if not
|
|
375
|
+
# connected; infinity if the connection has been explicitly
|
|
376
|
+
# retired.
|
|
377
|
+
def connection_age # :nodoc:
|
|
378
|
+
if @raw_connection && @connected_since
|
|
379
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) - @connected_since
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
# Mark the connection as needing to be retired, as if the age has
|
|
384
|
+
# exceeded the maximum allowed.
|
|
385
|
+
def force_retirement # :nodoc:
|
|
386
|
+
@connected_since &&= -Float::INFINITY
|
|
387
|
+
end
|
|
388
|
+
|
|
361
389
|
def unprepared_statement
|
|
362
390
|
cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
|
|
363
391
|
yield
|
|
@@ -572,6 +600,10 @@ module ActiveRecord
|
|
|
572
600
|
false
|
|
573
601
|
end
|
|
574
602
|
|
|
603
|
+
def supports_disabling_indexes?
|
|
604
|
+
false
|
|
605
|
+
end
|
|
606
|
+
|
|
575
607
|
def return_value_after_insert?(column) # :nodoc:
|
|
576
608
|
column.auto_populated?
|
|
577
609
|
end
|
|
@@ -590,23 +622,36 @@ module ActiveRecord
|
|
|
590
622
|
end
|
|
591
623
|
|
|
592
624
|
# This is meant to be implemented by the adapters that support custom enum types
|
|
593
|
-
def create_enum(
|
|
625
|
+
def create_enum(...) # :nodoc:
|
|
594
626
|
end
|
|
595
627
|
|
|
596
628
|
# This is meant to be implemented by the adapters that support custom enum types
|
|
597
|
-
def drop_enum(
|
|
629
|
+
def drop_enum(...) # :nodoc:
|
|
598
630
|
end
|
|
599
631
|
|
|
600
632
|
# This is meant to be implemented by the adapters that support custom enum types
|
|
601
|
-
def rename_enum(
|
|
633
|
+
def rename_enum(...) # :nodoc:
|
|
602
634
|
end
|
|
603
635
|
|
|
604
636
|
# This is meant to be implemented by the adapters that support custom enum types
|
|
605
|
-
def add_enum_value(
|
|
637
|
+
def add_enum_value(...) # :nodoc:
|
|
606
638
|
end
|
|
607
639
|
|
|
608
640
|
# This is meant to be implemented by the adapters that support custom enum types
|
|
609
|
-
def rename_enum_value(
|
|
641
|
+
def rename_enum_value(...) # :nodoc:
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
# This is meant to be implemented by the adapters that support virtual tables
|
|
645
|
+
def create_virtual_table(*) # :nodoc:
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
# This is meant to be implemented by the adapters that support virtual tables
|
|
649
|
+
def drop_virtual_table(*) # :nodoc:
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
# Lock used to read an existing record after a duplicate INSERT in a transaction.
|
|
653
|
+
def create_or_find_by_lock # :nodoc:
|
|
654
|
+
true
|
|
610
655
|
end
|
|
611
656
|
|
|
612
657
|
def advisory_locks_enabled? # :nodoc:
|
|
@@ -674,12 +719,15 @@ module ActiveRecord
|
|
|
674
719
|
|
|
675
720
|
@lock.synchronize do
|
|
676
721
|
attempt_configure_connection do
|
|
722
|
+
@allow_preconnect = false
|
|
723
|
+
|
|
677
724
|
reconnect
|
|
678
725
|
|
|
679
726
|
enable_lazy_transactions!
|
|
680
727
|
@raw_connection_dirty = false
|
|
681
|
-
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
728
|
+
@last_activity = @connected_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
682
729
|
@verified = true
|
|
730
|
+
@allow_preconnect = true
|
|
683
731
|
|
|
684
732
|
reset_transaction(restore: restore_transactions) do
|
|
685
733
|
clear_cache!(new_connection: true)
|
|
@@ -707,11 +755,12 @@ module ActiveRecord
|
|
|
707
755
|
# method does nothing.
|
|
708
756
|
def disconnect!
|
|
709
757
|
@lock.synchronize do
|
|
710
|
-
@last_activity = nil
|
|
711
|
-
@verified = false
|
|
712
758
|
clear_cache!(new_connection: true)
|
|
713
759
|
reset_transaction
|
|
714
760
|
@raw_connection_dirty = false
|
|
761
|
+
@connected_since = nil
|
|
762
|
+
@last_activity = nil
|
|
763
|
+
@verified = false
|
|
715
764
|
end
|
|
716
765
|
end
|
|
717
766
|
|
|
@@ -778,6 +827,7 @@ module ActiveRecord
|
|
|
778
827
|
configure_connection
|
|
779
828
|
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
780
829
|
@verified = true
|
|
830
|
+
@allow_preconnect = true
|
|
781
831
|
end
|
|
782
832
|
return
|
|
783
833
|
end
|
|
@@ -786,6 +836,7 @@ module ActiveRecord
|
|
|
786
836
|
end
|
|
787
837
|
end
|
|
788
838
|
|
|
839
|
+
@last_activity = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
789
840
|
@verified = true
|
|
790
841
|
end
|
|
791
842
|
|
|
@@ -795,8 +846,15 @@ module ActiveRecord
|
|
|
795
846
|
end
|
|
796
847
|
|
|
797
848
|
def clean! # :nodoc:
|
|
798
|
-
|
|
799
|
-
|
|
849
|
+
_run_checkout_callbacks do
|
|
850
|
+
@raw_connection_dirty = false
|
|
851
|
+
@verified = nil
|
|
852
|
+
end
|
|
853
|
+
self
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
def verified? # :nodoc:
|
|
857
|
+
@verified
|
|
800
858
|
end
|
|
801
859
|
|
|
802
860
|
# Provides access to the underlying database driver for this adapter. For
|
|
@@ -884,7 +942,7 @@ module ActiveRecord
|
|
|
884
942
|
def register_class_with_precision(mapping, key, klass, **kwargs) # :nodoc:
|
|
885
943
|
mapping.register_type(key) do |*args|
|
|
886
944
|
precision = extract_precision(args.last)
|
|
887
|
-
klass.new(precision: precision, **kwargs)
|
|
945
|
+
klass.new(precision: precision, **kwargs).freeze
|
|
888
946
|
end
|
|
889
947
|
end
|
|
890
948
|
|
|
@@ -896,6 +954,10 @@ module ActiveRecord
|
|
|
896
954
|
end
|
|
897
955
|
end
|
|
898
956
|
|
|
957
|
+
def valid_type?(type) # :nodoc:
|
|
958
|
+
!native_database_types[type].nil?
|
|
959
|
+
end
|
|
960
|
+
|
|
899
961
|
private
|
|
900
962
|
def initialize_type_map(m)
|
|
901
963
|
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
|
@@ -915,7 +977,7 @@ module ActiveRecord
|
|
|
915
977
|
m.alias_type %r(number)i, "decimal"
|
|
916
978
|
m.alias_type %r(double)i, "float"
|
|
917
979
|
|
|
918
|
-
m.register_type %r(^json)i, Type::Json.new
|
|
980
|
+
m.register_type %r(^json)i, Type::Json.new.freeze
|
|
919
981
|
|
|
920
982
|
m.register_type(%r(decimal)i) do |sql_type|
|
|
921
983
|
scale = extract_scale(sql_type)
|
|
@@ -923,9 +985,9 @@ module ActiveRecord
|
|
|
923
985
|
|
|
924
986
|
if scale == 0
|
|
925
987
|
# FIXME: Remove this class as well
|
|
926
|
-
Type::DecimalWithoutScale.new(precision: precision)
|
|
988
|
+
Type::DecimalWithoutScale.new(precision: precision).freeze
|
|
927
989
|
else
|
|
928
|
-
Type::Decimal.new(precision: precision, scale: scale)
|
|
990
|
+
Type::Decimal.new(precision: precision, scale: scale).freeze
|
|
929
991
|
end
|
|
930
992
|
end
|
|
931
993
|
end
|
|
@@ -933,7 +995,7 @@ module ActiveRecord
|
|
|
933
995
|
def register_class_with_limit(mapping, key, klass)
|
|
934
996
|
mapping.register_type(key) do |*args|
|
|
935
997
|
limit = extract_limit(args.last)
|
|
936
|
-
klass.new(limit: limit)
|
|
998
|
+
klass.new(limit: limit).freeze
|
|
937
999
|
end
|
|
938
1000
|
end
|
|
939
1001
|
|
|
@@ -1056,6 +1118,13 @@ module ActiveRecord
|
|
|
1056
1118
|
end
|
|
1057
1119
|
|
|
1058
1120
|
raise translated_exception
|
|
1121
|
+
rescue Exception
|
|
1122
|
+
# A non-StandardError (a Timeout, or a fiber scheduler's cancel) abandoned
|
|
1123
|
+
# the query partway through, so we mark the connection unverified, just as
|
|
1124
|
+
# a failed query would, forcing a reconnect before it's used again.
|
|
1125
|
+
@last_activity = nil
|
|
1126
|
+
@verified = false
|
|
1127
|
+
raise
|
|
1059
1128
|
ensure
|
|
1060
1129
|
dirty_current_transaction if materialize_transactions
|
|
1061
1130
|
end
|
|
@@ -1071,7 +1140,8 @@ module ActiveRecord
|
|
|
1071
1140
|
end
|
|
1072
1141
|
|
|
1073
1142
|
def retryable_connection_error?(exception)
|
|
1074
|
-
exception.is_a?(ConnectionNotEstablished)
|
|
1143
|
+
(exception.is_a?(ConnectionNotEstablished) && !exception.is_a?(ConnectionNotDefined)) ||
|
|
1144
|
+
exception.is_a?(ConnectionFailed)
|
|
1075
1145
|
end
|
|
1076
1146
|
|
|
1077
1147
|
def invalidate_transaction(exception)
|
|
@@ -1093,7 +1163,7 @@ module ActiveRecord
|
|
|
1093
1163
|
end
|
|
1094
1164
|
|
|
1095
1165
|
def reconnect
|
|
1096
|
-
raise NotImplementedError
|
|
1166
|
+
raise NotImplementedError.new("#{self.class} should define `reconnect` to implement adapter-specific logic for reconnecting to the database")
|
|
1097
1167
|
end
|
|
1098
1168
|
|
|
1099
1169
|
# Returns a raw connection for internal use with methods that are known
|
|
@@ -1132,27 +1202,30 @@ module ActiveRecord
|
|
|
1132
1202
|
end
|
|
1133
1203
|
end
|
|
1134
1204
|
|
|
1135
|
-
def translate_exception_class(
|
|
1136
|
-
|
|
1205
|
+
def translate_exception_class(native_error, sql, binds)
|
|
1206
|
+
return native_error if native_error.is_a?(ActiveRecordError)
|
|
1207
|
+
|
|
1208
|
+
message = "#{native_error.class.name}: #{native_error.message}"
|
|
1137
1209
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1210
|
+
active_record_error = translate_exception(
|
|
1211
|
+
native_error, message: message, sql: sql, binds: binds
|
|
1140
1212
|
)
|
|
1141
|
-
|
|
1142
|
-
|
|
1213
|
+
active_record_error.set_backtrace(native_error.backtrace)
|
|
1214
|
+
active_record_error
|
|
1143
1215
|
end
|
|
1144
1216
|
|
|
1145
|
-
def log(sql, name = "SQL", binds = [], type_casted_binds = [],
|
|
1146
|
-
|
|
1217
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], async: false, allow_retry: false, &block) # :doc:
|
|
1218
|
+
instrumenter.instrument(
|
|
1147
1219
|
"sql.active_record",
|
|
1148
1220
|
sql: sql,
|
|
1149
1221
|
name: name,
|
|
1150
1222
|
binds: binds,
|
|
1151
1223
|
type_casted_binds: type_casted_binds,
|
|
1152
|
-
statement_name: statement_name,
|
|
1153
1224
|
async: async,
|
|
1225
|
+
allow_retry: allow_retry,
|
|
1154
1226
|
connection: self,
|
|
1155
1227
|
transaction: current_transaction.user_transaction.presence,
|
|
1228
|
+
affected_rows: 0,
|
|
1156
1229
|
row_count: 0,
|
|
1157
1230
|
&block
|
|
1158
1231
|
)
|
|
@@ -1160,11 +1233,8 @@ module ActiveRecord
|
|
|
1160
1233
|
raise ex.set_query(sql, binds)
|
|
1161
1234
|
end
|
|
1162
1235
|
|
|
1163
|
-
def
|
|
1164
|
-
|
|
1165
|
-
sql = transformer.call(sql, self)
|
|
1166
|
-
end
|
|
1167
|
-
sql
|
|
1236
|
+
def instrumenter # :nodoc:
|
|
1237
|
+
ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] ||= ActiveSupport::Notifications.instrumenter
|
|
1168
1238
|
end
|
|
1169
1239
|
|
|
1170
1240
|
def translate_exception(exception, message:, sql:, binds:)
|
|
@@ -1177,10 +1247,6 @@ module ActiveRecord
|
|
|
1177
1247
|
end
|
|
1178
1248
|
end
|
|
1179
1249
|
|
|
1180
|
-
def without_prepared_statement?(binds)
|
|
1181
|
-
!prepared_statements || binds.empty?
|
|
1182
|
-
end
|
|
1183
|
-
|
|
1184
1250
|
def column_for(table_name, column_name)
|
|
1185
1251
|
column_name = column_name.to_s
|
|
1186
1252
|
columns(table_name).detect { |c| c.name == column_name } ||
|