activerecord 6.0.0 → 7.2.3

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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +996 -594
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +34 -34
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +22 -20
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +41 -30
  9. data/lib/active_record/associations/association.rb +106 -41
  10. data/lib/active_record/associations/association_scope.rb +30 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +69 -14
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
  13. data/lib/active_record/associations/builder/association.rb +39 -6
  14. data/lib/active_record/associations/builder/belongs_to.rb +47 -17
  15. data/lib/active_record/associations/builder/collection_association.rb +14 -6
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
  17. data/lib/active_record/associations/builder/has_many.rb +7 -3
  18. data/lib/active_record/associations/builder/has_one.rb +13 -16
  19. data/lib/active_record/associations/builder/singular_association.rb +7 -3
  20. data/lib/active_record/associations/collection_association.rb +90 -53
  21. data/lib/active_record/associations/collection_proxy.rb +54 -19
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/errors.rb +265 -0
  24. data/lib/active_record/associations/foreign_association.rb +21 -1
  25. data/lib/active_record/associations/has_many_association.rb +41 -10
  26. data/lib/active_record/associations/has_many_through_association.rb +29 -12
  27. data/lib/active_record/associations/has_one_association.rb +33 -9
  28. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  29. data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
  30. data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
  31. data/lib/active_record/associations/join_dependency.rb +97 -54
  32. data/lib/active_record/associations/nested_error.rb +47 -0
  33. data/lib/active_record/associations/preloader/association.rb +237 -54
  34. data/lib/active_record/associations/preloader/batch.rb +48 -0
  35. data/lib/active_record/associations/preloader/branch.rb +153 -0
  36. data/lib/active_record/associations/preloader/through_association.rb +51 -17
  37. data/lib/active_record/associations/preloader.rb +55 -121
  38. data/lib/active_record/associations/singular_association.rb +16 -4
  39. data/lib/active_record/associations/through_association.rb +26 -15
  40. data/lib/active_record/associations.rb +454 -440
  41. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  42. data/lib/active_record/attribute_assignment.rb +11 -14
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
  44. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  45. data/lib/active_record/attribute_methods/dirty.rb +75 -34
  46. data/lib/active_record/attribute_methods/primary_key.rb +53 -31
  47. data/lib/active_record/attribute_methods/query.rb +31 -22
  48. data/lib/active_record/attribute_methods/read.rb +16 -17
  49. data/lib/active_record/attribute_methods/serialization.rb +177 -35
  50. data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
  51. data/lib/active_record/attribute_methods/write.rb +16 -28
  52. data/lib/active_record/attribute_methods.rb +227 -100
  53. data/lib/active_record/attributes.rb +94 -56
  54. data/lib/active_record/autosave_association.rb +119 -73
  55. data/lib/active_record/base.rb +31 -21
  56. data/lib/active_record/callbacks.rb +168 -55
  57. data/lib/active_record/coders/column_serializer.rb +61 -0
  58. data/lib/active_record/coders/json.rb +1 -1
  59. data/lib/active_record/coders/yaml_column.rb +70 -25
  60. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
  64. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
  65. data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
  66. data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
  67. data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
  68. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  69. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
  70. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
  71. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
  72. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
  73. data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
  74. data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
  75. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
  76. data/lib/active_record/connection_adapters/column.rb +28 -1
  77. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  78. data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
  79. data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
  80. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  81. data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
  82. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
  83. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
  84. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
  85. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
  86. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
  87. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  88. data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
  89. data/lib/active_record/connection_adapters/pool_config.rb +83 -0
  90. data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
  91. data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
  92. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
  93. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -5
  95. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  97. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  98. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -15
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
  101. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
  103. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  104. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
  105. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
  106. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  110. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
  111. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
  121. data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
  123. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  124. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
  131. data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
  132. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  133. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  134. data/lib/active_record/connection_adapters.rb +176 -0
  135. data/lib/active_record/connection_handling.rb +243 -115
  136. data/lib/active_record/core.rb +481 -199
  137. data/lib/active_record/counter_cache.rb +69 -32
  138. data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
  139. data/lib/active_record/database_configurations/database_config.rb +77 -10
  140. data/lib/active_record/database_configurations/hash_config.rb +148 -26
  141. data/lib/active_record/database_configurations/url_config.rb +44 -45
  142. data/lib/active_record/database_configurations.rb +190 -114
  143. data/lib/active_record/delegated_type.rb +279 -0
  144. data/lib/active_record/deprecator.rb +7 -0
  145. data/lib/active_record/destroy_association_async_job.rb +38 -0
  146. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  147. data/lib/active_record/dynamic_matchers.rb +5 -6
  148. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  149. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  150. data/lib/active_record/encryption/cipher.rb +53 -0
  151. data/lib/active_record/encryption/config.rb +68 -0
  152. data/lib/active_record/encryption/configurable.rb +60 -0
  153. data/lib/active_record/encryption/context.rb +42 -0
  154. data/lib/active_record/encryption/contexts.rb +76 -0
  155. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  156. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  157. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  158. data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
  159. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  160. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  161. data/lib/active_record/encryption/encryptor.rb +171 -0
  162. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  163. data/lib/active_record/encryption/errors.rb +15 -0
  164. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  165. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  166. data/lib/active_record/encryption/key.rb +28 -0
  167. data/lib/active_record/encryption/key_generator.rb +53 -0
  168. data/lib/active_record/encryption/key_provider.rb +46 -0
  169. data/lib/active_record/encryption/message.rb +33 -0
  170. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  171. data/lib/active_record/encryption/message_serializer.rb +96 -0
  172. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  173. data/lib/active_record/encryption/properties.rb +76 -0
  174. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  175. data/lib/active_record/encryption/scheme.rb +100 -0
  176. data/lib/active_record/encryption.rb +58 -0
  177. data/lib/active_record/enum.rb +224 -73
  178. data/lib/active_record/errors.rb +254 -36
  179. data/lib/active_record/explain.rb +30 -17
  180. data/lib/active_record/explain_registry.rb +11 -6
  181. data/lib/active_record/explain_subscriber.rb +2 -2
  182. data/lib/active_record/fixture_set/file.rb +22 -15
  183. data/lib/active_record/fixture_set/model_metadata.rb +15 -6
  184. data/lib/active_record/fixture_set/render_context.rb +3 -1
  185. data/lib/active_record/fixture_set/table_row.rb +88 -16
  186. data/lib/active_record/fixture_set/table_rows.rb +4 -5
  187. data/lib/active_record/fixtures.rb +229 -116
  188. data/lib/active_record/future_result.rb +178 -0
  189. data/lib/active_record/gem_version.rb +4 -4
  190. data/lib/active_record/inheritance.rb +121 -48
  191. data/lib/active_record/insert_all.rb +178 -29
  192. data/lib/active_record/integration.rb +16 -14
  193. data/lib/active_record/internal_metadata.rb +132 -21
  194. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  195. data/lib/active_record/locking/optimistic.rb +64 -33
  196. data/lib/active_record/locking/pessimistic.rb +21 -8
  197. data/lib/active_record/log_subscriber.rb +61 -30
  198. data/lib/active_record/marshalling.rb +59 -0
  199. data/lib/active_record/message_pack.rb +124 -0
  200. data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
  201. data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
  202. data/lib/active_record/middleware/database_selector.rb +25 -13
  203. data/lib/active_record/middleware/shard_selector.rb +62 -0
  204. data/lib/active_record/migration/command_recorder.rb +160 -55
  205. data/lib/active_record/migration/compatibility.rb +286 -43
  206. data/lib/active_record/migration/default_strategy.rb +22 -0
  207. data/lib/active_record/migration/execution_strategy.rb +19 -0
  208. data/lib/active_record/migration/join_table.rb +1 -2
  209. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  210. data/lib/active_record/migration.rb +421 -193
  211. data/lib/active_record/model_schema.rb +217 -125
  212. data/lib/active_record/nested_attributes.rb +62 -27
  213. data/lib/active_record/no_touching.rb +4 -4
  214. data/lib/active_record/normalization.rb +163 -0
  215. data/lib/active_record/persistence.rb +322 -319
  216. data/lib/active_record/promise.rb +84 -0
  217. data/lib/active_record/query_cache.rb +18 -15
  218. data/lib/active_record/query_logs.rb +193 -0
  219. data/lib/active_record/query_logs_formatter.rb +41 -0
  220. data/lib/active_record/querying.rb +54 -14
  221. data/lib/active_record/railtie.rb +250 -72
  222. data/lib/active_record/railties/console_sandbox.rb +2 -4
  223. data/lib/active_record/railties/controller_runtime.rb +25 -11
  224. data/lib/active_record/railties/databases.rake +312 -197
  225. data/lib/active_record/railties/job_runtime.rb +23 -0
  226. data/lib/active_record/readonly_attributes.rb +45 -3
  227. data/lib/active_record/reflection.rb +389 -146
  228. data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
  229. data/lib/active_record/relation/batches.rb +214 -73
  230. data/lib/active_record/relation/calculations.rb +379 -124
  231. data/lib/active_record/relation/delegation.rb +36 -23
  232. data/lib/active_record/relation/finder_methods.rb +159 -49
  233. data/lib/active_record/relation/from_clause.rb +5 -1
  234. data/lib/active_record/relation/merger.rb +41 -33
  235. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
  236. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
  237. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
  238. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  239. data/lib/active_record/relation/predicate_builder.rb +79 -53
  240. data/lib/active_record/relation/query_attribute.rb +30 -12
  241. data/lib/active_record/relation/query_methods.rb +1156 -279
  242. data/lib/active_record/relation/record_fetch_warning.rb +12 -11
  243. data/lib/active_record/relation/spawn_methods.rb +10 -9
  244. data/lib/active_record/relation/where_clause.rb +100 -66
  245. data/lib/active_record/relation.rb +829 -194
  246. data/lib/active_record/result.rb +76 -56
  247. data/lib/active_record/runtime_registry.rb +71 -13
  248. data/lib/active_record/sanitization.rb +86 -47
  249. data/lib/active_record/schema.rb +39 -23
  250. data/lib/active_record/schema_dumper.rb +140 -33
  251. data/lib/active_record/schema_migration.rb +74 -29
  252. data/lib/active_record/scoping/default.rb +73 -19
  253. data/lib/active_record/scoping/named.rb +10 -28
  254. data/lib/active_record/scoping.rb +65 -35
  255. data/lib/active_record/secure_password.rb +60 -0
  256. data/lib/active_record/secure_token.rb +34 -8
  257. data/lib/active_record/serialization.rb +11 -4
  258. data/lib/active_record/signed_id.rb +138 -0
  259. data/lib/active_record/statement_cache.rb +26 -10
  260. data/lib/active_record/store.rb +19 -14
  261. data/lib/active_record/suppressor.rb +15 -17
  262. data/lib/active_record/table_metadata.rb +46 -36
  263. data/lib/active_record/tasks/database_tasks.rb +371 -205
  264. data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
  265. data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
  266. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
  267. data/lib/active_record/test_databases.rb +5 -4
  268. data/lib/active_record/test_fixtures.rb +189 -104
  269. data/lib/active_record/testing/query_assertions.rb +121 -0
  270. data/lib/active_record/timestamp.rb +35 -25
  271. data/lib/active_record/token_for.rb +123 -0
  272. data/lib/active_record/touch_later.rb +31 -27
  273. data/lib/active_record/transaction.rb +132 -0
  274. data/lib/active_record/transactions.rb +131 -99
  275. data/lib/active_record/translation.rb +3 -5
  276. data/lib/active_record/type/adapter_specific_registry.rb +33 -18
  277. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  278. data/lib/active_record/type/internal/timezone.rb +7 -2
  279. data/lib/active_record/type/serialized.rb +11 -6
  280. data/lib/active_record/type/time.rb +14 -0
  281. data/lib/active_record/type/type_map.rb +17 -21
  282. data/lib/active_record/type/unsigned_integer.rb +0 -1
  283. data/lib/active_record/type.rb +7 -2
  284. data/lib/active_record/type_caster/connection.rb +4 -5
  285. data/lib/active_record/type_caster/map.rb +8 -5
  286. data/lib/active_record/validations/absence.rb +1 -1
  287. data/lib/active_record/validations/associated.rb +13 -8
  288. data/lib/active_record/validations/numericality.rb +36 -0
  289. data/lib/active_record/validations/presence.rb +5 -28
  290. data/lib/active_record/validations/uniqueness.rb +88 -18
  291. data/lib/active_record/validations.rb +15 -8
  292. data/lib/active_record/version.rb +1 -1
  293. data/lib/active_record.rb +446 -40
  294. data/lib/arel/alias_predication.rb +1 -1
  295. data/lib/arel/attributes/attribute.rb +4 -8
  296. data/lib/arel/collectors/bind.rb +8 -1
  297. data/lib/arel/collectors/composite.rb +15 -0
  298. data/lib/arel/collectors/sql_string.rb +7 -0
  299. data/lib/arel/collectors/substitute_binds.rb +7 -0
  300. data/lib/arel/crud.rb +30 -22
  301. data/lib/arel/delete_manager.rb +23 -4
  302. data/lib/arel/errors.rb +10 -0
  303. data/lib/arel/factory_methods.rb +4 -0
  304. data/lib/arel/filter_predications.rb +9 -0
  305. data/lib/arel/insert_manager.rb +2 -3
  306. data/lib/arel/nodes/binary.rb +82 -9
  307. data/lib/arel/nodes/bind_param.rb +8 -0
  308. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  309. data/lib/arel/nodes/casted.rb +22 -10
  310. data/lib/arel/nodes/cte.rb +36 -0
  311. data/lib/arel/nodes/delete_statement.rb +14 -13
  312. data/lib/arel/nodes/equality.rb +6 -9
  313. data/lib/arel/nodes/filter.rb +10 -0
  314. data/lib/arel/nodes/fragments.rb +35 -0
  315. data/lib/arel/nodes/function.rb +1 -0
  316. data/lib/arel/nodes/grouping.rb +3 -0
  317. data/lib/arel/nodes/homogeneous_in.rb +68 -0
  318. data/lib/arel/nodes/in.rb +8 -1
  319. data/lib/arel/nodes/infix_operation.rb +13 -1
  320. data/lib/arel/nodes/insert_statement.rb +2 -2
  321. data/lib/arel/nodes/join_source.rb +1 -1
  322. data/lib/arel/nodes/leading_join.rb +8 -0
  323. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  324. data/lib/arel/nodes/node.rb +122 -11
  325. data/lib/arel/nodes/ordering.rb +27 -0
  326. data/lib/arel/nodes/select_core.rb +2 -2
  327. data/lib/arel/nodes/select_statement.rb +2 -2
  328. data/lib/arel/nodes/sql_literal.rb +16 -0
  329. data/lib/arel/nodes/table_alias.rb +11 -3
  330. data/lib/arel/nodes/unary.rb +0 -1
  331. data/lib/arel/nodes/update_statement.rb +11 -4
  332. data/lib/arel/nodes.rb +10 -3
  333. data/lib/arel/predications.rb +31 -28
  334. data/lib/arel/select_manager.rb +18 -9
  335. data/lib/arel/table.rb +21 -10
  336. data/lib/arel/tree_manager.rb +8 -15
  337. data/lib/arel/update_manager.rb +25 -5
  338. data/lib/arel/visitors/dot.rb +94 -90
  339. data/lib/arel/visitors/mysql.rb +34 -6
  340. data/lib/arel/visitors/postgresql.rb +5 -16
  341. data/lib/arel/visitors/sqlite.rb +25 -1
  342. data/lib/arel/visitors/to_sql.rb +227 -81
  343. data/lib/arel/visitors/visitor.rb +2 -3
  344. data/lib/arel/visitors.rb +0 -7
  345. data/lib/arel.rb +37 -15
  346. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  347. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  348. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  349. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
  350. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
  351. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
  352. data/lib/rails/generators/active_record/migration.rb +9 -3
  353. data/lib/rails/generators/active_record/model/USAGE +113 -0
  354. data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
  355. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  356. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  357. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  358. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  359. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  360. metadata +117 -30
  361. data/lib/active_record/attribute_decorators.rb +0 -90
  362. data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
  363. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
  364. data/lib/active_record/define_callbacks.rb +0 -22
  365. data/lib/active_record/null_relation.rb +0 -68
  366. data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
  367. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
  368. data/lib/active_record/relation/where_clause_factory.rb +0 -33
  369. data/lib/arel/attributes.rb +0 -22
  370. data/lib/arel/visitors/depth_first.rb +0 -204
  371. data/lib/arel/visitors/ibm_db.rb +0 -34
  372. data/lib/arel/visitors/informix.rb +0 -62
  373. data/lib/arel/visitors/mssql.rb +0 -157
  374. data/lib/arel/visitors/oracle.rb +0 -159
  375. data/lib/arel/visitors/oracle12.rb +0 -66
  376. data/lib/arel/visitors/where_sql.rb +0 -23
