activerecord 5.2.8.1 → 6.0.0.beta1

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 +299 -816
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +1 -1
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +4 -2
  7. data/lib/active_record/associations/association.rb +35 -19
  8. data/lib/active_record/associations/association_scope.rb +4 -6
  9. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  11. data/lib/active_record/associations/builder/belongs_to.rb +14 -50
  12. data/lib/active_record/associations/builder/collection_association.rb +3 -3
  13. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
  14. data/lib/active_record/associations/collection_association.rb +11 -25
  15. data/lib/active_record/associations/collection_proxy.rb +32 -6
  16. data/lib/active_record/associations/foreign_association.rb +7 -0
  17. data/lib/active_record/associations/has_many_association.rb +1 -1
  18. data/lib/active_record/associations/has_many_through_association.rb +25 -18
  19. data/lib/active_record/associations/has_one_association.rb +28 -30
  20. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  21. data/lib/active_record/associations/join_dependency/join_association.rb +11 -26
  22. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  23. data/lib/active_record/associations/join_dependency.rb +15 -20
  24. data/lib/active_record/associations/preloader/association.rb +1 -2
  25. data/lib/active_record/associations/preloader.rb +32 -29
  26. data/lib/active_record/associations/singular_association.rb +2 -16
  27. data/lib/active_record/associations.rb +16 -12
  28. data/lib/active_record/attribute_assignment.rb +7 -10
  29. data/lib/active_record/attribute_methods/dirty.rb +64 -26
  30. data/lib/active_record/attribute_methods/primary_key.rb +8 -7
  31. data/lib/active_record/attribute_methods/read.rb +16 -48
  32. data/lib/active_record/attribute_methods/serialization.rb +1 -1
  33. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  34. data/lib/active_record/attribute_methods/write.rb +15 -16
  35. data/lib/active_record/attribute_methods.rb +34 -56
  36. data/lib/active_record/autosave_association.rb +7 -21
  37. data/lib/active_record/base.rb +2 -2
  38. data/lib/active_record/callbacks.rb +3 -17
  39. data/lib/active_record/coders/yaml_column.rb +1 -13
  40. data/lib/active_record/collection_cache_key.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +13 -36
  42. data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
  43. data/lib/active_record/connection_adapters/abstract/database_statements.rb +25 -84
  44. data/lib/active_record/connection_adapters/abstract/query_cache.rb +17 -14
  45. data/lib/active_record/connection_adapters/abstract/quoting.rb +5 -11
  46. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -11
  47. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +30 -13
  48. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +0 -2
  49. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +41 -27
  50. data/lib/active_record/connection_adapters/abstract/transaction.rb +81 -52
  51. data/lib/active_record/connection_adapters/abstract_adapter.rb +95 -31
  52. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -90
  53. data/lib/active_record/connection_adapters/connection_specification.rb +52 -42
  54. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +5 -9
  55. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -7
  56. data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
  57. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
  58. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +65 -10
  59. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -4
  60. data/lib/active_record/connection_adapters/postgresql/column.rb +1 -2
  61. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +16 -1
  62. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  63. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  64. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
  65. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
  66. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  67. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
  68. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  69. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  70. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +11 -36
  71. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +9 -2
  72. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +38 -20
  73. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -1
  74. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -56
  75. data/lib/active_record/connection_adapters/schema_cache.rb +5 -0
  76. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +5 -5
  77. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +14 -9
  78. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +95 -62
  79. data/lib/active_record/connection_handling.rb +132 -26
  80. data/lib/active_record/core.rb +75 -52
  81. data/lib/active_record/counter_cache.rb +4 -29
  82. data/lib/active_record/database_configurations/database_config.rb +37 -0
  83. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  84. data/lib/active_record/database_configurations/url_config.rb +74 -0
  85. data/lib/active_record/database_configurations.rb +184 -0
  86. data/lib/active_record/enum.rb +22 -7
  87. data/lib/active_record/errors.rb +24 -21
  88. data/lib/active_record/explain.rb +1 -1
  89. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  90. data/lib/active_record/fixture_set/render_context.rb +17 -0
  91. data/lib/active_record/fixture_set/table_row.rb +153 -0
  92. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  93. data/lib/active_record/fixtures.rb +140 -472
  94. data/lib/active_record/gem_version.rb +4 -4
  95. data/lib/active_record/inheritance.rb +12 -2
  96. data/lib/active_record/integration.rb +56 -16
  97. data/lib/active_record/internal_metadata.rb +5 -1
  98. data/lib/active_record/locking/optimistic.rb +2 -2
  99. data/lib/active_record/locking/pessimistic.rb +3 -3
  100. data/lib/active_record/log_subscriber.rb +7 -26
  101. data/lib/active_record/migration/command_recorder.rb +35 -5
  102. data/lib/active_record/migration/compatibility.rb +34 -16
  103. data/lib/active_record/migration.rb +38 -37
  104. data/lib/active_record/model_schema.rb +30 -9
  105. data/lib/active_record/nested_attributes.rb +2 -2
  106. data/lib/active_record/no_touching.rb +7 -0
  107. data/lib/active_record/persistence.rb +18 -7
  108. data/lib/active_record/query_cache.rb +11 -4
  109. data/lib/active_record/querying.rb +19 -11
  110. data/lib/active_record/railtie.rb +71 -60
  111. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  112. data/lib/active_record/railties/controller_runtime.rb +30 -35
  113. data/lib/active_record/railties/databases.rake +94 -43
  114. data/lib/active_record/reflection.rb +60 -44
  115. data/lib/active_record/relation/batches.rb +13 -10
  116. data/lib/active_record/relation/calculations.rb +38 -28
  117. data/lib/active_record/relation/delegation.rb +4 -13
  118. data/lib/active_record/relation/finder_methods.rb +12 -25
  119. data/lib/active_record/relation/merger.rb +2 -6
  120. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  121. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  122. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  123. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  124. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  125. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  126. data/lib/active_record/relation/predicate_builder.rb +4 -6
  127. data/lib/active_record/relation/query_attribute.rb +15 -12
  128. data/lib/active_record/relation/query_methods.rb +29 -52
  129. data/lib/active_record/relation/where_clause.rb +4 -0
  130. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  131. data/lib/active_record/relation.rb +150 -69
  132. data/lib/active_record/result.rb +30 -11
  133. data/lib/active_record/sanitization.rb +2 -39
  134. data/lib/active_record/schema.rb +1 -10
  135. data/lib/active_record/schema_dumper.rb +12 -6
  136. data/lib/active_record/schema_migration.rb +4 -0
  137. data/lib/active_record/scoping/default.rb +10 -3
  138. data/lib/active_record/scoping/named.rb +10 -14
  139. data/lib/active_record/scoping.rb +9 -8
  140. data/lib/active_record/statement_cache.rb +32 -5
  141. data/lib/active_record/store.rb +39 -8
  142. data/lib/active_record/table_metadata.rb +1 -4
  143. data/lib/active_record/tasks/database_tasks.rb +89 -23
  144. data/lib/active_record/tasks/mysql_database_tasks.rb +2 -4
  145. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
  146. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
  147. data/lib/active_record/test_databases.rb +38 -0
  148. data/lib/active_record/test_fixtures.rb +224 -0
  149. data/lib/active_record/timestamp.rb +4 -6
  150. data/lib/active_record/transactions.rb +3 -22
  151. data/lib/active_record/translation.rb +1 -1
  152. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  153. data/lib/active_record/type.rb +3 -4
  154. data/lib/active_record/type_caster/connection.rb +1 -6
  155. data/lib/active_record/type_caster/map.rb +1 -4
  156. data/lib/active_record/validations/uniqueness.rb +13 -25
  157. data/lib/active_record.rb +2 -1
  158. data/lib/arel/alias_predication.rb +9 -0
  159. data/lib/arel/attributes/attribute.rb +37 -0
  160. data/lib/arel/attributes.rb +22 -0
  161. data/lib/arel/collectors/bind.rb +24 -0
  162. data/lib/arel/collectors/composite.rb +31 -0
  163. data/lib/arel/collectors/plain_string.rb +20 -0
  164. data/lib/arel/collectors/sql_string.rb +20 -0
  165. data/lib/arel/collectors/substitute_binds.rb +28 -0
  166. data/lib/arel/crud.rb +42 -0
  167. data/lib/arel/delete_manager.rb +18 -0
  168. data/lib/arel/errors.rb +9 -0
  169. data/lib/arel/expressions.rb +29 -0
  170. data/lib/arel/factory_methods.rb +49 -0
  171. data/lib/arel/insert_manager.rb +49 -0
  172. data/lib/arel/math.rb +45 -0
  173. data/lib/arel/nodes/and.rb +32 -0
  174. data/lib/arel/nodes/ascending.rb +23 -0
  175. data/lib/arel/nodes/binary.rb +52 -0
  176. data/lib/arel/nodes/bind_param.rb +36 -0
  177. data/lib/arel/nodes/case.rb +55 -0
  178. data/lib/arel/nodes/casted.rb +50 -0
  179. data/lib/arel/nodes/count.rb +12 -0
  180. data/lib/arel/nodes/delete_statement.rb +45 -0
  181. data/lib/arel/nodes/descending.rb +23 -0
  182. data/lib/arel/nodes/equality.rb +18 -0
  183. data/lib/arel/nodes/extract.rb +24 -0
  184. data/lib/arel/nodes/false.rb +16 -0
  185. data/lib/arel/nodes/full_outer_join.rb +8 -0
  186. data/lib/arel/nodes/function.rb +44 -0
  187. data/lib/arel/nodes/grouping.rb +8 -0
  188. data/lib/arel/nodes/in.rb +8 -0
  189. data/lib/arel/nodes/infix_operation.rb +80 -0
  190. data/lib/arel/nodes/inner_join.rb +8 -0
  191. data/lib/arel/nodes/insert_statement.rb +37 -0
  192. data/lib/arel/nodes/join_source.rb +20 -0
  193. data/lib/arel/nodes/matches.rb +18 -0
  194. data/lib/arel/nodes/named_function.rb +23 -0
  195. data/lib/arel/nodes/node.rb +50 -0
  196. data/lib/arel/nodes/node_expression.rb +13 -0
  197. data/lib/arel/nodes/outer_join.rb +8 -0
  198. data/lib/arel/nodes/over.rb +15 -0
  199. data/lib/arel/nodes/regexp.rb +16 -0
  200. data/lib/arel/nodes/right_outer_join.rb +8 -0
  201. data/lib/arel/nodes/select_core.rb +63 -0
  202. data/lib/arel/nodes/select_statement.rb +41 -0
  203. data/lib/arel/nodes/sql_literal.rb +16 -0
  204. data/lib/arel/nodes/string_join.rb +11 -0
  205. data/lib/arel/nodes/table_alias.rb +27 -0
  206. data/lib/arel/nodes/terminal.rb +16 -0
  207. data/lib/arel/nodes/true.rb +16 -0
  208. data/lib/arel/nodes/unary.rb +44 -0
  209. data/lib/arel/nodes/unary_operation.rb +20 -0
  210. data/lib/arel/nodes/unqualified_column.rb +22 -0
  211. data/lib/arel/nodes/update_statement.rb +41 -0
  212. data/lib/arel/nodes/values.rb +16 -0
  213. data/lib/arel/nodes/values_list.rb +24 -0
  214. data/lib/arel/nodes/window.rb +126 -0
  215. data/lib/arel/nodes/with.rb +11 -0
  216. data/lib/arel/nodes.rb +67 -0
  217. data/lib/arel/order_predications.rb +13 -0
  218. data/lib/arel/predications.rb +257 -0
  219. data/lib/arel/select_manager.rb +271 -0
  220. data/lib/arel/table.rb +110 -0
  221. data/lib/arel/tree_manager.rb +72 -0
  222. data/lib/arel/update_manager.rb +34 -0
  223. data/lib/arel/visitors/depth_first.rb +199 -0
  224. data/lib/arel/visitors/dot.rb +292 -0
  225. data/lib/arel/visitors/ibm_db.rb +21 -0
  226. data/lib/arel/visitors/informix.rb +56 -0
  227. data/lib/arel/visitors/mssql.rb +143 -0
  228. data/lib/arel/visitors/mysql.rb +83 -0
  229. data/lib/arel/visitors/oracle.rb +159 -0
  230. data/lib/arel/visitors/oracle12.rb +67 -0
  231. data/lib/arel/visitors/postgresql.rb +116 -0
  232. data/lib/arel/visitors/sqlite.rb +39 -0
  233. data/lib/arel/visitors/to_sql.rb +913 -0
  234. data/lib/arel/visitors/visitor.rb +42 -0
  235. data/lib/arel/visitors/where_sql.rb +23 -0
  236. data/lib/arel/visitors.rb +20 -0
  237. data/lib/arel/window_predications.rb +9 -0
  238. data/lib/arel.rb +44 -0
  239. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  240. data/lib/rails/generators/active_record/migration.rb +14 -1
  241. data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
  242. metadata +107 -29
