activerecord 5.2.6 → 6.0.5

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 (294) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +928 -559
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +5 -3
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/advisory_lock_base.rb +18 -0
  7. data/lib/active_record/aggregations.rb +4 -3
  8. data/lib/active_record/association_relation.rb +10 -8
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +55 -19
  11. data/lib/active_record/associations/association_scope.rb +11 -7
  12. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  14. data/lib/active_record/associations/builder/association.rb +14 -18
  15. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  16. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
  18. data/lib/active_record/associations/builder/has_many.rb +2 -0
  19. data/lib/active_record/associations/builder/has_one.rb +35 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  21. data/lib/active_record/associations/collection_association.rb +19 -23
  22. data/lib/active_record/associations/collection_proxy.rb +14 -17
  23. data/lib/active_record/associations/foreign_association.rb +7 -0
  24. data/lib/active_record/associations/has_many_association.rb +2 -11
  25. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  26. data/lib/active_record/associations/has_one_association.rb +28 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  28. data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
  29. data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
  30. data/lib/active_record/associations/join_dependency.rb +47 -30
  31. data/lib/active_record/associations/preloader/association.rb +61 -41
  32. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  33. data/lib/active_record/associations/preloader.rb +44 -33
  34. data/lib/active_record/associations/singular_association.rb +2 -16
  35. data/lib/active_record/associations/through_association.rb +1 -1
  36. data/lib/active_record/associations.rb +21 -16
  37. data/lib/active_record/attribute_assignment.rb +7 -11
  38. data/lib/active_record/attribute_decorators.rb +0 -2
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
  40. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  41. data/lib/active_record/attribute_methods/primary_key.rb +15 -24
  42. data/lib/active_record/attribute_methods/query.rb +2 -3
  43. data/lib/active_record/attribute_methods/read.rb +15 -54
  44. data/lib/active_record/attribute_methods/serialization.rb +1 -2
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
  46. data/lib/active_record/attribute_methods/write.rb +17 -25
  47. data/lib/active_record/attribute_methods.rb +28 -100
  48. data/lib/active_record/attributes.rb +13 -1
  49. data/lib/active_record/autosave_association.rb +12 -14
  50. data/lib/active_record/base.rb +2 -3
  51. data/lib/active_record/callbacks.rb +6 -21
  52. data/lib/active_record/coders/yaml_column.rb +0 -1
  53. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
  54. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  55. data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
  56. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
  57. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  58. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
  65. data/lib/active_record/connection_adapters/column.rb +17 -13
  66. data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
  67. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  68. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  69. data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
  70. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  71. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  72. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
  73. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  74. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  75. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
  76. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
  78. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  79. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  82. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
  83. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  89. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  91. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
  98. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
  101. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  102. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  105. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
  107. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  108. data/lib/active_record/connection_handling.rb +139 -26
  109. data/lib/active_record/core.rb +107 -66
  110. data/lib/active_record/counter_cache.rb +8 -30
  111. data/lib/active_record/database_configurations/database_config.rb +37 -0
  112. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  113. data/lib/active_record/database_configurations/url_config.rb +78 -0
  114. data/lib/active_record/database_configurations.rb +233 -0
  115. data/lib/active_record/dynamic_matchers.rb +3 -4
  116. data/lib/active_record/enum.rb +44 -7
  117. data/lib/active_record/errors.rb +15 -7
  118. data/lib/active_record/explain.rb +1 -2
  119. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  120. data/lib/active_record/fixture_set/render_context.rb +17 -0
  121. data/lib/active_record/fixture_set/table_row.rb +152 -0
  122. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  123. data/lib/active_record/fixtures.rb +144 -474
  124. data/lib/active_record/gem_version.rb +3 -3
  125. data/lib/active_record/inheritance.rb +13 -6
  126. data/lib/active_record/insert_all.rb +179 -0
  127. data/lib/active_record/integration.rb +68 -16
  128. data/lib/active_record/internal_metadata.rb +11 -3
  129. data/lib/active_record/locking/optimistic.rb +14 -7
  130. data/lib/active_record/locking/pessimistic.rb +3 -3
  131. data/lib/active_record/log_subscriber.rb +8 -27
  132. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  133. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  134. data/lib/active_record/middleware/database_selector.rb +74 -0
  135. data/lib/active_record/migration/command_recorder.rb +54 -22
  136. data/lib/active_record/migration/compatibility.rb +79 -52
  137. data/lib/active_record/migration/join_table.rb +0 -1
  138. data/lib/active_record/migration.rb +104 -85
  139. data/lib/active_record/model_schema.rb +62 -11
  140. data/lib/active_record/nested_attributes.rb +2 -4
  141. data/lib/active_record/no_touching.rb +9 -2
  142. data/lib/active_record/null_relation.rb +0 -1
  143. data/lib/active_record/persistence.rb +232 -29
  144. data/lib/active_record/query_cache.rb +11 -4
  145. data/lib/active_record/querying.rb +33 -21
  146. data/lib/active_record/railtie.rb +80 -43
  147. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  148. data/lib/active_record/railties/controller_runtime.rb +30 -35
  149. data/lib/active_record/railties/databases.rake +199 -46
  150. data/lib/active_record/reflection.rb +51 -51
  151. data/lib/active_record/relation/batches.rb +13 -11
  152. data/lib/active_record/relation/calculations.rb +55 -49
  153. data/lib/active_record/relation/delegation.rb +35 -50
  154. data/lib/active_record/relation/finder_methods.rb +23 -28
  155. data/lib/active_record/relation/from_clause.rb +4 -0
  156. data/lib/active_record/relation/merger.rb +12 -17
  157. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  158. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  159. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  160. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  161. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  162. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  163. data/lib/active_record/relation/predicate_builder.rb +5 -11
  164. data/lib/active_record/relation/query_attribute.rb +13 -8
  165. data/lib/active_record/relation/query_methods.rb +232 -69
  166. data/lib/active_record/relation/spawn_methods.rb +1 -2
  167. data/lib/active_record/relation/where_clause.rb +14 -11
  168. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  169. data/lib/active_record/relation.rb +326 -81
  170. data/lib/active_record/result.rb +30 -12
  171. data/lib/active_record/sanitization.rb +32 -40
  172. data/lib/active_record/schema.rb +2 -11
  173. data/lib/active_record/schema_dumper.rb +22 -7
  174. data/lib/active_record/schema_migration.rb +6 -2
  175. data/lib/active_record/scoping/default.rb +4 -6
  176. data/lib/active_record/scoping/named.rb +25 -16
  177. data/lib/active_record/scoping.rb +8 -9
  178. data/lib/active_record/statement_cache.rb +30 -3
  179. data/lib/active_record/store.rb +87 -8
  180. data/lib/active_record/suppressor.rb +2 -2
  181. data/lib/active_record/table_metadata.rb +23 -15
  182. data/lib/active_record/tasks/database_tasks.rb +194 -25
  183. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
  184. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
  185. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
  186. data/lib/active_record/test_databases.rb +23 -0
  187. data/lib/active_record/test_fixtures.rb +243 -0
  188. data/lib/active_record/timestamp.rb +39 -26
  189. data/lib/active_record/touch_later.rb +5 -4
  190. data/lib/active_record/transactions.rb +64 -73
  191. data/lib/active_record/translation.rb +1 -1
  192. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  193. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  194. data/lib/active_record/type/serialized.rb +0 -1
  195. data/lib/active_record/type/time.rb +10 -0
  196. data/lib/active_record/type/type_map.rb +0 -1
  197. data/lib/active_record/type/unsigned_integer.rb +0 -1
  198. data/lib/active_record/type.rb +3 -5
  199. data/lib/active_record/type_caster/connection.rb +15 -14
  200. data/lib/active_record/type_caster/map.rb +1 -4
  201. data/lib/active_record/validations/associated.rb +0 -1
  202. data/lib/active_record/validations/uniqueness.rb +15 -27
  203. data/lib/active_record/validations.rb +3 -3
  204. data/lib/active_record.rb +10 -2
  205. data/lib/arel/alias_predication.rb +9 -0
  206. data/lib/arel/attributes/attribute.rb +37 -0
  207. data/lib/arel/attributes.rb +22 -0
  208. data/lib/arel/collectors/bind.rb +24 -0
  209. data/lib/arel/collectors/composite.rb +31 -0
  210. data/lib/arel/collectors/plain_string.rb +20 -0
  211. data/lib/arel/collectors/sql_string.rb +20 -0
  212. data/lib/arel/collectors/substitute_binds.rb +28 -0
  213. data/lib/arel/crud.rb +42 -0
  214. data/lib/arel/delete_manager.rb +18 -0
  215. data/lib/arel/errors.rb +9 -0
  216. data/lib/arel/expressions.rb +29 -0
  217. data/lib/arel/factory_methods.rb +49 -0
  218. data/lib/arel/insert_manager.rb +49 -0
  219. data/lib/arel/math.rb +45 -0
  220. data/lib/arel/nodes/and.rb +32 -0
  221. data/lib/arel/nodes/ascending.rb +23 -0
  222. data/lib/arel/nodes/binary.rb +52 -0
  223. data/lib/arel/nodes/bind_param.rb +36 -0
  224. data/lib/arel/nodes/case.rb +55 -0
  225. data/lib/arel/nodes/casted.rb +50 -0
  226. data/lib/arel/nodes/comment.rb +29 -0
  227. data/lib/arel/nodes/count.rb +12 -0
  228. data/lib/arel/nodes/delete_statement.rb +45 -0
  229. data/lib/arel/nodes/descending.rb +23 -0
  230. data/lib/arel/nodes/equality.rb +18 -0
  231. data/lib/arel/nodes/extract.rb +24 -0
  232. data/lib/arel/nodes/false.rb +16 -0
  233. data/lib/arel/nodes/full_outer_join.rb +8 -0
  234. data/lib/arel/nodes/function.rb +44 -0
  235. data/lib/arel/nodes/grouping.rb +8 -0
  236. data/lib/arel/nodes/in.rb +8 -0
  237. data/lib/arel/nodes/infix_operation.rb +80 -0
  238. data/lib/arel/nodes/inner_join.rb +8 -0
  239. data/lib/arel/nodes/insert_statement.rb +37 -0
  240. data/lib/arel/nodes/join_source.rb +20 -0
  241. data/lib/arel/nodes/matches.rb +18 -0
  242. data/lib/arel/nodes/named_function.rb +23 -0
  243. data/lib/arel/nodes/node.rb +50 -0
  244. data/lib/arel/nodes/node_expression.rb +13 -0
  245. data/lib/arel/nodes/outer_join.rb +8 -0
  246. data/lib/arel/nodes/over.rb +15 -0
  247. data/lib/arel/nodes/regexp.rb +16 -0
  248. data/lib/arel/nodes/right_outer_join.rb +8 -0
  249. data/lib/arel/nodes/select_core.rb +67 -0
  250. data/lib/arel/nodes/select_statement.rb +41 -0
  251. data/lib/arel/nodes/sql_literal.rb +16 -0
  252. data/lib/arel/nodes/string_join.rb +11 -0
  253. data/lib/arel/nodes/table_alias.rb +27 -0
  254. data/lib/arel/nodes/terminal.rb +16 -0
  255. data/lib/arel/nodes/true.rb +16 -0
  256. data/lib/arel/nodes/unary.rb +45 -0
  257. data/lib/arel/nodes/unary_operation.rb +20 -0
  258. data/lib/arel/nodes/unqualified_column.rb +22 -0
  259. data/lib/arel/nodes/update_statement.rb +41 -0
  260. data/lib/arel/nodes/values_list.rb +9 -0
  261. data/lib/arel/nodes/window.rb +126 -0
  262. data/lib/arel/nodes/with.rb +11 -0
  263. data/lib/arel/nodes.rb +68 -0
  264. data/lib/arel/order_predications.rb +13 -0
  265. data/lib/arel/predications.rb +256 -0
  266. data/lib/arel/select_manager.rb +271 -0
  267. data/lib/arel/table.rb +110 -0
  268. data/lib/arel/tree_manager.rb +72 -0
  269. data/lib/arel/update_manager.rb +34 -0
  270. data/lib/arel/visitors/depth_first.rb +203 -0
  271. data/lib/arel/visitors/dot.rb +296 -0
  272. data/lib/arel/visitors/ibm_db.rb +34 -0
  273. data/lib/arel/visitors/informix.rb +62 -0
  274. data/lib/arel/visitors/mssql.rb +156 -0
  275. data/lib/arel/visitors/mysql.rb +83 -0
  276. data/lib/arel/visitors/oracle.rb +158 -0
  277. data/lib/arel/visitors/oracle12.rb +65 -0
  278. data/lib/arel/visitors/postgresql.rb +109 -0
  279. data/lib/arel/visitors/sqlite.rb +38 -0
  280. data/lib/arel/visitors/to_sql.rb +888 -0
  281. data/lib/arel/visitors/visitor.rb +45 -0
  282. data/lib/arel/visitors/where_sql.rb +22 -0
  283. data/lib/arel/visitors.rb +20 -0
  284. data/lib/arel/window_predications.rb +9 -0
  285. data/lib/arel.rb +62 -0
  286. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  287. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  288. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  289. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  290. data/lib/rails/generators/active_record/migration.rb +14 -2
  291. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  292. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  293. metadata +116 -29
  294. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "set"
