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
@@ -4,17 +4,20 @@ require "active_record/connection_adapters/abstract_adapter"
4
4
  require "active_record/connection_adapters/statement_pool"
5
5
  require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
6
6
  require "active_record/connection_adapters/sqlite3/quoting"
7
+ require "active_record/connection_adapters/sqlite3/database_statements"
7
8
  require "active_record/connection_adapters/sqlite3/schema_creation"
8
9
  require "active_record/connection_adapters/sqlite3/schema_definitions"
9
10
  require "active_record/connection_adapters/sqlite3/schema_dumper"
10
11
  require "active_record/connection_adapters/sqlite3/schema_statements"
11
12
 
12
- gem "sqlite3", "~> 1.3", ">= 1.3.6"
13
+ gem "sqlite3", "~> 1.4"
13
14
  require "sqlite3"
14
15
 
15
16
  module ActiveRecord
16
17
  module ConnectionHandling # :nodoc:
17
18
  def sqlite3_connection(config)
19
+ config = config.symbolize_keys
20
+
18
21
  # Require database.
19
22
  unless config[:database]
20
23
  raise ArgumentError, "No database file specified. Missing argument: database"
@@ -23,7 +26,7 @@ module ActiveRecord
23
26
  # Allow database path relative to Rails.root, but only if the database
24
27
  # path is not the special path that tells sqlite to build a database only
25
28
  # in memory.
26
- if ":memory:" != config[:database]
29
+ if ":memory:" != config[:database] && !config[:database].to_s.start_with?("file:")
27
30
  config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
28
31
  dirname = File.dirname(config[:database])
29
32
  Dir.mkdir(dirname) unless File.directory?(dirname)
@@ -31,11 +34,9 @@ module ActiveRecord
31
34
 
32
35
  db = SQLite3::Database.new(
33
36
  config[:database].to_s,
34
- results_as_hash: true
37
+ config.merge(results_as_hash: true)
35
38
  )
36
39
 
37
- db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]
38
-
39
40
  ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config)
40
41
  rescue Errno::ENOENT => error
41
42
  if error.message.include?("No such file or directory")
@@ -47,17 +48,18 @@ module ActiveRecord
47
48
  end
48
49
 
49
50
  module ConnectionAdapters #:nodoc:
50
- # The SQLite3 adapter works SQLite 3.6.16 or newer
51
- # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
51
+ # The SQLite3 adapter works with the sqlite3-ruby drivers
52
+ # (available as gem from https://rubygems.org/gems/sqlite3).
52
53
  #
53
54
  # Options:
54
55
  #
55
56
  # * <tt>:database</tt> - Path to the database file.
56
57
  class SQLite3Adapter < AbstractAdapter
57
- ADAPTER_NAME = "SQLite".freeze
58
+ ADAPTER_NAME = "SQLite"
58
59
 
59
60
  include SQLite3::Quoting
60
61
  include SQLite3::SchemaStatements
62
+ include SQLite3::DatabaseStatements
61
63
 
62
64
  NATIVE_DATABASE_TYPES = {
63
65
  primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
@@ -74,39 +76,28 @@ module ActiveRecord
74
76
  json: { name: "json" },
75
77
  }
76
78
 
77
- ##
78
- # :singleton-method:
79
- # Indicates whether boolean values are stored in sqlite3 databases as 1
80
- # and 0 or 't' and 'f'. Leaving <tt>ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer</tt>
81
- # set to false is deprecated. SQLite databases have used 't' and 'f' to
82
- # serialize boolean values and must have old data converted to 1 and 0
83
- # (its native boolean serialization) before setting this flag to true.
84
- # Conversion can be accomplished by setting up a rake task which runs
85
- #
86
- # ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
87
- # ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
88
- # for all models and all boolean columns, after which the flag must be set
89
- # to true by adding the following to your <tt>application.rb</tt> file:
90
- #
91
- # Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
92
- class_attribute :represent_boolean_as_integer, default: false
93
-
94
79
  class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
95
80
  private
96
81
  def dealloc(stmt)
