activerecord 6.0.6.1 → 6.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +764 -942
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +22 -14
  7. data/lib/active_record/associations/alias_tracker.rb +19 -15
  8. data/lib/active_record/associations/association.rb +39 -27
  9. data/lib/active_record/associations/association_scope.rb +11 -15
  10. data/lib/active_record/associations/belongs_to_association.rb +15 -5
  11. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  12. data/lib/active_record/associations/builder/association.rb +9 -3
  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 +19 -13
  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 +29 -14
  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 +13 -5
  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 +114 -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 +4 -4
  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 +52 -48
  43. data/lib/active_record/attributes.rb +27 -7
  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 +32 -22
  47. data/lib/active_record/coders/yaml_column.rb +2 -24
  48. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +180 -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 +65 -22
  51. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -7
  52. data/lib/active_record/connection_adapters/abstract/quoting.rb +35 -44
  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 +110 -30
  56. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +224 -85
  58. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -24
  59. data/lib/active_record/connection_adapters/abstract_adapter.rb +31 -70
  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 +31 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -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 +1 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +33 -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 +1 -1
  70. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +3 -3
  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 +63 -0
  74. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  75. data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
  76. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +12 -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 -10
  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/money.rb +2 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -1
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  88. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  89. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -1
  90. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +61 -29
  91. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql_adapter.rb +72 -55
  93. data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
  94. data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
  95. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +30 -5
  96. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -1
  97. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  98. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +36 -3
  99. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +48 -50
  100. data/lib/active_record/connection_adapters.rb +50 -0
  101. data/lib/active_record/connection_handling.rb +210 -71
  102. data/lib/active_record/core.rb +214 -58
  103. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  104. data/lib/active_record/database_configurations/database_config.rb +52 -9
  105. data/lib/active_record/database_configurations/hash_config.rb +54 -8
  106. data/lib/active_record/database_configurations/url_config.rb +15 -40
  107. data/lib/active_record/database_configurations.rb +124 -85
  108. data/lib/active_record/delegated_type.rb +209 -0
  109. data/lib/active_record/destroy_association_async_job.rb +36 -0
  110. data/lib/active_record/enum.rb +33 -23
  111. data/lib/active_record/errors.rb +47 -12
  112. data/lib/active_record/explain.rb +9 -4
  113. data/lib/active_record/explain_subscriber.rb +1 -1
  114. data/lib/active_record/fixture_set/file.rb +10 -17
  115. data/lib/active_record/fixture_set/model_metadata.rb +1 -2
  116. data/lib/active_record/fixture_set/render_context.rb +1 -1
  117. data/lib/active_record/fixture_set/table_row.rb +2 -2
  118. data/lib/active_record/fixtures.rb +54 -8
  119. data/lib/active_record/gem_version.rb +3 -3
  120. data/lib/active_record/inheritance.rb +40 -18
  121. data/lib/active_record/insert_all.rb +32 -5
  122. data/lib/active_record/integration.rb +3 -5
  123. data/lib/active_record/internal_metadata.rb +15 -4
  124. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  125. data/lib/active_record/locking/optimistic.rb +13 -16
  126. data/lib/active_record/locking/pessimistic.rb +6 -2
  127. data/lib/active_record/log_subscriber.rb +26 -8
  128. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  129. data/lib/active_record/middleware/database_selector/resolver.rb +5 -0
  130. data/lib/active_record/middleware/database_selector.rb +4 -1
  131. data/lib/active_record/migration/command_recorder.rb +47 -27
  132. data/lib/active_record/migration/compatibility.rb +67 -17
  133. data/lib/active_record/migration.rb +113 -83
  134. data/lib/active_record/model_schema.rb +88 -42
  135. data/lib/active_record/nested_attributes.rb +2 -3
  136. data/lib/active_record/no_touching.rb +1 -1
  137. data/lib/active_record/persistence.rb +50 -45
  138. data/lib/active_record/query_cache.rb +15 -5
  139. data/lib/active_record/querying.rb +11 -6
  140. data/lib/active_record/railtie.rb +64 -44
  141. data/lib/active_record/railties/databases.rake +253 -98
  142. data/lib/active_record/readonly_attributes.rb +4 -0
  143. data/lib/active_record/reflection.rb +59 -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 +100 -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 +2 -2
  152. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
  153. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  154. data/lib/active_record/relation/predicate_builder.rb +57 -33
  155. data/lib/active_record/relation/query_methods.rb +319 -198
  156. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  157. data/lib/active_record/relation/spawn_methods.rb +6 -5
  158. data/lib/active_record/relation/where_clause.rb +104 -57
  159. data/lib/active_record/relation.rb +90 -64
  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 +0 -4
  165. data/lib/active_record/scoping/named.rb +1 -17
  166. data/lib/active_record/secure_token.rb +16 -8
  167. data/lib/active_record/serialization.rb +5 -3
  168. data/lib/active_record/signed_id.rb +116 -0
  169. data/lib/active_record/statement_cache.rb +20 -4
  170. data/lib/active_record/store.rb +2 -2
  171. data/lib/active_record/suppressor.rb +2 -2
  172. data/lib/active_record/table_metadata.rb +36 -52
  173. data/lib/active_record/tasks/database_tasks.rb +139 -113
  174. data/lib/active_record/tasks/mysql_database_tasks.rb +34 -35
  175. data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -26
  176. data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -9
  177. data/lib/active_record/test_databases.rb +5 -4
  178. data/lib/active_record/test_fixtures.rb +36 -33
  179. data/lib/active_record/timestamp.rb +4 -6
  180. data/lib/active_record/touch_later.rb +21 -21
  181. data/lib/active_record/transactions.rb +15 -64
  182. data/lib/active_record/type/serialized.rb +6 -2
  183. data/lib/active_record/type.rb +8 -1
  184. data/lib/active_record/type_caster/connection.rb +0 -1
  185. data/lib/active_record/type_caster/map.rb +8 -5
  186. data/lib/active_record/validations/associated.rb +1 -1
  187. data/lib/active_record/validations/numericality.rb +35 -0
  188. data/lib/active_record/validations/uniqueness.rb +24 -4
  189. data/lib/active_record/validations.rb +1 -0
  190. data/lib/active_record.rb +7 -14
  191. data/lib/arel/attributes/attribute.rb +4 -0
  192. data/lib/arel/collectors/bind.rb +5 -0
  193. data/lib/arel/collectors/composite.rb +8 -0
  194. data/lib/arel/collectors/sql_string.rb +7 -0
  195. data/lib/arel/collectors/substitute_binds.rb +7 -0
  196. data/lib/arel/nodes/binary.rb +82 -8
  197. data/lib/arel/nodes/bind_param.rb +8 -0
  198. data/lib/arel/nodes/casted.rb +21 -9
  199. data/lib/arel/nodes/equality.rb +6 -9
  200. data/lib/arel/nodes/grouping.rb +3 -0
  201. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  202. data/lib/arel/nodes/in.rb +8 -1
  203. data/lib/arel/nodes/infix_operation.rb +13 -1
  204. data/lib/arel/nodes/join_source.rb +1 -1
  205. data/lib/arel/nodes/node.rb +7 -6
  206. data/lib/arel/nodes/ordering.rb +27 -0
  207. data/lib/arel/nodes/sql_literal.rb +3 -0
  208. data/lib/arel/nodes/table_alias.rb +7 -3
  209. data/lib/arel/nodes/unary.rb +0 -1
  210. data/lib/arel/nodes.rb +3 -1
  211. data/lib/arel/predications.rb +12 -18
  212. data/lib/arel/select_manager.rb +1 -2
  213. data/lib/arel/table.rb +13 -5
  214. data/lib/arel/visitors/dot.rb +14 -2
  215. data/lib/arel/visitors/mysql.rb +11 -1
  216. data/lib/arel/visitors/postgresql.rb +15 -4
  217. data/lib/arel/visitors/to_sql.rb +89 -78
  218. data/lib/arel/visitors.rb +0 -7
  219. data/lib/arel.rb +5 -13
  220. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  221. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
  222. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +3 -3
  223. data/lib/rails/generators/active_record/migration.rb +6 -1
  224. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  225. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  226. metadata +30 -32
  227. data/lib/active_record/advisory_lock_base.rb +0 -18
  228. data/lib/active_record/attribute_decorators.rb +0 -88
  229. data/lib/active_record/connection_adapters/connection_specification.rb +0 -296
  230. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  231. data/lib/active_record/define_callbacks.rb +0 -22
  232. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  233. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  234. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  235. data/lib/arel/attributes.rb +0 -22
  236. data/lib/arel/visitors/depth_first.rb +0 -203
  237. data/lib/arel/visitors/ibm_db.rb +0 -34
  238. data/lib/arel/visitors/informix.rb +0 -62
  239. data/lib/arel/visitors/mssql.rb +0 -156
  240. data/lib/arel/visitors/oracle.rb +0 -158
  241. data/lib/arel/visitors/oracle12.rb +0 -65
  242. data/lib/arel/visitors/where_sql.rb +0 -22
