activerecord 6.0.5.1 → 6.1.7.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1163 -774
  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 +16 -6
  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 +44 -35
  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 +265 -64
  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 +61 -59
  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 +324 -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 +24 -25
  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
@@ -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,8 +394,8 @@ 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).
355
- # Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
397
+ # something beyond a simple insert (e.g. Oracle).
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.
358
401
  def insert_fixture(fixture, table_name)
@@ -7,7 +7,7 @@ module ActiveRecord
7
7
  module QueryCache
8
8
  class << self
9
9
  def included(base) #:nodoc:
10
- dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
10
+ dirties_query_cache base, :create, :insert, :update, :delete, :truncate, :truncate_tables,
11
11
  :rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
12
12
 
13
13
  base.set_callback :checkout, :after, :configure_query_cache!
@@ -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 7.0.
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 7.0.
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 7.0.
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,7 +138,16 @@ module ActiveRecord
139
138
  end
140
139
 
141
140
  def sanitize_as_sql_comment(value) # :nodoc:
142
- value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
141
+ # Sanitize a string to appear within a SQL comment
142
+ # For compatibility, this also surrounding "/*+", "/*", and "*/"
143
+ # charcacters, possibly with single surrounding space.
144
+ # Then follows that by replacing any internal "*/" or "/ *" with
145
+ # "* /" or "/ *"
146
+ comment = value.to_s.dup
147
+ comment.gsub!(%r{\A\s*/\*\+?\s?|\s?\*/\s*\Z}, "")
148
+ comment.gsub!("*/", "* /")
149
+ comment.gsub!("/*", "/ *")
150
+ comment
143
151
  end
144
152
 
145
153
  def column_name_matcher # :nodoc:
@@ -162,7 +170,7 @@ module ActiveRecord
162
170
  # table_name.column_name | function(one or no argument)
163
171
  ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
164
172
  )
165
- (?:\s+AS\s+\w+)?
173
+ (?:(?:\s+AS)?\s+\w+)?
166
174
  )
167
175
  (?:\s*,\s*\g<1>)*
168
176
  \z
@@ -197,10 +205,17 @@ module ActiveRecord
197
205
 
198
206
  private
199
207
  def type_casted_binds(binds)
200
- if binds.first.is_a?(Array)
208
+ case binds.first
209
+ when Array
201
210
  binds.map { |column, value| type_cast(value, column) }
202
211
  else
203
- binds.map { |attr| type_cast(attr.value_for_database) }
212
+ binds.map do |value|
213
+ if ActiveModel::Attribute === value
214
+ type_cast(value.value_for_database)
215
+ else
216
+ type_cast(value)
217
+ end
218
+ end
204
219
  end
205
220
  end
206
221
 
@@ -208,12 +223,6 @@ module ActiveRecord
208
223
  type_map.lookup(sql_type)
209
224
  end
210
225
 
211
- def id_value_for_database(value)
212
- if primary_key = value.class.primary_key
213
- value.instance_variable_get(:@attributes)[primary_key].value_for_database
214
- end
215
- end
216
-
217
226
  def _quote(value)
218
227
  case value
219
228
  when String, Symbol, ActiveSupport::Multibyte::Chars
@@ -243,7 +252,7 @@ module ActiveRecord
243
252
  when nil, Numeric, String then value
244
253
  when Type::Time::Value then quoted_time(value)
245
254
  when Date, Time then quoted_date(value)
246
- else raise TypeError
255
+ else raise TypeError, "can't cast #{value.class.name}"
247
256
  end
248
257
  end
249
258
  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