activerecord 5.0.6 → 6.0.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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,9 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters # :nodoc:
3
7
  module QueryCache
4
8
  class << self
5
9
  def included(base) #:nodoc:
6
- dirties_query_cache base, :insert, :update, :delete, :rollback_to_savepoint, :rollback_db_transaction
10
+ dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
11
+ :rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
7
12
 
8
13
  base.set_callback :checkout, :after, :configure_query_cache!
9
14
  base.set_callback :checkin, :after, :disable_query_cache!
@@ -13,7 +18,7 @@ module ActiveRecord
13
18
  method_names.each do |method_name|
14
19
  base.class_eval <<-end_code, __FILE__, __LINE__ + 1
15
20
  def #{method_name}(*)
16
- clear_query_cache if @query_cache_enabled
21
+ ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
17
22
  super
18
23
  end
19
24
  end_code
@@ -28,17 +33,17 @@ module ActiveRecord
28
33
  end
29
34
 
30
35
  def enable_query_cache!
31
- @query_cache_enabled[connection_cache_key(Thread.current)] = true
36
+ @query_cache_enabled[connection_cache_key(current_thread)] = true
32
37
  connection.enable_query_cache! if active_connection?
33
38
  end
34
39
 
35
40
  def disable_query_cache!
36
- @query_cache_enabled.delete connection_cache_key(Thread.current)
41
+ @query_cache_enabled.delete connection_cache_key(current_thread)
37
42
  connection.disable_query_cache! if active_connection?
38
43
  end
39
44
 
40
45
  def query_cache_enabled
41
- @query_cache_enabled[connection_cache_key(Thread.current)]
46
+ @query_cache_enabled[connection_cache_key(current_thread)]
42
47
  end
43
48
  end
44
49
 
@@ -46,7 +51,7 @@ module ActiveRecord
46
51
 
47
52
  def initialize(*)
48
53
  super
49
- @query_cache = Hash.new { |h,sql| h[sql] = {} }
54
+ @query_cache = Hash.new { |h, sql| h[sql] = {} }
50
55
  @query_cache_enabled = false
51
56
  end
52
57
 
@@ -83,14 +88,21 @@ module ActiveRecord
83
88
  # the same SQL query and repeatedly return the same result each time, silently
84
89
  # undermining the randomness you were expecting.
85
90
  def clear_query_cache
86
- @query_cache.clear
91
+ @lock.synchronize do
92
+ @query_cache.clear
93
+ end
87
94
  end
88
95
 
89
96
  def select_all(arel, name = nil, binds = [], preparable: nil)
90
97
  if @query_cache_enabled && !locked?(arel)
91
- arel, binds = binds_from_relation arel, binds
92
- sql = to_sql(arel, binds)
93
- cache_sql(sql, binds) { super(sql, name, binds, preparable: preparable) }
98
+ arel = arel_from_relation(arel)
99
+ sql, binds = to_sql_and_binds(arel, binds)
100
+
101
+ if preparable.nil?
102
+ preparable = prepared_statements ? visitor.preparable : false
103
+ end
104
+
105
+ cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
94
106
  else
95
107
  super
96
108
  end
@@ -98,27 +110,46 @@ module ActiveRecord
98
110
 
99
111
  private
100
112
 
101
- def cache_sql(sql, binds)
102
- result =
103
- if @query_cache[sql].key?(binds)
104
- ActiveSupport::Notifications.instrument("sql.active_record",
105
- :sql => sql, :binds => binds, :name => "CACHE", :connection_id => object_id)
106
- @query_cache[sql][binds]
107
- else
108
- @query_cache[sql][binds] = yield
113
+ def cache_sql(sql, name, binds)
114
+ @lock.synchronize do
115
+ result =
116
+ if @query_cache[sql].key?(binds)
117
+ ActiveSupport::Notifications.instrument(
118
+ "sql.active_record",
119
+ cache_notification_info(sql, name, binds)
120
+ )
121
+ @query_cache[sql][binds]
122
+ else
123
+ @query_cache[sql][binds] = yield
124
+ end
125
+ result.dup
109
126
  end