@@ -13,54 +13,289 @@ module ActiveRecord
13
13
  const_get(name)
14
14
  end
15
15
 
16
- V6_0 = Current
16
+ # This file exists to ensure that old migrations run the same way they did before a Rails upgrade.
17
+ # e.g. if you write a migration on Rails 6.1, then upgrade to Rails 7, the migration should do the same thing to your
18
+ # database as it did when you were running Rails 6.1
19
+ #
20
+ # "Current" is an alias for `ActiveRecord::Migration`, it represents the current Rails version.
21
+ # New migration functionality that will never be backward compatible should be added directly to `ActiveRecord::Migration`.
22
+ #
23
+ # There are classes for each prior Rails version. Each class descends from the *next* Rails version, so:
24
+ # 5.2 < 6.0 < 6.1 < 7.0 < 7.1 < 7.2
25
+ #
26
+ # If you are introducing new migration functionality that should only apply from Rails 7 onward, then you should
27
+ # find the class that immediately precedes it (6.1), and override the relevant migration methods to undo your changes.
28
+ #
29
+ # For example, Rails 6 added a default value for the `precision` option on datetime columns. So in this file, the `V5_2`
30
+ # class sets the value of `precision` to `nil` if it's not explicitly provided. This way, the default value will not apply
31
+ # for migrations written for 5.2, but will for migrations written for 6.0.
32
+ V7_2 = Current
33
+
34
+ class V7_1 < V7_2
35
+ end
36
+
37
+ class V7_0 < V7_1
38
+ module LegacyIndexName
39
+ private
40
+ def legacy_index_name(table_name, options)
41
+ if Hash === options
42
+ if options[:column]
43
+ "index_#{table_name}_on_#{Array(options[:column]) * '_and_'}"
44
+ elsif options[:name]
45
+ options[:name]
46
+ else
47
+ raise ArgumentError, "You must specify the index name"
48
+ end
49
+ else
50
+ legacy_index_name(table_name, index_name_options(options))
51
+ end
52
+ end
53
+
54
+ def index_name_options(column_names)
55
+ if expression_column_name?(column_names)
56
+ column_names = column_names.scan(/\w+/).join("_")
57
+ end
58
+
59
+ { column: column_names }
60
+ end
61
+
62
+ def expression_column_name?(column_name)
63
+ column_name.is_a?(String) && /\W/.match?(column_name)
64
+ end
65
+ end
17
66
 
