activerecord 7.1.3.2 → 7.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +570 -2094
- 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_one_association.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +27 -25
- data/lib/active_record/associations/join_dependency.rb +6 -8
- 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 +34 -273
- data/lib/active_record/attribute_assignment.rb +1 -11
- 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 +7 -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 +60 -45
- data/lib/active_record/autosave_association.rb +17 -31
- data/lib/active_record/base.rb +2 -3
- 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 +244 -58
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +35 -18
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +188 -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 +22 -9
- 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 +69 -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 +16 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -21
- 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 +60 -39
- data/lib/active_record/counter_cache.rb +23 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +7 -2
- 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/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/enum.rb +26 -6
- 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 +1 -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 +39 -70
- data/lib/active_record/nested_attributes.rb +11 -3
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +32 -354
- data/lib/active_record/query_cache.rb +18 -6
- 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 +54 -67
- 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 +102 -37
- 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 +95 -62
- 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 +212 -47
- 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 +87 -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 +14 -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/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 +18 -12
@@ -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
|