110
- result.dup
111
- end
127
+ end
112
128
 
113
- # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
114
- # queries should not be cached.
115
- def locked?(arel)
116
- arel.respond_to?(:locked) && arel.locked
117
- end
129
+ # Database adapters can override this method to
130
+ # provide custom cache information.
131
+ def cache_notification_info(sql, name, binds)
132
+ {
133
+ sql: sql,
134
+ binds: binds,
135
+ type_casted_binds: -> { type_casted_binds(binds) },
136
+ name: name,
137
+ connection_id: object_id,
138
+ connection: self,
139
+ cached: true
140
+ }
141
+ end
118
142
 
119
- def configure_query_cache!
120
- enable_query_cache! if pool.query_cache_enabled
121
- end
143
+ # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
144
+ # queries should not be cached.
145
+ def locked?(arel)
146
+ arel = arel.arel if arel.is_a?(Relation)
147
+ arel.respond_to?(:locked) && arel.locked
148
+ end
149
+
150
+ def configure_query_cache!
151
+ enable_query_cache! if pool.query_cache_enabled
152
+ end
122
153
  end
123
154
  end
124
155
  end
@@ -1,23 +1,18 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/big_decimal/conversions"
2
4
  require "active_support/multibyte/chars"
3
5
 
4
6
  module ActiveRecord
5
7
  module ConnectionAdapters # :nodoc:
6
8
  module Quoting
7
9
  # Quotes the column value to help prevent
8
- # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
9
- def quote(value, column = nil)
10
- # records are quoted as their primary key
11
- return value.quoted_id if value.respond_to?(:quoted_id)
10
+ # {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
11
+ def quote(value)
12
+ value = id_value_for_database(value) if value.is_a?(Base)
12
13
 
13
- if column
14
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
15
- Passing a column to `quote` has been deprecated. It is only used
16
- for type casting, which should be handled elsewhere. See
17
- https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
18
- for more information.
19
- MSG
20
- value = type_cast_from_column(column, value)
14
+ if value.respond_to?(:value_for_database)
15
+ value = value.value_for_database
21
16
  end
22
17
 
23
18
  _quote(value)
@@ -27,9 +22,7 @@ module ActiveRecord
27
22
  # SQLite does not understand dates, so this method will convert a Date
28
23
  # to a String.
29
24
  def type_cast(value, column = nil)
30
- if value.respond_to?(:quoted_id) && value.respond_to?(:id)
31
- return value.id
32
- end
25
+ value = id_value_for_database(value) if value.is_a?(Base)
33
26
 
34
27
  if column
35
28
  value = type_cast_from_column(column, value)
@@ -64,21 +57,10 @@ module ActiveRecord
64
57
  lookup_cast_type(column.sql_type)
65
58
  end
66
59
 
67
- def fetch_type_metadata(sql_type)
68
- cast_type = lookup_cast_type(sql_type)
69
- SqlTypeMetadata.new(
70
- sql_type: sql_type,
71
- type: cast_type.type,
72
- limit: cast_type.limit,
73
- precision: cast_type.precision,
74
- scale: cast_type.scale,
75
- )
76
- end
77
-
78
60
  # Quotes a string, escaping any ' (single quote) and \ (backslash)
79
61
  # characters.
80
62
  def quote_string(s)
81
- s.gsub('\\'.freeze, '\&\&'.freeze).gsub("'".freeze, "''".freeze) # ' (for ruby-mode)
63
+ s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
82
64
  end
83
65
 
84
66
  # Quotes the column name. Defaults to no quoting.
@@ -113,19 +95,19 @@ module ActiveRecord
113
95
  end
114
96
 
115
97
  def quoted_true