18
- class V5_2 < V6_0
19
67
  module TableDefinition
20
- def timestamps(**options)
21
- options[:precision] ||= nil
68
+ include LegacyIndexName
69
+
70
+ def column(name, type, **options)
71
+ options[:_skip_validate_options] = true
22
72
  super
23
73
  end
24
- end
25
74
 
26
- module CommandRecorder
27
- def invert_transaction(args, &block)
28
- [:transaction, args, block]
75
+ def change(name, type, **options)
76
+ options[:_skip_validate_options] = true
77
+ super
29
78
  end
30
79
 
31
- def invert_change_column_comment(args)
32
- table_name, column_name, comment = args
33
- [:change_column_comment, [table_name, column_name, from: comment, to: comment]]
80
+ def index(column_name, **options)
81
+ options[:name] = legacy_index_name(name, column_name) if options[:name].nil?
82
+ super
34
83
  end
35
84
 
36
- def invert_change_table_comment(args)
37
- table_name, comment = args
38
- [:change_table_comment, [table_name, from: comment, to: comment]]
85
+ def references(*args, **options)
86
+ options[:_skip_validate_options] = true
87
+ super
39
88
  end
89
+
90
+ private
91
+ def raise_on_if_exist_options(options)
92
+ end
40
93
  end
41
94
 