97
- stmt[:stmt].close unless stmt[:stmt].closed?
82
+ stmt.close unless stmt.closed?
98
83
  end
99
84
  end
100
85
 
101
86
  def initialize(connection, logger, connection_options, config)
102
87
  super(connection, logger, config)
103
-
104
- @active = true
105
- @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
106
-
107
88
  configure_connection
108
89
  end
109
90
 
91
+ def self.database_exists?(config)
92
+ config = config.symbolize_keys
93
+ if config[:database] == ":memory:"
94
+ true
95
+ else
96
+ database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
97
+ File.exist?(database_file)
98
+ end
99
+ end
100
+
110
101
  def supports_ddl_transactions?
111
102
  true
112
103
  end
@@ -115,16 +106,28 @@ module ActiveRecord
115
106
  true
116
107
  end
117
108
 
109
+ def supports_transaction_isolation?
110
+ true
111
+ end
112
+
118
113
  def supports_partial_index?
119
- sqlite_version >= "3.8.0"
114
+ true
115
+ end
116
+
117
+ def supports_expression_index?
118
+ database_version >= "3.9.0"
120
119
  end
121
120
 
122
121
  def requires_reloading?
123
122
  true
124
123
  end
125
124
 
126
- def supports_foreign_keys_in_create?
127
- sqlite_version >= "3.6.19"
125
+ def supports_foreign_keys?
126
+ true
127
+ end
128
+
129
+ def supports_check_constraints?
130
+ true
128
131
  end
129
132
 
130
133
  def supports_views?
@@ -139,38 +142,37 @@ module ActiveRecord
139
142
  true
140
143
  end
141
144
 
142
- def supports_multi_insert?
143
- sqlite_version >= "3.7.11"
145
+ def supports_common_table_expressions?
146
+ database_version >= "3.8.3"
147
+ end
148
+
149
+ def supports_insert_on_conflict?
150
+ database_version >= "3.24.0"
144
151
  end
152
+ alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
153
+ alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
154
+ alias supports_insert_conflict_target? supports_insert_on_conflict?
145
155
 
146
156
  def active?
147
- @active
157
+ !@connection.closed?
158
+ end
159
+
160
+ def reconnect!
161
+ super
162
+ connect if @connection.closed?
148
163
  end
149
164
 
150
165
  # Disconnects from the database if already connected. Otherwise, this
151
166
  # method does nothing.
152
167
  def disconnect!
153
168
  super
154
- @active = false
155
169
  @connection.close rescue nil
156
170
  end
157
171
 
158
- # Clears the prepared statements cache.
159
- def clear_cache!
160
- @statements.clear
161
- end
162
-
163
172
  def supports_index_sort_order?
164
173
  true
165
174
  end
166
175
 
167
- # Returns 62. SQLite supports index names up to 64
168
- # characters. The rest is used by Rails internally to perform
169
- # temporary rename operations
170
- def allowed_index_name_length
171
- index_name_length - 2
172
- end
173
-
174
176
  def native_database_types #:nodoc:
175
177
  NATIVE_DATABASE_TYPES
176
178
  end
@@ -184,91 +186,26 @@ module ActiveRecord
184
186
  true
185
187
  end
186
188
 
189
+ def supports_lazy_transactions?
190
+ true
191
+ end
192
+
187
193
  # REFERENTIAL INTEGRITY ====================================
188
194
 
189
195
  def disable_referential_integrity # :nodoc:
190
- old = query_value("PRAGMA foreign_keys")
196
+ old_foreign_keys = query_value("PRAGMA foreign_keys")
197
+ old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys")
191
198
 
192
199
  begin
200
+ execute("PRAGMA defer_foreign_keys = ON")
193
201
  execute("PRAGMA foreign_keys = OFF")
194
202
  yield
195
203
  ensure
196
- execute("PRAGMA foreign_keys = #{old}")
204
+ execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
205
+ execute("PRAGMA foreign_keys = #{old_foreign_keys}")
197
206
  end
198
207
  end
199
208
 