116
- "'t'".freeze
98
+ "TRUE"
117
99
  end
118
100
 
119
101
  def unquoted_true
120
- 't'.freeze
102
+ true
121
103
  end
122
104
 
123
105
  def quoted_false
124
- "'f'".freeze
106
+ "FALSE"
125
107
  end
126
108
 
127
109
  def unquoted_false
128
- 'f'.freeze
110
+ false
129
111
  end
130
112
 
131
113
  # Quote date/time values for use in SQL input. Includes microseconds
@@ -148,60 +130,122 @@ module ActiveRecord
148
130
  end
149
131
 
150
132
  def quoted_time(value) # :nodoc:
151
- quoted_date(value).sub(/\A2000-01-01 /, '')
133
+ value = value.change(year: 2000, month: 1, day: 1)
134
+ quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
152
135
  end
153
136
 
154
- def prepare_binds_for_database(binds) # :nodoc:
155
- binds.map(&:value_for_database)
137
+ def quoted_binary(value) # :nodoc:
138
+ "'#{quote_string(value.to_s)}'"
156
139
  end
157
140
 
158
- def type_casted_binds(binds) # :nodoc:
159
- if binds.first.is_a?(Array)
160
- binds.map { |column, value| type_cast(value, column) }
161
- else
162
- binds.map { |attr| type_cast(attr.value_for_database) }
163
- end
141
+ def sanitize_as_sql_comment(value) # :nodoc:
142
+ value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
143
+ end
144
+
145
+ def column_name_matcher # :nodoc:
146
+ COLUMN_NAME
147
+ end
148
+
149
+ def column_name_with_order_matcher # :nodoc:
150
+ COLUMN_NAME_WITH_ORDER
164
151
  end
165
152
 
153
+ # Regexp for column names (with or without a table name prefix).
154
+ # Matches the following:
155
+ #
156
+ # "#{table_name}.#{column_name}"
157
+ # "#{column_name}"
158
+ COLUMN_NAME = /
159
+ \A
160
+ (
161
+ (?:
162
+ # table_name.column_name | function(one or no argument)
163
+ ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
164
+ )
165
+ (?:\s+AS\s+\w+)?
166
+ )
167
+ (?:\s*,\s*\g<1>)*
168
+ \z
169
+ /ix
170
+
171
+ # Regexp for column names with order (with or without a table name prefix,
172
+ # with or without various order modifiers). Matches the following:
173
+ #
174
+ # "#{table_name}.#{column_name}"
175
+ # "#{table_name}.#{column_name} #{direction}"
176
+ # "#{table_name}.#{column_name} #{direction} NULLS FIRST"
177
+ # "#{table_name}.#{column_name} NULLS LAST"
178
+ # "#{column_name}"
179
+ # "#{column_name} #{direction}"
180
+ # "#{column_name} #{direction} NULLS FIRST"
181
+ # "#{column_name} NULLS LAST"
182
+ COLUMN_NAME_WITH_ORDER = /
183
+ \A
184
+ (
185
+ (?:
186
+ # table_name.column_name | function(one or no argument)
187
+ ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
188
+ )
189
+ (?:\s+ASC|\s+DESC)?
190
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
191
+ )
192
+ (?:\s*,\s*\g<1>)*
193
+ \z
194
+ /ix
195
+
196
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
197
+
166
198
  private
199
+ def type_casted_binds(binds)
200
+ if binds.first.is_a?(Array)
201
+ binds.map { |column, value| type_cast(value, column) }
202
+ else
203
+ binds.map { |attr| type_cast(attr.value_for_database) }
204
+ end
205
+ end
167
206
 