95
+ include LegacyIndexName
96
+
97
+ def add_column(table_name, column_name, type, **options)
98
+ options[:_skip_validate_options] = true
99
+ super
100
+ end
101
+
102
+ def add_index(table_name, column_name, **options)
103
+ options[:name] = legacy_index_name(table_name, column_name) if options[:name].nil?
104
+ super
105
+ end
106
+
107
+ def add_reference(table_name, ref_name, **options)
108
+ options[:_skip_validate_options] = true
109
+ super
110
+ end
111
+ alias :add_belongs_to :add_reference
112
+
42
113
  def create_table(table_name, **options)
43
- if block_given?
44
- super { |t| yield compatible_table_definition(t) }
45
- else
114
+ options[:_uses_legacy_table_name] = true
115
+ options[:_skip_validate_options] = true
116
+
117
+ super
118
+ end
119
+
120
+ def rename_table(table_name, new_name, **options)
121
+ options[:_uses_legacy_table_name] = true
122
+ options[:_uses_legacy_index_name] = true
123
+ super
124
+ end
125
+
126
+ def change_column(table_name, column_name, type, **options)
127
+ options[:_skip_validate_options] = true
128
+ if connection.adapter_name == "Mysql2" || connection.adapter_name == "Trilogy"
129
+ options[:collation] ||= :no_collation
130
+ end
131
+ super
132
+ end
133
+
134
+ def change_column_null(table_name, column_name, null, default = nil)
135
+ super(table_name, column_name, !!null, default)
136
+ end
137
+
138
+ def disable_extension(name, **options)
139
+ if connection.adapter_name == "PostgreSQL"
140
+ options[:force] = :cascade
141
+ end
142
+ super
143
+ end
144
+
145
+ def add_foreign_key(from_table, to_table, **options)
146
+ if connection.adapter_name == "PostgreSQL" && options[:deferrable] == true
147
+ options[:deferrable] = :immediate
148
+ end
149
+ super
150
+ end
151
+
152
+ private
153
+ def compatible_table_definition(t)
154
+ class << t
155
+ prepend TableDefinition
156
+ end
46
157
  super
