activerecord 4.2.0 → 6.1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -73
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +78 -161
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -57
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +499 -293
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -389
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +273 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +212 -94
  143. data/lib/active_record/errors.rb +225 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +11 -6
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +273 -496
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +574 -135
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +175 -54
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +133 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +291 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +181 -152
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +33 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  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/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -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/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -10
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  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.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  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 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Relation
5
+ module RecordFetchWarning
6
+ # When this module is prepended to ActiveRecord::Relation and
7
+ # +config.active_record.warn_on_records_fetched_greater_than+ is
8
+ # set to an integer, if the number of records a query returns is
9
+ # greater than the value of +warn_on_records_fetched_greater_than+,
10
+ # a warning is logged. This allows for the detection of queries that
11
+ # return a large number of records, which could cause memory bloat.
12
+ #
13
+ # In most cases, fetching large number of records can be performed
14
+ # efficiently using the ActiveRecord::Batches methods.
15
+ # See ActiveRecord::Batches for more information.
16
+ def exec_queries
17
+ QueryRegistry.reset
18
+
19
+ super.tap do |records|
20
+ if logger && warn_on_records_fetched_greater_than
21
+ if records.length > warn_on_records_fetched_greater_than
22
+ logger.warn "Query fetched #{records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ # :stopdoc:
29
+ ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
30
+ QueryRegistry.queries << payload[:sql]
31
+ end
32
+ # :startdoc:
33
+
34
+ class QueryRegistry # :nodoc:
35
+ extend ActiveSupport::PerThreadRegistry
36
+
37
+ attr_reader :queries
38
+
39
+ def initialize
40
+ @queries = []
41
+ end
42
+
43
+ def reset
44
+ @queries.clear
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ ActiveRecord::Relation.prepend ActiveRecord::Relation::RecordFetchWarning
@@ -1,17 +1,19 @@
1
- require 'active_support/core_ext/hash/except'
2
- require 'active_support/core_ext/hash/slice'
3
- require 'active_record/relation/merger'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/except"
4
+ require "active_support/core_ext/hash/slice"
5
+ require "active_record/relation/merger"
4
6
 
5
7
  module ActiveRecord
6
8
  module SpawnMethods
7
-
8
9
  # This is overridden by Associations::CollectionProxy
9
10
  def spawn #:nodoc:
10
- clone
11
+ already_in_scope? ? klass.all : clone
11
12
  end
12
13
 
13
- # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>.
14
+ # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
14
15
  # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
16
+ #
15
17
  # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
16
18
  # # Performs a single join query with both where conditions.
17
19
  #
@@ -26,22 +28,26 @@ module ActiveRecord
26
28
  # # => Post.where(published: true).joins(:comments)
27
29
  #
28
30
  # This is mainly intended for sharing common conditions between multiple associations.
29
- def merge(other)
31
+ def merge(other, *rest)
30
32
  if other.is_a?(Array)
31
- to_a & other
33
+ records & other
32
34
  elsif other
33
- spawn.merge!(other)
35
+ spawn.merge!(other, *rest)
34
36
  else
35
- self
37
+ raise ArgumentError, "invalid argument: #{other.inspect}."
36
38
  end
37
39
  end
38
40
 
39
- def merge!(other) # :nodoc:
40
- if !other.is_a?(Relation) && other.respond_to?(:to_proc)
41
+ def merge!(other, *rest) # :nodoc:
42
+ options = rest.extract_options!
43
+ if other.is_a?(Hash)
44
+ Relation::HashMerger.new(self, other, options[:rewhere]).merge
45
+ elsif other.is_a?(Relation)
46
+ Relation::Merger.new(self, other, options[:rewhere]).merge
47
+ elsif other.respond_to?(:to_proc)
41
48
  instance_exec(&other)
42
49
  else
43
- klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger
44
- klass.new(self, other).merge
50
+ raise ArgumentError, "#{other.inspect} is not an ActiveRecord::Relation"
45
51
  end
46
52
  end
47
53
 