168
- def types_which_need_no_typecasting
169
- [nil, Numeric, String]
170
- end
171
-
172
- def _quote(value)
173
- case value
174
- when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data
175
- "'#{quote_string(value.to_s)}'"
176
- when true then quoted_true
177
- when false then quoted_false
178
- when nil then "NULL"
179
- # BigDecimals need to be put in a non-normalized form and quoted.
180
- when BigDecimal then value.to_s('F')
181
- when Numeric, ActiveSupport::Duration then value.to_s
182
- when Type::Time::Value then "'#{quoted_time(value)}'"
183
- when Date, Time then "'#{quoted_date(value)}'"
184
- when Symbol then "'#{quote_string(value.to_s)}'"
185
- when Class then "'#{value}'"
186
- else raise TypeError, "can't quote #{value.class.name}"
207
+ def lookup_cast_type(sql_type)
208
+ type_map.lookup(sql_type)
187
209
  end
188
- end
189
210
 
190
- def _type_cast(value)
191
- case value
192
- when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
193
- value.to_s
194
- when true then unquoted_true
195
- when false then unquoted_false
196
- # BigDecimals need to be put in a non-normalized form and quoted.
197
- when BigDecimal then value.to_s('F')
198
- when Type::Time::Value then quoted_time(value)
199
- when Date, Time then quoted_date(value)
200
- when *types_which_need_no_typecasting
201
- value
202
- else raise TypeError
211
+ def id_value_for_database(value)
212
+ if primary_key = value.class.primary_key
213
+ value.instance_variable_get(:@attributes)[primary_key].value_for_database
214
+ end
215
+ end
216
+
217
+ def _quote(value)
218
+ case value
219
+ when String, Symbol, ActiveSupport::Multibyte::Chars
220
+ "'#{quote_string(value.to_s)}'"
221
+ when true then quoted_true
222
+ when false then quoted_false
223
+ when nil then "NULL"
224
+ # BigDecimals need to be put in a non-normalized form and quoted.
225
+ when BigDecimal then value.to_s("F")
226
+ when Numeric, ActiveSupport::Duration then value.to_s
227
+ when Type::Binary::Data then quoted_binary(value)
228
+ when Type::Time::Value then "'#{quoted_time(value)}'"
229
+ when Date, Time then "'#{quoted_date(value)}'"
230
+ when Class then "'#{value}'"
231
+ else raise TypeError, "can't quote #{value.class.name}"
232
+ end
233
+ end
234
+
235
+ def _type_cast(value)
236
+ case value
237
+ when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
238
+ value.to_s
239
+ when true then unquoted_true
240
+ when false then unquoted_false
241
+ # BigDecimals need to be put in a non-normalized form and quoted.
242
+ when BigDecimal then value.to_s("F")
243
+ when nil, Numeric, String then value
244
+ when Type::Time::Value then quoted_time(value)
245
+ when Date, Time then quoted_date(value)
246
+ else raise TypeError
247
+ end
203
248
  end
204
- end
205
249
  end
206
250
  end
207
251
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module Savepoints
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/string/strip'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
@@ -15,32 +15,33 @@ module ActiveRecord
15
15
  end
16
16
 
17
17
  delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
18
- :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options, to: :@conn
19
- private :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
20
- :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options
18
+ :options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
19
+ to: :@conn, private: true
21
20
 
22
21
  private
23
22
 
24
23
  def visit_AlterTable(o)
25
- sql = "ALTER TABLE #{quote_table_name(o.name)} "
26
- sql << o.adds.map { |col| accept col }.join(' ')
27
- sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(' ')
28
- sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(' ')
24
+ sql = +"ALTER TABLE #{quote_table_name(o.name)} "
25
+ sql << o.adds.map { |col| accept col }.join(" ")
26
+ sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
27
+ sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
29
28
  end
30
29
 
31
30
  def visit_ColumnDefinition(o)
32
- o.sql_type ||= type_to_sql(o.type, o.limit, o.precision, o.scale)
33
- column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
31
+ o.sql_type = type_to_sql(o.type, o.options)
32
+ column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
34
33
  add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
35
34
  column_sql
36
35
  end
