activerecord 6.0.6.1 → 6.1.7.6

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.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1152 -779
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/active_record/aggregations.rb +5 -5
  6. data/lib/active_record/association_relation.rb +30 -12
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +49 -26
  9. data/lib/active_record/associations/association_scope.rb +18 -20
  10. data/lib/active_record/associations/belongs_to_association.rb +23 -10
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -3
  12. data/lib/active_record/associations/builder/association.rb +32 -5
  13. data/lib/active_record/associations/builder/belongs_to.rb +10 -7
  14. data/lib/active_record/associations/builder/collection_association.rb +5 -4
  15. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -1
  16. data/lib/active_record/associations/builder/has_many.rb +6 -2
  17. data/lib/active_record/associations/builder/has_one.rb +11 -14
  18. data/lib/active_record/associations/builder/singular_association.rb +1 -1
  19. data/lib/active_record/associations/collection_association.rb +32 -18
  20. data/lib/active_record/associations/collection_proxy.rb +12 -5
  21. data/lib/active_record/associations/foreign_association.rb +13 -0
  22. data/lib/active_record/associations/has_many_association.rb +24 -2
  23. data/lib/active_record/associations/has_many_through_association.rb +10 -4
  24. data/lib/active_record/associations/has_one_association.rb +15 -1
  25. data/lib/active_record/associations/join_dependency/join_association.rb +37 -21
  26. data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
  27. data/lib/active_record/associations/join_dependency.rb +63 -49
  28. data/lib/active_record/associations/preloader/association.rb +14 -8
  29. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  30. data/lib/active_record/associations/preloader.rb +5 -3
  31. data/lib/active_record/associations/singular_association.rb +1 -1
  32. data/lib/active_record/associations.rb +118 -11
  33. data/lib/active_record/attribute_assignment.rb +10 -8
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  35. data/lib/active_record/attribute_methods/dirty.rb +1 -11
  36. data/lib/active_record/attribute_methods/primary_key.rb +6 -2
  37. data/lib/active_record/attribute_methods/query.rb +3 -6
  38. data/lib/active_record/attribute_methods/read.rb +8 -11
  39. data/lib/active_record/attribute_methods/serialization.rb +11 -5
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -13
  41. data/lib/active_record/attribute_methods/write.rb +12 -20
  42. data/lib/active_record/attribute_methods.rb +64 -54
  43. data/lib/active_record/attributes.rb +33 -8
  44. data/lib/active_record/autosave_association.rb +47 -30
  45. data/lib/active_record/base.rb +2 -14
  46. data/lib/active_record/callbacks.rb +152 -22
  47. data/lib/active_record/coders/yaml_column.rb +1 -1
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +185 -134
  49. data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
  50. data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -23
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -8
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
  53. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  54. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  55. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +114 -26
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +228 -83
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +92 -33
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +52 -76
  60. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +123 -87
  61. data/lib/active_record/connection_adapters/column.rb +15 -1
  62. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  63. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +24 -24
  65. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/quoting.rb +18 -3
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -6
  68. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
  69. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +5 -2
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +7 -4
  71. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  72. data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -12
  73. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +14 -53
  77. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  78. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  79. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
  80. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  81. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/quoting.rb +30 -4
  87. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  88. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  90. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  91. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -64
  92. data/lib/active_record/connection_adapters/schema_cache.rb +130 -15
  93. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  94. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +32 -5
  95. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  96. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  98. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  99. data/lib/active_record/connection_adapters.rb +52 -0
  100. data/lib/active_record/connection_handling.rb +218 -71
  101. data/lib/active_record/core.rb +264 -63
  102. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  103. data/lib/active_record/database_configurations/database_config.rb +52 -9
  104. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  105. data/lib/active_record/database_configurations/url_config.rb +15 -40
  106. data/lib/active_record/database_configurations.rb +125 -85
  107. data/lib/active_record/delegated_type.rb +209 -0
  108. data/lib/active_record/destroy_association_async_job.rb +36 -0
  109. data/lib/active_record/enum.rb +69 -34
  110. data/lib/active_record/errors.rb +47 -12
  111. data/lib/active_record/explain.rb +9 -4
  112. data/lib/active_record/explain_subscriber.rb +1 -1
  113. data/lib/active_record/fixture_set/file.rb +10 -17
  114. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  115. data/lib/active_record/fixture_set/render_context.rb +1 -1
  116. data/lib/active_record/fixture_set/table_row.rb +2 -2
  117. data/lib/active_record/fixtures.rb +58 -9
  118. data/lib/active_record/gem_version.rb +3 -3
  119. data/lib/active_record/inheritance.rb +40 -18
  120. data/lib/active_record/insert_all.rb +38 -5
  121. data/lib/active_record/integration.rb +3 -5
  122. data/lib/active_record/internal_metadata.rb +18 -7
  123. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  124. data/lib/active_record/locking/optimistic.rb +24 -17
  125. data/lib/active_record/locking/pessimistic.rb +6 -2
  126. data/lib/active_record/log_subscriber.rb +27 -8
  127. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  128. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  129. data/lib/active_record/middleware/database_selector.rb +4 -1
  130. data/lib/active_record/migration/command_recorder.rb +47 -27
  131. data/lib/active_record/migration/compatibility.rb +72 -18
  132. data/lib/active_record/migration.rb +114 -84
  133. data/lib/active_record/model_schema.rb +89 -14
  134. data/lib/active_record/nested_attributes.rb +2 -3
  135. data/lib/active_record/no_touching.rb +1 -1
  136. data/lib/active_record/persistence.rb +50 -45
  137. data/lib/active_record/query_cache.rb +15 -5
  138. data/lib/active_record/querying.rb +11 -6
  139. data/lib/active_record/railtie.rb +64 -44
  140. data/lib/active_record/railties/console_sandbox.rb +2 -4
  141. data/lib/active_record/railties/databases.rake +279 -101
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +60 -44
  144. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  145. data/lib/active_record/relation/batches.rb +38 -31
  146. data/lib/active_record/relation/calculations.rb +104 -43
  147. data/lib/active_record/relation/finder_methods.rb +44 -14
  148. data/lib/active_record/relation/from_clause.rb +1 -1
  149. data/lib/active_record/relation/merger.rb +20 -23
  150. data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
  151. data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -6
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +61 -38
  155. data/lib/active_record/relation/query_methods.rb +322 -196
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +8 -7
  158. data/lib/active_record/relation/where_clause.rb +111 -61
  159. data/lib/active_record/relation.rb +100 -81
  160. data/lib/active_record/result.rb +41 -33
  161. data/lib/active_record/runtime_registry.rb +2 -2
  162. data/lib/active_record/sanitization.rb +6 -17
  163. data/lib/active_record/schema_dumper.rb +34 -4
  164. data/lib/active_record/schema_migration.rb +2 -8
  165. data/lib/active_record/scoping/default.rb +1 -3
  166. data/lib/active_record/scoping/named.rb +1 -17
  167. data/lib/active_record/secure_token.rb +16 -8
  168. data/lib/active_record/serialization.rb +5 -3
  169. data/lib/active_record/signed_id.rb +116 -0
  170. data/lib/active_record/statement_cache.rb +20 -4
  171. data/lib/active_record/store.rb +8 -3
  172. data/lib/active_record/suppressor.rb +2 -2
  173. data/lib/active_record/table_metadata.rb +42 -51
  174. data/lib/active_record/tasks/database_tasks.rb +140 -113
  175. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  176. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  177. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  178. data/lib/active_record/test_databases.rb +5 -4
  179. data/lib/active_record/test_fixtures.rb +79 -31
  180. data/lib/active_record/timestamp.rb +4 -6
  181. data/lib/active_record/touch_later.rb +21 -21
  182. data/lib/active_record/transactions.rb +19 -66
  183. data/lib/active_record/type/serialized.rb +6 -2
  184. data/lib/active_record/type.rb +8 -1
  185. data/lib/active_record/type_caster/connection.rb +0 -1
  186. data/lib/active_record/type_caster/map.rb +8 -5
  187. data/lib/active_record/validations/associated.rb +1 -1
  188. data/lib/active_record/validations/numericality.rb +35 -0
  189. data/lib/active_record/validations/uniqueness.rb +24 -4
  190. data/lib/active_record/validations.rb +1 -0
  191. data/lib/active_record.rb +7 -14
  192. data/lib/arel/attributes/attribute.rb +4 -0
  193. data/lib/arel/collectors/bind.rb +5 -0
  194. data/lib/arel/collectors/composite.rb +8 -0
  195. data/lib/arel/collectors/sql_string.rb +7 -0
  196. data/lib/arel/collectors/substitute_binds.rb +7 -0
  197. data/lib/arel/nodes/binary.rb +82 -8
  198. data/lib/arel/nodes/bind_param.rb +8 -0
  199. data/lib/arel/nodes/casted.rb +21 -9
  200. data/lib/arel/nodes/equality.rb +6 -9
  201. data/lib/arel/nodes/grouping.rb +3 -0
  202. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  203. data/lib/arel/nodes/in.rb +8 -1
  204. data/lib/arel/nodes/infix_operation.rb +13 -1
  205. data/lib/arel/nodes/join_source.rb +1 -1
  206. data/lib/arel/nodes/node.rb +7 -6
  207. data/lib/arel/nodes/ordering.rb +27 -0
  208. data/lib/arel/nodes/sql_literal.rb +3 -0
  209. data/lib/arel/nodes/table_alias.rb +7 -3
  210. data/lib/arel/nodes/unary.rb +0 -1
  211. data/lib/arel/nodes.rb +3 -1
  212. data/lib/arel/predications.rb +12 -18
  213. data/lib/arel/select_manager.rb +1 -2
  214. data/lib/arel/table.rb +13 -5
  215. data/lib/arel/visitors/dot.rb +14 -2
  216. data/lib/arel/visitors/mysql.rb +11 -1
  217. data/lib/arel/visitors/postgresql.rb +15 -4
  218. data/lib/arel/visitors/to_sql.rb +89 -78
  219. data/lib/arel/visitors.rb +0 -7
  220. data/lib/arel.rb +5 -13
  221. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  222. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  223. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  224. data/lib/rails/generators/active_record/migration.rb +6 -1
  225. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  226. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  227. metadata +25 -26
  228. data/lib/active_record/advisory_lock_base.rb +0 -18
  229. data/lib/active_record/attribute_decorators.rb +0 -88
  230. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  231. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  232. data/lib/active_record/define_callbacks.rb +0 -22
  233. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  234. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  235. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  236. data/lib/arel/attributes.rb +0 -22
  237. data/lib/arel/visitors/depth_first.rb +0 -203
  238. data/lib/arel/visitors/ibm_db.rb +0 -34
  239. data/lib/arel/visitors/informix.rb +0 -62
  240. data/lib/arel/visitors/mssql.rb +0 -156
  241. data/lib/arel/visitors/oracle.rb +0 -158
  242. data/lib/arel/visitors/oracle12.rb +0 -65
  243. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -5,10 +5,11 @@ module ActiveRecord