200
- #--
201
- # DATABASE STATEMENTS ======================================
202
- #++
203
-
204
- def explain(arel, binds = [])
205
- sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
206
- SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
207
- end
208
-
209
- def exec_query(sql, name = nil, binds = [], prepare: false)
210
- type_casted_binds = type_casted_binds(binds)
211
-
212
- log(sql, name, binds, type_casted_binds) do
213
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
214
- # Don't cache statements if they are not prepared
215
- unless prepare
216
- stmt = @connection.prepare(sql)
217
- begin
218
- cols = stmt.columns
219
- unless without_prepared_statement?(binds)
220
- stmt.bind_params(type_casted_binds)
221
- end
222
- records = stmt.to_a
223
- ensure
224
- stmt.close
225
- end
226
- else
227
- cache = @statements[sql] ||= {
228
- stmt: @connection.prepare(sql)
229
- }
230
- stmt = cache[:stmt]
231
- cols = cache[:cols] ||= stmt.columns
232
- stmt.reset!
233
- stmt.bind_params(type_casted_binds)
234
- records = stmt.to_a
235
- end
236
-
237
- ActiveRecord::Result.new(cols, records)
238
- end
239
- end
240
- end
241
-
242
- def exec_delete(sql, name = "SQL", binds = [])
243
- exec_query(sql, name, binds)
244
- @connection.changes
245
- end
246
- alias :exec_update :exec_delete
247
-
248
- def last_inserted_id(result)
249
- @connection.last_insert_row_id
250
- end
251
-
252
- def execute(sql, name = nil) #:nodoc:
253
- log(sql, name) do
254
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
255
- @connection.execute(sql)
256
- end
257
- end
258
- end
259
-
260
- def begin_db_transaction #:nodoc:
261
- log("begin transaction", nil) { @connection.transaction }
262
- end
263
-
264
- def commit_db_transaction #:nodoc:
265
- log("commit transaction", nil) { @connection.commit }
266
- end
267
-
268
- def exec_rollback_db_transaction #:nodoc:
269
- log("rollback transaction", nil) { @connection.rollback }
270
- end
271
-
272
209
  # SCHEMA STATEMENTS ========================================
273
210
 
274
211
  def primary_keys(table_name) # :nodoc:
@@ -276,8 +213,11 @@ module ActiveRecord
276
213
  pks.sort_by { |f| f["pk"] }.map { |f| f["name"] }
277
214
  end
278
215
 
279
- def remove_index(table_name, options = {}) #:nodoc:
280
- index_name = index_name_for_remove(table_name, options)
216
+ def remove_index(table_name, column_name = nil, **options) # :nodoc:
217
+ return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
218
+
219
+ index_name = index_name_for_remove(table_name, column_name, options)
220
+
281
221
  exec_query "DROP INDEX #{quote_column_name(index_name)}"
282
222
  end
283
223
 
@@ -286,28 +226,28 @@ module ActiveRecord
286
226
  # Example:
287
227
  # rename_table('octopuses', 'octopi')
288
228
  def rename_table(table_name, new_name)
229
+ schema_cache.clear_data_source_cache!(table_name.to_s)
230
+ schema_cache.clear_data_source_cache!(new_name.to_s)
289
231
  exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
290
232
  rename_table_indexes(table_name, new_name)
291
233
  end
292
234
 
293
- def valid_alter_table_type?(type, options = {})
294
- !invalid_alter_table_type?(type, options)
295
- end
296
- deprecate :valid_alter_table_type?
297
-
298
- def add_column(table_name, column_name, type, options = {}) #:nodoc:
235
+ def add_column(table_name, column_name, type, **options) #:nodoc:
299
236
  if invalid_alter_table_type?(type, options)
300
237
  alter_table(table_name) do |definition|
301
- definition.column(column_name, type, options)
238
+ definition.column(column_name, type, **options)
302
239
  end
303
240
  else
304
241
  super
305
242
  end
306
243
  end
307
244
 
308
- def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
245
+ def remove_column(table_name, column_name, type = nil, **options) #:nodoc:
309
246
  alter_table(table_name) do |definition|
310
247
  definition.remove_column column_name
248
+ definition.foreign_keys.delete_if do |_, fk_options|
249
+ fk_options[:column] == column_name.to_s
250
+ end
311
251
  end
