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
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/digest"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
module ConnectionAdapters
|
5
7
|
# = Active Record Connection Adapters Transaction State
|
@@ -89,7 +91,9 @@ module ActiveRecord
|
|
89
91
|
raise InstrumentationAlreadyStartedError.new("Called start on an already started transaction") if @started
|
90
92
|
@started = true
|
91
93
|
|
92
|
-
|
94
|
+
ActiveSupport::Notifications.instrument("start_transaction.active_record", @base_payload)
|
95
|
+
|
96
|
+
@payload = @base_payload.dup # We dup because the payload for a given event is mutated later to add the outcome.
|
93
97
|
@handle = ActiveSupport::Notifications.instrumenter.build_handle("transaction.active_record", @payload)
|
94
98
|
@handle.start
|
95
99
|
end
|
@@ -104,7 +108,6 @@ module ActiveRecord
|
|
104
108
|
end
|
105
109
|
|
106
110
|
class NullTransaction # :nodoc:
|
107
|
-
def initialize; end
|
108
111
|
def state; end
|
109
112
|
def closed?; true; end
|
110
113
|
def open?; false; end
|
@@ -115,17 +118,43 @@ module ActiveRecord
|
|
115
118
|
def dirty!; end
|
116
119
|
def invalidated?; false; end
|
117
120
|
def invalidate!; end
|
121
|
+
def materialized?; false; end
|
122
|
+
def before_commit; yield; end
|
123
|
+
def after_commit; yield; end
|
124
|
+
def after_rollback; end
|
125
|
+
def user_transaction; ActiveRecord::Transaction::NULL_TRANSACTION; end
|
118
126
|
end
|
119
127
|
|
120
128
|
class Transaction # :nodoc:
|
121
|
-
|
129
|
+
class Callback # :nodoc:
|
130
|
+
def initialize(event, callback)
|
131
|
+
@event = event
|
132
|
+
@callback = callback
|
133
|
+
end
|
134
|
+
|
135
|
+
def before_commit
|
136
|
+
@callback.call if @event == :before_commit
|
137
|
+
end
|
138
|
+
|
139
|
+
def after_commit
|
140
|
+
@callback.call if @event == :after_commit
|
141
|
+
end
|
142
|
+
|
143
|
+
def after_rollback
|
144
|
+
@callback.call if @event == :after_rollback
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
attr_reader :connection, :state, :savepoint_name, :isolation_level, :user_transaction
|
122
149
|
attr_accessor :written
|
123
150
|
|
124
151
|
delegate :invalidate!, :invalidated?, to: :@state
|
125
152
|
|
126
153
|
def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
|
154
|
+
super()
|
127
155
|
@connection = connection
|
128
156
|
@state = TransactionState.new
|
157
|
+
@callbacks = nil
|
129
158
|
@records = nil
|
130
159
|
@isolation_level = isolation
|
131
160
|
@materialized = false
|
@@ -133,7 +162,8 @@ module ActiveRecord
|
|
133
162
|
@run_commit_callbacks = run_commit_callbacks
|
134
163
|
@lazy_enrollment_records = nil
|
135
164
|
@dirty = false
|
136
|
-
@
|
165
|
+
@user_transaction = joinable ? ActiveRecord::Transaction.new(self) : ActiveRecord::Transaction::NULL_TRANSACTION
|
166
|
+
@instrumenter = TransactionInstrumenter.new(connection: connection, transaction: @user_transaction)
|
137
167
|
end
|
138
168
|
|
139
169
|
def dirty!
|
@@ -144,6 +174,14 @@ module ActiveRecord
|
|
144
174
|
@dirty
|
145
175
|
end
|
146
176
|
|
177
|
+
def open?
|
178
|
+
true
|
179
|
+
end
|
180
|
+
|
181
|
+
def closed?
|
182
|
+
false
|
183
|
+
end
|
184
|
+
|
147
185
|
def add_record(record, ensure_finalize = true)
|
148
186
|
@records ||= []
|
149
187
|
if ensure_finalize
|
@@ -154,6 +192,30 @@ module ActiveRecord
|
|
154
192
|
end
|
155
193
|
end
|
156
194
|
|
195
|
+
def before_commit(&block)
|
196
|
+
if @state.finalized?
|
197
|
+
raise ActiveRecordError, "Cannot register callbacks on a finalized transaction"
|
198
|
+
end
|
199
|
+
|
200
|
+
(@callbacks ||= []) << Callback.new(:before_commit, block)
|
201
|
+
end
|
202
|
+
|
203
|
+
def after_commit(&block)
|
204
|
+
if @state.finalized?
|
205
|
+
raise ActiveRecordError, "Cannot register callbacks on a finalized transaction"
|
206
|
+
end
|
207
|
+
|
208
|
+
(@callbacks ||= []) << Callback.new(:after_commit, block)
|
209
|
+
end
|
210
|
+
|
211
|
+
def after_rollback(&block)
|
212
|
+
if @state.finalized?
|
213
|
+
raise ActiveRecordError, "Cannot register callbacks on a finalized transaction"
|
214
|
+
end
|
215
|
+
|
216
|
+
(@callbacks ||= []) << Callback.new(:after_rollback, block)
|
217
|
+
end
|
218
|
+
|
157
219
|
def records
|
158
220
|
if @lazy_enrollment_records
|
159
221
|
@records.concat @lazy_enrollment_records.values
|
@@ -190,66 +252,85 @@ module ActiveRecord
|
|
190
252
|
end
|
191
253
|
|
192
254
|
def rollback_records
|
193
|
-
|
194
|
-
|
195
|
-
|
255
|
+
if records
|
256
|
+
begin
|
257
|
+
ite = unique_records
|
196
258
|
|
197
|
-
|
259
|
+
instances_to_run_callbacks_on = prepare_instances_to_run_callbacks_on(ite)
|
198
260
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
261
|
+
run_action_on_records(ite, instances_to_run_callbacks_on) do |record, should_run_callbacks|
|
262
|
+
record.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: should_run_callbacks)
|
263
|
+
end
|
264
|
+
ensure
|
265
|
+
ite&.each do |i|
|
266
|
+
i.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: false)
|
267
|
+
end
|
268
|
+
end
|
205
269
|
end
|
270
|
+
|
271
|
+
@callbacks&.each(&:after_rollback)
|
206
272
|
end
|
207
273
|
|
208
274
|
def before_commit_records
|
209
|
-
return unless records
|
210
|
-
|
211
275
|
if @run_commit_callbacks
|
212
|
-
if
|
213
|
-
|
276
|
+
if records
|
277
|
+
if ActiveRecord.before_committed_on_all_records
|
278
|
+
ite = unique_records
|
214
279
|
|
215
|
-
|
216
|
-
|
217
|
-
|
280
|
+
instances_to_run_callbacks_on = records.each_with_object({}) do |record, candidates|
|
281
|
+
candidates[record] = record
|
282
|
+
end
|
218
283
|
|
219
|
-
|
220
|
-
|
284
|
+
run_action_on_records(ite, instances_to_run_callbacks_on) do |record, should_run_callbacks|
|
285
|
+
record.before_committed! if should_run_callbacks
|
286
|
+
end
|
287
|
+
else
|
288
|
+
records.uniq.each(&:before_committed!)
|
221
289
|
end
|
222
|
-
else
|
223
|
-
records.uniq.each(&:before_committed!)
|
224
290
|
end
|
291
|
+
|
292
|
+
@callbacks&.each(&:before_commit)
|
225
293
|
end
|
294
|
+
# Note: When @run_commit_callbacks is false #commit_records takes care of appending
|
295
|
+
# remaining callbacks to the parent transaction
|
226
296
|
end
|
227
297
|
|
228
298
|
def commit_records
|
229
|
-
|
230
|
-
|
231
|
-
|
299
|
+
if records
|
300
|
+
begin
|
301
|
+
ite = unique_records
|
232
302
|
|
233
|
-
|
234
|
-
|
303
|
+
if @run_commit_callbacks
|
304
|
+
instances_to_run_callbacks_on = prepare_instances_to_run_callbacks_on(ite)
|
235
305
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
306
|
+
run_action_on_records(ite, instances_to_run_callbacks_on) do |record, should_run_callbacks|
|
307
|
+
record.committed!(should_run_callbacks: should_run_callbacks)
|
308
|
+
end
|
309
|
+
else
|
310
|
+
while record = ite.shift
|
311
|
+
# if not running callbacks, only adds the record to the parent transaction
|
312
|
+
connection.add_transaction_record(record)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
ensure
|
316
|
+
ite&.each { |i| i.committed!(should_run_callbacks: false) }
|
243
317
|
end
|
244
318
|
end
|
245
|
-
|
246
|
-
|
319
|
+
|
320
|
+
if @run_commit_callbacks
|
321
|
+
@callbacks&.each(&:after_commit)
|
322
|
+
elsif @callbacks
|
323
|
+
connection.current_transaction.append_callbacks(@callbacks)
|
324
|
+
end
|
247
325
|
end
|
248
326
|
|
249
327
|
def full_rollback?; true; end
|
250
328
|
def joinable?; @joinable; end
|
251
|
-
|
252
|
-
|
329
|
+
|
330
|
+
protected
|
331
|
+
def append_callbacks(callbacks) # :nodoc:
|
332
|
+
(@callbacks ||= []).concat(callbacks)
|
333
|
+
end
|
253
334
|
|
254
335
|
private
|
255
336
|
def unique_records
|
@@ -349,7 +430,7 @@ module ActiveRecord
|
|
349
430
|
|
350
431
|
def rollback
|
351
432
|
unless @state.invalidated?
|
352
|
-
connection.rollback_to_savepoint(savepoint_name) if materialized?
|
433
|
+
connection.rollback_to_savepoint(savepoint_name) if materialized? && connection.active?
|
353
434
|
end
|
354
435
|
@state.rollback!
|
355
436
|
@instrumenter.finish(:rollback) if materialized?
|
@@ -532,9 +613,7 @@ module ActiveRecord
|
|
532
613
|
@connection.lock.synchronize do
|
533
614
|
transaction = begin_transaction(isolation: isolation, joinable: joinable)
|
534
615
|
begin
|
535
|
-
|
536
|
-
completed = true
|
537
|
-
ret
|
616
|
+
yield transaction.user_transaction
|
538
617
|
rescue Exception => error
|
539
618
|
rollback_transaction
|
540
619
|
after_failure_actions(transaction, error)
|
@@ -542,24 +621,8 @@ module ActiveRecord
|
|
542
621
|
raise
|
543
622
|
ensure
|
544
623
|
unless error
|
545
|
-
# In 7.1 we enforce timeout >= 0.4.0 which no longer use throw, so we can
|
546
|
-
# go back to the original behavior of committing on non-local return.
|
547
|
-
# If users are using throw, we assume it's not an error case.
|
548
|
-
completed = true if ActiveRecord.commit_transaction_on_non_local_return
|
549
|
-
|
550
624
|
if Thread.current.status == "aborting"
|
551
625
|
rollback_transaction
|
552
|
-
elsif !completed && transaction.written
|
553
|
-
ActiveRecord.deprecator.warn(<<~EOW)
|
554
|
-
A transaction is being rolled back because the transaction block was
|
555
|
-
exited using `return`, `break` or `throw`.
|
556
|
-
In Rails 7.2 this transaction will be committed instead.
|
557
|
-
To opt-in to the new behavior now and suppress this warning
|
558
|
-
you can set:
|
559
|
-
|
560
|
-
Rails.application.config.active_record.commit_transaction_on_non_local_return = true
|
561
|
-
EOW
|
562
|
-
rollback_transaction
|
563
626
|
else
|
564
627
|
begin
|
565
628
|
commit_transaction
|
@@ -590,7 +653,7 @@ module ActiveRecord
|
|
590
653
|
end
|
591
654
|
|
592
655
|
private
|
593
|
-
NULL_TRANSACTION = NullTransaction.new
|
656
|
+
NULL_TRANSACTION = NullTransaction.new.freeze
|
594
657
|
|
595
658
|
# Deallocate invalidated prepared statements outside of the transaction
|
596
659
|
def after_failure_actions(transaction, error)
|
@@ -23,7 +23,7 @@ module ActiveRecord
|
|
23
23
|
# and +:limit+ options, etc.
|
24
24
|
#
|
25
25
|
# All the concrete database adapters follow the interface laid down in this class.
|
26
|
-
# {ActiveRecord::Base.
|
26
|
+
# {ActiveRecord::Base.lease_connection}[rdoc-ref:ConnectionHandling#lease_connection] returns an AbstractAdapter object, which
|
27
27
|
# you can use.
|
28
28
|
#
|
29
29
|
# Most of the methods in the adapter are useful during migrations. Most
|
@@ -49,8 +49,6 @@ module ActiveRecord
|
|
49
49
|
return if value.eql?(@pool)
|
50
50
|
@schema_cache = nil
|
51
51
|
@pool = value
|
52
|
-
|
53
|
-
@pool.schema_reflection.load!(self) if ActiveRecord.lazily_load_schema_cache
|
54
52
|
end
|
55
53
|
|
56
54
|
set_callback :checkin, :after, :enable_lazy_transactions!
|
@@ -136,7 +134,7 @@ module ActiveRecord
|
|
136
134
|
@logger = ActiveRecord::Base.logger
|
137
135
|
|
138
136
|
if deprecated_logger || deprecated_connection_options || deprecated_config
|
139
|
-
raise ArgumentError, "when initializing an
|
137
|
+
raise ArgumentError, "when initializing an Active Record adapter with a config hash, that should be the only argument"
|
140
138
|
end
|
141
139
|
else
|
142
140
|
# Soft-deprecated for now; we'll probably warn in future.
|
@@ -174,19 +172,20 @@ module ActiveRecord
|
|
174
172
|
@verified = false
|
175
173
|
end
|
176
174
|
|
177
|
-
|
178
|
-
|
175
|
+
def inspect # :nodoc:
|
176
|
+
name_field = " name=#{pool.db_config.name.inspect}" unless pool.db_config.name == "primary"
|
177
|
+
shard_field = " shard=#{shard.inspect}" unless shard == :default
|
179
178
|
|
180
|
-
|
181
|
-
|
179
|
+
"#<#{self.class.name}:#{'%#016x' % (object_id << 1)} env_name=#{pool.db_config.env_name.inspect}#{name_field} role=#{role.inspect}#{shard_field}>"
|
180
|
+
end
|
182
181
|
|
183
182
|
def lock_thread=(lock_thread) # :nodoc:
|
184
183
|
@lock =
|
185
184
|
case lock_thread
|
186
185
|
when Thread
|
187
|
-
|
186
|
+
ActiveSupport::Concurrency::ThreadLoadInterlockAwareMonitor.new
|
188
187
|
when Fiber
|
189
|
-
|
188
|
+
ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
190
189
|
else
|
191
190
|
ActiveSupport::Concurrency::NullLock
|
192
191
|
end
|
@@ -215,10 +214,6 @@ module ActiveRecord
|
|
215
214
|
@config[:replica] || false
|
216
215
|
end
|
217
216
|
|
218
|
-
def use_metadata_table?
|
219
|
-
@config.fetch(:use_metadata_table, true)
|
220
|
-
end
|
221
|
-
|
222
217
|
def connection_retries
|
223
218
|
(@config[:connection_retries] || 1).to_i
|
224
219
|
end
|
@@ -246,22 +241,6 @@ module ActiveRecord
|
|
246
241
|
connection_class.current_preventing_writes
|
247
242
|
end
|
248
243
|
|
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)
|
263
|
-
end
|
264
|
-
|
265
244
|
def prepared_statements?
|
266
245
|
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
|
267
246
|
end
|
@@ -327,7 +306,7 @@ module ActiveRecord
|
|
327
306
|
end
|
328
307
|
|
329
308
|
def schema_cache
|
330
|
-
@schema_cache ||= BoundSchemaReflection.
|
309
|
+
@pool.schema_cache || (@schema_cache ||= BoundSchemaReflection.for_lone_connection(@pool.schema_reflection, self))
|
331
310
|
end
|
332
311
|
|
333
312
|
# this method must only be called while holding connection pool's mutex
|
@@ -580,7 +559,7 @@ module ActiveRecord
|
|
580
559
|
end
|
581
560
|
|
582
561
|
def return_value_after_insert?(column) # :nodoc:
|
583
|
-
column.
|
562
|
+
column.auto_populated?
|
584
563
|
end
|
585
564
|
|
586
565
|
def async_enabled? # :nodoc:
|
@@ -651,15 +630,6 @@ module ActiveRecord
|
|
651
630
|
yield
|
652
631
|
end
|
653
632
|
|
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
633
|
# Override to check all foreign key constraints in a database.
|
664
634
|
# The adapter should raise a +ActiveRecord::StatementInvalid+ if foreign key
|
665
635
|
# constraints are not met.
|
@@ -668,6 +638,13 @@ module ActiveRecord
|
|
668
638
|
|
669
639
|
# CONNECTION MANAGEMENT ====================================
|
670
640
|
|
641
|
+
# Checks whether the connection to the database was established. This doesn't
|
642
|
+
# include checking whether the database is actually capable of responding, i.e.
|
643
|
+
# whether the connection is stale.
|
644
|
+
def connected?
|
645
|
+
!@raw_connection.nil?
|
646
|
+
end
|
647
|
+
|
671
648
|
# Checks whether the connection to the database is still active. This includes
|
672
649
|
# checking whether the database is actually capable of responding, i.e. whether
|
673
650
|
# the connection isn't stale.
|
@@ -711,13 +688,14 @@ module ActiveRecord
|
|
711
688
|
end
|
712
689
|
end
|
713
690
|
|
714
|
-
|
715
691
|
# Disconnects from the database if already connected. Otherwise, this
|
716
692
|
# method does nothing.
|
717
693
|
def disconnect!
|
718
|
-
|
719
|
-
|
720
|
-
|
694
|
+
@lock.synchronize do
|
695
|
+
clear_cache!(new_connection: true)
|
696
|
+
reset_transaction
|
697
|
+
@raw_connection_dirty = false
|
698
|
+
end
|
721
699
|
end
|
722
700
|
|
723
701
|
# Immediately forget this connection ever existed. Unlike disconnect!,
|
@@ -773,19 +751,17 @@ module ActiveRecord
|
|
773
751
|
# is no longer active, then this method will reconnect to the database.
|
774
752
|
def verify!
|
775
753
|
unless active?
|
776
|
-
|
777
|
-
@
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
return
|
784
|
-
end
|
754
|
+
@lock.synchronize do
|
755
|
+
if @unconfigured_connection
|
756
|
+
@raw_connection = @unconfigured_connection
|
757
|
+
@unconfigured_connection = nil
|
758
|
+
configure_connection
|
759
|
+
@verified = true
|
760
|
+
return
|
785
761
|
end
|
786
|
-
end
|
787
762
|
|
788
|
-
|
763
|
+
reconnect!(restore_transactions: true)
|
764
|
+
end
|
789
765
|
end
|
790
766
|
|
791
767
|
@verified = true
|
@@ -868,7 +844,7 @@ module ActiveRecord
|
|
868
844
|
end
|
869
845
|
|
870
846
|
def database_version # :nodoc:
|
871
|
-
|
847
|
+
pool.server_version(self)
|
872
848
|
end
|
873
849
|
|
874
850
|
def check_version # :nodoc:
|
@@ -879,7 +855,7 @@ module ActiveRecord
|
|
879
855
|
# numbered migration that has been executed, or 0 if no schema
|
880
856
|
# information is present / the database is empty.
|
881
857
|
def schema_version
|
882
|
-
migration_context.current_version
|
858
|
+
pool.migration_context.current_version
|
883
859
|
end
|
884
860
|
|
885
861
|
class << self
|
@@ -1149,6 +1125,8 @@ module ActiveRecord
|
|
1149
1125
|
statement_name: statement_name,
|
1150
1126
|
async: async,
|
1151
1127
|
connection: self,
|
1128
|
+
transaction: current_transaction.user_transaction.presence,
|
1129
|
+
row_count: 0,
|
1152
1130
|
&block
|
1153
1131
|
)
|
1154
1132
|
rescue ActiveRecord::StatementInvalid => ex
|
@@ -1212,7 +1190,7 @@ module ActiveRecord
|
|
1212
1190
|
#
|
1213
1191
|
# This is an internal hook to make possible connection adapters to build
|
1214
1192
|
# custom result objects with connection-specific data.
|
1215
|
-
def build_result(columns:, rows:, column_types:
|
1193
|
+
def build_result(columns:, rows:, column_types: nil)
|
1216
1194
|
ActiveRecord::Result.new(columns, rows, column_types)
|
1217
1195
|
end
|
1218
1196
|
|
@@ -1224,6 +1202,7 @@ module ActiveRecord
|
|
1224
1202
|
# Implementations may assume this method will only be called while
|
1225
1203
|
# holding @lock (or from #initialize).
|
1226
1204
|
def configure_connection
|
1205
|
+
check_version
|
1227
1206
|
end
|
1228
1207
|
|
1229
1208
|
def default_prepared_statements
|