@@ -58,17 +64,13 @@ module ActiveRecord
58
64
  # Post.order('id asc').only(:where) # discards the order condition
59
65
  # Post.order('id asc').only(:where, :order) # uses the specified order
60
66
  def only(*onlies)
61
- if onlies.any? { |o| o == :where }
62
- onlies << :bind
63
- end
64
67
  relation_with values.slice(*onlies)
65
68
  end
66
69
 
67
70
  private
68
-
69
- def relation_with(values) # :nodoc:
70
- result = Relation.create(klass, table, values)
71
- result.extend(*extending_values) if extending_values.any?
71
+ def relation_with(values)
72
+ result = spawn
73
+ result.instance_variable_set(:@values, values)
72
74
  result
73
75
  end
74
76
  end
@@ -0,0 +1,239 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/extract"
4
+
5
+ module ActiveRecord
6
+ class Relation
7
+ class WhereClause # :nodoc:
8
+ delegate :any?, :empty?, to: :predicates
9
+
10
+ def initialize(predicates)
11
+ @predicates = predicates
12
+ end
13
+
14
+ def +(other)
15
+ WhereClause.new(predicates + other.predicates)
16
+ end
17
+
18
+ def -(other)
19
+ WhereClause.new(predicates - other.predicates)
20
+ end
21
+
22
+ def |(other)
23
+ WhereClause.new(predicates | other.predicates)
24
+ end
25
+
26
+ def merge(other, rewhere = nil)
27
+ predicates = if rewhere
28
+ except_predicates(other.extract_attributes)
29
+ else
30
+ predicates_unreferenced_by(other)
31
+ end
32
+
33
+ WhereClause.new(predicates | other.predicates)
34
+ end
35
+
36
+ def except(*columns)
37
+ WhereClause.new(except_predicates(columns))
38
+ end
39
+
40
+ def or(other)
41
+ left = self - other
42
+ common = self - left
43
+ right = other - common
44
+
45
+ if left.empty? || right.empty?
46
+ common
47
+ else
48
+ left = left.ast
49
+ left = left.expr if left.is_a?(Arel::Nodes::Grouping)
50
+
51
+ right = right.ast
52
+ right = right.expr if right.is_a?(Arel::Nodes::Grouping)
53
+
54
+ or_clause = Arel::Nodes::Or.new(left, right)
55
+
56
+ common.predicates << Arel::Nodes::Grouping.new(or_clause)
57
+ common
58
+ end
59
+ end
60
+
61
+ def to_h(table_name = nil, equality_only: false)
62
+ equalities(predicates, equality_only).each_with_object({}) do |node, hash|
63
+ next if table_name&.!= node.left.relation.name
64
+ name = node.left.name.to_s
65
+ value = extract_node_value(node.right)
66
+ hash[name] = value
67
+ end
68
+ end
69
+
70
+ def ast
71
+ predicates = predicates_with_wrapped_sql_literals
72
+ predicates.one? ? predicates.first : Arel::Nodes::And.new(predicates)
73
+ end
74
+
75
+ def ==(other)
76
+ other.is_a?(WhereClause) &&
77
+ predicates == other.predicates
78
+ end
79
+
80
+ def invert
81
+ if predicates.size == 1
82
+ inverted_predicates = [ invert_predicate(predicates.first) ]
83
+ else
84
+ inverted_predicates = [ Arel::Nodes::Not.new(ast) ]
85
+ end
86
+
87
+ WhereClause.new(inverted_predicates)
88
+ end
89
+
90
+ def self.empty
91
+ @empty ||= new([]).freeze
92
+ end
93
+
94
+ def contradiction?
95
+ predicates.any? do |x|
96
+ case x
97
+ when Arel::Nodes::In
98
+ Array === x.right && x.right.empty?
99
+ when Arel::Nodes::Equality
100
+ x.right.respond_to?(:unboundable?) && x.right.unboundable?
101
+ end
102
+ end
103
+ end
104
+
105
+ def extract_attributes
106
+ attrs = []
107
+ each_attributes { |attr, _| attrs << attr }
108
+ attrs
109
+ end
110
+
111
+ protected
112
+ attr_reader :predicates
113
+
114
+ def referenced_columns
115
+ hash = {}
116
+ each_attributes { |attr, node| hash[attr] = node }
117
+ hash
118
+ end
119
+
120
+ private
121
+ def each_attributes
122
+ predicates.each do |node|
123
+ attr = extract_attribute(node) || begin
124
+ node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
125
+ end
126
+
127
+ yield attr, node if attr
128
+ end
129
+ end
130
+
131
+ def extract_attribute(node)
132
+ attr_node = nil
133
+ Arel.fetch_attribute(node) do |attr|
134
+ return if attr_node&.!= attr # all attr nodes should be the same
135
+ attr_node = attr
136
+ end
137
+ attr_node
138
+ end
139
+
140
+ def equalities(predicates, equality_only)
141
+ equalities = []
142
+
143
+ predicates.each do |node|
144
+ if equality_only ? Arel::Nodes::Equality === node : equality_node?(node)
145
+ equalities << node
146
+ elsif node.is_a?(Arel::Nodes::And)
147
+ equalities.concat equalities(node.children, equality_only)
148
+ end
149
+ end
150
+
151
+ equalities
152
+ end
153
+
154
+ def predicates_unreferenced_by(other)
155
+ referenced_columns = other.referenced_columns
156
+
157
+ predicates.reject do |node|
158
+ attr = extract_attribute(node) || begin
159
+ node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
160
+ end
161
+ next false unless attr
162
+
163
+ ref = referenced_columns[attr]
164
+ next false unless ref
165
+
166
+ if equality_node?(node) && equality_node?(ref) || node == ref
167
+ true
168
+ else
169
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
170
+ Merging (#{node.to_sql}) and (#{ref.to_sql}) no longer maintain
171
+ both conditions, and will be replaced by the latter in Rails 7.0.
172
+ To migrate to Rails 7.0's behavior, use `relation.merge(other, rewhere: true)`.
173
+ MSG
174
+ false
175
+ end
176
+ end
177
+ end
178
+
179
+ def equality_node?(node)
180
+ !node.is_a?(String) && node.equality?
181
+ end
182
+
183
+ def invert_predicate(node)
184
+ case node
185
+ when NilClass
186
+ raise ArgumentError, "Invalid argument for .where.not(), got nil."
187
+ when String
188
+ Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
189
+ else
190
+ node.invert
191
+ end
192
+ end
193
+
194
+ def except_predicates(columns)
195
+ attrs = columns.extract! { |node| node.is_a?(Arel::Attribute) }
196
+ non_attrs = columns.extract! { |node| node.is_a?(Arel::Predications) }
197
+
198
+ predicates.reject do |node|
199
+ if !non_attrs.empty? && node.equality? && node.left.is_a?(Arel::Predications)
200
+ non_attrs.include?(node.left)
201
+ end || Arel.fetch_attribute(node) do |attr|
202
+ attrs.include?(attr) || columns.include?(attr.name.to_s)
203
+ end
204
+ end
205
+ end
206
+
207
+ def predicates_with_wrapped_sql_literals
208
+ non_empty_predicates.map do |node|
209
+ case node
210
+ when Arel::Nodes::SqlLiteral, ::String
211
+ wrap_sql_literal(node)
212
+ else node
213
+ end
214
+ end
215
+ end
216
+
217
+ ARRAY_WITH_EMPTY_STRING = [""]
218
+ def non_empty_predicates
219
+ predicates - ARRAY_WITH_EMPTY_STRING
220
+ end
221
+
222
+ def wrap_sql_literal(node)
223
+ if ::String === node
224
+ node = Arel.sql(node)
225
+ end
226
+ Arel::Nodes::Grouping.new(node)
227
+ end
228
+
229
+ def extract_node_value(node)
230
+ case node
231
+ when Array
232
+ node.map { |v| extract_node_value(v) }
233
+ when Arel::Nodes::BindParam, Arel::Nodes::Casted, Arel::Nodes::Quoted
234
+ node.value_before_type_cast
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end