5
5
  class TransactionState
6
6
  def initialize(state = nil)
7
7
  @state = state
8
- @children = []
8
+ @children = nil
9
9
  end
10
10
 
11
11
  def add_child(state)
12
+ @children ||= []
12
13
  @children << state
13
14
  end
14
15
 
@@ -32,6 +33,10 @@ module ActiveRecord
32
33
  @state == :fully_rolledback
33
34
  end
34
35
 
36
+ def invalidated?
37
+ @state == :invalidated
38
+ end
39
+
35
40
  def fully_completed?
36
41
  completed?
37
42
  end
@@ -41,15 +46,20 @@ module ActiveRecord
41
46
  end
42
47
 
43
48
  def rollback!
44
- @children.each { |c| c.rollback! }
49
+ @children&.each { |c| c.rollback! }
45
50
  @state = :rolledback
46
51
  end
47
52
 
48
53
  def full_rollback!
49
- @children.each { |c| c.rollback! }
54
+ @children&.each { |c| c.rollback! }
50
55
  @state = :fully_rolledback
51
56
  end
52
57
 
58
+ def invalidate!
59
+ @children&.each { |c| c.invalidate! }
60
+ @state = :invalidated
61
+ end
62
+
53
63
  def commit!
54
64
  @state = :committed
55
65
  end