@@ -9,7 +9,6 @@ require "active_support/core_ext/module/attribute_accessors"
9
9
  require "active_support/core_ext/array/extract_options"
10
10
  require "active_support/core_ext/hash/deep_merge"
11
11
  require "active_support/core_ext/hash/slice"
12
- require "active_support/core_ext/hash/transform_values"
13
12
  require "active_support/core_ext/string/behavior"
14
13
  require "active_support/core_ext/kernel/singleton_class"
15
14
  require "active_support/core_ext/module/introspection"
@@ -23,6 +22,7 @@ require "active_record/explain_subscriber"
23
22
  require "active_record/relation/delegation"
24
23
  require "active_record/attributes"
25
24
  require "active_record/type_caster"
25
+ require "active_record/database_configurations"
26
26
 
27
27
  module ActiveRecord #:nodoc:
28
28
  # = Active Record
@@ -289,6 +289,7 @@ module ActiveRecord #:nodoc:
289
289
  extend Enum
290
290
  extend Delegation::DelegateCache
291
291
  extend CollectionCacheKey
292
+ extend Aggregations::ClassMethods
292
293
 
293
294
  include Core
294
295
  include Persistence
@@ -314,7 +315,6 @@ module ActiveRecord #:nodoc:
314
315
  include ActiveModel::SecurePassword