312
252
  end
313
253
 
@@ -328,16 +268,11 @@ module ActiveRecord
328
268
  end
329
269
  end
330
270
 
331
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
271
+ def change_column(table_name, column_name, type, **options) #:nodoc:
332
272
  alter_table(table_name) do |definition|
333
273
  definition[column_name].instance_eval do
334
- self.type = type
335
- self.limit = options[:limit] if options.include?(:limit)
336
- self.default = options[:default] if options.include?(:default)
337
- self.null = options[:null] if options.include?(:null)
338
- self.precision = options[:precision] if options.include?(:precision)
339
- self.scale = options[:scale] if options.include?(:scale)
340
- self.collation = options[:collation] if options.include?(:collation)
274
+ self.type = aliased_types(type.to_s, type)
275
+ self.options.merge!(options)
341
276
  end
342
277
  end
343
278
  end
@@ -366,27 +301,41 @@ module ActiveRecord
366
301
  end
367
302
  end
368
303
 
369
- def insert_fixtures(rows, table_name)
370
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
371
- `insert_fixtures` is deprecated and will be removed in the next version of Rails.
372
- Consider using `insert_fixtures_set` for performance improvement.
373
- MSG
374
- insert_fixtures_set(table_name => rows)
304
+ def build_insert_sql(insert) # :nodoc:
305
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
306
+
307
+ if insert.skip_duplicates?
308
+ sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
309
+ elsif insert.update_duplicates?
310
+ sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
311
+ sql << insert.touch_model_timestamps_unless { |column| "#{column} IS excluded.#{column}" }
312
+ sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
313
+ end
314
+
315
+ sql
375
316
  end
376
317
 
377
- def insert_fixtures_set(fixture_set, tables_to_delete = [])
378
- disable_referential_integrity do
379
- transaction(requires_new: true) do
380
- tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
318
+ def shared_cache? # :nodoc:
319
+ @config.fetch(:flags, 0).anybits?(::SQLite3::Constants::Open::SHAREDCACHE)
320
+ end
381
321
 
382
- fixture_set.each do |table_name, rows|
383
- rows.each { |row| insert_fixture(row, table_name) }
384
- end
385
- end
322
+ def get_database_version # :nodoc:
323
+ SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
324
+ end
325
+
326
+ def check_version # :nodoc:
327
+ if database_version < "3.8.0"
328
+ raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
386
329
  end
387
330
  end
388
331
 
389
332
  private
333
+ # See https://www.sqlite.org/limits.html,
334
+ # the default value is 999 when not configured.
335
+ def bind_params_length
336
+ 999
337
+ end
338
+
390
339
  def initialize_type_map(m = type_map)
391
340
  super
392
341
  register_class_with_limit m, %r(int)i, SQLite3Integer
@@ -402,17 +351,40 @@ module ActiveRecord
402
351
  # See: https://www.sqlite.org/lang_altertable.html
403
352
  # SQLite has an additional restriction on the ALTER TABLE statement
404
353
  def invalid_alter_table_type?(type, options)
405
- type.to_sym == :primary_key || options[:primary_key]
354
+ type.to_sym == :primary_key || options[:primary_key] ||
355
+ options[:null] == false && options[:default].nil?
406
356
  end
407
357
 
408
- def alter_table(table_name, options = {})
358
+ def alter_table(
359
+ table_name,
360
+ foreign_keys = foreign_keys(table_name),
361
+ check_constraints = check_constraints(table_name),
362
+ **options
363
+ )
409
364
  altered_table_name = "a#{table_name}"
410
- caller = lambda { |definition| yield definition if block_given? }
365
+
366
+ caller = lambda do |definition|
367
+ rename = options[:rename] || {}
368
+ foreign_keys.each do |fk|
369
+ if column = rename[fk.options[:column]]
370
+ fk.options[:column] = column
371
+ end
372
+ to_table = strip_table_name_prefix_and_suffix(fk.to_table)
373
+ definition.foreign_key(to_table, **fk.options)
374
+ end
375
+
376
+ check_constraints.each do |chk|
377
+ definition.check_constraint(chk.expression, **chk.options)
378
+ end
379
+
380
+ yield definition if block_given?
381
+ end
411
382
 