@@ -14,29 +14,32 @@ module ActiveRecord
14
14
  sql
15
15
  end
16
16
 
17
- def to_sql_and_binds(arel_or_sql_string, binds = []) # :nodoc:
17
+ def to_sql_and_binds(arel_or_sql_string, binds = [], preparable = nil) # :nodoc:
18
18
  if arel_or_sql_string.respond_to?(:ast)
19
19
  unless binds.empty?
20
20
  raise "Passing bind parameters with an arel AST is forbidden. " \
21
21
  "The values must be stored on the AST directly"
22
22
  end
23
23
 
24
+ collector = collector()
25
+
24
26
  if prepared_statements
27
+ collector.preparable = true
25
28
  sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
26
29
 
27
30
  if binds.length > bind_params_length
28
31
  unprepared_statement do
29
- sql, binds = to_sql_and_binds(arel_or_sql_string)
30
- visitor.preparable = false
32
+ return to_sql_and_binds(arel_or_sql_string)
31
33
  end
32
34
  end
35
+ preparable = collector.preparable
33
36
  else
34
37
  sql = visitor.compile(arel_or_sql_string.ast, collector)
35
38
  end
36
- [sql.freeze, binds]
39
+ [sql.freeze, binds, preparable]
37
40
  else
38
- visitor.preparable = false if prepared_statements
39
- [arel_or_sql_string.dup.freeze, binds]
41
+ arel_or_sql_string = arel_or_sql_string.dup.freeze unless arel_or_sql_string.frozen?
42
+ [arel_or_sql_string, binds, preparable]
40
43
  end
