activerecord 5.0.7.2 → 6.1.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 (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  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.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. 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
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,48 +88,62 @@ 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, preparable = to_sql_and_binds(arel, binds, preparable)
100
+
101
+ cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
94
102
  else
95
103
  super
96
104
  end
97
105
  end
98
106
 
99
107
  private
100
-
101
- def cache_sql(sql, binds)
102
- result =
103
- if @query_cache[sql].key?(binds)
104
- ActiveSupport::Notifications.instrument(
105
- "sql.active_record",
106
- sql: sql,
107
- binds: binds,
108
- type_casted_binds: -> { type_casted_binds(binds) },
109
- name: "CACHE",
110
- connection_id: object_id,
111
- )
112
- @query_cache[sql][binds]
113
- else
114
- @query_cache[sql][binds] = yield
108
+ def cache_sql(sql, name, binds)
109
+ @lock.synchronize do
110
+ result =
111
+ if @query_cache[sql].key?(binds)
112
+ ActiveSupport::Notifications.instrument(
113
+ "sql.active_record",
114
+ cache_notification_info(sql, name, binds)
115
+ )
116
+ @query_cache[sql][binds]
117
+ else
118
+ @query_cache[sql][binds] = yield
119
+ end
120
+ result.dup
115
121
  end
116
- result.dup
117
- end
122
+ end
118
123
 
119
- # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
120
- # queries should not be cached.
121
- def locked?(arel)
122
- arel.respond_to?(:locked) && arel.locked
123
- end
124
+ # Database adapters can override this method to
125
+ # provide custom cache information.
126
+ def cache_notification_info(sql, name, binds)
127
+ {
128
+ sql: sql,
129
+ binds: binds,
130
+ type_casted_binds: -> { type_casted_binds(binds) },
131
+ name: name,
132
+ connection: self,
133
+ cached: true
134
+ }
135
+ end
124
136
 
125
- def configure_query_cache!
126
- enable_query_cache! if pool.query_cache_enabled
127
- end
137
+ # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
138
+ # queries should not be cached.
139
+ def locked?(arel)
140
+ arel = arel.arel if arel.is_a?(Relation)
141
+ arel.respond_to?(:locked) && arel.locked
142
+ end
143
+
144
+ def configure_query_cache!
145
+ enable_query_cache! if pool.query_cache_enabled
146
+ end
128
147
  end
129
148
  end
130
149
  end
@@ -1,23 +1,20 @@
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)
12
-
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.
10
+ # {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
11
+ def quote(value)
12
+ if value.is_a?(Base)
13
+ ActiveSupport::Deprecation.warn(<<~MSG)
14
+ Passing an Active Record object to `quote` directly is deprecated
15
+ and will be no longer quoted as id value in Rails 6.2.
19
16
  MSG
20
- value = type_cast_from_column(column, value)
17
+ value = value.id_for_database
21
18
  end
22
19
 
23
20
  _quote(value)
@@ -27,18 +24,23 @@ module ActiveRecord
27
24
  # SQLite does not understand dates, so this method will convert a Date
28
25
  # to a String.
29
26
  def type_cast(value, column = nil)
30
- if value.respond_to?(:quoted_id) && value.respond_to?(:id)
31
- return value.id
27
+ if value.is_a?(Base)
28
+ ActiveSupport::Deprecation.warn(<<~MSG)
29
+ Passing an Active Record object to `type_cast` directly is deprecated
30
+ and will be no longer type casted as id value in Rails 6.2.
31
+ MSG
32
+ value = value.id_for_database
32
33
  end
33
34
 
34
35
  if column
35
- value = type_cast_from_column(column, value)
36
+ ActiveSupport::Deprecation.warn(<<~MSG)
37
+ Passing a column to `type_cast` is deprecated and will be removed in Rails 6.2.
38
+ MSG
39
+ type = lookup_cast_type_from_column(column)
40
+ value = type.serialize(value)
36
41
  end
37
42
 
38
43
  _type_cast(value)
39
- rescue TypeError
40
- to_type = column ? " to #{column.type}" : ""
41
- raise TypeError, "can't cast #{value.class}#{to_type}"
42
44
  end
43
45
 
44
46
  # If you are having to call this function, you are likely doing something
@@ -50,35 +52,14 @@ module ActiveRecord
50
52
  # represent the type doesn't sufficiently reflect the differences
51
53
  # (varchar vs binary) for example. The type used to get this primitive
52
54
  # should have been provided before reaching the connection adapter.
53
- def type_cast_from_column(column, value) # :nodoc:
54
- if column
55
- type = lookup_cast_type_from_column(column)
56
- type.serialize(value)
57
- else
58
- value
59
- end
60
- end
61
-
62
- # See docs for #type_cast_from_column
63
55
  def lookup_cast_type_from_column(column) # :nodoc:
64
56
  lookup_cast_type(column.sql_type)
65
57
  end
66
58
 
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
59
  # Quotes a string, escaping any ' (single quote) and \ (backslash)
