activerecord 5.2.8 → 7.0.2

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 (364) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1393 -587
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +10 -9
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +122 -47
  10. data/lib/active_record/associations/association_scope.rb +24 -24
  11. data/lib/active_record/associations/belongs_to_association.rb +67 -49
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
  13. data/lib/active_record/associations/builder/association.rb +52 -23
  14. data/lib/active_record/associations/builder/belongs_to.rb +44 -61
  15. data/lib/active_record/associations/builder/collection_association.rb +17 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +10 -3
  18. data/lib/active_record/associations/builder/has_one.rb +35 -3
  19. data/lib/active_record/associations/builder/singular_association.rb +5 -3
  20. data/lib/active_record/associations/collection_association.rb +59 -50
  21. data/lib/active_record/associations/collection_proxy.rb +32 -23
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +27 -14
  25. data/lib/active_record/associations/has_many_through_association.rb +26 -19
  26. data/lib/active_record/associations/has_one_association.rb +52 -37
  27. data/lib/active_record/associations/has_one_through_association.rb +6 -6
  28. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  30. data/lib/active_record/associations/join_dependency.rb +97 -62
  31. data/lib/active_record/associations/preloader/association.rb +220 -60
  32. data/lib/active_record/associations/preloader/batch.rb +48 -0
  33. data/lib/active_record/associations/preloader/branch.rb +147 -0
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -40
  35. data/lib/active_record/associations/preloader.rb +44 -105
  36. data/lib/active_record/associations/singular_association.rb +9 -17
  37. data/lib/active_record/associations/through_association.rb +4 -4
  38. data/lib/active_record/associations.rb +207 -66
  39. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  40. data/lib/active_record/attribute_assignment.rb +17 -19
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +141 -47
  43. data/lib/active_record/attribute_methods/primary_key.rb +22 -27
  44. data/lib/active_record/attribute_methods/query.rb +6 -10
  45. data/lib/active_record/attribute_methods/read.rb +15 -55
  46. data/lib/active_record/attribute_methods/serialization.rb +77 -18
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
  48. data/lib/active_record/attribute_methods/write.rb +18 -37
  49. data/lib/active_record/attribute_methods.rb +90 -153
  50. data/lib/active_record/attributes.rb +38 -12
  51. data/lib/active_record/autosave_association.rb +50 -50
  52. data/lib/active_record/base.rb +23 -18
  53. data/lib/active_record/callbacks.rb +159 -44
  54. data/lib/active_record/coders/yaml_column.rb +12 -3
  55. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
  63. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
  71. data/lib/active_record/connection_adapters/column.rb +33 -11
  72. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  73. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  74. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  75. data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
  76. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  77. data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
  78. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  80. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
  81. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
  82. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  83. data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
  84. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  85. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  86. data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
  87. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
  95. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +26 -12
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
  116. data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  121. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
  122. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
  123. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  124. data/lib/active_record/connection_adapters.rb +53 -0
  125. data/lib/active_record/connection_handling.rb +292 -38
  126. data/lib/active_record/core.rb +385 -158
  127. data/lib/active_record/counter_cache.rb +8 -30
  128. data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
  129. data/lib/active_record/database_configurations/database_config.rb +83 -0
  130. data/lib/active_record/database_configurations/hash_config.rb +154 -0
  131. data/lib/active_record/database_configurations/url_config.rb +53 -0
  132. data/lib/active_record/database_configurations.rb +256 -0
  133. data/lib/active_record/delegated_type.rb +250 -0
  134. data/lib/active_record/destroy_association_async_job.rb +36 -0
  135. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  136. data/lib/active_record/dynamic_matchers.rb +4 -5
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +44 -0
  140. data/lib/active_record/encryption/configurable.rb +61 -0
  141. data/lib/active_record/encryption/context.rb +35 -0
  142. data/lib/active_record/encryption/contexts.rb +72 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +155 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +42 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_serializer.rb +90 -0
  159. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  160. data/lib/active_record/encryption/properties.rb +76 -0
  161. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  162. data/lib/active_record/encryption/scheme.rb +99 -0
  163. data/lib/active_record/encryption.rb +55 -0
  164. data/lib/active_record/enum.rb +130 -51
  165. data/lib/active_record/errors.rb +129 -23
  166. data/lib/active_record/explain.rb +10 -6
  167. data/lib/active_record/explain_registry.rb +11 -6
  168. data/lib/active_record/explain_subscriber.rb +1 -1
  169. data/lib/active_record/fixture_set/file.rb +22 -15
  170. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  171. data/lib/active_record/fixture_set/render_context.rb +17 -0
  172. data/lib/active_record/fixture_set/table_row.rb +187 -0
  173. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  174. data/lib/active_record/fixtures.rb +206 -490
  175. data/lib/active_record/future_result.rb +139 -0
  176. data/lib/active_record/gem_version.rb +3 -3
  177. data/lib/active_record/inheritance.rb +104 -37
  178. data/lib/active_record/insert_all.rb +278 -0
  179. data/lib/active_record/integration.rb +69 -18
  180. data/lib/active_record/internal_metadata.rb +24 -9
  181. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  182. data/lib/active_record/locking/optimistic.rb +41 -26
  183. data/lib/active_record/locking/pessimistic.rb +18 -8
  184. data/lib/active_record/log_subscriber.rb +46 -35
  185. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  186. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  187. data/lib/active_record/middleware/database_selector.rb +82 -0
  188. data/lib/active_record/middleware/shard_selector.rb +60 -0
  189. data/lib/active_record/migration/command_recorder.rb +96 -44
  190. data/lib/active_record/migration/compatibility.rb +246 -64
  191. data/lib/active_record/migration/join_table.rb +1 -2
  192. data/lib/active_record/migration.rb +266 -187
  193. data/lib/active_record/model_schema.rb +165 -52
  194. data/lib/active_record/nested_attributes.rb +17 -19
  195. data/lib/active_record/no_touching.rb +11 -4
  196. data/lib/active_record/null_relation.rb +2 -7
  197. data/lib/active_record/persistence.rb +467 -92
  198. data/lib/active_record/query_cache.rb +21 -4
  199. data/lib/active_record/query_logs.rb +138 -0
  200. data/lib/active_record/querying.rb +51 -24
  201. data/lib/active_record/railtie.rb +224 -57
  202. data/lib/active_record/railties/console_sandbox.rb +2 -4
  203. data/lib/active_record/railties/controller_runtime.rb +31 -36
  204. data/lib/active_record/railties/databases.rake +369 -101
  205. data/lib/active_record/readonly_attributes.rb +15 -0
  206. data/lib/active_record/reflection.rb +170 -137
  207. data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
  208. data/lib/active_record/relation/batches.rb +46 -37
  209. data/lib/active_record/relation/calculations.rb +168 -96
  210. data/lib/active_record/relation/delegation.rb +37 -52
  211. data/lib/active_record/relation/finder_methods.rb +79 -58
  212. data/lib/active_record/relation/from_clause.rb +5 -1
  213. data/lib/active_record/relation/merger.rb +50 -51
  214. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  215. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  216. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  217. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  218. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  219. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  220. data/lib/active_record/relation/predicate_builder.rb +58 -46
  221. data/lib/active_record/relation/query_attribute.rb +9 -10
  222. data/lib/active_record/relation/query_methods.rb +685 -208
  223. data/lib/active_record/relation/record_fetch_warning.rb +9 -11
  224. data/lib/active_record/relation/spawn_methods.rb +10 -10
  225. data/lib/active_record/relation/where_clause.rb +108 -64
  226. data/lib/active_record/relation.rb +515 -151
  227. data/lib/active_record/result.rb +78 -42
  228. data/lib/active_record/runtime_registry.rb +9 -13
  229. data/lib/active_record/sanitization.rb +29 -44
  230. data/lib/active_record/schema.rb +37 -31
  231. data/lib/active_record/schema_dumper.rb +74 -23
  232. data/lib/active_record/schema_migration.rb +7 -9
  233. data/lib/active_record/scoping/default.rb +62 -17
  234. data/lib/active_record/scoping/named.rb +17 -32
  235. data/lib/active_record/scoping.rb +70 -41
  236. data/lib/active_record/secure_token.rb +16 -8
  237. data/lib/active_record/serialization.rb +6 -4
  238. data/lib/active_record/signed_id.rb +116 -0
  239. data/lib/active_record/statement_cache.rb +49 -6
  240. data/lib/active_record/store.rb +88 -9
  241. data/lib/active_record/suppressor.rb +13 -17
  242. data/lib/active_record/table_metadata.rb +42 -43
  243. data/lib/active_record/tasks/database_tasks.rb +352 -94
  244. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  245. data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
  246. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  247. data/lib/active_record/test_databases.rb +24 -0
  248. data/lib/active_record/test_fixtures.rb +287 -0
  249. data/lib/active_record/timestamp.rb +44 -34
  250. data/lib/active_record/touch_later.rb +23 -22
  251. data/lib/active_record/transactions.rb +67 -128
  252. data/lib/active_record/translation.rb +3 -3
  253. data/lib/active_record/type/adapter_specific_registry.rb +34 -19
  254. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  255. data/lib/active_record/type/internal/timezone.rb +2 -2
  256. data/lib/active_record/type/serialized.rb +7 -4
  257. data/lib/active_record/type/time.rb +10 -0
  258. data/lib/active_record/type/type_map.rb +17 -21
  259. data/lib/active_record/type/unsigned_integer.rb +0 -1
  260. data/lib/active_record/type.rb +9 -5
  261. data/lib/active_record/type_caster/connection.rb +15 -15
  262. data/lib/active_record/type_caster/map.rb +8 -8
  263. data/lib/active_record/validations/associated.rb +2 -3
  264. data/lib/active_record/validations/numericality.rb +35 -0
  265. data/lib/active_record/validations/uniqueness.rb +39 -31
  266. data/lib/active_record/validations.rb +4 -3
  267. data/lib/active_record.rb +209 -32
  268. data/lib/arel/alias_predication.rb +9 -0
  269. data/lib/arel/attributes/attribute.rb +33 -0
  270. data/lib/arel/collectors/bind.rb +29 -0
  271. data/lib/arel/collectors/composite.rb +39 -0
  272. data/lib/arel/collectors/plain_string.rb +20 -0
  273. data/lib/arel/collectors/sql_string.rb +27 -0
  274. data/lib/arel/collectors/substitute_binds.rb +35 -0
  275. data/lib/arel/crud.rb +48 -0
  276. data/lib/arel/delete_manager.rb +32 -0
  277. data/lib/arel/errors.rb +9 -0
  278. data/lib/arel/expressions.rb +29 -0
  279. data/lib/arel/factory_methods.rb +49 -0
  280. data/lib/arel/filter_predications.rb +9 -0
  281. data/lib/arel/insert_manager.rb +48 -0
  282. data/lib/arel/math.rb +45 -0
  283. data/lib/arel/nodes/and.rb +32 -0
  284. data/lib/arel/nodes/ascending.rb +23 -0
  285. data/lib/arel/nodes/binary.rb +126 -0
  286. data/lib/arel/nodes/bind_param.rb +44 -0
  287. data/lib/arel/nodes/case.rb +55 -0
  288. data/lib/arel/nodes/casted.rb +62 -0
  289. data/lib/arel/nodes/comment.rb +29 -0
  290. data/lib/arel/nodes/count.rb +12 -0
  291. data/lib/arel/nodes/delete_statement.rb +44 -0
  292. data/lib/arel/nodes/descending.rb +23 -0
  293. data/lib/arel/nodes/equality.rb +15 -0
  294. data/lib/arel/nodes/extract.rb +24 -0
  295. data/lib/arel/nodes/false.rb +16 -0
  296. data/lib/arel/nodes/filter.rb +10 -0
  297. data/lib/arel/nodes/full_outer_join.rb +8 -0
  298. data/lib/arel/nodes/function.rb +45 -0
  299. data/lib/arel/nodes/grouping.rb +11 -0
  300. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  301. data/lib/arel/nodes/in.rb +15 -0
  302. data/lib/arel/nodes/infix_operation.rb +92 -0
  303. data/lib/arel/nodes/inner_join.rb +8 -0
  304. data/lib/arel/nodes/insert_statement.rb +37 -0
  305. data/lib/arel/nodes/join_source.rb +20 -0
  306. data/lib/arel/nodes/matches.rb +18 -0
  307. data/lib/arel/nodes/named_function.rb +23 -0
  308. data/lib/arel/nodes/node.rb +51 -0
  309. data/lib/arel/nodes/node_expression.rb +13 -0
  310. data/lib/arel/nodes/ordering.rb +27 -0
  311. data/lib/arel/nodes/outer_join.rb +8 -0
  312. data/lib/arel/nodes/over.rb +15 -0
  313. data/lib/arel/nodes/regexp.rb +16 -0
  314. data/lib/arel/nodes/right_outer_join.rb +8 -0
  315. data/lib/arel/nodes/select_core.rb +67 -0
  316. data/lib/arel/nodes/select_statement.rb +41 -0
  317. data/lib/arel/nodes/sql_literal.rb +19 -0
  318. data/lib/arel/nodes/string_join.rb +11 -0
  319. data/lib/arel/nodes/table_alias.rb +31 -0
  320. data/lib/arel/nodes/terminal.rb +16 -0
  321. data/lib/arel/nodes/true.rb +16 -0
  322. data/lib/arel/nodes/unary.rb +44 -0
  323. data/lib/arel/nodes/unary_operation.rb +20 -0
  324. data/lib/arel/nodes/unqualified_column.rb +22 -0
  325. data/lib/arel/nodes/update_statement.rb +46 -0
  326. data/lib/arel/nodes/values_list.rb +9 -0
  327. data/lib/arel/nodes/window.rb +126 -0
  328. data/lib/arel/nodes/with.rb +11 -0
  329. data/lib/arel/nodes.rb +71 -0
  330. data/lib/arel/order_predications.rb +13 -0
  331. data/lib/arel/predications.rb +258 -0
  332. data/lib/arel/select_manager.rb +276 -0
  333. data/lib/arel/table.rb +117 -0
  334. data/lib/arel/tree_manager.rb +60 -0
  335. data/lib/arel/update_manager.rb +48 -0
  336. data/lib/arel/visitors/dot.rb +298 -0
  337. data/lib/arel/visitors/mysql.rb +99 -0
  338. data/lib/arel/visitors/postgresql.rb +110 -0
  339. data/lib/arel/visitors/sqlite.rb +38 -0
  340. data/lib/arel/visitors/to_sql.rb +955 -0
  341. data/lib/arel/visitors/visitor.rb +45 -0
  342. data/lib/arel/visitors.rb +13 -0
  343. data/lib/arel/window_predications.rb +9 -0
  344. data/lib/arel.rb +55 -0
  345. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  346. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  347. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  348. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  349. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  350. data/lib/rails/generators/active_record/migration.rb +19 -2
  351. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  352. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  353. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  354. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  355. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  356. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  357. metadata +162 -32
  358. data/lib/active_record/attribute_decorators.rb +0 -90
  359. data/lib/active_record/collection_cache_key.rb +0 -53
  360. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  361. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  362. data/lib/active_record/define_callbacks.rb +0 -22
  363. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  364. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