412
383
  transaction do
413
- move_table(table_name, altered_table_name,
414
- options.merge(temporary: true))
415
- move_table(altered_table_name, table_name, &caller)
384
+ disable_referential_integrity do
385
+ move_table(table_name, altered_table_name, options.merge(temporary: true))
386
+ move_table(altered_table_name, table_name, &caller)
387
+ end
416
388
  end
417
389
  end
418
390
 
@@ -424,11 +396,12 @@ module ActiveRecord
424
396
  def copy_table(from, to, options = {})
425
397
  from_primary_key = primary_key(from)
426
398
  options[:id] = false
427
- create_table(to, options) do |definition|
399
+ create_table(to, **options) do |definition|
428
400
  @definition = definition
429
401
  if from_primary_key.is_a?(Array)
430
402
  @definition.primary_keys from_primary_key
431
403
  end
404
+
432
405
  columns(from).each do |column|
433
406
  column_name = options[:rename] ?
434
407
  (options[:rename][column.name] ||
@@ -442,6 +415,7 @@ module ActiveRecord
442
415
  primary_key: column_name == from_primary_key
443
416
  )
444
417
  end
418
+
445
419
  yield @definition if block_given?
446
420
  end
447
421
  copy_table_indexes(from, to, options[:rename] || {})
@@ -459,17 +433,20 @@ module ActiveRecord
459
433
  name = name[1..-1]
460
434
  end
461
435
 
462
- to_column_names = columns(to).map(&:name)
463
- columns = index.columns.map { |c| rename[c] || c }.select do |column|
464
- to_column_names.include?(column)
436
+ columns = index.columns
437
+ if columns.is_a?(Array)
438
+ to_column_names = columns(to).map(&:name)
439
+ columns = columns.map { |c| rename[c] || c }.select do |column|
440
+ to_column_names.include?(column)
441
+ end
465
442
  end
466
443
 
467
444
  unless columns.empty?
468
445
  # index name can't be the same
469
- opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
470
- opts[:unique] = true if index.unique
471
- opts[:where] = index.where if index.where
472
- add_index(to, columns, opts)
446
+ options = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
447
+ options[:unique] = true if index.unique
448
+ options[:where] = index.where if index.where
449
+ add_index(to, columns, **options)
473
450
  end
474
451
  end
475
452
  end
@@ -487,22 +464,19 @@ module ActiveRecord
487
464
  SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
488
465
  end
489
466
 
490
- def sqlite_version
491
- @sqlite_version ||= SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
492
- end
493
-
494
- def translate_exception(exception, message)
495
- case exception.message
467
+ def translate_exception(exception, message:, sql:, binds:)
496
468
  # SQLite 3.8.2 returns a newly formatted error message:
497
469
  # UNIQUE constraint failed: *table_name*.*column_name*
498
470
  # Older versions of SQLite return:
499
471
  # column *column_name* is not unique
500
- when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
501
- RecordNotUnique.new(message)
502
- when /.* may not be NULL/, /NOT NULL constraint failed: .*/
503
- NotNullViolation.new(message)
504
- when /FOREIGN KEY constraint failed/i
505
- InvalidForeignKey.new(message)
472
+ if exception.message.match?(/(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)/i)
473
+ RecordNotUnique.new(message, sql: sql, binds: binds)
474
+ elsif exception.message.match?(/(.* may not be NULL|NOT NULL constraint failed: .*)/i)
475
+ NotNullViolation.new(message, sql: sql, binds: binds)
476
+ elsif exception.message.match?(/FOREIGN KEY constraint failed/i)
477
+ InvalidForeignKey.new(message, sql: sql, binds: binds)
478
+ elsif exception.message.match?(/called on a closed database/i)
479
+ ConnectionNotEstablished.new(exception)
506
480
  else
507
481
  super
508
482
  end
@@ -512,7 +486,7 @@ module ActiveRecord
512
486
 