41
44
  end
42
45
  private :to_sql_and_binds
@@ -58,17 +61,15 @@ module ActiveRecord
58
61
  # Returns an ActiveRecord::Result instance.
59
62
  def select_all(arel, name = nil, binds = [], preparable: nil)
60
63
  arel = arel_from_relation(arel)
61
- sql, binds = to_sql_and_binds(arel, binds)
62
-
63
- if preparable.nil?
64
- preparable = prepared_statements ? visitor.preparable : false
65
- end
64
+ sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
66
65
 
67
66
  if prepared_statements && preparable
68
67
  select_prepared(sql, name, binds)
69
68
  else
70
69
  select(sql, name, binds)
71
70
  end
71
+ rescue ::RangeError
72
+ ActiveRecord::Result.new([], [])
72
73
  end
73
74
 
74
75
  # Returns a record hash with the column names as keys and column values
@@ -153,6 +154,10 @@ module ActiveRecord
153
154
  exec_query(sql, name)
154
155
  end
155
156
 
157
+ def explain(arel, binds = []) # :nodoc:
158
+ raise NotImplementedError
159
+ end
160
+
156
161
  # Executes an INSERT query and returns the new record's ID
157
162
  #
158
163
  # +id_value+ will be returned unless the value is +nil+, in
@@ -186,6 +191,8 @@ module ActiveRecord
186
191
  end
187
192
 
188
193
  def truncate_tables(*table_names) # :nodoc:
194
+ table_names -= [schema_migration.table_name, InternalMetadata.table_name]
195
+
189
196
  return if table_names.empty?
190
197
 
191
198
  with_multi_statements do
@@ -201,15 +208,30 @@ module ActiveRecord
201
208
  #
202
209
  # == Nested transactions support
203
210
  #