315
316
  include AutosaveAssociation
316
317
  include NestedAttributes
317
- include Aggregations
318
318
  include Transactions
319
319
  include TouchLater
320
320
  include NoTouching
@@ -75,21 +75,7 @@ module ActiveRecord
75
75
  # end
76
76
  #
77
77
  # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
78
- # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
79
- # where the +before_destroy+ method is overridden:
80
- #
81
- # class Topic < ActiveRecord::Base
82
- # def before_destroy() destroy_author end
83
- # end
84
- #
85
- # class Reply < Topic
86
- # def before_destroy() destroy_readers end
87
- # end
88
- #
89
- # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
90
- # So, use the callback macros when you want to ensure that a certain callback is called for the entire
91
- # hierarchy, and use the regular overwritable methods when you want to leave it up to each descendant
92
- # to decide whether they want to call +super+ and trigger the inherited callbacks.
78
+ # run, both +destroy_author+ and +destroy_readers+ are called.
93
79
  #
94
80
  # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
95
81
  # callbacks before specifying the associations. Otherwise, you might trigger the loading of a
@@ -109,7 +95,7 @@ module ActiveRecord
109
95
  #
110
96
  # private
111
97
  # def delete_parents
112
- # self.class.delete_all "parent_id = #{id}"
98
+ # self.class.where(parent_id: id).delete_all
113
99
  # end