3
4
  require "active_record/connection_adapters/determine_if_preparable_visitor"
4
5
  require "active_record/connection_adapters/schema_cache"
5
6
  require "active_record/connection_adapters/sql_type_metadata"
6
7
  require "active_record/connection_adapters/abstract/schema_dumper"
7
8
  require "active_record/connection_adapters/abstract/schema_creation"
8
9
  require "active_support/concurrency/load_interlock_aware_monitor"
10
+ require "active_support/deprecation"
9
11
  require "arel/collectors/bind"
10
12
  require "arel/collectors/composite"
11
13
  require "arel/collectors/sql_string"
@@ -65,7 +67,7 @@ module ActiveRecord
65
67
  # Most of the methods in the adapter are useful during migrations. Most
66
68
  # notably, the instance methods provided by SchemaStatements are very useful.
67
69
  class AbstractAdapter
68
- ADAPTER_NAME = "Abstract".freeze
70
+ ADAPTER_NAME = "Abstract"
69
71
  include ActiveSupport::Callbacks
70
72
  define_callbacks :checkout, :checkin
71
73
 
@@ -75,15 +77,18 @@ module ActiveRecord
75
77
  include Savepoints
76
78
 
77
79
  SIMPLE_INT = /\A\d+\z/
80
+ COMMENT_REGEX = %r{/\*(?:[^\*]|\*[^/])*\*/}m
78
81
 