37
36
 
38
37
  def visit_AddColumnDefinition(o)
39
- "ADD #{accept(o.column)}"
38
+ +"ADD #{accept(o.column)}"
40
39
  end
41
40
 
42
41
  def visit_TableDefinition(o)
43
- create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
42
+ create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
43
+ create_sql << "IF NOT EXISTS " if o.if_not_exists
44
+ create_sql << "#{quote_table_name(o.name)} "
44
45
 
45
46
  statements = o.columns.map { |c| accept c }
46
47
  statements << accept(o.primary_keys) if o.primary_keys
@@ -55,16 +56,16 @@ module ActiveRecord
55
56
 
56
57
  create_sql << "(#{statements.join(', ')})" if statements.present?
57
58
  add_table_options!(create_sql, table_options(o))
58
- create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
59
+ create_sql << " AS #{to_sql(o.as)}" if o.as
59
60
  create_sql
60
61
  end
61
62
 
62
63
  def visit_PrimaryKeyDefinition(o)
63
- "PRIMARY KEY (#{o.name.join(', ')})"
64
+ "PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
64
65
  end
65
66
 
66
67
  def visit_ForeignKeyDefinition(o)
67
- sql = <<-SQL.strip_heredoc
68
+ sql = +<<~SQL
68
69
  CONSTRAINT #{quote_column_name(o.name)}
69
70
  FOREIGN KEY (#{quote_column_name(o.column)})
70
71
  REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
@@ -93,20 +94,11 @@ module ActiveRecord
93
94
  if options_sql = options[:options]
94
95
  create_sql << " #{options_sql}"
95
96
  end
97
+ create_sql
96
98
  end
97
99
 
98
100
  def column_options(o)
99
- column_options = {}
100
- column_options[:null] = o.null unless o.null.nil?
101
- column_options[:default] = o.default unless o.default.nil?
102
- column_options[:column] = o
103
- column_options[:first] = o.first
104
- column_options[:after] = o.after
105
- column_options[:auto_increment] = o.auto_increment
106
- column_options[:primary_key] = o.primary_key
107
- column_options[:collation] = o.collation
108
- column_options[:comment] = o.comment
109
- column_options
101
+ o.options.merge(column: o)
110
102
  end
111
103
 
112
104
  def add_column_options!(sql, options)
@@ -124,7 +116,20 @@ module ActiveRecord
124
116
  sql
125
117
  end
126
118
 
119
+ def to_sql(sql)
120
+ sql = sql.to_sql if sql.respond_to?(:to_sql)
121
+ sql
122
+ end
123
+
124
+ # Returns any SQL string to go between CREATE and TABLE. May be nil.
125
+ def table_modifier_in_create(o)
126
+ " TEMPORARY" if o.temporary
127
+ end
128
+
127
129
  def foreign_key_in_create(from_table, to_table, options)
130
+ prefix = ActiveRecord::Base.table_name_prefix
131
+ suffix = ActiveRecord::Base.table_name_suffix
132
+ to_table = "#{prefix}#{to_table}#{suffix}"
128
133
  options = foreign_key_options(from_table, to_table, options)
129
134
  accept ForeignKeyDefinition.new(from_table, to_table, options)
130
135
  end
@@ -135,7 +140,7 @@ module ActiveRecord
135
140
  when :cascade then "ON #{action} CASCADE"
136
141
  when :restrict then "ON #{action} RESTRICT"
137
142
  else
138
- raise ArgumentError, <<-MSG.strip_heredoc
143
+ raise ArgumentError, <<~MSG
139
144
  '#{dependency}' is not supported for :on_update or :on_delete.
140
145
  Supported values are: :nullify, :cascade, :restrict
141
146
  MSG
@@ -143,5 +148,6 @@ module ActiveRecord
143
148
  end
144
149
  end
145
150
  end
151
+ SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
146
152
  end
147
153
  end