activerecord 5.2.8.1 → 6.1.6.1

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 +1255 -596
  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 +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  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 +44 -34
  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 +24 -18
  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 +44 -22
  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 +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  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 +137 -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 +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  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 +272 -130
  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 +18 -14
  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 +211 -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 +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  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 +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -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 +59 -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 +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -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 +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -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/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  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 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  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 +11 -10
  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 +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  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 +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  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 +4 -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 +49 -6
  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 +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -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 +287 -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 +62 -118
  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 +76 -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 +116 -30
  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,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_record/connection_adapters/determine_if_preparable_visitor"
4
- require "active_record/connection_adapters/schema_cache"
3
+ require "set"
5
4
  require "active_record/connection_adapters/sql_type_metadata"
6
5
  require "active_record/connection_adapters/abstract/schema_dumper"
7
6
  require "active_record/connection_adapters/abstract/schema_creation"
@@ -13,44 +12,6 @@ require "arel/collectors/substitute_binds"
13
12
 
14
13
  module ActiveRecord
15
14
  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
15
  # Active Record supports multiple database systems. AbstractAdapter and
55
16
  # related classes form the abstraction layer which makes this possible.
56
17
  # An AbstractAdapter represents a connection to a database, and provides an
@@ -65,7 +26,7 @@ module ActiveRecord
65
26
  # Most of the methods in the adapter are useful during migrations. Most
66
27
  # notably, the instance methods provided by SchemaStatements are very useful.
67
28
  class AbstractAdapter
68
- ADAPTER_NAME = "Abstract".freeze
29
+ ADAPTER_NAME = "Abstract"
69
30
  include ActiveSupport::Callbacks
70
31
  define_callbacks :checkout, :checkin
71
32
 
@@ -75,15 +36,18 @@ module ActiveRecord
75
36
  include Savepoints
76
37
 
77
38
  SIMPLE_INT = /\A\d+\z/
39
+ COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
78
40
 
79
- attr_accessor :visitor, :pool
80
- attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
41
+ attr_accessor :pool
42
+ attr_reader :visitor, :owner, :logger, :lock
81
43
  alias :in_use? :owner
82
44
 
45
+ set_callback :checkin, :after, :enable_lazy_transactions!
46
+
83
47
  def self.type_cast_config_to_integer(config)
84
48
  if config.is_a?(Integer)
85
49
  config
86
- elsif config =~ SIMPLE_INT
50
+ elsif SIMPLE_INT.match?(config)
87
51
  config.to_i
88
52
  else
89
53
  config
@@ -98,6 +62,23 @@ module ActiveRecord
98
62
  end
99
63
  end
100
64
 