79
- attr_accessor :visitor, :pool
80
- attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
82
+ attr_accessor :pool
83
+ attr_reader :visitor, :owner, :logger, :lock
81
84
  alias :in_use? :owner
82
85
 
86
+ set_callback :checkin, :after, :enable_lazy_transactions!
87
+
83
88
  def self.type_cast_config_to_integer(config)
84
89
  if config.is_a?(Integer)
85
90
  config
86
- elsif config =~ SIMPLE_INT
91
+ elsif SIMPLE_INT.match?(config)
87
92
  config.to_i
88
93
  else
89
94
  config
@@ -98,6 +103,23 @@ module ActiveRecord
98
103
  end
99
104
  end
100
105
 
106
+ DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
107
+ private_constant :DEFAULT_READ_QUERY
108
+
109
+ def self.build_read_query_regexp(*parts) # :nodoc:
110
+ parts += DEFAULT_READ_QUERY
111
+ parts = parts.map { |part| /#{part}/i }
112
+ /\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
113
+ end
114
+
115
+ def self.quoted_column_names # :nodoc:
116
+ @quoted_column_names ||= {}
117
+ end
118
+
119
+ def self.quoted_table_names # :nodoc:
120
+ @quoted_table_names ||= {}
121
+ end
122
+
101
123
  def initialize(connection, logger = nil, config = {}) # :nodoc:
102
124
  super()
103
125
 
@@ -106,11 +128,10 @@ module ActiveRecord
106
128
  @instrumenter = ActiveSupport::Notifications.instrumenter
107
129
  @logger = logger
108
130
  @config = config
109
- @pool = nil
131
+ @pool = ActiveRecord::ConnectionAdapters::NullPool.new
110
132
  @idle_since = Concurrent.monotonic_time
111
- @schema_cache = SchemaCache.new self
112
- @quoted_column_names, @quoted_table_names = {}, {}
113
133
  @visitor = arel_visitor
134
+ @statements = build_statement_pool
114
135
  @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
115
136
 
116
137
  if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@@ -119,6 +140,22 @@ module ActiveRecord
119
140
  else
120
141
  @prepared_statements = false
121
142
  end
143
+
144
+ @advisory_locks_enabled = self.class.type_cast_config_to_boolean(
145
+ config.fetch(:advisory_locks, true)
146
+ )
147
+ end
148
+
149
+ def replica?
150
+ @config[:replica] || false
151
+ end
152
+
153
+ # Determines whether writes are currently being prevents.
154
+ #
155
+ # Returns true if the connection is a replica, or if +prevent_writes+
156
+ # is set to true.
157
+ def preventing_writes?
158
+ replica? || ActiveRecord::Base.connection_handler.prevent_writes
122
159
  end
123
160
 
124
161
  def migrations_paths # :nodoc:
@@ -126,19 +163,51 @@ module ActiveRecord
126
163
  end
127
164
 
128
165
  def migration_context # :nodoc:
129
- MigrationContext.new(migrations_paths)
166
+ MigrationContext.new(migrations_paths, schema_migration)
167
+ end
168
+
169
+ def schema_migration # :nodoc:
170
+ @schema_migration ||= begin
171
+ conn = self
172
+ spec_name = conn.pool.spec.name
173
+ name = "#{spec_name}::SchemaMigration"
174
+
175
+ return ActiveRecord::SchemaMigration if spec_name == "primary"
176
+
177
+ Class.new(ActiveRecord::SchemaMigration) do
178
+ define_singleton_method(:name) { name }
179
+ define_singleton_method(:to_s) { name }
180
+
181
+ self.connection_specification_name = spec_name
182
+ end
183
+ end
184
+ end
185
+
186
+ def prepared_statements
187
+ @prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
188
+ end
189
+
190
+ def prepared_statements_disabled_cache # :nodoc:
191
+ Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
130
192
  end
131
193
 
132
194
  class Version
133
195
  include Comparable
134
196
 
135
- def initialize(version_string)
197
+ attr_reader :full_version_string
198
+
199
+ def initialize(version_string, full_version_string = nil)
136
200
  @version = version_string.split(".").map(&:to_i)
201
+ @full_version_string = full_version_string
137
202
  end
138
203
 
139
204
  def <=>(version_string)
140
205
  @version <=> version_string.split(".").map(&:to_i)
141
206
  end
207
+
208
+ def to_s
209
+ @version.join(".")
210
+ end
142
211
  end
143
212
 
144
213
  def valid_type?(type) # :nodoc:
@@ -148,7 +217,7 @@ module ActiveRecord
148
217
  # this method must only be called while holding connection pool's mutex
149
218
  def lease
150
219
  if in_use?
151
- msg = "Cannot lease connection, ".dup
220
+ msg = +"Cannot lease connection, "
152
221
  if @owner == Thread.current
153
222
  msg << "it is already leased by the current thread."
154
223
  else
@@ -161,9 +230,13 @@ module ActiveRecord
161
230
  @owner = Thread.current
162
231
  end
163
232
 
233
+ def schema_cache
234
+ @pool.get_schema_cache(self)
235
+ end
236
+
164
237
  def schema_cache=(cache)
165
238
  cache.connection = self
166
- @schema_cache = cache
239
+ @pool.set_schema_cache(cache)
167
240
  end
168
241
 
169
242
  # this method must only be called while holding connection pool's mutex
@@ -202,10 +275,10 @@ module ActiveRecord
202
275
  end
203
276
 
204
277
  def unprepared_statement
205
- old_prepared_statements, @prepared_statements = @prepared_statements, false
278
+ cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
206
279
  yield
207
280
  ensure
208
- @prepared_statements = old_prepared_statements
281
+ cache&.delete(object_id)
209
282
  end
210
283
 
211
284
  # Returns the human-readable name of the adapter. Use mixed case - one
@@ -214,6 +287,11 @@ module ActiveRecord
214
287
  self.class::ADAPTER_NAME
215
288
  end
216
289
 
290
+ # Does the database for this adapter exist?
291
+ def self.database_exists?(config)
292
+ raise NotImplementedError
293
+ end
294
+
217
295
  # Does this adapter support DDL rollbacks in transactions? That is, would
218
296
  # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
219
297
  def supports_ddl_transactions?
@@ -241,6 +319,10 @@ module ActiveRecord
241
319
  false
242
320
  end
243
321
 
322
+ def supports_partitioned_indexes?
323
+ false
324
+ end
325
+
244
326
  # Does this adapter support index sort order?
245
327
  def supports_index_sort_order?
246
328
  false
@@ -292,12 +374,18 @@ module ActiveRecord
292
374
  def supports_foreign_keys_in_create?
293
375
  supports_foreign_keys?
294
376
  end
377
+ deprecate :supports_foreign_keys_in_create?
295
378
 
296
379
  # Does this adapter support views?
297
380
  def supports_views?
298
381
  false
299
382
  end
300
383
 
384
+ # Does this adapter support materialized views?
385
+ def supports_materialized_views?
386
+ false
387
+ end
388
+
301
389
  # Does this adapter support datetime with precision?
302
390
  def supports_datetime_with_precision?
303
391
  false
@@ -322,6 +410,7 @@ module ActiveRecord
322
410
  def supports_multi_insert?
323
411
  true
324
412
  end
413
+ deprecate :supports_multi_insert?
325
414
 
326
415
  # Does this adapter support virtual columns?
327
416
  def supports_virtual_columns?
@@ -333,6 +422,35 @@ module ActiveRecord
333
422
  false
334
423
  end
335
424
 
425
+ # Does this adapter support optimizer hints?
426
+ def supports_optimizer_hints?
427
+ false
428
+ end
429
+
430
+ def supports_common_table_expressions?
431
+ false
432
+ end
433
+
434
+ def supports_lazy_transactions?
435
+ false
436
+ end
437
+
438
+ def supports_insert_returning?
439
+ false
440
+ end
441
+
442
+ def supports_insert_on_duplicate_skip?
443
+ false
444
+ end
445
+
446
+ def supports_insert_on_duplicate_update?
447
+ false
448
+ end
449
+
450
+ def supports_insert_conflict_target?
451
+ false
452
+ end
453
+
336
454
  # This is meant to be implemented by the adapters that support extensions
337
455
  def disable_extension(name)
338
456
  end
@@ -341,6 +459,10 @@ module ActiveRecord
341
459
  def enable_extension(name)
342
460
  end
343
461
 
462
+ def advisory_locks_enabled? # :nodoc:
463
+ supports_advisory_locks? && @advisory_locks_enabled
464
+ end
465
+
344
466
  # This is meant to be implemented by the adapters that support advisory
345
467
  # locks
346
468
  #
@@ -406,6 +528,9 @@ module ActiveRecord
406
528
  #
407
529
  # Prevent @connection's finalizer from touching the socket, or
408
530
  # otherwise communicating with its server, when it is collected.
531
+ if schema_cache.connection == self
532
+ schema_cache.connection = nil
533
+ end
409
534
  end
410
535
 
411
536
  # Reset the state of this connection, directing the DBMS to clear
@@ -418,11 +543,9 @@ module ActiveRecord
418
543
  # this should be overridden by concrete adapters
419
544
  end
420
545
 
421
- ###
422
- # Clear any caching the database adapter may be doing, for example
423
- # clearing the prepared statement cache. This is database specific.
546
+ # Clear any caching the database adapter may be doing.
424
547
  def clear_cache!
425
- # this should be overridden by concrete adapters
548
+ @lock.synchronize { @statements.clear } if @statements
426
549
  end
427
550
 
428
551
  # Returns true if its required to reload the connection between requests for development mode.
@@ -444,18 +567,25 @@ module ActiveRecord
444
567
  # This is useful for when you need to call a proprietary method such as
445
568
  # PostgreSQL's lo_* methods.
446
569
  def raw_connection
570
+ disable_lazy_transactions!
447
571
  @connection
448
572
  end
449
573
 
450
- def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
451
- table[attribute].eq(value)
574
+ def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
575
+ attribute.eq(value)
452
576
  end
453
577
 
454
- def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
578
+ def case_sensitive_comparison(attribute, value) # :nodoc:
579
+ attribute.eq(value)
580
+ end
581
+
582
+ def case_insensitive_comparison(attribute, value) # :nodoc:
583
+ column = column_for_attribute(attribute)
584
+
455
585
  if can_perform_case_insensitive_comparison_for?(column)
456
- table[attribute].lower.eq(table.lower(value))
586
+ attribute.lower.eq(attribute.relation.lower(value))
457
587
  else
458
- table[attribute].eq(value)
588
+ attribute.eq(value)
459
589
  end
460
590
  end
461
591
 
@@ -470,17 +600,36 @@ module ActiveRecord
470
600
  end
471
601
 
472
602
  def column_name_for_operation(operation, node) # :nodoc:
473
- column_name_from_arel_node(node)
474
- end
475
-
476
- def column_name_from_arel_node(node) # :nodoc:
477
- visitor.accept(node, Arel::Collectors::SQLString.new).value
603
+ visitor.compile(node)
478
604
  end
479
605
 
480
606
  def default_index_type?(index) # :nodoc:
481
607
  index.using.nil?
482
608
  end
483
609
 
610
+ # Called by ActiveRecord::InsertAll,
611
+ # Passed an instance of ActiveRecord::InsertAll::Builder,
612
+ # This method implements standard bulk inserts for all databases, but
613
+ # should be overridden by adapters to implement common features with
614
+ # non-standard syntax like handling duplicates or returning values.
615
+ def build_insert_sql(insert) # :nodoc:
616
+ if insert.skip_duplicates? || insert.update_duplicates?
617
+ raise NotImplementedError, "#{self.class} should define `build_insert_sql` to implement adapter-specific logic for handling duplicates during INSERT"
618
+ end
619
+
620
+ "INSERT #{insert.into} #{insert.values_list}"
621
+ end
622
+
623
+ def get_database_version # :nodoc:
624
+ end
625
+
626
+ def database_version # :nodoc:
627
+ schema_cache.database_version
628
+ end
629
+
630
+ def check_version # :nodoc:
631
+ end
632
+
484
633
  private
485
634
  def type_map
486
635
  @type_map ||= Type::TypeMap.new.tap do |mapping|
@@ -555,14 +704,12 @@ module ActiveRecord
555
704
  $1.to_i if sql_type =~ /\((.*)\)/
556
705
  end
557
706
 
558
- def translate_exception_class(e, sql)
559
- begin
560
- message = "#{e.class.name}: #{e.message}: #{sql}"
561
- rescue Encoding::CompatibilityError
562
- message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
563
- end
707
+ def translate_exception_class(e, sql, binds)
708
+ message = "#{e.class.name}: #{e.message}"
564
709
 
565
- exception = translate_exception(e, message)
710
+ exception = translate_exception(
711
+ e, message: message, sql: sql, binds: binds
712
+ )
566
713
  exception.set_backtrace e.backtrace
567
714
  exception
568
715
  end
@@ -575,24 +722,23 @@ module ActiveRecord
575
722
  binds: binds,
576
723
  type_casted_binds: type_casted_binds,
577
724
  statement_name: statement_name,
578
- connection_id: object_id) do
579
- begin
580
- @lock.synchronize do
581
- yield
582
- end
583
- rescue => e
584
- raise translate_exception_class(e, sql)
725
+ connection_id: object_id,
726
+ connection: self) do
727
+ @lock.synchronize do
728
+ yield
585
729
  end
730
+ rescue => e
731
+ raise translate_exception_class(e, sql, binds)
586
732
  end
587
733
  end
588
734
 
589
- def translate_exception(exception, message)
735
+ def translate_exception(exception, message:, sql:, binds:)
590
736
  # override in derived class
591
737
  case exception
592
738
  when RuntimeError
593
739
  exception
594
740
  else
595
- ActiveRecord::StatementInvalid.new(message)
741
+ ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
596
742
  end
597
743
  end
598
744
 
@@ -606,6 +752,11 @@ module ActiveRecord
606
752
  raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
607
753
  end
608
754
 
755
+ def column_for_attribute(attribute)
756
+ table_name = attribute.relation.name
757
+ schema_cache.columns_hash(table_name)[attribute.name.to_s]
758
+ end
759
+
609
760
  def collector
610
761
  if prepared_statements
611
762
  Arel::Collectors::Composite.new(
@@ -623,6 +774,9 @@ module ActiveRecord
623
774
  def arel_visitor
624
775
  Arel::Visitors::ToSql.new(self)
625
776
  end
777
+
778
+ def build_statement_pool
779
+ end
626
780
  end
627
781
  end
628
782
  end