47
158
  end
159
+ end
160
+
161
+ class V6_1 < V7_0
162
+ class PostgreSQLCompat
163
+ def self.compatible_timestamp_type(type, connection)
164
+ if connection.adapter_name == "PostgreSQL"
165
+ # For Rails <= 6.1, :datetime was aliased to :timestamp
166
+ # See: https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L108
167
+ # From Rails 7 onwards, you can define what :datetime resolves to (the default is still :timestamp)
168
+ # See `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`
169
+ type.to_sym == :datetime ? :timestamp : type
170
+ else
171
+ type
172
+ end
173
+ end
48
174
  end
49
175
 
50
- def change_table(table_name, **options)
51
- if block_given?
52
- super { |t| yield compatible_table_definition(t) }
53
- else
176
+ def add_column(table_name, column_name, type, **options)
177
+ if type == :datetime
178
+ options[:precision] ||= nil
179
+ end
180
+
181
+ type = PostgreSQLCompat.compatible_timestamp_type(type, connection)
182
+ super
183
+ end
184
+
185
+ def change_column(table_name, column_name, type, **options)
186
+ if type == :datetime
187
+ options[:precision] ||= nil
188
+ end
189
+
190
+ type = PostgreSQLCompat.compatible_timestamp_type(type, connection)
191
+ super
192
+ end
193
+
194
+ module TableDefinition
195
+ def new_column_definition(name, type, **options)
196
+ type = PostgreSQLCompat.compatible_timestamp_type(type, @conn)
197
+ super
198
+ end
199
+
200
+ def change(name, type, index: nil, **options)
201
+ options[:precision] ||= nil
54
202
  super