65
+ DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
66
+ private_constant :DEFAULT_READ_QUERY
67
+
68
+ def self.build_read_query_regexp(*parts) # :nodoc:
69
+ parts += DEFAULT_READ_QUERY
70
+ parts = parts.map { |part| /#{part}/i }
71
+ /\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
72
+ end
73
+
74
+ def self.quoted_column_names # :nodoc:
75
+ @quoted_column_names ||= {}
76
+ end
77
+
78
+ def self.quoted_table_names # :nodoc:
79
+ @quoted_table_names ||= {}
80
+ end
81
+
101
82
  def initialize(connection, logger = nil, config = {}) # :nodoc:
102
83
  super()
103
84
 
@@ -106,19 +87,44 @@ module ActiveRecord
106
87
  @instrumenter = ActiveSupport::Notifications.instrumenter
107
88
  @logger = logger
108
89
  @config = config
109
- @pool = nil
90
+ @pool = ActiveRecord::ConnectionAdapters::NullPool.new
110
91
  @idle_since = Concurrent.monotonic_time
111
- @schema_cache = SchemaCache.new self
112
- @quoted_column_names, @quoted_table_names = {}, {}
113
92
  @visitor = arel_visitor
93
+ @statements = build_statement_pool
114
94
  @lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
115
95
 
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
96
+ @prepared_statements = self.class.type_cast_config_to_boolean(
97
+ config.fetch(:prepared_statements, true)
98
+ )
99
+
100
+ @advisory_locks_enabled = self.class.type_cast_config_to_boolean(
101
+ config.fetch(:advisory_locks, true)
102
+ )
103
+ end
104
+
105
+ def replica?
106
+ @config[:replica] || false
107
+ end
108
+
109
+ def use_metadata_table?
110
+ @config.fetch(:use_metadata_table, true)
111
+ end
112
+
113
+ # Determines whether writes are currently being prevented.
114
+ #
115
+ # Returns true if the connection is a replica.
116
+ #
117
+ # If the application is using legacy handling, returns
118
+ # true if +connection_handler.prevent_writes+ is set.
119
+ #
120
+ # If the application is using the new connection handling
121
+ # will return true based on +current_preventing_writes+.
122
+ def preventing_writes?
123
+ return true if replica?
124
+ return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
125
+ return false if connection_klass.nil?
126
+
127
+ connection_klass.current_preventing_writes
122
128
  end
123
129
 
124
130
  def migrations_paths # :nodoc:
@@ -126,19 +132,53 @@ module ActiveRecord
126
132
  end
127
133
 
128
134
  def migration_context # :nodoc:
129
- MigrationContext.new(migrations_paths)
135
+ MigrationContext.new(migrations_paths, schema_migration)
136
+ end
137
+
138
+ def schema_migration # :nodoc:
139
+ @schema_migration ||= begin
140
+ conn = self
141
+ spec_name = conn.pool.pool_config.connection_specification_name
142
+
143
+ return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
144
+
145
+ schema_migration_name = "#{spec_name}::SchemaMigration"
146
+
147
+ Class.new(ActiveRecord::SchemaMigration) do
148
+ define_singleton_method(:name) { schema_migration_name }
149
+ define_singleton_method(:to_s) { schema_migration_name }
150
+
151
+ self.connection_specification_name = spec_name
152
+ end
153
+ end
154
+ end
155
+
156
+ def prepared_statements?
157
+ @prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
158
+ end
159
+ alias :prepared_statements :prepared_statements?
160
+
161
+ def prepared_statements_disabled_cache # :nodoc:
162
+ Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
130
163
  end
131
164
 
132
165
  class Version
133
166
  include Comparable
134
167
 
135
- def initialize(version_string)
168
+ attr_reader :full_version_string
169
+
170
+ def initialize(version_string, full_version_string = nil)
136
171
  @version = version_string.split(".").map(&:to_i)
172
+ @full_version_string = full_version_string
137
173
  end
138
174
 
139
175
  def <=>(version_string)
140
176
  @version <=> version_string.split(".").map(&:to_i)
141
177
  end
178
+
179
+ def to_s
180
+ @version.join(".")
181
+ end
142
182
  end
143
183
 
144
184
  def valid_type?(type) # :nodoc:
@@ -148,7 +188,7 @@ module ActiveRecord
148
188
  # this method must only be called while holding connection pool's mutex
149
189
  def lease
150
190
  if in_use?
151
- msg = "Cannot lease connection, ".dup
191
+ msg = +"Cannot lease connection, "
152
192
  if @owner == Thread.current
153
193
  msg << "it is already leased by the current thread."
154
194
  else
@@ -161,9 +201,17 @@ module ActiveRecord
161
201
  @owner = Thread.current
162
202
  end
163
203
 
204
+ def connection_klass # :nodoc:
205
+ @pool.connection_klass
206
+ end
207
+
208
+ def schema_cache
209
+ @pool.get_schema_cache(self)
210
+ end
211
+
164
212
  def schema_cache=(cache)
165
213
  cache.connection = self
166
- @schema_cache = cache
214
+ @pool.set_schema_cache(cache)
167
215
  end
168
216
 
169
217
  # this method must only be called while holding connection pool's mutex
@@ -202,10 +250,10 @@ module ActiveRecord
202
250
  end
203
251
 
204
252
  def unprepared_statement
205
- old_prepared_statements, @prepared_statements = @prepared_statements, false
253
+ cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
206
254
  yield
207
255
  ensure
208
- @prepared_statements = old_prepared_statements
256
+ cache&.delete(object_id)
209
257
  end
210
258
 
211
259
  # Returns the human-readable name of the adapter. Use mixed case - one
@@ -214,6 +262,11 @@ module ActiveRecord
214
262
  self.class::ADAPTER_NAME
215
263
  end
216
264
 
265
+ # Does the database for this adapter exist?
266
+ def self.database_exists?(config)
267
+ raise NotImplementedError
268
+ end
269
+
217
270
  # Does this adapter support DDL rollbacks in transactions? That is, would
218
271
  # CREATE TABLE or ALTER TABLE get rolled back by a transaction?
219
272
  def supports_ddl_transactions?
@@ -241,6 +294,10 @@ module ActiveRecord
241
294
  false
242
295
  end
243
296
 
297
+ def supports_partitioned_indexes?
298
+ false
299
+ end
300
+
244
301
  # Does this adapter support index sort order?
245
302
  def supports_index_sort_order?
246
303
  false
@@ -287,10 +344,9 @@ module ActiveRecord
287
344
  false
288
345
  end
289
346
 
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?
347
+ # Does this adapter support creating check constraints?
348
+ def supports_check_constraints?
349
+ false
294
350
  end
295
351
 
296
352
  # Does this adapter support views?
@@ -298,6 +354,11 @@ module ActiveRecord
298
354
  false
299
355
  end
300
356
 
357
+ # Does this adapter support materialized views?
358
+ def supports_materialized_views?
359
+ false
360
+ end
361
+
301
362
  # Does this adapter support datetime with precision?
302
363
  def supports_datetime_with_precision?
303
364
  false
@@ -318,11 +379,6 @@ module ActiveRecord
318
379
  false
319
380
  end
320
381
 
321
- # Does this adapter support multi-value insert?
322
- def supports_multi_insert?
323
- true
324
- end
325
-
326
382
  # Does this adapter support virtual columns?
327
383
  def supports_virtual_columns?
328
384
  false
@@ -333,6 +389,35 @@ module ActiveRecord
333
389
  false
334
390
  end
335
391
 
392
+ # Does this adapter support optimizer hints?
393
+ def supports_optimizer_hints?
394
+ false
395
+ end
396
+
397
+ def supports_common_table_expressions?
398
+ false
399
+ end
400
+
401
+ def supports_lazy_transactions?
402
+ false
403
+ end
404
+
405
+ def supports_insert_returning?
406
+ false
407
+ end
408
+
409
+ def supports_insert_on_duplicate_skip?
410
+ false
411
+ end
412
+
413
+ def supports_insert_on_duplicate_update?
414
+ false
415
+ end
416
+
417
+ def supports_insert_conflict_target?
418
+ false
419
+ end
420
+
336
421
  # This is meant to be implemented by the adapters that support extensions
337
422
  def disable_extension(name)
338
423
  end
@@ -341,6 +426,10 @@ module ActiveRecord
341
426
  def enable_extension(name)
342
427
  end
343
428
 
429
+ def advisory_locks_enabled? # :nodoc:
430
+ supports_advisory_locks? && @advisory_locks_enabled
431
+ end
432
+
344
433
  # This is meant to be implemented by the adapters that support advisory
345
434
  # locks
346
435
  #
@@ -406,6 +495,9 @@ module ActiveRecord
406
495
  #
407
496
  # Prevent @connection's finalizer from touching the socket, or
408
497
  # otherwise communicating with its server, when it is collected.
498
+ if schema_cache.connection == self
499
+ schema_cache.connection = nil
500
+ end
409
501
  end
410
502
 
411
503
  # Reset the state of this connection, directing the DBMS to clear
@@ -418,11 +510,15 @@ module ActiveRecord
418
510
  # this should be overridden by concrete adapters
419
511
  end
420
512
 
421
- ###
422
- # Clear any caching the database adapter may be doing, for example
423
- # clearing the prepared statement cache. This is database specific.
513
+ # Removes the connection from the pool and disconnect it.
514
+ def throw_away!
515
+ pool.remove self
516
+ disconnect!
517
+ end
518
+
519
+ # Clear any caching the database adapter may be doing.
424
520
  def clear_cache!
425
- # this should be overridden by concrete adapters
521
+ @lock.synchronize { @statements.clear } if @statements
426
522
  end
427
523
 
428
524
  # Returns true if its required to reload the connection between requests for development mode.
@@ -444,18 +540,25 @@ module ActiveRecord
444
540
  # This is useful for when you need to call a proprietary method such as
445
541
  # PostgreSQL's lo_* methods.
446
542
  def raw_connection
543
+ disable_lazy_transactions!
447
544
  @connection
448
545
  end
449
546
 
450
- def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
451
- table[attribute].eq(value)
547
+ def default_uniqueness_comparison(attribute, value) # :nodoc:
548
+ attribute.eq(value)
549
+ end
550
+
551
+ def case_sensitive_comparison(attribute, value) # :nodoc:
552
+ attribute.eq(value)
452
553
  end
453
554
 
454
- def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
555
+ def case_insensitive_comparison(attribute, value) # :nodoc:
556
+ column = column_for_attribute(attribute)
557
+
455
558
  if can_perform_case_insensitive_comparison_for?(column)
456
- table[attribute].lower.eq(table.lower(value))
559
+ attribute.lower.eq(attribute.relation.lower(value))
457
560
  else
458
- table[attribute].eq(value)
561
+ attribute.eq(value)
459
562
  end
460
563
  end
461
564
 
@@ -469,16 +572,31 @@ module ActiveRecord
469
572
  pool.checkin self
470
573
  end
471
574
 
472
- def column_name_for_operation(operation, node) # :nodoc:
473
- column_name_from_arel_node(node)
575
+ def default_index_type?(index) # :nodoc:
576
+ index.using.nil?
474
577
  end
475
578
 
476
- def column_name_from_arel_node(node) # :nodoc:
477
- visitor.accept(node, Arel::Collectors::SQLString.new).value
579
+ # Called by ActiveRecord::InsertAll,
580
+ # Passed an instance of ActiveRecord::InsertAll::Builder,
581
+ # This method implements standard bulk inserts for all databases, but
582
+ # should be overridden by adapters to implement common features with
583
+ # non-standard syntax like handling duplicates or returning values.
584
+ def build_insert_sql(insert) # :nodoc:
585
+ if insert.skip_duplicates? || insert.update_duplicates?
586
+ raise NotImplementedError, "#{self.class} should define `build_insert_sql` to implement adapter-specific logic for handling duplicates during INSERT"
587
+ end
588
+
589
+ "INSERT #{insert.into} #{insert.values_list}"
478
590
  end
479
591
 
480
- def default_index_type?(index) # :nodoc:
481
- index.using.nil?
592
+ def get_database_version # :nodoc:
593
+ end
594
+
595
+ def database_version # :nodoc:
596
+ schema_cache.database_version
597
+ end
598
+
599
+ def check_version # :nodoc:
482
600
  end
483
601
 
484
602
  private
@@ -555,14 +673,12 @@ module ActiveRecord
555
673
  $1.to_i if sql_type =~ /\((.*)\)/
556
674
  end
557
675
 
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
676
+ def translate_exception_class(e, sql, binds)
677
+ message = "#{e.class.name}: #{e.message}"
564
678
 
565
- exception = translate_exception(e, message)
679
+ exception = translate_exception(
680
+ e, message: message, sql: sql, binds: binds
681
+ )
566
682
  exception.set_backtrace e.backtrace
567
683
  exception
568
684
  end
@@ -575,24 +691,22 @@ module ActiveRecord
575
691
  binds: binds,
576
692
  type_casted_binds: type_casted_binds,
577
693
  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)