79
60
  # characters.
80
61
  def quote_string(s)
81
- s.gsub('\\'.freeze, '\&\&'.freeze).gsub("'".freeze, "''".freeze) # ' (for ruby-mode)
62
+ s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
82
63
  end
83
64
 
84
65
  # Quotes the column name. Defaults to no quoting.
@@ -113,95 +94,158 @@ module ActiveRecord
113
94
  end
114
95
 
115
96
  def quoted_true
116
- "'t'".freeze
97
+ "TRUE"
117
98
  end
118
99
 
119
100
  def unquoted_true
120
- 't'.freeze
101
+ true
121
102
  end
122
103
 
123
104
  def quoted_false
124
- "'f'".freeze
105
+ "FALSE"
125
106
  end
126
107
 
127
108
  def unquoted_false
128
- 'f'.freeze
109
+ false
129
110
  end
130
111
 
131
112
  # Quote date/time values for use in SQL input. Includes microseconds
132
113
  # if the value is a Time responding to usec.
133
114
  def quoted_date(value)
134
115
  if value.acts_like?(:time)
135
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
136
-
137
- if value.respond_to?(zone_conversion_method)
138
- value = value.send(zone_conversion_method)
116
+ if ActiveRecord::Base.default_timezone == :utc
117
+ value = value.getutc if value.respond_to?(:getutc) && !value.utc?
118
+ else
119
+ value = value.getlocal if value.respond_to?(:getlocal)
139
120
  end
140
121
  end
141
122
 
142
123
  result = value.to_s(:db)
143
124
  if value.respond_to?(:usec) && value.usec > 0
144
- "#{result}.#{sprintf("%06d", value.usec)}"
125
+ result << "." << sprintf("%06d", value.usec)
145
126
  else
146
127
  result
147
128
  end
148
129
  end
149
130
 
150
131
  def quoted_time(value) # :nodoc:
151
- quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, '')
132
+ value = value.change(year: 2000, month: 1, day: 1)
133
+ quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
152
134
  end
153
135
 
154
- def prepare_binds_for_database(binds) # :nodoc:
155
- binds.map(&:value_for_database)
136
+ def quoted_binary(value) # :nodoc:
137
+ "'#{quote_string(value.to_s)}'"
156
138
  end
157
139
 
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
140
+ def sanitize_as_sql_comment(value) # :nodoc:
141
+ value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
164
142
  end
165
143
 
144
+ def column_name_matcher # :nodoc:
145
+ COLUMN_NAME
146
+ end
147
+
148
+ def column_name_with_order_matcher # :nodoc:
149
+ COLUMN_NAME_WITH_ORDER
150
+ end
151
+
152
+ # Regexp for column names (with or without a table name prefix).
153
+ # Matches the following:
154
+ #
155
+ # "#{table_name}.#{column_name}"
156
+ # "#{column_name}"
157
+ COLUMN_NAME = /
158
+ \A
159
+ (
160
+ (?:
161
+ # table_name.column_name | function(one or no argument)
162
+ ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
163
+ )
164
+ (?:(?:\s+AS)?\s+\w+)?
165
+ )
166
+ (?:\s*,\s*\g<1>)*
167
+ \z
168
+ /ix
169
+
170
+ # Regexp for column names with order (with or without a table name prefix,
171
+ # with or without various order modifiers). Matches the following:
172
+ #
173
+ # "#{table_name}.#{column_name}"
174
+ # "#{table_name}.#{column_name} #{direction}"
175
+ # "#{table_name}.#{column_name} #{direction} NULLS FIRST"
176
+ # "#{table_name}.#{column_name} NULLS LAST"
177
+ # "#{column_name}"
178
+ # "#{column_name} #{direction}"
179
+ # "#{column_name} #{direction} NULLS FIRST"
180
+ # "#{column_name} NULLS LAST"
181
+ COLUMN_NAME_WITH_ORDER = /
182
+ \A
183
+ (
184
+ (?:
185
+ # table_name.column_name | function(one or no argument)
186
+ ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
187
+ )
188
+ (?:\s+ASC|\s+DESC)?
189
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
190
+ )
191
+ (?:\s*,\s*\g<1>)*
192
+ \z
193
+ /ix
194
+
195
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
196
+
166
197
  private
198
+ def type_casted_binds(binds)
199
+ case binds.first
200
+ when Array
201
+ binds.map { |column, value| type_cast(value, column) }
202
+ else
203
+ binds.map do |value|
204
+ if ActiveModel::Attribute === value
205
+ type_cast(value.value_for_database)
206
+ else
207
+ type_cast(value)
208
+ end
209
+ end
210
+ end
211
+ end
167
212
 
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}"
213
+ def lookup_cast_type(sql_type)
214
+ type_map.lookup(sql_type)
187
215
  end
188
- end
189
216
 
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
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, "can't cast #{value.class.name}"
247
+ end
203
248
  end
204
- end
205
249
  end
206
250
  end
207
251
  end