211
+ # #transaction calls can be nested. By default, this makes all database
212
+ # statements in the nested transaction block become part of the parent
213
+ # transaction. For example, the following behavior may be surprising:
214
+ #
215
+ # ActiveRecord::Base.transaction do
216
+ # Post.create(title: 'first')
217
+ # ActiveRecord::Base.transaction do
218
+ # Post.create(title: 'second')
219
+ # raise ActiveRecord::Rollback
220
+ # end
221
+ # end
222
+ #
223
+ # This creates both "first" and "second" posts. Reason is the
224
+ # ActiveRecord::Rollback exception in the nested block does not issue a
225
+ # ROLLBACK. Since these exceptions are captured in transaction blocks,
226
+ # the parent block does not see it and the real transaction is committed.
227
+ #
204
228
  # Most databases don't support true nested transactions. At the time of
205
229
  # writing, the only database that supports true nested transactions that
206
230
  # we're aware of, is MS-SQL.
207
231
  #
208
232
  # In order to get around this problem, #transaction will emulate the effect
209
233
  # of nested transactions, by using savepoints:
210
- # https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
211
- # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
212
- # supports savepoints.
234
+ # https://dev.mysql.com/doc/refman/en/savepoint.html.
213
235
  #
214
236
  # It is safe to call this method if a database transaction is already open,
215
237
  # i.e. if #transaction is called within another #transaction block. In case
@@ -221,6 +243,24 @@ module ActiveRecord
221
243
  # - However, if +:requires_new+ is set, the block will be wrapped in a
222
244
  # database savepoint acting as a sub-transaction.
223
245
  #
246
+ # In order to get a ROLLBACK for the nested transaction you may ask for a
247
+ # real sub-transaction by passing <tt>requires_new: true</tt>.
248
+ # If anything goes wrong, the database rolls back to the beginning of
249
+ # the sub-transaction without rolling back the parent transaction.
250
+ # If we add it to the previous example:
251
+ #
252
+ # ActiveRecord::Base.transaction do
253
+ # Post.create(title: 'first')
254
+ # ActiveRecord::Base.transaction(requires_new: true) do
255
+ # Post.create(title: 'second')
256
+ # raise ActiveRecord::Rollback
257
+ # end
258
+ # end
259
+ #
260
+ # only post with title "first" is created.
261
+ #
262
+ # See ActiveRecord::Transactions to learn more.
263
+ #
224
264
  # === Caveats
225
265
  #
226
266
  # MySQL doesn't support DDL transactions. If you perform a DDL operation,
@@ -260,7 +300,7 @@ module ActiveRecord
260
300
  # semantics of these different levels:
261
301
  #
262
302
  # * https://www.postgresql.org/docs/current/static/transaction-iso.html
263
- # * https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html
303
+ # * https://dev.mysql.com/doc/refman/en/set-transaction.html
264
304
  #
265
305
  # An ActiveRecord::TransactionIsolationError will be raised if:
266
306
  #
@@ -289,6 +329,13 @@ module ActiveRecord
289
329
  :commit_transaction, :rollback_transaction, :materialize_transactions,
290
330
  :disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
291
331
 
332
+ def mark_transaction_written_if_write(sql) # :nodoc:
333
+ transaction = current_transaction
334
+ if transaction.open?
335
+ transaction.written ||= write_query?(sql)
336
+ end
337
+ end
338
+
292
339
  def transaction_open?
293
340
  current_transaction.open?
294
341
  end
@@ -299,12 +346,8 @@ module ActiveRecord
299
346
 
300
347
  # Register a record with the current transaction so that its after_commit and after_rollback callbacks
301
348
  # can be called.
302
- def add_transaction_record(record)
303
- current_transaction.add_record(record)
304
- end
305
-
306
- def transaction_state
307
- current_transaction.state
349
+ def add_transaction_record(record, ensure_finalize = true)
350
+ current_transaction.add_record(record, ensure_finalize)
308
351
  end
309
352
 
310
353
  # Begins the transaction (and turns off auto-committing).
@@ -351,7 +394,7 @@ module ActiveRecord
351
394
  end
352
395
 
353
396
  # Inserts the given fixture into the table. Overridden in adapters that require
354
- # something beyond a simple insert (eg. Oracle).
397
+ # something beyond a simple insert (e.g. Oracle).
355
398
  # Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