114
100
  # end
115
101
  #
@@ -142,7 +128,7 @@ module ActiveRecord
142
128
  # end
143
129
  # end
144
130
  #
145
- # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
131
+ # So you specify the object you want to be messaged on a given callback. When that callback is triggered, the object has
146
132
  # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
147
133
  # initialization data such as the name of the attribute to work with:
148
134
  #
@@ -23,7 +23,7 @@ module ActiveRecord
23
23
  def load(yaml)
24
24
  return object_class.new if object_class != Object && yaml.nil?
25
25
  return yaml unless yaml.is_a?(String) && /^---/.match?(yaml)
26
- obj = yaml_load(yaml)
26
+ obj = YAML.load(yaml)
27
27
 
28
28
  assert_valid_value(obj, action: "load")
29
29
  obj ||= object_class.new if object_class != Object
@@ -45,18 +45,6 @@ module ActiveRecord
45
45
  rescue ArgumentError
46
46
  raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor."
47
47
  end
48
-
49
- def yaml_load(payload)
50
- if !ActiveRecord::Base.use_yaml_unsafe_load
51
- YAML.safe_load(payload, permitted_classes: ActiveRecord::Base.yaml_column_permitted_classes, aliases: true)
52
- else
53
- if YAML.respond_to?(:unsafe_load)
54
- YAML.unsafe_load(payload)
55
- else
56
- YAML.load(payload)
57
- end
58
- end
59
- end
60
48
  end
61
49
  end
62
50
  end
@@ -16,7 +16,7 @@ module ActiveRecord
16
16
  collection = collection.send(:apply_join_dependency)
17
17
  end
18
18
  column_type = type_for_attribute(timestamp_column)
19
- column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
19
+ column = connection.visitor.compile(collection.arel_attribute(timestamp_column))
20
20
  select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
21
21
 
22
22
  if collection.has_limit_or_offset?
@@ -310,7 +310,7 @@ module ActiveRecord
310
310
  include QueryCache::ConnectionPoolConfiguration
311
311
 
312
312
  attr_accessor :automatic_reconnect, :checkout_timeout, :schema_cache
313
- attr_reader :spec, :size, :reaper
313
+ attr_reader :spec, :connections, :size, :reaper
314
314
 
315
315
  # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
316
316
  # object which describes database connection information (e.g. adapter,
@@ -379,7 +379,7 @@ module ActiveRecord
379
379
  # #connection can be called any number of times; the connection is
380
380
  # held in a cache keyed by a thread.
381
381
  def connection
382
- @thread_cached_conns[connection_cache_key(current_thread)] ||= checkout
382
+ @thread_cached_conns[connection_cache_key(@lock_thread || Thread.current)] ||= checkout
383
383
  end
384
384
 
385
385
  # Returns true if there is an open connection being used for the current thread.
@@ -388,7 +388,7 @@ module ActiveRecord
388
388
  # #connection or #with_connection methods. Connections obtained through
389
389
  # #checkout will not be detected by #active_connection?