55
203
  end
204
+
205
+ def column(name, type, index: nil, **options)
206
+ options[:precision] ||= nil
207
+ super
208
+ end
209
+
210
+ private
211
+ def raise_on_if_exist_options(options)
212
+ end
56
213
  end
57
214
 
58
- def create_join_table(table_1, table_2, **options)
59
- if block_given?
60
- super { |t| yield compatible_table_definition(t) }
61
- else
215
+ private
216
+ def compatible_table_definition(t)
217
+ class << t
218
+ prepend TableDefinition
219
+ end
220
+ super
221
+ end
222
+ end
223
+
224
+ class V6_0 < V6_1
225
+ class ReferenceDefinition < ConnectionAdapters::ReferenceDefinition
226
+ def index_options(table_name)
227
+ as_options(index)
228
+ end
229
+ end
230
+
231
+ module TableDefinition
232
+ def references(*args, **options)
233
+ options[:_uses_legacy_reference_index_name] = true
234
+ super
235
+ end
236
+ alias :belongs_to :references
237
+
238
+ def column(name, type, index: nil, **options)
239
+ options[:precision] ||= nil
240
+ super
241
+ end
242
+
243
+ private
244
+ def raise_on_if_exist_options(options)
245
+ end
246
+ end
247
+
248
+ def add_reference(table_name, ref_name, **options)
249
+ if connection.adapter_name == "SQLite"
250
+ options[:type] = :integer
251
+ end
252
+
253
+ options[:_uses_legacy_reference_index_name] = true
254
+ super
255
+ end
256
+ alias :add_belongs_to :add_reference
257
+
258
+ private
259
+ def compatible_table_definition(t)
260
+ class << t
261
+ prepend TableDefinition
262
+ end
263
+ super
264
+ end
265
+ end
266
+
267
+ class V5_2 < V6_0
268
+ module TableDefinition
269
+ def timestamps(**options)
270
+ options[:precision] ||= nil
62
271
  super