356
399
  # We keep this method to provide fallback
357
400
  # for databases like sqlite that do not support bulk inserts.
@@ -18,7 +18,7 @@ module ActiveRecord
18
18
  method_names.each do |method_name|
19
19
  base.class_eval <<-end_code, __FILE__, __LINE__ + 1
20
20
  def #{method_name}(*)
21
- ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
21
+ ActiveRecord::Base.clear_query_caches_for_current_thread
22
22
  super
23
23
  end
24
24
  end_code
@@ -96,11 +96,7 @@ module ActiveRecord
96
96
  def select_all(arel, name = nil, binds = [], preparable: nil)
97
97
  if @query_cache_enabled && !locked?(arel)
98
98
  arel = arel_from_relation(arel)
99
- sql, binds = to_sql_and_binds(arel, binds)
100
-
101
- if preparable.nil?
102
- preparable = prepared_statements ? visitor.preparable : false
103
- end
99
+ sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
104
100
 
105
101
  cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
106
102
  else
@@ -133,7 +129,6 @@ module ActiveRecord
133
129
  binds: binds,
134
130
  type_casted_binds: -> { type_casted_binds(binds) },
135
131
  name: name,
136
- connection_id: object_id,
137
132
  connection: self,
138
133
  cached: true
139
134
  }
@@ -9,10 +9,12 @@ module ActiveRecord
9
9
  # Quotes the column value to help prevent
10
10
  # {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
11
11
  def quote(value)
12
- value = id_value_for_database(value) if value.is_a?(Base)
13
-
14
- if value.respond_to?(:value_for_database)
15
- value = value.value_for_database
12
+ if value.is_a?(Base)
13
+ ActiveSupport::Deprecation.warn(<<~MSG)
14
+ Passing an Active Record object to `quote` directly is deprecated
15
+ and will be no longer quoted as id value in Rails 6.2.
16
+ MSG
17
+ value = value.id_for_database
16
18
  end
17
19
 
18
20
  _quote(value)
@@ -22,16 +24,23 @@ module ActiveRecord
22
24
  # SQLite does not understand dates, so this method will convert a Date
23
25
  # to a String.
24
26
  def type_cast(value, column = nil)
25
- value = id_value_for_database(value) if value.is_a?(Base)
27
+ if value.is_a?(Base)
28
+ ActiveSupport::Deprecation.warn(<<~MSG)
29
+ Passing an Active Record object to `type_cast` directly is deprecated
30
+ and will be no longer type casted as id value in Rails 6.2.
31
+ MSG
32
+ value = value.id_for_database
33
+ end
26
34
 
27
35
  if column
28
- value = type_cast_from_column(column, value)
36
+ ActiveSupport::Deprecation.warn(<<~MSG)
37
+ Passing a column to `type_cast` is deprecated and will be removed in Rails 6.2.
38
+ MSG
39
+ type = lookup_cast_type_from_column(column)
40
+ value = type.serialize(value)
29
41
  end
30
42
 
31
43
  _type_cast(value)
32
- rescue TypeError
33
- to_type = column ? " to #{column.type}" : ""
34
- raise TypeError, "can't cast #{value.class}#{to_type}"
35
44
  end
36
45
 
37
46
  # If you are having to call this function, you are likely doing something
@@ -43,16 +52,6 @@ module ActiveRecord
43
52
  # represent the type doesn't sufficiently reflect the differences
44
53
  # (varchar vs binary) for example. The type used to get this primitive
45
54
  # should have been provided before reaching the connection adapter.
46
- def type_cast_from_column(column, value) # :nodoc:
47
- if column
48
- type = lookup_cast_type_from_column(column)
49
- type.serialize(value)
50
- else
51
- value
52
- end
53
- end
54
-
55
- # See docs for #type_cast_from_column
56
55
  def lookup_cast_type_from_column(column) # :nodoc:
57
56
  lookup_cast_type(column.sql_type)
58
57
  end
@@ -114,16 +113,16 @@ module ActiveRecord
114
113
  # if the value is a Time responding to usec.
115
114
  def quoted_date(value)
116
115
  if value.acts_like?(:time)