@@ -69,24 +79,40 @@ module ActiveRecord
69
79
  def closed?; true; end
70
80
  def open?; false; end
71
81
  def joinable?; false; end
72
- def add_record(record); end
82
+ def add_record(record, _ = true); end
73
83
  end
74
84
 
75
85
  class Transaction #:nodoc:
76
- attr_reader :connection, :state, :records, :savepoint_name, :isolation_level
86
+ attr_reader :connection, :state, :savepoint_name, :isolation_level
87
+ attr_accessor :written
77
88
 
78
- def initialize(connection, options, run_commit_callbacks: false)
89
+ def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
79
90
  @connection = connection
80
91
  @state = TransactionState.new
81
- @records = []
82
- @isolation_level = options[:isolation]
92
+ @records = nil
93
+ @isolation_level = isolation
83
94
  @materialized = false
84
- @joinable = options.fetch(:joinable, true)
95
+ @joinable = joinable
85
96
  @run_commit_callbacks = run_commit_callbacks
97
+ @lazy_enrollment_records = nil
86
98
  end
87
99
 
88
- def add_record(record)
89
- records << record
100
+ def add_record(record, ensure_finalize = true)
101
+ @records ||= []
102
+ if ensure_finalize
103
+ @records << record
104
+ else
105
+ @lazy_enrollment_records ||= ObjectSpace::WeakMap.new
106
+ @lazy_enrollment_records[record] = record
107
+ end
108
+ end
109
+
110
+ def records
111
+ if @lazy_enrollment_records
112
+ @records.concat @lazy_enrollment_records.values
113
+ @lazy_enrollment_records = nil
114
+ end
115
+ @records
90
116
  end