390
390
  def active_connection?
391
- @thread_cached_conns[connection_cache_key(current_thread)]
391
+ @thread_cached_conns[connection_cache_key(Thread.current)]
392
392
  end
393
393
 
394
394
  # Signal that the thread is finished with the current connection.
@@ -423,21 +423,6 @@ module ActiveRecord
423
423
  synchronize { @connections.any? }
424
424
  end
425
425
 
426
- # Returns an array containing the connections currently in the pool.
427
- # Access to the array does not require synchronization on the pool because
428
- # the array is newly created and not retained by the pool.
429
- #
430
- # However; this method bypasses the ConnectionPool's thread-safe connection
431
- # access pattern. A returned connection may be owned by another thread,
432
- # unowned, or by happen-stance owned by the calling thread.
433
- #
434
- # Calling methods on a connection without ownership is subject to the
435
- # thread-safety guarantees of the underlying method. Many of the methods
436
- # on connection adapter classes are inherently multi-thread unsafe.
437
- def connections
438
- synchronize { @connections.dup }
439
- end
440
-
441
426
  # Disconnects all connections in the pool, and clears the pool.
442
427
  #
443
428
  # Raises:
@@ -683,10 +668,6 @@ module ActiveRecord
683
668
  thread
684
669
  end
685
670
 
686
- def current_thread
687
- @lock_thread || Thread.current
688
- end
689
-
690
671
  # Take control of all existing connections so a "group" action such as
691
672
  # reload/disconnect can be performed safely. It is no longer enough to
692
673
  # wrap it in +synchronize+ because some pool's actions are allowed
@@ -750,7 +731,7 @@ module ActiveRecord
750
731
  # this block can't be easily moved into attempt_to_checkout_all_existing_connections's
751
732
  # rescue block, because doing so would put it outside of synchronize section, without
752
733
  # being in a critical section thread_report might become inaccurate
753
- msg = "could not obtain ownership of all database connections in #{checkout_timeout} seconds".dup
734
+ msg = +"could not obtain ownership of all database connections in #{checkout_timeout} seconds"
754
735
 
755
736
  thread_report = []
756
737
  @connections.each do |conn|
@@ -934,16 +915,6 @@ module ActiveRecord
934
915
  # about the model. The model needs to pass a specification name to the handler,
935
916
  # in order to look up the correct connection pool.
936
917
  class ConnectionHandler
937
- def self.create_owner_to_pool # :nodoc:
938
- Concurrent::Map.new(initial_capacity: 2) do |h, k|
939
- # Discard the parent's connection pools immediately; we have no need
940
- # of them
941
- discard_unowned_pools(h)
942
-
943
- h[k] = Concurrent::Map.new(initial_capacity: 2)
944
- end
945
- end
946
-
947
918
  def self.unowned_pool_finalizer(pid_map) # :nodoc:
948
919
  lambda do |_|
949
920
  discard_unowned_pools(pid_map)
@@ -958,7 +929,13 @@ module ActiveRecord
958
929
 
959
930
  def initialize
960
931
  # These caches are keyed by spec.name (ConnectionSpecification#name).
961
- @owner_to_pool = ConnectionHandler.create_owner_to_pool
932
+ @owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
933
+ # Discard the parent's connection pools immediately; we have no need
934
+ # of them
935
+ ConnectionHandler.discard_unowned_pools(h)
936
+
937
+ h[k] = Concurrent::Map.new(initial_capacity: 2)
938
+ end
962
939
 
963
940
  # Backup finalizer: if the forked child never needed a pool, the above
964
941
  # early discard has not occurred
@@ -1036,8 +1013,8 @@ module ActiveRecord
1036
1013
  # Returns true if a connection that's accessible to this class has
1037
1014
  # already been opened.
1038
1015
  def connected?(spec_name)
1039
- conn = retrieve_connection_pool(spec_name)
1040
- conn && conn.connected?
1016
+ pool = retrieve_connection_pool(spec_name)
1017
+ pool && pool.connected?
1041
1018
  end
1042
1019
 
1043
1020
  # Remove the connection for this class. This will close the active
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/deprecation"
4
+
3
5
  module ActiveRecord
4
6
  module ConnectionAdapters # :nodoc:
5
7
  module DatabaseLimits
@@ -12,11 +14,13 @@ module ActiveRecord
12
14
  def column_name_length
13
15
  64
14
16
  end
17
+ deprecate :column_name_length
15
18
 
16
19
  # Returns the maximum length of a table name.
17
20
  def table_name_length
18
21
  64
19
22
  end
23
+ deprecate :table_name_length
20
24
 
21
25
  # Returns the maximum allowed length for an index name. This
22
26
  # limit is enforced by \Rails and is less than or equal to