- module ConnectionAdapters #:nodoc:
4
+ module ConnectionAdapters # :nodoc:
5
5
  # Abstract representation of an index definition on a table. Instances of
6
6
  # this type are typically created and returned by methods in database
7
7
  # adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
@@ -33,6 +33,14 @@ module ActiveRecord
33
33
  @comment = comment
34
34
  end
35
35
 
36
+ def column_options
37
+ {
38
+ length: lengths,
39
+ order: orders,
40
+ opclass: opclasses,
41
+ }
42
+ end
43
+
36
44
  private
37
45
  def concise_options(options)
38
46
  if columns.size == options.size && options.values.uniq.size == 1
@@ -63,15 +71,21 @@ module ActiveRecord
63
71
  end
64
72
  CODE
65
73
  end
74
+
75
+ def aliased_types(name, fallback)
76
+ "timestamp" == name ? :datetime : fallback
77
+ end
66
78
  end
67
79
 
68
80
  AddColumnDefinition = Struct.new(:column) # :nodoc:
69
81
 
70
- ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
82
+ ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc:
83
+
84
+ CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
71
85
 
72
86
  PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
73
87
 
74
- ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
88
+ ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do # :nodoc:
75
89
  def name
76
90
  options[:name]
77
91
  end
@@ -92,6 +106,10 @@ module ActiveRecord
92
106
  options[:on_update]