91
117
 
92
118
  def materialize!
@@ -98,6 +124,7 @@ module ActiveRecord
98
124
  end
99
125
 
100
126
  def rollback_records
127
+ return unless records
101
128
  ite = records.uniq(&:__id__)
102
129
  already_run_callbacks = {}
103
130
  while record = ite.shift
@@ -107,16 +134,17 @@ module ActiveRecord
107
134
  record.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: should_run_callbacks)
108
135
  end
109
136
  ensure
110
- ite.each do |i|
137
+ ite&.each do |i|
111
138
  i.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: false)
112
139
  end
113
140
  end
114
141
 
115
142
  def before_commit_records
116
- records.uniq.each(&:before_committed!) if @run_commit_callbacks
143
+ records.uniq.each(&:before_committed!) if records && @run_commit_callbacks
117
144
  end
118
145
 
119
146
  def commit_records
147
+ return unless records
120
148
  ite = records.uniq(&:__id__)
121
149
  already_run_callbacks = {}
122
150
  while record = ite.shift
@@ -131,7 +159,7 @@ module ActiveRecord
131
159
  end
132
160
  end
133
161
  ensure
134
- ite.each { |i| i.committed!(should_run_callbacks: false) }
162
+ ite&.each { |i| i.committed!(should_run_callbacks: false) }
135
163
  end
136
164
 
137
165
  def full_rollback?; true; end
@@ -141,8 +169,8 @@ module ActiveRecord
141
169
  end
142
170
 
143
171
  class SavepointTransaction < Transaction
144
- def initialize(connection, savepoint_name, parent_transaction, *args, **options)
145
- super(connection, *args, **options)
172
+ def initialize(connection, savepoint_name, parent_transaction, **options)
173
+ super(connection, **options)
146
174
 
147
175
  parent_transaction.state.add_child(@state)
148
176
 
@@ -202,18 +230,29 @@ module ActiveRecord
202
230
  @lazy_transactions_enabled = true
203
231
  end
204
232
 
205
- def begin_transaction(options = {})
233
+ def begin_transaction(isolation: nil, joinable: true, _lazy: true)
206
234
  @connection.lock.synchronize do
207
235
  run_commit_callbacks = !current_transaction.joinable?