@@ -36,16 +40,19 @@ module ActiveRecord
36
40
  def columns_per_table
37
41
  1024
38
42
  end
43
+ deprecate :columns_per_table
39
44
 
40
45
  # Returns the maximum number of indexes per table.
41
46
  def indexes_per_table
42
47
  16
43
48
  end
49
+ deprecate :indexes_per_table
44
50
 
45
51
  # Returns the maximum number of columns in a multicolumn index.
46
52
  def columns_per_multicolumn_index
47
53
  16
48
54
  end
55
+ deprecate :columns_per_multicolumn_index
49
56
 
50
57
  # Returns the maximum number of elements in an IN (x,y,z) clause.
51
58
  # +nil+ means no limit.
@@ -57,11 +64,13 @@ module ActiveRecord
57
64
  def sql_query_length
58
65
  1048575
59
66
  end
67
+ deprecate :sql_query_length
60
68
 
61
69
  # Returns maximum number of joins in a single query.
62
70
  def joins_per_query
63
71
  256
64
72
  end
73
+ deprecate :joins_per_query
65
74
 
66
75
  private
67
76
  def bind_params_length
@@ -20,22 +20,9 @@ module ActiveRecord
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
-
24
- if prepared_statements
25
- sql, binds = visitor.accept(arel_or_sql_string.ast, collector).value
26
-
27
- if binds.length > bind_params_length
28
- unprepared_statement do
29
- sql, binds = to_sql_and_binds(arel_or_sql_string)
30
- visitor.preparable = false
31
- end
32
- end
33
- else
34
- sql = visitor.accept(arel_or_sql_string.ast, collector).value
35
- end
36
- [sql.freeze, binds]
23
+ sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
24
+ [sql.freeze, binds || []]
37
25
  else
38
- visitor.preparable = false if prepared_statements
39
26
  [arel_or_sql_string.dup.freeze, binds]
40
27
  end
41
28
  end
@@ -45,11 +32,11 @@ module ActiveRecord
45
32
  # can be used to query the database repeatedly.
46
33
  def cacheable_query(klass, arel) # :nodoc:
47
34
  if prepared_statements
48
- sql, binds = visitor.accept(arel.ast, collector).value
35
+ sql, binds = visitor.compile(arel.ast, collector)
49
36
  query = klass.query(sql)
50
37
  else
51
- collector = PartialQueryCollector.new
52
- parts, binds = visitor.accept(arel.ast, collector).value
38
+ collector = klass.partial_query_collector
39
+ parts, binds = visitor.compile(arel.ast, collector)
53
40
  query = klass.partial_query(parts)
54
41
  end
55
42
  [query, binds]
@@ -60,8 +47,13 @@ module ActiveRecord
60
47
  arel = arel_from_relation(arel)
61
48
  sql, binds = to_sql_and_binds(arel, binds)
62
49
 
63
- if preparable.nil?
64
- preparable = prepared_statements ? visitor.preparable : false
50
+ if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
51
+ preparable = false
52
+ elsif binds.length > bind_params_length
53
+ sql, binds = unprepared_statement { to_sql_and_binds(arel) }
54
+ preparable = false
55
+ else
56
+ preparable = visitor.preparable
65
57
  end
66
58
 
67
59
  if prepared_statements && preparable
@@ -106,6 +98,11 @@ module ActiveRecord
106
98
  exec_query(sql, name).rows
107
99
  end
108
100
 
101
+ # Determines whether the SQL statement is a write query.
102
+ def write_query?(sql)
103
+ raise NotImplementedError
104
+ end
105
+
109
106
  # Executes the SQL statement in the context of this connection and returns
110
107
  # the raw result from the connection adapter.
111
108
  # Note: depending on your database connector, the result returned by this
@@ -126,7 +123,7 @@ module ActiveRecord
126
123
  # +binds+ as the bind substitutes. +name+ is logged along with
127
124
  # the executed +sql+ statement.
128
125
  def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
129
- sql, binds = sql_for_insert(sql, pk, nil, sequence_name, binds)
126
+ sql, binds = sql_for_insert(sql, pk, sequence_name, binds)
130
127
  exec_query(sql, name, binds)
131
128
  end
132
129
 
@@ -176,13 +173,6 @@ module ActiveRecord
176
173
  exec_delete(sql, name, binds)
177
174
  end
178
175
 
179
- # Returns +true+ when the connection adapter supports prepared statement
180
- # caching, otherwise returns +false+
181
- def supports_statement_cache? # :nodoc:
182
- true
183
- end
184
- deprecate :supports_statement_cache?
185
-
186
176
  # Runs the given block in a database transaction, and returns the result
187
177
  # of the block.
188
178
  #
@@ -272,7 +262,9 @@ module ActiveRecord
272
262
 