93
107
  end
94
108
 
109
+ def deferrable
110
+ options[:deferrable]
111
+ end
112
+
95
113
  def custom_primary_key?
96
114
  options[:primary_key] != default_primary_key
97
115
  end
@@ -101,13 +119,14 @@ module ActiveRecord
101
119
  end
102
120
  alias validated? validate?
103
121
 
104
- def defined_for?(to_table_ord = nil, to_table: nil, **options)
105
- if to_table_ord
106
- self.to_table == to_table_ord.to_s
107
- else
108
- (to_table.nil? || to_table.to_s == self.to_table) &&
109
- options.all? { |k, v| self.options[k].to_s == v.to_s }
110
- end
122
+ def export_name_on_schema_dump?
123
+ !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
124
+ end
125
+
126
+ def defined_for?(to_table: nil, validate: nil, **options)
127
+ (to_table.nil? || to_table.to_s == self.to_table) &&
128
+ (validate.nil? || validate == options.fetch(:validate, validate)) &&
129
+ options.all? { |k, v| self.options[k].to_s == v.to_s }
111
130
  end
112
131
 
113
132
  private
@@ -116,6 +135,21 @@ module ActiveRecord
116
135
  end
117
136
  end
118
137
 
138
+ CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
139
+ def name
140
+ options[:name]
141
+ end
142
+
143
+ def validate?
144
+ options.fetch(:validate, true)
145
+ end
146
+ alias validated? validate?
147
+
148
+ def export_name_on_schema_dump?
149
+ !ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
150
+ end
151
+ end
152
+
119
153
  class ReferenceDefinition # :nodoc:
120
154
  def initialize(
121
155
  name,
@@ -138,26 +172,21 @@ module ActiveRecord
138
172
  end
139
173
 
140
174
  def add_to(table)
141
- columns.each do |column_options|
142
- table.column(*column_options)
175
+ columns.each do |name, type, options|
176
+ table.column(name, type, **options)
143
177
  end
144
178
 
145
179
  if index
146
- table.index(column_names, index_options)
180
+ table.index(column_names, **index_options(table.name))
147
181
  end
148
182
 
149
183
  if foreign_key
150
- table.foreign_key(foreign_table_name, foreign_key_options)
184
+ table.foreign_key(foreign_table_name, **foreign_key_options)
151
185
  end
152
186
  end
153
187
 
154
- # TODO Change this to private once we've dropped Ruby 2.2 support.
155
- # Workaround for Ruby 2.2 "private attribute?" warning.
156
- protected
157
-
158
- attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
159
-
160
188
  private
189
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
161
190
 
162
191
  def as_options(value)
163
192
  value.is_a?(Hash) ? value : {}
@@ -167,8 +196,14 @@ module ActiveRecord
167
196
  as_options(polymorphic).merge(options.slice(:null, :first, :after))
168
197
  end
169
198
 
170
- def index_options
171
- as_options(index)
199
+ def polymorphic_index_name(table_name)
200
+ "index_#{table_name}_on_#{name}"
201
+ end
202
+
203
+ def index_options(table_name)
204
+ index_options = as_options(index)
205
+ index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
206
+ index_options
172
207
  end
173
208
 
174
209
  def foreign_key_options
@@ -199,41 +234,46 @@ module ActiveRecord
199
234
  end
200
235
 
201
236
  module ColumnMethods
237
+ extend ActiveSupport::Concern
238
+
202
239
  # Appends a primary key definition to the table definition.
203
240
  # Can be called multiple times, but this is probably not a good idea.
204
241
  def primary_key(name, type = :primary_key, **options)
205
- column(name, type, options.merge(primary_key: true))
242
+ column(name, type, **options.merge(primary_key: true))
206
243
  end
207
244
 
245
+ ##
246
+ # :method: column
247
+ # :call-seq: column(name, type, **options)
248
+ #
208
249
  # Appends a column or columns of a specified type.
209
250
  #
210
251
  # t.string(:goat)
211
252
  # t.string(:goat, :sheep)
212
253
  #
213
254
  # See TableDefinition#column
214
- [
215
- :bigint,
216
- :binary,
217
- :boolean,
218
- :date,
219
- :datetime,
220
- :decimal,
221
- :float,
222
- :integer,
223
- :json,
224
- :string,
225
- :text,
226
- :time,
227
- :timestamp,
228
- :virtual,
229
- ].each do |column_type|
230
- module_eval <<-CODE, __FILE__, __LINE__ + 1
231
- def #{column_type}(*args, **options)
232
- args.each { |name| column(name, :#{column_type}, options) }
255
+
256
+ included do
257
+ define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
258
+ :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
259
+
260
+ alias :blob :binary
261
+ alias :numeric :decimal
262
+ end
263
+
264
+ class_methods do
265
+ def define_column_methods(*column_types) # :nodoc:
266
+ column_types.each do |column_type|
267
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
268
+ def #{column_type}(*names, **options)
269
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
270
+ names.each { |name| column(name, :#{column_type}, **options) }
271
+ end
272
+ RUBY
233
273
  end
234
- CODE
274
+ end
275
+ private :define_column_methods
235
276
  end
236
- alias_method :numeric, :decimal
237
277
  end
238
278
 
239
279
  # Represents the schema of an SQL table in an abstract way. This class
@@ -242,7 +282,7 @@ module ActiveRecord
242
282
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
243
283
  # is actually of this type:
244
284
  #
245
- # class SomeMigration < ActiveRecord::Migration[5.0]
285
+ # class SomeMigration < ActiveRecord::Migration[7.0]
246
286
  # def up
247
287
  # create_table :foo do |t|
248
288
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -257,15 +297,26 @@ module ActiveRecord
257
297
  class TableDefinition
258
298
  include ColumnMethods
259
299
 
260
- attr_accessor :indexes
261
- attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
300
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
262
301
 
263
- def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
302
+ def initialize(
303
+ conn,
304
+ name,
305
+ temporary: false,
306
+ if_not_exists: false,
307
+ options: nil,
308
+ as: nil,
309
+ comment: nil,
310
+ **
311
+ )
312
+ @conn = conn
264
313
  @columns_hash = {}
265
314
  @indexes = []
266
315
  @foreign_keys = []
267
316
  @primary_keys = nil
317
+ @check_constraints = []
268
318
  @temporary = temporary
319
+ @if_not_exists = if_not_exists
269
320
  @options = options
270
321
  @as = as
271
322
  @name = name
@@ -349,21 +400,34 @@ module ActiveRecord
349
400
  #
350
401
  # create_table :taggings do |t|
351
402
  # t.references :tag, index: { name: 'index_taggings_on_tag_id' }
352
- # t.references :tagger, polymorphic: true, index: true
353
- # t.references :taggable, polymorphic: { default: 'Photo' }
403
+ # t.references :tagger, polymorphic: true
404
+ # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
354
405
  # end
355
- def column(name, type, options = {})
406
+ def column(name, type, index: nil, **options)
356
407
  name = name.to_s
357
408
  type = type.to_sym if type
358
- options = options.dup
359
409
 
360
- if @columns_hash[name] && @columns_hash[name].primary_key?
361
- raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
410
+ if @columns_hash[name]
411
+ if @columns_hash[name].primary_key?
412
+ raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
413
+ else
414
+ raise ArgumentError, "you can't define an already defined column '#{name}'."
415
+ end
416
+ end
417
+
418
+ if @conn.supports_datetime_with_precision?
419
+ if type == :datetime && !options.key?(:precision)
420
+ options[:precision] = 6
421
+ end
422
+ end
423
+
424
+ @columns_hash[name] = new_column_definition(name, type, **options)
425
+
426
+ if index
427
+ index_options = index.is_a?(Hash) ? index : {}
428
+ index(name, **index_options)
362
429
  end
363
430
 
364
- index_options = options.delete(:index)
365
- index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
366
- @columns_hash[name] = new_column_definition(name, type, options)
367
431
  self
368
432
  end
369
433
 
@@ -377,15 +441,16 @@ module ActiveRecord
377
441
  # This is primarily used to track indexes that need to be created after the table
378
442
  #
379
443
  # index(:account_id, name: 'index_projects_on_account_id')
380
- def index(column_name, options = {})
444
+ def index(column_name, **options)
381
445
  indexes << [column_name, options]
382
446
  end
383
447
 
384
- def foreign_key(table_name, options = {}) # :nodoc:
385
- table_name_prefix = ActiveRecord::Base.table_name_prefix
386
- table_name_suffix = ActiveRecord::Base.table_name_suffix
387
- table_name = "#{table_name_prefix}#{table_name}#{table_name_suffix}"
388
- foreign_keys.push([table_name, options])
448
+ def foreign_key(to_table, **options)
449
+ foreign_keys << new_foreign_key_definition(to_table, options)
450
+ end
451
+
452
+ def check_constraint(expression, **options)
453
+ check_constraints << new_check_constraint_definition(expression, options)
389
454
  end
390
455
 
391
456
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
@@ -395,19 +460,24 @@ module ActiveRecord
395
460
  def timestamps(**options)
396
461
  options[:null] = false if options[:null].nil?
397
462
 
398
- column(:created_at, :datetime, options)
399
- column(:updated_at, :datetime, options)
463
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
464
+ options[:precision] = 6
465
+ end
466
+
467
+ column(:created_at, :datetime, **options)
468
+ column(:updated_at, :datetime, **options)
400
469
  end
401
470
 
402
471
  # Adds a reference.
403
472
  #
404
473
  # t.references(:user)
405
474
  # t.belongs_to(:supplier, foreign_key: true)
475
+ # t.belongs_to(:supplier, foreign_key: true, type: :integer)
406
476
  #
407
477
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
408
478
  def references(*args, **options)
409
479
  args.each do |ref_name|
410
- ReferenceDefinition.new(ref_name, options).add_to(self)
480
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
411
481
  end
412
482
  end
413
483
  alias :belongs_to :references
@@ -422,6 +492,19 @@ module ActiveRecord
422
492
  create_column_definition(name, type, options)
423
493
  end
424
494
 
495
+ def new_foreign_key_definition(to_table, options) # :nodoc:
496
+ prefix = ActiveRecord::Base.table_name_prefix
497
+ suffix = ActiveRecord::Base.table_name_suffix
498
+ to_table = "#{prefix}#{to_table}#{suffix}"
499
+ options = @conn.foreign_key_options(name, to_table, options)
500
+ ForeignKeyDefinition.new(name, to_table, options)
501
+ end
502
+
503
+ def new_check_constraint_definition(expression, options) # :nodoc:
504
+ options = @conn.check_constraint_options(name, expression, options)
505
+ CheckConstraintDefinition.new(name, expression, options)
506
+ end
507
+
425
508
  private
426
509
  def create_column_definition(name, type, options)
427
510
  ColumnDefinition.new(name, type, options)
@@ -442,30 +525,40 @@ module ActiveRecord
442
525
 
443
526
  class AlterTable # :nodoc:
444
527
  attr_reader :adds
445
- attr_reader :foreign_key_adds
446
- attr_reader :foreign_key_drops
528
+ attr_reader :foreign_key_adds, :foreign_key_drops
529
+ attr_reader :check_constraint_adds, :check_constraint_drops
447
530
 
448
531
  def initialize(td)
449
532
  @td = td
450
533
  @adds = []
451
534
  @foreign_key_adds = []
452
535
  @foreign_key_drops = []
536
+ @check_constraint_adds = []
537
+ @check_constraint_drops = []
453
538
  end
454
539
 
455
540
  def name; @td.name; end
456
541
 
457
542
  def add_foreign_key(to_table, options)
458
- @foreign_key_adds << ForeignKeyDefinition.new(name, to_table, options)
543
+ @foreign_key_adds << @td.new_foreign_key_definition(to_table, options)
459
544
  end
460
545
 
461
546
  def drop_foreign_key(name)
462
547
  @foreign_key_drops << name
463
548
  end
464
549
 
465
- def add_column(name, type, options)
550
+ def add_check_constraint(expression, options)
551
+ @check_constraint_adds << @td.new_check_constraint_definition(expression, options)
552
+ end
553
+
554
+ def drop_check_constraint(constraint_name)
555
+ @check_constraint_drops << constraint_name
556
+ end
557
+
558
+ def add_column(name, type, **options)
466
559
  name = name.to_s
467
560
  type = type.to_sym
468
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
561
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
469
562
  end
470
563
  end
471
564
 
@@ -482,9 +575,11 @@ module ActiveRecord
482
575
  # t.timestamps
483
576
  # t.change
484
577
  # t.change_default
578
+ # t.change_null
485
579
  # t.rename
486
580
  # t.references
487
581
  # t.belongs_to
582
+ # t.check_constraint
488
583
  # t.string
489
584
  # t.text
490
585
  # t.integer
@@ -497,14 +592,17 @@ module ActiveRecord
497
592
  # t.time
498
593
  # t.date
499
594
  # t.binary
595
+ # t.blob
500
596
  # t.boolean
501
597
  # t.foreign_key
502
598
  # t.json
503
599
  # t.virtual
504
600
  # t.remove
601
+ # t.remove_foreign_key
505
602
  # t.remove_references
506
603
  # t.remove_belongs_to
507
604
  # t.remove_index
605
+ # t.remove_check_constraint
508
606
  # t.remove_timestamps
509
607
  # end
510
608
  #
@@ -523,8 +621,12 @@ module ActiveRecord
523
621
  # t.column(:name, :string)
524
622
  #
525
623
  # See TableDefinition#column for details of the options you can use.
526
- def column(column_name, type, options = {})
527
- @base.add_column(name, column_name, type, options)
624
+ def column(column_name, type, index: nil, **options)
625
+ @base.add_column(name, column_name, type, **options)
626
+ if index
627
+ index_options = index.is_a?(Hash) ? index : {}
628
+ index(column_name, **index_options)
629
+ end
528
630
  end
529
631
 
530
632
  # Checks to see if a column exists.
@@ -532,8 +634,8 @@ module ActiveRecord
532
634
  # t.string(:name) unless t.column_exists?(:name, :string)
533
635
  #
534
636
  # See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
535
- def column_exists?(column_name, type = nil, options = {})
536
- @base.column_exists?(name, column_name, type, options)
637
+ def column_exists?(column_name, type = nil, **options)
638
+ @base.column_exists?(name, column_name, type, **options)
537
639
  end
538
640
 
539
641
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -544,8 +646,8 @@ module ActiveRecord
544
646
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
545
647
  #
546
648
  # See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
547
- def index(column_name, options = {})
548
- @base.add_index(name, column_name, options)
649
+ def index(column_name, **options)
650
+ @base.add_index(name, column_name, **options)
549
651
  end
550
652
 
551
653
  # Checks to see if an index exists.
@@ -573,8 +675,8 @@ module ActiveRecord
573
675
  # t.timestamps(null: false)
574
676
  #
575
677
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
576
- def timestamps(options = {})
577
- @base.add_timestamps(name, options)
678
+ def timestamps(**options)
679
+ @base.add_timestamps(name, **options)
578
680
  end
579
681
 
580
682
  # Changes the column's definition according to the new options.
@@ -583,8 +685,8 @@ module ActiveRecord
583
685
  # t.change(:description, :text)
584
686
  #
585
687
  # See TableDefinition#column for details of the options you can use.
586
- def change(column_name, type, options = {})
587
- @base.change_column(name, column_name, type, options)
688
+ def change(column_name, type, **options)
689
+ @base.change_column(name, column_name, type, **options)
588
690
  end
589
691
 
590
692
  # Sets a new default value for a column.
@@ -598,14 +700,24 @@ module ActiveRecord
598
700
  @base.change_column_default(name, column_name, default_or_changes)
599
701
  end
600
702
 
703
+ # Sets or removes a NOT NULL constraint on a column.
704
+ #
705
+ # t.change_null(:qualification, true)
706
+ # t.change_null(:qualification, false, 0)
707
+ #
708
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
709
+ def change_null(column_name, null, default = nil)
710
+ @base.change_column_null(name, column_name, null, default)
711
+ end
712
+
601
713
  # Removes the column(s) from the table definition.
602
714
  #
603
715
  # t.remove(:qualification)
604
716
  # t.remove(:qualification, :experience)
605
717
  #
606
718
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
607
- def remove(*column_names)
608
- @base.remove_columns(name, *column_names)
719
+ def remove(*column_names, **options)
720
+ @base.remove_columns(name, *column_names, **options)
609
721
  end
610
722
 
611
723
  # Removes the given index from the table.
@@ -613,10 +725,11 @@ module ActiveRecord
613
725
  # t.remove_index(:branch_id)
614
726
  # t.remove_index(column: [:branch_id, :party_id])
615
727
  # t.remove_index(name: :by_branch_party)
728
+ # t.remove_index(:branch_id, name: :by_branch_party)
616
729
  #
617
730
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
618
- def remove_index(options = {})
619
- @base.remove_index(name, options)
731
+ def remove_index(column_name = nil, **options)
732
+ @base.remove_index(name, column_name, **options)
620
733
  end
621
734
 
622
735
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -624,8 +737,8 @@ module ActiveRecord
624
737
  # t.remove_timestamps
625
738
  #
626
739
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
627
- def remove_timestamps(options = {})
628
- @base.remove_timestamps(name, options)
740
+ def remove_timestamps(**options)
741
+ @base.remove_timestamps(name, **options)
629
742
  end
630
743
 
631
744
  # Renames a column.
@@ -645,7 +758,7 @@ module ActiveRecord
645
758
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
646
759
  def references(*args, **options)
647
760
  args.each do |ref_name|
648
- @base.add_reference(name, ref_name, options)
761
+ @base.add_reference(name, ref_name, **options)
649
762
  end
650
763
  end
651
764
  alias :belongs_to :references
@@ -658,18 +771,29 @@ module ActiveRecord
658
771
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
659
772
  def remove_references(*args, **options)
660
773
  args.each do |ref_name|
661
- @base.remove_reference(name, ref_name, options)
774
+ @base.remove_reference(name, ref_name, **options)
662
775
  end
663
776
  end
664
777
  alias :remove_belongs_to :remove_references
665
778
 
666
- # Adds a foreign key.
779
+ # Adds a foreign key to the table using a supplied table name.
667
780
  #
668
781
  # t.foreign_key(:authors)
782
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
669
783
  #
670
784
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
671
- def foreign_key(*args)
672
- @base.add_foreign_key(name, *args)
785
+ def foreign_key(*args, **options)
786
+ @base.add_foreign_key(name, *args, **options)
787
+ end
788
+
789
+ # Removes the given foreign key from the table.
790
+ #
791
+ # t.remove_foreign_key(:authors)
792
+ # t.remove_foreign_key(column: :author_id)
793
+ #
794
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
795
+ def remove_foreign_key(*args, **options)
796
+ @base.remove_foreign_key(name, *args, **options)
673
797
  end
674
798
 
675
799
  # Checks to see if a foreign key exists.
@@ -677,8 +801,26 @@ module ActiveRecord
677
801
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
678
802
  #
679
803
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
680
- def foreign_key_exists?(*args)
681
- @base.foreign_key_exists?(name, *args)
804
+ def foreign_key_exists?(*args, **options)
805
+ @base.foreign_key_exists?(name, *args, **options)
806
+ end
807
+
808
+ # Adds a check constraint.
809
+ #
810
+ # t.check_constraint("price > 0", name: "price_check")
811
+ #
812
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
813
+ def check_constraint(*args, **options)
814
+ @base.add_check_constraint(name, *args, **options)
815
+ end
816
+
817
+ # Removes the given check constraint from the table.
818
+ #
819
+ # t.remove_check_constraint(name: "price_check")
820
+ #
821
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
822
+ def remove_check_constraint(*args, **options)
823
+ @base.remove_check_constraint(name, *args, **options)
682
824
  end
683
825
  end
684
826
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/hash/compact"
4
-
5
3
  module ActiveRecord
6
4
  module ConnectionAdapters # :nodoc:
7
5
  class SchemaDumper < SchemaDumper # :nodoc:
6
+ DEFAULT_DATETIME_PRECISION = 6 # :nodoc:
7
+
8
8
  def self.create(connection, options)
9
9
  new(connection, options)
10
10
  end
@@ -15,8 +15,8 @@ module ActiveRecord
15
15
  end
16
16
 
17
17
  def column_spec_for_primary_key(column)
18
- return {} if default_primary_key?(column)
19
- spec = { id: schema_type(column).inspect }
18
+ spec = {}
19
+ spec[:id] = schema_type(column).inspect unless default_primary_key?(column)
20
20
  spec.merge!(prepare_column_options(column).except!(:null))
21
21
  spec[:default] ||= "nil" if explicit_primary_key_default?(column)
22
22
  spec
@@ -65,7 +65,18 @@ module ActiveRecord
65
65
  end
66
66
 
67
67
  def schema_precision(column)
68
- column.precision.inspect if column.precision
68
+ if column.type == :datetime
69
+ case column.precision
70
+ when nil
71
+ "nil"
72
+ when DEFAULT_DATETIME_PRECISION
73
+ nil
74
+ else
75
+ column.precision.inspect
76
+ end
77
+ elsif column.precision
78
+ column.precision.inspect
79
+ end
69
80
  end
70
81
 
71
82
  def schema_scale(column)