208
236
  transaction =
209
237
  if @stack.empty?
210
- RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
238
+ RealTransaction.new(
239
+ @connection,
240
+ isolation: isolation,
241
+ joinable: joinable,
242
+ run_commit_callbacks: run_commit_callbacks
243
+ )
211
244
  else
212
- SavepointTransaction.new(@connection, "active_record_#{@stack.size}", @stack.last, options,
213
- run_commit_callbacks: run_commit_callbacks)
245
+ SavepointTransaction.new(
246
+ @connection,
247
+ "active_record_#{@stack.size}",
248
+ @stack.last,
249
+ isolation: isolation,
250
+ joinable: joinable,
251
+ run_commit_callbacks: run_commit_callbacks
252
+ )
214
253
  end
215
254
 
216
- if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && options[:_lazy] != false
255
+ if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy
217
256
  @has_unmaterialized_transactions = true
218
257
  else
219
258
  transaction.materialize!
@@ -269,31 +308,51 @@ module ActiveRecord
269
308
  def rollback_transaction(transaction = nil)
270
309
  @connection.lock.synchronize do
271
310
  transaction ||= @stack.pop
272
- transaction.rollback
311
+ transaction.rollback unless transaction.state.invalidated?
273
312
  transaction.rollback_records
274
313
  end
275
314
  end
276
315
 
277
- def within_new_transaction(options = {})
316
+ def within_new_transaction(isolation: nil, joinable: true)
278
317
  @connection.lock.synchronize do
279
- transaction = begin_transaction options
280
- yield
318
+ transaction = begin_transaction(isolation: isolation, joinable: joinable)
319
+ ret = yield
320
+ completed = true
321
+ ret
281
322
  rescue Exception => error
282
323
  if transaction
324
+ transaction.state.invalidate! if error.is_a? ActiveRecord::TransactionRollbackError
283
325
  rollback_transaction
284
326
  after_failure_actions(transaction, error)
285
327
  end
328
+
286
329
  raise
287
330
  ensure
288
- if !error && transaction
289
- if Thread.current.status == "aborting"
290
- rollback_transaction
331
+ if transaction
332
+ if error
333
+ # @connection still holds an open or invalid transaction, so we must not
334
+ # put it back in the pool for reuse.
335
+ @connection.throw_away! unless transaction.state.rolledback?
291
336
  else
292
- begin
293
- commit_transaction
294
- rescue Exception
295
- rollback_transaction(transaction) unless transaction.state.completed?
296
- raise
337
+ if Thread.current.status == "aborting"
338
+ rollback_transaction
339
+ else
340
+ if !completed && transaction.written
341
+ ActiveSupport::Deprecation.warn(<<~EOW)
342
+ Using `return`, `break` or `throw` to exit a transaction block is
343
+ deprecated without replacement. If the `throw` came from
344
+ `Timeout.timeout(duration)`, pass an exception class as a second
345
+ argument so it doesn't use `throw` to abort its block. This results
346
+ in the transaction being committed, but in the next release of Rails
347
+ it will rollback.
348
+ EOW
349
+ end
350
+ begin
351
+ commit_transaction
352
+ rescue Exception
353
+ rollback_transaction(transaction) unless transaction.state.completed?
354
+ raise
355
+ end
297
356
  end
298
357
  end
299
358
  end
@@ -1,13 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "set"
4
- require "active_record/connection_adapters/determine_if_preparable_visitor"
5
- require "active_record/connection_adapters/schema_cache"
6
4
  require "active_record/connection_adapters/sql_type_metadata"
7
5
  require "active_record/connection_adapters/abstract/schema_dumper"
8
6
  require "active_record/connection_adapters/abstract/schema_creation"
9
7
  require "active_support/concurrency/load_interlock_aware_monitor"
10
- require "active_support/deprecation"
11
8
  require "arel/collectors/bind"
12
9
  require "arel/collectors/composite"
13
10
  require "arel/collectors/sql_string"
@@ -15,44 +12,6 @@ require "arel/collectors/substitute_binds"
15
12
 
16
13
  module ActiveRecord