63
272
  end
273
+
274
+ def column(name, type, index: nil, **options)
275
+ options[:precision] ||= nil
276
+ super
277
+ end
278
+
279
+ private
280
+ def raise_on_if_exist_options(options)
281
+ end
282
+
283
+ def raise_on_duplicate_column(name)
284
+ end
285
+ end
286
+
287
+ module CommandRecorder
288
+ def invert_transaction(args, &block)
289
+ [:transaction, args, block]
290
+ end
291
+
292
+ def invert_change_column_comment(args)
293
+ [:change_column_comment, args]
294
+ end
295
+
296
+ def invert_change_table_comment(args)
297
+ [:change_table_comment, args]
298
+ end
64
299
  end
65
300
 
66
301
  def add_timestamps(table_name, **options)
@@ -73,7 +308,7 @@ module ActiveRecord
73
308
  class << t
74
309
  prepend TableDefinition
75
310
  end
76
- t
311
+ super
77
312
  end
78
313
 
79
314
  def command_recorder
@@ -86,9 +321,9 @@ module ActiveRecord
86
321
  end
87
322
 
88
323
  class V5_1 < V5_2
89
- def change_column(table_name, column_name, type, options = {})
324
+ def change_column(table_name, column_name, type, **options)
90
325
  if connection.adapter_name == "PostgreSQL"
91
- super(table_name, column_name, type, options.except(:default, :null, :comment))
326
+ super(table_name, column_name, type, **options.except(:default, :null, :comment))
92
327
  connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
93
328
  connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
94
329
  connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
@@ -97,8 +332,8 @@ module ActiveRecord
97
332
  end
98
333
  end
99
334
 
100
- def create_table(table_name, options = {})
101
- if connection.adapter_name == "Mysql2"
335
+ def create_table(table_name, **options)
336
+ if connection.adapter_name == "Mysql2" || connection.adapter_name == "Trilogy"
102
337
  super(table_name, options: "ENGINE=InnoDB", **options)
103
338
  else
104
339
  super
@@ -117,16 +352,20 @@ module ActiveRecord
117
352
  super(*args, type: :integer, **options)
118
353
  end
119
354
  alias :belongs_to :references
355
+
356
+ private
357
+ def raise_on_if_exist_options(options)
358
+ end
120
359
  end
121
360
 
122
- def create_table(table_name, options = {})
361
+ def create_table(table_name, **options)
123
362
  if connection.adapter_name == "PostgreSQL"
124
363
  if options[:id] == :uuid && !options.key?(:default)
125
364
  options[:default] = "uuid_generate_v4()"
126
365
  end
127
366
  end
128
367
 
129
- unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
368
+ unless ["Mysql2", "Trilogy"].include?(connection.adapter_name) && options[:id] == :bigint
130
369
  if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
131
370
  options[:default] = nil
132
371
  end
@@ -147,10 +386,12 @@ module ActiveRecord
147
386
  super
148
387
  end
149
388
 
