activerecord 5.2.3 → 6.1.0

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +898 -532
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +5 -4
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +95 -42
  10. data/lib/active_record/associations/association_scope.rb +21 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +50 -46
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -5
  13. data/lib/active_record/associations/builder/association.rb +23 -21
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +10 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +31 -29
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +27 -28
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +54 -12
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +71 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +48 -35
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +133 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +45 -8
  47. data/lib/active_record/autosave_association.rb +76 -47
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +293 -132
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +21 -17
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +203 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +381 -146
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -98
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  95. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  97. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  98. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  100. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +222 -112
  108. data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
  110. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  113. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  114. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +175 -187
  115. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  116. data/lib/active_record/connection_adapters.rb +50 -0
  117. data/lib/active_record/connection_handling.rb +285 -33
  118. data/lib/active_record/core.rb +308 -100
  119. data/lib/active_record/counter_cache.rb +8 -30
  120. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  121. data/lib/active_record/database_configurations/database_config.rb +80 -0
  122. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  123. data/lib/active_record/database_configurations/url_config.rb +53 -0
  124. data/lib/active_record/database_configurations.rb +272 -0
  125. data/lib/active_record/delegated_type.rb +209 -0
  126. data/lib/active_record/destroy_association_async_job.rb +36 -0
  127. data/lib/active_record/dynamic_matchers.rb +3 -4
  128. data/lib/active_record/enum.rb +71 -17
  129. data/lib/active_record/errors.rb +62 -19
  130. data/lib/active_record/explain.rb +10 -6
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/file.rb +10 -17
  133. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  134. data/lib/active_record/fixture_set/render_context.rb +17 -0
  135. data/lib/active_record/fixture_set/table_row.rb +152 -0
  136. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  137. data/lib/active_record/fixtures.rb +197 -481
  138. data/lib/active_record/gem_version.rb +3 -3
  139. data/lib/active_record/inheritance.rb +53 -24
  140. data/lib/active_record/insert_all.rb +208 -0
  141. data/lib/active_record/integration.rb +67 -17
  142. data/lib/active_record/internal_metadata.rb +26 -9
  143. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  144. data/lib/active_record/locking/optimistic.rb +26 -22
  145. data/lib/active_record/locking/pessimistic.rb +9 -5
  146. data/lib/active_record/log_subscriber.rb +34 -35
  147. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  148. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  149. data/lib/active_record/middleware/database_selector.rb +77 -0
  150. data/lib/active_record/migration/command_recorder.rb +96 -44
  151. data/lib/active_record/migration/compatibility.rb +141 -64
  152. data/lib/active_record/migration/join_table.rb +0 -1
  153. data/lib/active_record/migration.rb +205 -156
  154. data/lib/active_record/model_schema.rb +148 -22
  155. data/lib/active_record/nested_attributes.rb +4 -7
  156. data/lib/active_record/no_touching.rb +8 -1
  157. data/lib/active_record/null_relation.rb +0 -1
  158. data/lib/active_record/persistence.rb +267 -59
  159. data/lib/active_record/query_cache.rb +21 -4
  160. data/lib/active_record/querying.rb +40 -23
  161. data/lib/active_record/railtie.rb +115 -58
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +402 -78
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +113 -101
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -93
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +65 -40
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -7
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +58 -40
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +487 -199
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +108 -58
  185. data/lib/active_record/relation.rb +375 -104
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +6 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +51 -8
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +39 -43
  202. data/lib/active_record/tasks/database_tasks.rb +276 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +246 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +59 -117
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +117 -32
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_record/connection_adapters/determine_if_preparable_visitor"
3
+ require "set"
4
4
  require "active_record/connection_adapters/schema_cache"
5
5
  require "active_record/connection_adapters/sql_type_metadata"
6
6
  require "active_record/connection_adapters/abstract/schema_dumper"
@@ -13,44 +13,6 @@ require "arel/collectors/substitute_binds"
13
13
 
14
14
  module ActiveRecord
15
15
  module ConnectionAdapters # :nodoc:
16
- extend ActiveSupport::Autoload
17
-
18
- autoload :Column
19
- autoload :ConnectionSpecification
20
-
21
- autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
22
- autoload :IndexDefinition
23
- autoload :ColumnDefinition
24
- autoload :ChangeColumnDefinition
25
- autoload :ForeignKeyDefinition
26
- autoload :TableDefinition
27
- autoload :Table
28
- autoload :AlterTable
29
- autoload :ReferenceDefinition
30
- end
31
-
32
- autoload_at "active_record/connection_adapters/abstract/connection_pool" do
33
- autoload :ConnectionHandler
34
- end
35
-
36
- autoload_under "abstract" do
37
- autoload :SchemaStatements
38
- autoload :DatabaseStatements
39
- autoload :DatabaseLimits
40
- autoload :Quoting
41
- autoload :ConnectionPool
42
- autoload :QueryCache
43
- autoload :Savepoints
44
- end
45
-
46
- autoload_at "active_record/connection_adapters/abstract/transaction" do
47
- autoload :TransactionManager
48
- autoload :NullTransaction
49
- autoload :RealTransaction
50
- autoload :SavepointTransaction
51
- autoload :TransactionState
52
- end
53
-
54
16
  # Active Record supports multiple database systems. AbstractAdapter and
55
17
  # related classes form the abstraction layer which makes this possible.
56
18
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -65,7 +27,7 @@ module ActiveRecord
65
27
  # Most of the methods in the adapter are useful during migrations. Most
66
28
  # notably, the instance methods provided by SchemaStatements are very useful.
67
29
  class AbstractAdapter
68
- ADAPTER_NAME = "Abstract".freeze
30
+ ADAPTER_NAME = "Abstract"
69
31
  include ActiveSupport::Callbacks
70
32
  define_callbacks :checkout, :checkin
71
33
 
@@ -75,15 +37,18 @@ module ActiveRecord
75
37
  include Savepoints
76
38
 
77
39
  SIMPLE_INT = /\A\d+\z/
40
+ COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
78
41
 
79
- attr_accessor :visitor, :pool
80
- attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
42
+ attr_accessor :pool
43
+ attr_reader :visitor, :owner, :logger, :lock
81
44
  alias :in_use? :owner
82
45
 
46
+ set_callback :checkin, :after, :enable_lazy_transactions!
47
+
83
48
  def self.type_cast_config_to_integer(config)
84
49
  if config.is_a?(Integer)
85
50
  config
86
- elsif config =~ SIMPLE_INT
51
+ elsif SIMPLE_INT.match?(config)
87
52
  config.to_i
88
53
  else
89
54
  config
@@ -98,6 +63,23 @@ module ActiveRecord
98
63
  end
99
64
  end
100
65
 