273
263
  attr_reader :transaction_manager #:nodoc:
274
264
 
275
- delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction, :commit_transaction, :rollback_transaction, to: :transaction_manager
265
+ delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction,
266
+ :commit_transaction, :rollback_transaction, :materialize_transactions,
267
+ :disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
276
268
 
277
269
  def transaction_open?
278
270
  current_transaction.open?
@@ -337,7 +329,7 @@ module ActiveRecord
337
329
 
338
330
  # Inserts the given fixture into the table. Overridden in adapters that require
339
331
  # something beyond a simple insert (eg. Oracle).
340
- # Most of adapters should implement `insert_fixtures` that leverages bulk SQL insert.
332
+ # Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
341
333
  # We keep this method to provide fallback
342
334
  # for databases like sqlite that do not support bulk inserts.
343
335
  def insert_fixture(fixture, table_name)
@@ -366,18 +358,6 @@ module ActiveRecord
366
358
  execute manager.to_sql, "Fixture Insert"
367
359
  end
368
360
 
369
- # Inserts a set of fixtures into the table. Overridden in adapters that require
370
- # something beyond a simple insert (eg. Oracle).
371
- def insert_fixtures(fixtures, table_name)
372
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
373
- `insert_fixtures` is deprecated and will be removed in the next version of Rails.
374
- Consider using `insert_fixtures_set` for performance improvement.
375
- MSG
376
- return if fixtures.empty?
377
-
378
- execute(build_fixture_sql(fixtures, table_name), "Fixtures Insert")
379
- end
380
-
381
361
  def insert_fixtures_set(fixture_set, tables_to_delete = [])
382
362
  fixture_inserts = fixture_set.map do |table_name, fixtures|
383
363
  next if fixtures.empty?
@@ -385,7 +365,7 @@ module ActiveRecord
385
365
  build_fixture_sql(fixtures, table_name)
386
366
  end.compact
387
367
 
388
- table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}".dup }
368
+ table_deletes = tables_to_delete.map { |table| +"DELETE FROM #{quote_table_name table}" }
389
369
  total_sql = Array.wrap(combine_multi_statements(table_deletes + fixture_inserts))
390
370
 
391
371
  disable_referential_integrity do
@@ -398,7 +378,7 @@ module ActiveRecord
398
378
  end
399
379
  end
400
380
 
401
- def empty_insert_statement_value
381
+ def empty_insert_statement_value(primary_key = nil)
402
382
  "DEFAULT VALUES"
403
383
  end
404
384
 
@@ -416,16 +396,6 @@ module ActiveRecord
416
396
  end
417
397
  end
418
398
 
419
- # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
420
- # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
421
- # an UPDATE statement, so in the MySQL adapters we redefine this to do that.
422
- def join_to_update(update, select, key) # :nodoc:
423
- subselect = subquery_for(key, select)
424
-
425
- update.where key.in(subselect)
426
- end
427
- alias join_to_delete join_to_update
428
-
429
399
  private
430
400
  def default_insert_value(column)
431
401
  Arel.sql("DEFAULT")
@@ -466,13 +436,6 @@ module ActiveRecord
466
436
  total_sql.join(";\n")
467
437
  end
468
438
 
469
- # Returns a subquery for the given key using the join information.
470
- def subquery_for(key, select)
471
- subselect = select.clone
472
- subselect.projections = [key]
473
- subselect
474
- end
475
-
476
439
  # Returns an ActiveRecord::Result instance.
477
440
  def select(sql, name = nil, binds = [])
478
441
  exec_query(sql, name, binds, prepare: false)
@@ -482,7 +445,7 @@ module ActiveRecord
482
445
  exec_query(sql, name, binds, prepare: true)
483
446
  end
484
447
 
485
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
448
+ def sql_for_insert(sql, pk, sequence_name, binds)
486
449
  [sql, binds]
487
450
  end
488
451
 
@@ -513,28 +476,6 @@ module ActiveRecord
513
476
  value
514
477
  end
515
478
  end
516
-
517
- class PartialQueryCollector
518
- def initialize
519
- @parts = []
520
- @binds = []
521
- end
522
-
523
- def <<(str)
524
- @parts << str
525
- self
526
- end
527
-
528
- def add_bind(obj)
529
- @binds << obj
530
- @parts << Arel::Nodes::BindParam.new(1)
531
- self
532
- end
533
-
534
- def value
535
- [@parts, @binds]
536
- end
537
- end
538
479
  end
539
480
  end
540
481
  end
@@ -32,17 +32,17 @@ module ActiveRecord
32
32
  end
33
33
 
34
34
  def enable_query_cache!