694
+ connection: self) do
695
+ @lock.synchronize do
696
+ yield
585
697
  end
698
+ rescue => e
699
+ raise translate_exception_class(e, sql, binds)
586
700
  end
587
701
  end
588
702
 
589
- def translate_exception(exception, message)
703
+ def translate_exception(exception, message:, sql:, binds:)
590
704
  # override in derived class
591
705
  case exception
592
706
  when RuntimeError
593
707
  exception
594
708
  else
595
- ActiveRecord::StatementInvalid.new(message)
709
+ ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
596
710
  end
597
711
  end
598
712
 
@@ -606,6 +720,11 @@ module ActiveRecord
606
720
  raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
607
721
  end
608
722
 
723
+ def column_for_attribute(attribute)
724
+ table_name = attribute.relation.name
725
+ schema_cache.columns_hash(table_name)[attribute.name.to_s]
726
+ end
727
+
609
728
  def collector
610
729
  if prepared_statements
611
730
  Arel::Collectors::Composite.new(
@@ -623,6 +742,17 @@ module ActiveRecord
623
742
  def arel_visitor
624
743
  Arel::Visitors::ToSql.new(self)
625
744
  end
745
+
746
+ def build_statement_pool
747
+ end
748
+
749
+ # Builds the result object.
750
+ #
751
+ # This is an internal hook to make possible connection adapters to build
752
+ # custom result objects with connection-specific data.
753
+ def build_result(columns:, rows:, column_types: {})
754
+ ActiveRecord::Result.new(columns, rows, column_types)
755
+ end
626
756
  end
627
757
  end
628
758
  end