17
14
  module ConnectionAdapters # :nodoc:
18
- extend ActiveSupport::Autoload
19
-
20
- autoload :Column
21
- autoload :ConnectionSpecification
22
-
23
- autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
24
- autoload :IndexDefinition
25
- autoload :ColumnDefinition
26
- autoload :ChangeColumnDefinition
27
- autoload :ForeignKeyDefinition
28
- autoload :TableDefinition
29
- autoload :Table
30
- autoload :AlterTable
31
- autoload :ReferenceDefinition
32
- end
33
-
34
- autoload_at "active_record/connection_adapters/abstract/connection_pool" do
35
- autoload :ConnectionHandler
36
- end
37
-
38
- autoload_under "abstract" do
39
- autoload :SchemaStatements
40
- autoload :DatabaseStatements
41
- autoload :DatabaseLimits
42
- autoload :Quoting
43
- autoload :ConnectionPool
44
- autoload :QueryCache
45
- autoload :Savepoints
46
- end
47
-
48
- autoload_at "active_record/connection_adapters/abstract/transaction" do
49
- autoload :TransactionManager
50
- autoload :NullTransaction
51
- autoload :RealTransaction
52
- autoload :SavepointTransaction
53
- autoload :TransactionState
54
- end
55
-
56
15
  # Active Record supports multiple database systems. AbstractAdapter and
57
16
  # related classes form the abstraction layer which makes this possible.
58
17
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -77,7 +36,7 @@ module ActiveRecord
77
36
  include Savepoints
78
37
 
79
38
  SIMPLE_INT = /\A\d+\z/
80
- COMMENT_REGEX = %r{/\*(?:[^\*]|\*[^/])*\*/}m
39
+ COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
81
40
 
82
41
  attr_accessor :pool
83
42
  attr_reader :visitor, :owner, :logger, :lock
@@ -134,12 +93,9 @@ module ActiveRecord
134
93
  @statements = build_statement_pool
135
94
  @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
136
95
 
137
- if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
138
- @prepared_statements = true
139
- @visitor.extend(DetermineIfPreparableVisitor)
140
- else
141
- @prepared_statements = false
142
- end
96
+ @prepared_statements = self.class.type_cast_config_to_boolean(
97
+ config.fetch(:prepared_statements, true)
98
+ )
143
99
 