35
- @query_cache_enabled[connection_cache_key(current_thread)] = true
35
+ @query_cache_enabled[connection_cache_key(Thread.current)] = true
36
36
  connection.enable_query_cache! if active_connection?
37
37
  end
38
38
 
39
39
  def disable_query_cache!
40
- @query_cache_enabled.delete connection_cache_key(current_thread)
40
+ @query_cache_enabled.delete connection_cache_key(Thread.current)
41
41
  connection.disable_query_cache! if active_connection?
42
42
  end
43
43
 
44
44
  def query_cache_enabled
45
- @query_cache_enabled[connection_cache_key(current_thread)]
45
+ @query_cache_enabled[connection_cache_key(Thread.current)]
46
46
  end
47
47
  end
48
48
 
@@ -96,11 +96,6 @@ module ActiveRecord
96
96
  if @query_cache_enabled && !locked?(arel)
97
97
  arel = arel_from_relation(arel)
98
98
  sql, binds = to_sql_and_binds(arel, binds)
99
-
100
- if preparable.nil?
101
- preparable = prepared_statements ? visitor.preparable : false
102
- end
103
-
104
99
  cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
105
100
  else
106
101
  super
@@ -115,12 +110,7 @@ module ActiveRecord
115
110
  if @query_cache[sql].key?(binds)
116
111
  ActiveSupport::Notifications.instrument(
117
112
  "sql.active_record",
118
- sql: sql,
119
- binds: binds,
120
- type_casted_binds: -> { type_casted_binds(binds) },
121
- name: name,
122
- connection_id: object_id,
123
- cached: true,
113
+ cache_notification_info(sql, name, binds)
124
114
  )
125
115
  @query_cache[sql][binds]
126
116
  else
@@ -130,6 +120,19 @@ module ActiveRecord
130
120
  end
131
121
  end
132
122
 
123
+ # Database adapters can override this method to
124
+ # provide custom cache information.
125
+ def cache_notification_info(sql, name, binds)
126
+ {
127
+ sql: sql,
128
+ binds: binds,
129
+ type_casted_binds: -> { type_casted_binds(binds) },
130
+ name: name,
131
+ connection_id: object_id,
132
+ cached: true
133
+ }
134
+ end
135
+
133
136
  # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
134
137
  # queries should not be cached.
135
138
  def locked?(arel)
@@ -60,7 +60,7 @@ module ActiveRecord
60
60
  # Quotes a string, escaping any ' (single quote) and \ (backslash)
61
61
  # characters.
62
62
  def quote_string(s)
63
- s.gsub('\\'.freeze, '\&\&'.freeze).gsub("'".freeze, "''".freeze) # ' (for ruby-mode)
63
+ s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
64
64
  end
65
65
 
66
66
  # Quotes the column name. Defaults to no quoting.
@@ -95,7 +95,7 @@ module ActiveRecord
95
95
  end
96
96
 
97
97
  def quoted_true
98
- "TRUE".freeze
98
+ "TRUE"
99
99
  end
100
100
 
101
101
  def unquoted_true
@@ -103,7 +103,7 @@ module ActiveRecord
103
103
  end
104
104
 
105
105
  def quoted_false
106
- "FALSE".freeze
106
+ "FALSE"
107
107
  end
108
108
 
109
109
  def unquoted_false
@@ -157,13 +157,9 @@ module ActiveRecord
157
157
  end
158
158
  end
159
159
 
160
- def types_which_need_no_typecasting
161
- [nil, Numeric, String]
162
- end
163
-
164
160
  def _quote(value)
165
161
  case value
166
- when String, ActiveSupport::Multibyte::Chars
162
+ when String, Symbol, ActiveSupport::Multibyte::Chars
167
163
  "'#{quote_string(value.to_s)}'"
168
164
  when true then quoted_true
169
165
  when false then quoted_false
@@ -174,7 +170,6 @@ module ActiveRecord
174
170
  when Type::Binary::Data then quoted_binary(value)
175
171
  when Type::Time::Value then "'#{quoted_time(value)}'"
176
172
  when Date, Time then "'#{quoted_date(value)}'"
177
- when Symbol then "'#{quote_string(value.to_s)}'"
178
173
  when Class then "'#{value}'"
179
174
  else raise TypeError, "can't quote #{value.class.name}"
180
175
  end
@@ -188,10 +183,9 @@ module ActiveRecord
188
183
  when false then unquoted_false
189
184
  # BigDecimals need to be put in a non-normalized form and quoted.
190
185
  when BigDecimal then value.to_s("F")
186
+ when nil, Numeric, String then value
191
187
  when Type::Time::Value then quoted_time(value)
192
188
  when Date, Time then quoted_date(value)
193
- when *types_which_need_no_typecasting
194
- value
195
189
  else raise TypeError
196
190
  end
197
191
  end