513
487
  def table_structure_with_collation(table_name, basic_structure)
514
488
  collation_hash = {}
515
- sql = <<-SQL
489
+ sql = <<~SQL
516
490
  SELECT sql FROM
517
491
  (SELECT * FROM sqlite_master UNION ALL
518
492
  SELECT * FROM sqlite_temp_master)
@@ -522,12 +496,12 @@ module ActiveRecord
522
496
  # Result will have following sample string
523
497
  # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
524
498
  # "password_digest" varchar COLLATE "NOCASE");
525
- result = exec_query(sql, "SCHEMA").first
499
+ result = query_value(sql, "SCHEMA")
526
500
 
527
501
  if result
528
502
  # Splitting with left parentheses and discarding the first part will return all
529
503
  # columns separated with comma(,).
530
- columns_string = result["sql"].split("(", 2).last
504
+ columns_string = result.split("(", 2).last
531
505
 
532
506
  columns_string.split(",").each do |column_string|
533
507
  # This regex will match the column name and collation type and will save
@@ -535,7 +509,7 @@ module ActiveRecord
535
509
  collation_hash[$1] = $2 if COLLATE_REGEX =~ column_string
536
510
  end
537
511
 
538
- basic_structure.map! do |column|
512
+ basic_structure.map do |column|
539
513
  column_name = column["name"]
540
514
 
541
515
  if collation_hash.has_key? column_name
@@ -545,7 +519,7 @@ module ActiveRecord
545
519
  column
546
520
  end
547
521
  else
548
- basic_structure.to_hash
522
+ basic_structure.to_a
549
523
  end
550
524
  end
551
525
 
@@ -553,7 +527,21 @@ module ActiveRecord
553
527
  Arel::Visitors::SQLite.new(self)
554
528
  end
555
529
 
530
+ def build_statement_pool
531
+ StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
532
+ end
533
+
534
+ def connect
535
+ @connection = ::SQLite3::Database.new(
536
+ @config[:database].to_s,
537
+ @config.merge(results_as_hash: true)
538
+ )
539
+ configure_connection
540
+ end
541
+
556
542
  def configure_connection
543
+ @connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout])) if @config[:timeout]
544
+
557
545
  execute("PRAGMA foreign_keys = ON", "SCHEMA")
558
546
  end
559
547
 
@@ -48,7 +48,6 @@ module ActiveRecord
48
48
  end
49
49
 
50
50
  private
51
-
52
51
  def cache
53
52
  @cache[Process.pid]
54
53
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ extend ActiveSupport::Autoload
6
+
7
+ eager_autoload do
8
+ autoload :AbstractAdapter
9
+ end
10
+
11
+ autoload :Column
12
+ autoload :PoolConfig
13
+ autoload :PoolManager
14
+ autoload :LegacyPoolManager
15
+ autoload :SchemaCache
16
+ autoload :Deduplicable
17
+
18
+ autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
19
+ autoload :IndexDefinition
20
+ autoload :ColumnDefinition
21
+ autoload :ChangeColumnDefinition
22
+ autoload :ForeignKeyDefinition
23
+ autoload :CheckConstraintDefinition
24
+ autoload :TableDefinition
25
+ autoload :Table
26
+ autoload :AlterTable
27
+ autoload :ReferenceDefinition
28
+ end
29
+
30
+ autoload_at "active_record/connection_adapters/abstract/connection_pool" do
31
+ autoload :ConnectionHandler
32
+ end
33
+
34
+ autoload_under "abstract" do
35
+ autoload :SchemaStatements
36
+ autoload :DatabaseStatements
37
+ autoload :DatabaseLimits
38
+ autoload :Quoting
39
+ autoload :ConnectionPool
40
+ autoload :QueryCache
41
+ autoload :Savepoints
42
+ end
43
+
44
+ autoload_at "active_record/connection_adapters/abstract/transaction" do
45
+ autoload :TransactionManager
46
+ autoload :NullTransaction
47
+ autoload :RealTransaction
48
+ autoload :SavepointTransaction
49
+ autoload :TransactionState
50
+ end
51
+ end
52
+ end