150
- def add_column(table_name, column_name, type, options = {})
389
+ def add_column(table_name, column_name, type, **options)
151
390
  if type == :primary_key
152
391
  type = :integer
153
392
  options[:primary_key] = true
393
+ elsif type == :datetime
394
+ options[:precision] ||= nil
154
395
  end
155
396
  super
156
397
  end
@@ -181,6 +422,10 @@ module ActiveRecord
181
422
  options[:null] = true if options[:null].nil?
182
423
  super
183
424
  end
425
+
426
+ private
427
+ def raise_on_if_exist_options(options)
428
+ end
184
429
  end
185
430
 
186
431
  def add_reference(table_name, ref_name, **options)
@@ -194,7 +439,7 @@ module ActiveRecord
194
439
  super
195
440
  end
196
441
 
197
- def index_exists?(table_name, column_name, options = {})
442
+ def index_exists?(table_name, column_name, **options)
198
443
  column_names = Array(column_name).map(&:to_s)
199
444
  options[:name] =
200
445
  if options[:name].present?
@@ -205,10 +450,9 @@ module ActiveRecord
205
450
  super
206
451
  end
207
452
 
208
- def remove_index(table_name, options = {})
209
- options = { column: options } unless options.is_a?(Hash)
210
- options[:name] = index_name_for_remove(table_name, options)
211
- super(table_name, options)
453
+ def remove_index(table_name, column_name = nil, **options)
454
+ options[:name] = index_name_for_remove(table_name, column_name, options)
455
+ super
212
456
  end
213
457
 
214
458
  private
@@ -219,13 +463,12 @@ module ActiveRecord
219
463
  super
220
464
  end
221
465
 
222
- def index_name_for_remove(table_name, options = {})
223
- index_name = connection.index_name(table_name, options)
466
+ def index_name_for_remove(table_name, column_name, options)
467
+ index_name = connection.index_name(table_name, column_name || options)
224
468
 
225
469
  unless connection.index_name_exists?(table_name, index_name)
226
- if options.is_a?(Hash) && options.has_key?(:name)
227
- options_without_column = options.dup
228
- options_without_column.delete :column
470
+ if options.key?(:name)
471
+ options_without_column = options.except(:column)
229
472
  index_name_without_column = connection.index_name(table_name, options_without_column)
230
473
 
231
474
  if connection.index_name_exists?(table_name, index_name_without_column)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ # The default strategy for executing migrations. Delegates method calls
6
+ # to the connection adapter.
7
+ class DefaultStrategy < ExecutionStrategy # :nodoc:
8
+ private
9
+ def method_missing(method, ...)
10
+ connection.send(method, ...)
11
+ end
12
+
13
+ def respond_to_missing?(method, include_private = false)
14
+ connection.respond_to?(method, include_private) || super
15
+ end
16
+
17
+ def connection
18
+ migration.connection
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ # ExecutionStrategy is used by the migration to respond to any method calls
6
+ # that the migration class does not implement directly. This is the base strategy.
7
+ # All strategies should inherit from this class.
8
+ #
9
+ # The ExecutionStrategy receives the current +migration+ when initialized.
10
+ class ExecutionStrategy # :nodoc:
11
+ def initialize(migration)
12
+ @migration = migration
13
+ end
14
+
15
+ private
16
+ attr_reader :migration
17
+ end
18
+ end
19
+ end
@@ -2,9 +2,8 @@
2
2
 
3
3
  module ActiveRecord
4
4
  class Migration
5
- module JoinTable #:nodoc:
5
+ module JoinTable # :nodoc:
6
6
  private
7
-
8
7
  def find_join_table_name(table_1, table_2, options = {})
9
8
  options.delete(:table_name) || join_table_name(table_1, table_2)
10
9
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class PendingMigrationConnection # :nodoc:
5
+ def self.with_temporary_pool(db_config, &block)
6
+ pool = ActiveRecord::Base.connection_handler.establish_connection(db_config, owner_name: self)
7
+
8
+ yield pool
9
+ ensure
10
+ ActiveRecord::Base.connection_handler.remove_connection_pool(self.name)
11
+ end
12
+
13
+ def self.primary_class?
14
+ false
15
+ end
16
+
17
+ def self.current_preventing_writes
18
+ false
19
+ end
20
+ end
21
+ end