117
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
118
-
119
- if value.respond_to?(zone_conversion_method)
120
- value = value.send(zone_conversion_method)
116
+ if ActiveRecord::Base.default_timezone == :utc
117
+ value = value.getutc if value.respond_to?(:getutc) && !value.utc?
118
+ else
119
+ value = value.getlocal if value.respond_to?(:getlocal)
121
120
  end
122
121
  end
123
122
 
124
123
  result = value.to_s(:db)
125
124
  if value.respond_to?(:usec) && value.usec > 0
126
- "#{result}.#{sprintf("%06d", value.usec)}"
125
+ result << "." << sprintf("%06d", value.usec)
127
126
  else
128
127
  result
129
128
  end
@@ -139,16 +138,7 @@ module ActiveRecord
139
138
  end
140
139
 
141
140
  def sanitize_as_sql_comment(value) # :nodoc:
142
- # Sanitize a string to appear within a SQL comment
143
- # For compatibility, this also surrounding "/*+", "/*", and "*/"
144
- # charcacters, possibly with single surrounding space.
145
- # Then follows that by replacing any internal "*/" or "/ *" with
146
- # "* /" or "/ *"
147
- comment = value.to_s.dup
148
- comment.gsub!(%r{\A\s*/\*\+?\s?|\s?\*/\s*\Z}, "")
149
- comment.gsub!("*/", "* /")
150
- comment.gsub!("/*", "/ *")
151
- comment
141
+ value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
152
142
  end
153
143
 
154
144
  def column_name_matcher # :nodoc:
@@ -171,7 +161,7 @@ module ActiveRecord
171
161
  # table_name.column_name | function(one or no argument)
172
162
  ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
173
163
  )
174
- (?:\s+AS\s+\w+)?
164
+ (?:(?:\s+AS)?\s+\w+)?
175
165
  )
176
166
  (?:\s*,\s*\g<1>)*
177
167
  \z
@@ -206,10 +196,17 @@ module ActiveRecord
206
196
 
207
197
  private
208
198
  def type_casted_binds(binds)
209
- if binds.first.is_a?(Array)
199
+ case binds.first
200
+ when Array
210
201
  binds.map { |column, value| type_cast(value, column) }
211
202
  else
212
- binds.map { |attr| type_cast(attr.value_for_database) }
203
+ binds.map do |value|
204
+ if ActiveModel::Attribute === value
205
+ type_cast(value.value_for_database)
206
+ else
207
+ type_cast(value)
208
+ end
209
+ end
213
210
  end
214
211
  end
215
212
 
@@ -217,12 +214,6 @@ module ActiveRecord
217
214
  type_map.lookup(sql_type)
218
215
  end
219
216
 
220
- def id_value_for_database(value)
221
- if primary_key = value.class.primary_key
222
- value.instance_variable_get(:@attributes)[primary_key].value_for_database
223
- end
224
- end
225
-
226
217
  def _quote(value)
227
218
  case value
228
219
  when String, Symbol, ActiveSupport::Multibyte::Chars
@@ -252,7 +243,7 @@ module ActiveRecord
252
243
  when nil, Numeric, String then value
253
244
  when Type::Time::Value then quoted_time(value)
254
245
  when Date, Time then quoted_date(value)
255
- else raise TypeError
246
+ else raise TypeError, "can't cast #{value.class.name}"
256
247
  end
257
248
  end
258
249
  end
@@ -8,15 +8,15 @@ module ActiveRecord
8
8
  end
9
9
 
10
10
  def create_savepoint(name = current_savepoint_name)
11
- execute("SAVEPOINT #{name}")
11
+ execute("SAVEPOINT #{name}", "TRANSACTION")
12
12
  end
13
13
 
14
14
  def exec_rollback_to_savepoint(name = current_savepoint_name)
15
- execute("ROLLBACK TO SAVEPOINT #{name}")
15
+ execute("ROLLBACK TO SAVEPOINT #{name}", "TRANSACTION")
16
16
  end
17
17
 
18
18
  def release_savepoint(name = current_savepoint_name)
19
- execute("RELEASE SAVEPOINT #{name}")
19
+ execute("RELEASE SAVEPOINT #{name}", "TRANSACTION")
20
20
  end
21
21
  end
22
22
  end