66
+ DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
67
+ private_constant :DEFAULT_READ_QUERY
68
+
69
+ def self.build_read_query_regexp(*parts) # :nodoc:
70
+ parts += DEFAULT_READ_QUERY
71
+ parts = parts.map { |part| /#{part}/i }
72
+ /\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
73
+ end
74
+
75
+ def self.quoted_column_names # :nodoc:
76
+ @quoted_column_names ||= {}
77
+ end
78
+
79
+ def self.quoted_table_names # :nodoc:
80
+ @quoted_table_names ||= {}
81
+ end
82
+
101
83
  def initialize(connection, logger = nil, config = {}) # :nodoc:
102
84
  super()
103
85
 
@@ -106,19 +88,45 @@ module ActiveRecord
106
88
  @instrumenter = ActiveSupport::Notifications.instrumenter
107
89
  @logger = logger
108
90
  @config = config
109
- @pool = nil
91
+ @pool = ActiveRecord::ConnectionAdapters::NullPool.new
110
92
  @idle_since = Concurrent.monotonic_time
111
- @schema_cache = SchemaCache.new self
112
- @quoted_column_names, @quoted_table_names = {}, {}
113
93
  @visitor = arel_visitor
94
+ @statements = build_statement_pool
114
95
  @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
115
96
 
116
- if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
117
- @prepared_statements = true
118
- @visitor.extend(DetermineIfPreparableVisitor)
119
- else
120
- @prepared_statements = false
121
- end
97
+ @prepared_statements = self.class.type_cast_config_to_boolean(
98
+ config.fetch(:prepared_statements, true)
99
+ )
100
+
101
+ @advisory_locks_enabled = self.class.type_cast_config_to_boolean(
102
+ config.fetch(:advisory_locks, true)
103
+ )
104
+ end
105
+
106
+ def replica?
107
+ @config[:replica] || false
108
+ end
109
+
110
+ def use_metadata_table?
111
+ @config.fetch(:use_metadata_table, true)
112
+ end
113
+
114
+ # Determines whether writes are currently being prevents.
115
+ #
116
+ # Returns true if the connection is a replica.
117
+ #
118
+ # If the application is using legacy handling, returns
119
+ # true if `connection_handler.prevent_writes` is set.
120
+ #
121
+ # If the application is using the new connection handling
122
+ # will return true based on `current_preventing_writes`.
123
+ def preventing_writes?
124
+ return true if replica?
125
+ return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
126
+ return false if owner_name.nil?
127
+
128
+ klass = self.owner_name.safe_constantize
129
+ klass&.current_preventing_writes
122
130
  end
123
131
 
124
132
  def migrations_paths # :nodoc:
@@ -126,19 +134,52 @@ module ActiveRecord
126
134
  end
127
135
 
128
136
  def migration_context # :nodoc:
129
- MigrationContext.new(migrations_paths)
137
+ MigrationContext.new(migrations_paths, schema_migration)
138
+ end
139
+
140
+ def schema_migration # :nodoc:
141
+ @schema_migration ||= begin
142
+ conn = self
143
+ spec_name = conn.pool.pool_config.connection_specification_name
144
+
145
+ return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
146
+
147
+ schema_migration_name = "#{spec_name}::SchemaMigration"
148
+
149
+ Class.new(ActiveRecord::SchemaMigration) do
150
+ define_singleton_method(:name) { schema_migration_name }
151
+ define_singleton_method(:to_s) { schema_migration_name }
152
+
153
+ self.connection_specification_name = spec_name
154
+ end
155
+ end
156
+ end
157
+
158
+ def prepared_statements
159
+ @prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
160
+ end
161
+
162
+ def prepared_statements_disabled_cache # :nodoc:
163
+ Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
130
164
  end
131
165
 
132
166
  class Version
133
167
  include Comparable
134
168
 
135
- def initialize(version_string)
169
+ attr_reader :full_version_string
170
+
171
+ def initialize(version_string, full_version_string = nil)
136
172
  @version = version_string.split(".").map(&:to_i)
173
+ @full_version_string = full_version_string
137
174
  end
138
175
 
139
176
  def <=>(version_string)
140
177
  @version <=> version_string.split(".").map(&:to_i)
141
178
  end
179
+
180
+ def to_s
181
+ @version.join(".")
182
+ end
142
183
  end
143
184
 
144
185
  def valid_type?(type) # :nodoc:
@@ -148,7 +189,7 @@ module ActiveRecord
148
189
  # this method must only be called while holding connection pool's mutex
149
190
  def lease
150
191
  if in_use?
151
- msg = "Cannot lease connection, ".dup
192
+ msg = +"Cannot lease connection, "
152
193
  if @owner == Thread.current
153
194
  msg << "it is already leased by the current thread."
154
195
  else
@@ -161,9 +202,17 @@ module ActiveRecord
161
202
  @owner = Thread.current
162
203
  end
163
204
 
205
+ def owner_name # :nodoc:
206
+ @pool.owner_name
207
+ end
208
+
209
+ def schema_cache
210
+ @pool.get_schema_cache(self)
211
+ end
212
+
164
213
  def schema_cache=(cache)
165
214
  cache.connection = self
166
- @schema_cache = cache
215
+ @pool.set_schema_cache(cache)
167
216
  end
168
217
 
169
218
  # this method must only be called while holding connection pool's mutex
@@ -202,10 +251,10 @@ module ActiveRecord
202
251
  end
203
252
 
204
253
  def unprepared_statement
205
- old_prepared_statements, @prepared_statements = @prepared_statements, false
254
+ cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
206
255
  yield
207
256
  ensure
208
- @prepared_statements = old_prepared_statements
257
+ cache&.delete(object_id)
209
258
  end
210
259
 
211
260
  # Returns the human-readable name of the adapter. Use mixed case - one
@@ -214,6 +263,11 @@ module ActiveRecord
214
263
  self.class::ADAPTER_NAME
215
264
  end
216
265
 
266
+ # Does the database for this adapter exist?
267
+ def self.database_exists?(config)
268
+ raise NotImplementedError
269
+ end
270
+
217
271
  # Does this adapter support DDL rollbacks in transactions? That is, would
218
272
  # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
219
273
  def supports_ddl_transactions?
@@ -241,6 +295,10 @@ module ActiveRecord
241
295
  false
242
296
  end
243
297
 
298
+ def supports_partitioned_indexes?
299
+ false
300
+ end
301
+
244
302
  # Does this adapter support index sort order?
245
303
  def supports_index_sort_order?
246
304
  false
@@ -287,10 +345,9 @@ module ActiveRecord
287
345
  false
288
346
  end
289
347
 
290
- # Does this adapter support creating foreign key constraints
291
- # in the same statement as creating the table?
292
- def supports_foreign_keys_in_create?
293
- supports_foreign_keys?
348
+ # Does this adapter support creating check constraints?
349
+ def supports_check_constraints?
350
+ false
294
351
  end
295
352
 
296
353
  # Does this adapter support views?
@@ -298,6 +355,11 @@ module ActiveRecord
298
355
  false
299
356
  end
300
357
 
358
+ # Does this adapter support materialized views?
359
+ def supports_materialized_views?
360
+ false
361
+ end
362
+
301
363
  # Does this adapter support datetime with precision?
302
364
  def supports_datetime_with_precision?
303
365
  false
@@ -318,11 +380,6 @@ module ActiveRecord
318
380
  false
319
381
  end
320
382
 
321
- # Does this adapter support multi-value insert?
322
- def supports_multi_insert?
323
- true
324
- end
325
-
326
383
  # Does this adapter support virtual columns?
327
384
  def supports_virtual_columns?
328
385
  false
@@ -333,6 +390,35 @@ module ActiveRecord
333
390
  false
334
391
  end
335
392
 
393
+ # Does this adapter support optimizer hints?
394
+ def supports_optimizer_hints?
395
+ false
396
+ end
397
+
398
+ def supports_common_table_expressions?
399
+ false
400
+ end
401
+
402
+ def supports_lazy_transactions?
403
+ false
404
+ end
405
+
406
+ def supports_insert_returning?
407
+ false
408
+ end
409
+
410
+ def supports_insert_on_duplicate_skip?
411
+ false
412
+ end
413
+
414
+ def supports_insert_on_duplicate_update?
415
+ false
416
+ end
417
+
418
+ def supports_insert_conflict_target?
419
+ false
420
+ end
421
+
336
422
  # This is meant to be implemented by the adapters that support extensions
337
423
  def disable_extension(name)
338
424
  end
@@ -341,6 +427,10 @@ module ActiveRecord
341
427
  def enable_extension(name)
342
428
  end
343
429
 
430
+ def advisory_locks_enabled? # :nodoc:
431
+ supports_advisory_locks? && @advisory_locks_enabled
432
+ end
433
+
344
434
  # This is meant to be implemented by the adapters that support advisory
345
435
  # locks
346
436
  #
@@ -406,6 +496,9 @@ module ActiveRecord
406
496
  #
407
497
  # Prevent @connection's finalizer from touching the socket, or
408
498
  # otherwise communicating with its server, when it is collected.
499
+ if schema_cache.connection == self
500
+ schema_cache.connection = nil
501
+ end
409
502
  end
410
503
 
411
504
  # Reset the state of this connection, directing the DBMS to clear
@@ -418,11 +511,15 @@ module ActiveRecord
418
511
  # this should be overridden by concrete adapters
419
512
  end
420
513
 
421
- ###
422
- # Clear any caching the database adapter may be doing, for example
423
- # clearing the prepared statement cache. This is database specific.
514
+ # Removes the connection from the pool and disconnect it.
515
+ def throw_away!
516
+ pool.remove self
517
+ disconnect!
518
+ end
519
+
520
+ # Clear any caching the database adapter may be doing.
424
521
  def clear_cache!
425
- # this should be overridden by concrete adapters
522
+ @lock.synchronize { @statements.clear } if @statements
426
523
  end
427
524
 
428
525
  # Returns true if its required to reload the connection between requests for development mode.
@@ -444,18 +541,25 @@ module ActiveRecord
444
541
  # This is useful for when you need to call a proprietary method such as
445
542
  # PostgreSQL's lo_* methods.
446
543
  def raw_connection
544
+ disable_lazy_transactions!
447
545
  @connection
448
546
  end
449
547
 
450
- def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
451
- table[attribute].eq(value)
548
+ def default_uniqueness_comparison(attribute, value) # :nodoc:
549
+ attribute.eq(value)
550
+ end
551
+
552
+ def case_sensitive_comparison(attribute, value) # :nodoc:
553
+ attribute.eq(value)
452
554
  end
453
555
 
454
- def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
556
+ def case_insensitive_comparison(attribute, value) # :nodoc:
557
+ column = column_for_attribute(attribute)
558
+
455
559
  if can_perform_case_insensitive_comparison_for?(column)
456
- table[attribute].lower.eq(table.lower(value))
560
+ attribute.lower.eq(attribute.relation.lower(value))
457
561
  else
458
- table[attribute].eq(value)
562
+ attribute.eq(value)
459
563
  end
460
564
  end
461
565
 
@@ -469,16 +573,31 @@ module ActiveRecord
469
573
  pool.checkin self
470
574
  end
471
575
 
472
- def column_name_for_operation(operation, node) # :nodoc:
473
- column_name_from_arel_node(node)
576
+ def default_index_type?(index) # :nodoc:
577
+ index.using.nil?
474
578
  end
475
579
 
476
- def column_name_from_arel_node(node) # :nodoc:
477
- visitor.accept(node, Arel::Collectors::SQLString.new).value
580
+ # Called by ActiveRecord::InsertAll,
581
+ # Passed an instance of ActiveRecord::InsertAll::Builder,
582
+ # This method implements standard bulk inserts for all databases, but
583
+ # should be overridden by adapters to implement common features with
584
+ # non-standard syntax like handling duplicates or returning values.
585
+ def build_insert_sql(insert) # :nodoc:
586
+ if insert.skip_duplicates? || insert.update_duplicates?
587
+ raise NotImplementedError, "#{self.class} should define `build_insert_sql` to implement adapter-specific logic for handling duplicates during INSERT"
588
+ end
589
+
590
+ "INSERT #{insert.into} #{insert.values_list}"
478
591
  end
479
592
 
480
- def default_index_type?(index) # :nodoc:
481
- index.using.nil?
593
+ def get_database_version # :nodoc:
594
+ end
595
+
596
+ def database_version # :nodoc:
597
+ schema_cache.database_version
598
+ end
599
+
600
+ def check_version # :nodoc:
482
601
  end
483
602
 
484
603
  private
@@ -555,14 +674,12 @@ module ActiveRecord
555
674
  $1.to_i if sql_type =~ /\((.*)\)/
556
675
  end
557
676
 
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
677
+ def translate_exception_class(e, sql, binds)
678
+ message = "#{e.class.name}: #{e.message}"
564
679
 
565
- exception = translate_exception(e, message)
680
+ exception = translate_exception(
681
+ e, message: message, sql: sql, binds: binds
682
+ )
566
683
  exception.set_backtrace e.backtrace
567
684
  exception
568
685
  end
@@ -575,24 +692,22 @@ module ActiveRecord
575
692
  binds: binds,
576
693
  type_casted_binds: type_casted_binds,
577
694
  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)
