activerecord 5.2.8.1 → 6.1.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1255 -596
  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 +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  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 +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +44 -34
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -18
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +137 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +4 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +49 -6
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +287 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +62 -118
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +116 -30
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -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,12 +71,18 @@ 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
82
  ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
71
83
 
84
+ CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
85
+
72
86
  PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
73
87
 
74
88
  ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
@@ -101,13 +115,14 @@ module ActiveRecord
101
115
  end
102
116
  alias validated? validate?
103
117
 
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
118
+ def export_name_on_schema_dump?
119
+ !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
120
+ end
121
+
122
+ def defined_for?(to_table: nil, validate: nil, **options)
123
+ (to_table.nil? || to_table.to_s == self.to_table) &&
124
+ (validate.nil? || validate == options.fetch(:validate, validate)) &&
125
+ options.all? { |k, v| self.options[k].to_s == v.to_s }
111
126
  end
112
127
 
113
128
  private
@@ -116,6 +131,21 @@ module ActiveRecord
116
131
  end
117
132
  end
118
133
 
134
+ CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
135
+ def name
136
+ options[:name]
137
+ end
138
+
139
+ def validate?
140
+ options.fetch(:validate, true)
141
+ end
142
+ alias validated? validate?
143
+
144
+ def export_name_on_schema_dump?
145
+ !ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
146
+ end
147
+ end
148
+
119
149
  class ReferenceDefinition # :nodoc:
120
150
  def initialize(
121
151
  name,
@@ -138,26 +168,21 @@ module ActiveRecord
138
168
  end
139
169
 
140
170
  def add_to(table)
141
- columns.each do |column_options|
142
- table.column(*column_options)
171
+ columns.each do |name, type, options|
172
+ table.column(name, type, **options)
143
173
  end
144
174
 
145
175
  if index
146
- table.index(column_names, index_options)
176
+ table.index(column_names, **index_options(table.name))
147
177
  end
148
178
 
149
179
  if foreign_key
150
- table.foreign_key(foreign_table_name, foreign_key_options)
180
+ table.foreign_key(foreign_table_name, **foreign_key_options)
151
181
  end
152
182
  end
153
183
 
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
184
  private
185
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
161
186
 
162
187
  def as_options(value)
163
188
  value.is_a?(Hash) ? value : {}
@@ -167,8 +192,18 @@ module ActiveRecord
167
192
  as_options(polymorphic).merge(options.slice(:null, :first, :after))
168
193
  end
169
194
 
170
- def index_options
171
- as_options(index)
195
+ def polymorphic_index_name(table_name)
196
+ "index_#{table_name}_on_#{name}"
197
+ end
198
+
199
+ def index_options(table_name)
200
+ index_options = as_options(index)
201
+
202
+ # legacy reference index names are used on versions 6.0 and earlier
203
+ return index_options if options[:_uses_legacy_reference_index_name]
204
+
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,45 @@ 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 :numeric :decimal
261
+ end
262
+
263
+ class_methods do
264
+ def define_column_methods(*column_types) # :nodoc:
265
+ column_types.each do |column_type|
266
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
267
+ def #{column_type}(*names, **options)
268
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
269
+ names.each { |name| column(name, :#{column_type}, **options) }
270
+ end
271
+ RUBY
233
272
  end
234
- CODE
273
+ end
274
+ private :define_column_methods
235
275
  end
236
- alias_method :numeric, :decimal
237
276
  end
238
277
 
239
278
  # Represents the schema of an SQL table in an abstract way. This class
@@ -242,7 +281,7 @@ module ActiveRecord
242
281
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
243
282
  # is actually of this type:
244
283
  #
245
- # class SomeMigration < ActiveRecord::Migration[5.0]
284
+ # class SomeMigration < ActiveRecord::Migration[6.0]
246
285
  # def up
247
286
  # create_table :foo do |t|
248
287
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -257,15 +296,26 @@ module ActiveRecord
257
296
  class TableDefinition
258
297
  include ColumnMethods
259
298
 
260
- attr_accessor :indexes
261
- attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
299
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
262
300
 
263
- def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
301
+ def initialize(
302
+ conn,
303
+ name,
304
+ temporary: false,
305
+ if_not_exists: false,
306
+ options: nil,
307
+ as: nil,
308
+ comment: nil,
309
+ **
310
+ )
311
+ @conn = conn
264
312
  @columns_hash = {}
265
313
  @indexes = []
266
314
  @foreign_keys = []
267
315
  @primary_keys = nil
316
+ @check_constraints = []
268
317
  @temporary = temporary
318
+ @if_not_exists = if_not_exists
269
319
  @options = options
270
320
  @as = as
271
321
  @name = name
@@ -349,21 +399,28 @@ module ActiveRecord
349
399
  #
350
400
  # create_table :taggings do |t|
351
401
  # 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' }
402
+ # t.references :tagger, polymorphic: true
403
+ # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
354
404
  # end
355
- def column(name, type, options = {})
405
+ def column(name, type, index: nil, **options)
356
406
  name = name.to_s
357
407
  type = type.to_sym if type
358
- options = options.dup
359
408
 
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."
409
+ if @columns_hash[name]
410
+ if @columns_hash[name].primary_key?
411
+ raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
412
+ else
413
+ raise ArgumentError, "you can't define an already defined column '#{name}'."
414
+ end
415
+ end
416
+
417
+ @columns_hash[name] = new_column_definition(name, type, **options)
418
+
419
+ if index
420
+ index_options = index.is_a?(Hash) ? index : {}
421
+ index(name, **index_options)
362
422
  end
363
423
 
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
424
  self
368
425
  end
369
426
 
@@ -377,15 +434,16 @@ module ActiveRecord
377
434
  # This is primarily used to track indexes that need to be created after the table
378
435
  #
379
436
  # index(:account_id, name: 'index_projects_on_account_id')
380
- def index(column_name, options = {})
437
+ def index(column_name, **options)
381
438
  indexes << [column_name, options]
382
439
  end
383
440
 
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])
441
+ def foreign_key(table_name, **options) # :nodoc:
442
+ foreign_keys << [table_name, options]
443
+ end
444
+
445
+ def check_constraint(expression, **options)
446
+ check_constraints << [expression, options]
389
447
  end
390
448
 
391
449
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
@@ -395,19 +453,24 @@ module ActiveRecord
395
453
  def timestamps(**options)
396
454
  options[:null] = false if options[:null].nil?
397
455
 
398
- column(:created_at, :datetime, options)
399
- column(:updated_at, :datetime, options)
456
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
457
+ options[:precision] = 6
458
+ end
459
+
460
+ column(:created_at, :datetime, **options)
461
+ column(:updated_at, :datetime, **options)
400
462
  end
401
463
 
402
464
  # Adds a reference.
403
465
  #
404
466
  # t.references(:user)
405
467
  # t.belongs_to(:supplier, foreign_key: true)
468
+ # t.belongs_to(:supplier, foreign_key: true, type: :integer)
406
469
  #
407
470
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
408
471
  def references(*args, **options)
409
472
  args.each do |ref_name|
410
- ReferenceDefinition.new(ref_name, options).add_to(self)
473
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
411
474
  end
412
475
  end
413
476
  alias :belongs_to :references
@@ -442,14 +505,16 @@ module ActiveRecord
442
505
 
443
506
  class AlterTable # :nodoc:
444
507
  attr_reader :adds
445
- attr_reader :foreign_key_adds
446
- attr_reader :foreign_key_drops
508
+ attr_reader :foreign_key_adds, :foreign_key_drops
509
+ attr_reader :check_constraint_adds, :check_constraint_drops
447
510
 
448
511
  def initialize(td)
449
512
  @td = td
450
513
  @adds = []
451
514
  @foreign_key_adds = []
452
515
  @foreign_key_drops = []
516
+ @check_constraint_adds = []
517
+ @check_constraint_drops = []
453
518
  end
454
519
 
455
520
  def name; @td.name; end
@@ -462,10 +527,18 @@ module ActiveRecord
462
527
  @foreign_key_drops << name
463
528
  end
464
529
 
465
- def add_column(name, type, options)
530
+ def add_check_constraint(expression, options)
531
+ @check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
532
+ end
533
+
534
+ def drop_check_constraint(constraint_name)
535
+ @check_constraint_drops << constraint_name
536
+ end
537
+
538
+ def add_column(name, type, **options)
466
539
  name = name.to_s
467
540
  type = type.to_sym
468
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
541
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
469
542
  end
470
543
  end
471
544
 
@@ -482,9 +555,11 @@ module ActiveRecord
482
555
  # t.timestamps
483
556
  # t.change
484
557
  # t.change_default
558
+ # t.change_null
485
559
  # t.rename
486
560
  # t.references
487
561
  # t.belongs_to
562
+ # t.check_constraint
488
563
  # t.string
489
564
  # t.text
490
565
  # t.integer
@@ -502,9 +577,11 @@ module ActiveRecord
502
577
  # t.json
503
578
  # t.virtual
504
579
  # t.remove
580
+ # t.remove_foreign_key
505
581
  # t.remove_references
506
582
  # t.remove_belongs_to
507
583
  # t.remove_index
584
+ # t.remove_check_constraint
508
585
  # t.remove_timestamps
509
586
  # end
510
587
  #
@@ -523,8 +600,12 @@ module ActiveRecord
523
600
  # t.column(:name, :string)
524
601
  #
525
602
  # 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)
603
+ def column(column_name, type, index: nil, **options)
604
+ @base.add_column(name, column_name, type, **options)
605
+ if index
606
+ index_options = index.is_a?(Hash) ? index : {}
607
+ index(column_name, **index_options)
608
+ end
528
609
  end
529
610
 
530
611
  # Checks to see if a column exists.
@@ -532,8 +613,8 @@ module ActiveRecord
532
613
  # t.string(:name) unless t.column_exists?(:name, :string)
533
614
  #
534
615
  # 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)
616
+ def column_exists?(column_name, type = nil, **options)
617
+ @base.column_exists?(name, column_name, type, **options)
537
618
  end
538
619
 
539
620
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -544,8 +625,8 @@ module ActiveRecord
544
625
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
545
626
  #
546
627
  # 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)
628
+ def index(column_name, **options)
629
+ @base.add_index(name, column_name, **options)
549
630
  end
550
631
 
551
632
  # Checks to see if an index exists.
@@ -573,8 +654,8 @@ module ActiveRecord
573
654
  # t.timestamps(null: false)
574
655
  #
575
656
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
576
- def timestamps(options = {})
577
- @base.add_timestamps(name, options)
657
+ def timestamps(**options)
658
+ @base.add_timestamps(name, **options)
578
659
  end
579
660
 
580
661
  # Changes the column's definition according to the new options.
@@ -583,8 +664,8 @@ module ActiveRecord
583
664
  # t.change(:description, :text)
584
665
  #
585
666
  # 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)
667
+ def change(column_name, type, **options)
668
+ @base.change_column(name, column_name, type, **options)
588
669
  end
589
670
 
590
671
  # Sets a new default value for a column.
@@ -598,14 +679,24 @@ module ActiveRecord
598
679
  @base.change_column_default(name, column_name, default_or_changes)
599
680
  end
600
681
 
682
+ # Sets or removes a NOT NULL constraint on a column.
683
+ #
684
+ # t.change_null(:qualification, true)
685
+ # t.change_null(:qualification, false, 0)
686
+ #
687
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
688
+ def change_null(column_name, null, default = nil)
689
+ @base.change_column_null(name, column_name, null, default)
690
+ end
691
+
601
692
  # Removes the column(s) from the table definition.
602
693
  #
603
694
  # t.remove(:qualification)
604
695
  # t.remove(:qualification, :experience)
605
696
  #
606
697
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
607
- def remove(*column_names)
608
- @base.remove_columns(name, *column_names)
698
+ def remove(*column_names, **options)
699
+ @base.remove_columns(name, *column_names, **options)
609
700
  end
610
701
 
611
702
  # Removes the given index from the table.
@@ -613,10 +704,11 @@ module ActiveRecord
613
704
  # t.remove_index(:branch_id)
614
705
  # t.remove_index(column: [:branch_id, :party_id])
615
706
  # t.remove_index(name: :by_branch_party)
707
+ # t.remove_index(:branch_id, name: :by_branch_party)
616
708
  #
617
709
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
618
- def remove_index(options = {})
619
- @base.remove_index(name, options)
710
+ def remove_index(column_name = nil, **options)
711
+ @base.remove_index(name, column_name, **options)
620
712
  end
621
713
 
622
714
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -624,8 +716,8 @@ module ActiveRecord
624
716
  # t.remove_timestamps
625
717
  #
626
718
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
627
- def remove_timestamps(options = {})
628
- @base.remove_timestamps(name, options)
719
+ def remove_timestamps(**options)
720
+ @base.remove_timestamps(name, **options)
629
721
  end
630
722
 
631
723
  # Renames a column.
@@ -645,7 +737,7 @@ module ActiveRecord
645
737
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
646
738
  def references(*args, **options)
647
739
  args.each do |ref_name|
648
- @base.add_reference(name, ref_name, options)
740
+ @base.add_reference(name, ref_name, **options)
649
741
  end
650
742
  end
651
743
  alias :belongs_to :references
@@ -658,18 +750,29 @@ module ActiveRecord
658
750
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
659
751
  def remove_references(*args, **options)
660
752
  args.each do |ref_name|
661
- @base.remove_reference(name, ref_name, options)
753
+ @base.remove_reference(name, ref_name, **options)
662
754
  end
663
755
  end
664
756
  alias :remove_belongs_to :remove_references
665
757
 
666
- # Adds a foreign key.
758
+ # Adds a foreign key to the table using a supplied table name.
667
759
  #
668
760
  # t.foreign_key(:authors)
761
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
669
762
  #
670
763
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
671
- def foreign_key(*args)
672
- @base.add_foreign_key(name, *args)
764
+ def foreign_key(*args, **options)
765
+ @base.add_foreign_key(name, *args, **options)
766
+ end
767
+
768
+ # Removes the given foreign key from the table.
769
+ #
770
+ # t.remove_foreign_key(:authors)
771
+ # t.remove_foreign_key(column: :author_id)
772
+ #
773
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
774
+ def remove_foreign_key(*args, **options)
775
+ @base.remove_foreign_key(name, *args, **options)
673
776
  end
674
777
 
675
778
  # Checks to see if a foreign key exists.
@@ -677,8 +780,26 @@ module ActiveRecord
677
780
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
678
781
  #
679
782
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
680
- def foreign_key_exists?(*args)
681
- @base.foreign_key_exists?(name, *args)
783
+ def foreign_key_exists?(*args, **options)
784
+ @base.foreign_key_exists?(name, *args, **options)
785
+ end
786
+
787
+ # Adds a check constraint.
788
+ #
789
+ # t.check_constraint("price > 0", name: "price_check")
790
+ #
791
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
792
+ def check_constraint(*args)
793
+ @base.add_check_constraint(name, *args)
794
+ end
795
+
796
+ # Removes the given check constraint from the table.
797
+ #
798
+ # t.remove_check_constraint(name: "price_check")
799
+ #
800
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
801
+ def remove_check_constraint(*args)
802
+ @base.remove_check_constraint(name, *args)
682
803
  end
683
804
  end
684
805
  end
@@ -1,7 +1,5 @@
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:
@@ -15,8 +13,8 @@ module ActiveRecord
15
13
  end
16
14
 
17
15
  def column_spec_for_primary_key(column)
18
- return {} if default_primary_key?(column)
19
- spec = { id: schema_type(column).inspect }
16
+ spec = {}
17
+ spec[:id] = schema_type(column).inspect unless default_primary_key?(column)
20
18
  spec.merge!(prepare_column_options(column).except!(:null))
21
19
  spec[:default] ||= "nil" if explicit_primary_key_default?(column)
22
20
  spec