144
100
  @advisory_locks_enabled = self.class.type_cast_config_to_boolean(
145
101
  config.fetch(:advisory_locks, true)
@@ -150,12 +106,25 @@ module ActiveRecord
150
106
  @config[:replica] || false
151
107
  end
152
108
 
153
- # Determines whether writes are currently being prevents.
109
+ def use_metadata_table?
110
+ @config.fetch(:use_metadata_table, true)
111
+ end
112
+
113
+ # Determines whether writes are currently being prevented.
114
+ #
115
+ # Returns true if the connection is a replica.
116
+ #
117
+ # If the application is using legacy handling, returns
118
+ # true if +connection_handler.prevent_writes+ is set.
154
119
  #
155
- # Returns true if the connection is a replica, or if +prevent_writes+
156
- # is set to true.
120
+ # If the application is using the new connection handling
121
+ # will return true based on +current_preventing_writes+.
157
122
  def preventing_writes?
158
- replica? || ActiveRecord::Base.connection_handler.prevent_writes
123
+ return true if replica?
124
+ return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
125
+ return false if connection_klass.nil?
126
+
127
+ connection_klass.current_preventing_writes
159
128
  end
160
129
 
161
130
  def migrations_paths # :nodoc:
@@ -169,23 +138,25 @@ module ActiveRecord
169
138
  def schema_migration # :nodoc:
170
139
  @schema_migration ||= begin
171
140
  conn = self
172
- spec_name = conn.pool.spec.name
173
- name = "#{spec_name}::SchemaMigration"
141
+ spec_name = conn.pool.pool_config.connection_specification_name
142
+
143
+ return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
174
144
 
175
- return ActiveRecord::SchemaMigration if spec_name == "primary"
145
+ schema_migration_name = "#{spec_name}::SchemaMigration"
176
146
 
177
147
  Class.new(ActiveRecord::SchemaMigration) do
178
- define_singleton_method(:name) { name }
179
- define_singleton_method(:to_s) { name }
148
+ define_singleton_method(:name) { schema_migration_name }
149
+ define_singleton_method(:to_s) { schema_migration_name }
180
150
 
181
151
  self.connection_specification_name = spec_name
182
152
  end
183
153
  end
184
154
  end
185
155
 
186
- def prepared_statements
156
+ def prepared_statements?
187
157
  @prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
188
158
  end
159
+ alias :prepared_statements :prepared_statements?
189
160
 
190
161
  def prepared_statements_disabled_cache # :nodoc:
191
162
  Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
@@ -230,6 +201,10 @@ module ActiveRecord
230
201
  @owner = Thread.current
231
202
  end
232
203
 
204
+ def connection_klass # :nodoc:
205
+ @pool.connection_klass
206
+ end
207
+
233
208
  def schema_cache
234
209
  @pool.get_schema_cache(self)
235
210
  end
@@ -275,7 +250,7 @@ module ActiveRecord
275
250
  end
276
251
 
277
252
  def unprepared_statement
278
- cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
253
+ cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
279
254
  yield
280
255
  ensure
281
256
  cache&.delete(object_id)
@@ -369,12 +344,10 @@ module ActiveRecord
369
344
  false
370
345
  end
371
346
 
372
- # Does this adapter support creating foreign key constraints
373
- # in the same statement as creating the table?
374
- def supports_foreign_keys_in_create?
375
- supports_foreign_keys?
347
+ # Does this adapter support creating check constraints?
348
+ def supports_check_constraints?
349
+ false
376
350
  end
377
- deprecate :supports_foreign_keys_in_create?
378
351
 
379
352
  # Does this adapter support views?
380
353
  def supports_views?
@@ -406,12 +379,6 @@ module ActiveRecord
406
379
  false
407
380
  end
408
381
 
409
- # Does this adapter support multi-value insert?
410
- def supports_multi_insert?
411
- true
412
- end
413
- deprecate :supports_multi_insert?
414
-
415
382
  # Does this adapter support virtual columns?
416
383
  def supports_virtual_columns?
417
384
  false
@@ -543,6 +510,12 @@ module ActiveRecord
543
510
  # this should be overridden by concrete adapters
544
511
  end
545
512
 
513
+ # Removes the connection from the pool and disconnect it.
514
+ def throw_away!
515
+ pool.remove self
516
+ disconnect!
517
+ end
518
+
546
519
  # Clear any caching the database adapter may be doing.
547
520
  def clear_cache!
548
521
  @lock.synchronize { @statements.clear } if @statements
@@ -571,7 +544,7 @@ module ActiveRecord
571
544
  @connection
572
545
  end
573
546
 
574
- def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
547
+ def default_uniqueness_comparison(attribute, value) # :nodoc:
575
548
  attribute.eq(value)
576
549
  end
577
550
 
@@ -599,10 +572,6 @@ module ActiveRecord
599
572
  pool.checkin self
600
573
  end
601
574
 
602
- def column_name_for_operation(operation, node) # :nodoc:
603
- visitor.compile(node)
604
- end
605
-
606
575
  def default_index_type?(index) # :nodoc:
607
576
  index.using.nil?
608
577
  end
@@ -722,7 +691,6 @@ module ActiveRecord
722
691
  binds: binds,
723
692
  type_casted_binds: type_casted_binds,
724
693
  statement_name: statement_name,
725
- connection_id: object_id,
726
694
  connection: self) do
727
695
  @lock.synchronize do
728
696
  yield
@@ -777,6 +745,14 @@ module ActiveRecord
777
745
 
778
746
  def build_statement_pool
779
747
  end
748
+
749
+ # Builds the result object.
750
+ #
751
+ # This is an internal hook to make possible connection adapters to build
752
+ # custom result objects with connection-specific data.
753
+ def build_result(columns:, rows:, column_types: {})
754
+ ActiveRecord::Result.new(columns, rows, column_types)
755
+ end
780
756
  end
781
757
  end
782
758
  end