695
+ connection: self) do
696
+ @lock.synchronize do
697
+ yield
585
698
  end
699
+ rescue => e
700
+ raise translate_exception_class(e, sql, binds)
586
701
  end
587
702
  end
588
703
 
589
- def translate_exception(exception, message)
704
+ def translate_exception(exception, message:, sql:, binds:)
590
705
  # override in derived class
591
706
  case exception
592
707
  when RuntimeError
593
708
  exception
594
709
  else
595
- ActiveRecord::StatementInvalid.new(message)
710
+ ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
596
711
  end
597
712
  end
598
713
 
@@ -606,6 +721,11 @@ module ActiveRecord
606
721
  raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
607
722
  end
608
723
 
724
+ def column_for_attribute(attribute)
725
+ table_name = attribute.relation.name
726
+ schema_cache.columns_hash(table_name)[attribute.name.to_s]
727
+ end
728
+
609
729
  def collector
610
730
  if prepared_statements
611
731
  Arel::Collectors::Composite.new(
@@ -623,6 +743,17 @@ module ActiveRecord
623
743
  def arel_visitor
624
744
  Arel::Visitors::ToSql.new(self)
625
745
  end
746
+
747
+ def build_statement_pool
748
+ end
749
+
750
+ # Builds the result object.
751
+ #
752
+ # This is an internal hook to make possible connection adapters to build
753
+ # custom result objects with connection-specific data.
754
+ def build_result(columns:, rows:, column_types: {})
755
+ ActiveRecord::Result.new(columns, rows, column_types)
756
+ end
626
757
  end
627
758
  end
628
759
  end