activerecord 5.2.7.1 → 6.1.4.6

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 +1145 -575
  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 +31 -29
  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 +71 -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 +12 -3
  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 +207 -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 +86 -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 +139 -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 +38 -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 +135 -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 +144 -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 +334 -97
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -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 +272 -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 +4 -4
  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 +26 -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 +142 -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 +115 -58
  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 +117 -32
  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,14 @@ 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
+ index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
202
+ index_options
172
203
  end
173
204
 
174
205
  def foreign_key_options
@@ -199,41 +230,45 @@ module ActiveRecord
199
230
  end
200
231
 
201
232
  module ColumnMethods
233
+ extend ActiveSupport::Concern
234
+
202
235
  # Appends a primary key definition to the table definition.
203
236
  # Can be called multiple times, but this is probably not a good idea.
204
237
  def primary_key(name, type = :primary_key, **options)
205
- column(name, type, options.merge(primary_key: true))
238
+ column(name, type, **options.merge(primary_key: true))
206
239
  end
207
240
 
241
+ ##
242
+ # :method: column
243
+ # :call-seq: column(name, type, **options)
244
+ #
208
245
  # Appends a column or columns of a specified type.
209
246
  #
210
247
  # t.string(:goat)
211
248
  # t.string(:goat, :sheep)
212
249
  #
213
250
  # 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) }
251
+
252
+ included do
253
+ define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
254
+ :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
255
+
256
+ alias :numeric :decimal
257
+ end
258
+
259
+ class_methods do
260
+ def define_column_methods(*column_types) # :nodoc:
261
+ column_types.each do |column_type|
262
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
263
+ def #{column_type}(*names, **options)
264
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
265
+ names.each { |name| column(name, :#{column_type}, **options) }
266
+ end
267
+ RUBY
233
268
  end
234
- CODE
269
+ end
270
+ private :define_column_methods
235
271
  end
236
- alias_method :numeric, :decimal
237
272
  end
238
273
 
239
274
  # Represents the schema of an SQL table in an abstract way. This class
@@ -242,7 +277,7 @@ module ActiveRecord
242
277
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
243
278
  # is actually of this type:
244
279
  #
245
- # class SomeMigration < ActiveRecord::Migration[5.0]
280
+ # class SomeMigration < ActiveRecord::Migration[6.0]
246
281
  # def up
247
282
  # create_table :foo do |t|
248
283
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -257,15 +292,26 @@ module ActiveRecord
257
292
  class TableDefinition
258
293
  include ColumnMethods
259
294
 
260
- attr_accessor :indexes
261
- attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
295
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
262
296
 
263
- def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
297
+ def initialize(
298
+ conn,
299
+ name,
300
+ temporary: false,
301
+ if_not_exists: false,
302
+ options: nil,
303
+ as: nil,
304
+ comment: nil,
305
+ **
306
+ )
307
+ @conn = conn
264
308
  @columns_hash = {}
265
309
  @indexes = []
266
310
  @foreign_keys = []
267
311
  @primary_keys = nil
312
+ @check_constraints = []
268
313
  @temporary = temporary
314
+ @if_not_exists = if_not_exists
269
315
  @options = options
270
316
  @as = as
271
317
  @name = name
@@ -349,21 +395,28 @@ module ActiveRecord
349
395
  #
350
396
  # create_table :taggings do |t|
351
397
  # 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' }
398
+ # t.references :tagger, polymorphic: true
399
+ # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
354
400
  # end
355
- def column(name, type, options = {})
401
+ def column(name, type, index: nil, **options)
356
402
  name = name.to_s
357
403
  type = type.to_sym if type
358
- options = options.dup
359
404
 
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."
405
+ if @columns_hash[name]
406
+ if @columns_hash[name].primary_key?
407
+ raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
408
+ else
409
+ raise ArgumentError, "you can't define an already defined column '#{name}'."
410
+ end
411
+ end
412
+
413
+ @columns_hash[name] = new_column_definition(name, type, **options)
414
+
415
+ if index
416
+ index_options = index.is_a?(Hash) ? index : {}
417
+ index(name, **index_options)
362
418
  end
363
419
 
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
420
  self
368
421
  end
369
422
 
@@ -377,15 +430,16 @@ module ActiveRecord
377
430
  # This is primarily used to track indexes that need to be created after the table
378
431
  #
379
432
  # index(:account_id, name: 'index_projects_on_account_id')
380
- def index(column_name, options = {})
433
+ def index(column_name, **options)
381
434
  indexes << [column_name, options]
382
435
  end
383
436
 
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])
437
+ def foreign_key(table_name, **options) # :nodoc:
438
+ foreign_keys << [table_name, options]
439
+ end
440
+
441
+ def check_constraint(expression, **options)
442
+ check_constraints << [expression, options]
389
443
  end
390
444
 
391
445
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
@@ -395,19 +449,24 @@ module ActiveRecord
395
449
  def timestamps(**options)
396
450
  options[:null] = false if options[:null].nil?
397
451
 
398
- column(:created_at, :datetime, options)
399
- column(:updated_at, :datetime, options)
452
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
453
+ options[:precision] = 6
454
+ end
455
+
456
+ column(:created_at, :datetime, **options)
457
+ column(:updated_at, :datetime, **options)
400
458
  end
401
459
 
402
460
  # Adds a reference.
403
461
  #
404
462
  # t.references(:user)
405
463
  # t.belongs_to(:supplier, foreign_key: true)
464
+ # t.belongs_to(:supplier, foreign_key: true, type: :integer)
406
465
  #
407
466
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
408
467
  def references(*args, **options)
409
468
  args.each do |ref_name|
410
- ReferenceDefinition.new(ref_name, options).add_to(self)
469
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
411
470
  end
412
471
  end
413
472
  alias :belongs_to :references
@@ -442,14 +501,16 @@ module ActiveRecord
442
501
 
443
502
  class AlterTable # :nodoc:
444
503
  attr_reader :adds
445
- attr_reader :foreign_key_adds
446
- attr_reader :foreign_key_drops
504
+ attr_reader :foreign_key_adds, :foreign_key_drops
505
+ attr_reader :check_constraint_adds, :check_constraint_drops
447
506
 
448
507
  def initialize(td)
449
508
  @td = td
450
509
  @adds = []
451
510
  @foreign_key_adds = []
452
511
  @foreign_key_drops = []
512
+ @check_constraint_adds = []
513
+ @check_constraint_drops = []
453
514
  end
454
515
 
455
516
  def name; @td.name; end
@@ -462,10 +523,18 @@ module ActiveRecord
462
523
  @foreign_key_drops << name
463
524
  end
464
525
 
465
- def add_column(name, type, options)
526
+ def add_check_constraint(expression, options)
527
+ @check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
528
+ end
529
+
530
+ def drop_check_constraint(constraint_name)
531
+ @check_constraint_drops << constraint_name
532
+ end
533
+
534
+ def add_column(name, type, **options)
466
535
  name = name.to_s
467
536
  type = type.to_sym
468
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
537
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
469
538
  end
470
539
  end
471
540
 
@@ -482,9 +551,11 @@ module ActiveRecord
482
551
  # t.timestamps
483
552
  # t.change
484
553
  # t.change_default
554
+ # t.change_null
485
555
  # t.rename
486
556
  # t.references
487
557
  # t.belongs_to
558
+ # t.check_constraint
488
559
  # t.string
489
560
  # t.text
490
561
  # t.integer
@@ -502,9 +573,11 @@ module ActiveRecord
502
573
  # t.json
503
574
  # t.virtual
504
575
  # t.remove
576
+ # t.remove_foreign_key
505
577
  # t.remove_references
506
578
  # t.remove_belongs_to
507
579
  # t.remove_index
580
+ # t.remove_check_constraint
508
581
  # t.remove_timestamps
509
582
  # end
510
583
  #
@@ -523,8 +596,12 @@ module ActiveRecord
523
596
  # t.column(:name, :string)
524
597
  #
525
598
  # 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)
599
+ def column(column_name, type, index: nil, **options)
600
+ @base.add_column(name, column_name, type, **options)
601
+ if index
602
+ index_options = index.is_a?(Hash) ? index : {}
603
+ index(column_name, **index_options)
604
+ end
528
605
  end
529
606
 
530
607
  # Checks to see if a column exists.
@@ -532,8 +609,8 @@ module ActiveRecord
532
609
  # t.string(:name) unless t.column_exists?(:name, :string)
533
610
  #
534
611
  # 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)
612
+ def column_exists?(column_name, type = nil, **options)
613
+ @base.column_exists?(name, column_name, type, **options)
537
614
  end
538
615
 
539
616
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -544,8 +621,8 @@ module ActiveRecord
544
621
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
545
622
  #
546
623
  # 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)
624
+ def index(column_name, **options)
625
+ @base.add_index(name, column_name, **options)
549
626
  end
550
627
 
551
628
  # Checks to see if an index exists.
@@ -573,8 +650,8 @@ module ActiveRecord
573
650
  # t.timestamps(null: false)
574
651
  #
575
652
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
576
- def timestamps(options = {})
577
- @base.add_timestamps(name, options)
653
+ def timestamps(**options)
654
+ @base.add_timestamps(name, **options)
578
655
  end
579
656
 
580
657
  # Changes the column's definition according to the new options.
@@ -583,8 +660,8 @@ module ActiveRecord
583
660
  # t.change(:description, :text)
584
661
  #
585
662
  # 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)
663
+ def change(column_name, type, **options)
664
+ @base.change_column(name, column_name, type, **options)
588
665
  end
589
666
 
590
667
  # Sets a new default value for a column.
@@ -598,14 +675,24 @@ module ActiveRecord
598
675
  @base.change_column_default(name, column_name, default_or_changes)
599
676
  end
600
677
 
678
+ # Sets or removes a NOT NULL constraint on a column.
679
+ #
680
+ # t.change_null(:qualification, true)
681
+ # t.change_null(:qualification, false, 0)
682
+ #
683
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
684
+ def change_null(column_name, null, default = nil)
685
+ @base.change_column_null(name, column_name, null, default)
686
+ end
687
+
601
688
  # Removes the column(s) from the table definition.
602
689
  #
603
690
  # t.remove(:qualification)
604
691
  # t.remove(:qualification, :experience)
605
692
  #
606
693
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
607
- def remove(*column_names)
608
- @base.remove_columns(name, *column_names)
694
+ def remove(*column_names, **options)
695
+ @base.remove_columns(name, *column_names, **options)
609
696
  end
610
697
 
611
698
  # Removes the given index from the table.
@@ -613,10 +700,11 @@ module ActiveRecord
613
700
  # t.remove_index(:branch_id)
614
701
  # t.remove_index(column: [:branch_id, :party_id])
615
702
  # t.remove_index(name: :by_branch_party)
703
+ # t.remove_index(:branch_id, name: :by_branch_party)
616
704
  #
617
705
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
618
- def remove_index(options = {})
619
- @base.remove_index(name, options)
706
+ def remove_index(column_name = nil, **options)
707
+ @base.remove_index(name, column_name, **options)
620
708
  end
621
709
 
622
710
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -624,8 +712,8 @@ module ActiveRecord
624
712
  # t.remove_timestamps
625
713
  #
626
714
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
627
- def remove_timestamps(options = {})
628
- @base.remove_timestamps(name, options)
715
+ def remove_timestamps(**options)
716
+ @base.remove_timestamps(name, **options)
629
717
  end
630
718
 
631
719
  # Renames a column.
@@ -645,7 +733,7 @@ module ActiveRecord
645
733
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
646
734
  def references(*args, **options)
647
735
  args.each do |ref_name|
648
- @base.add_reference(name, ref_name, options)
736
+ @base.add_reference(name, ref_name, **options)
649
737
  end
650
738
  end
651
739
  alias :belongs_to :references
@@ -658,18 +746,29 @@ module ActiveRecord
658
746
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
659
747
  def remove_references(*args, **options)
660
748
  args.each do |ref_name|
661
- @base.remove_reference(name, ref_name, options)
749
+ @base.remove_reference(name, ref_name, **options)
662
750
  end
663
751
  end
664
752
  alias :remove_belongs_to :remove_references
665
753
 
666
- # Adds a foreign key.
754
+ # Adds a foreign key to the table using a supplied table name.
667
755
  #
668
756
  # t.foreign_key(:authors)
757
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
669
758
  #
670
759
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
671
- def foreign_key(*args)
672
- @base.add_foreign_key(name, *args)
760
+ def foreign_key(*args, **options)
761
+ @base.add_foreign_key(name, *args, **options)
762
+ end
763
+
764
+ # Removes the given foreign key from the table.
765
+ #
766
+ # t.remove_foreign_key(:authors)
767
+ # t.remove_foreign_key(column: :author_id)
768
+ #
769
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
770
+ def remove_foreign_key(*args, **options)
771
+ @base.remove_foreign_key(name, *args, **options)
673
772
  end
674
773
 
675
774
  # Checks to see if a foreign key exists.
@@ -677,8 +776,26 @@ module ActiveRecord
677
776
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
678
777
  #
679
778
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
680
- def foreign_key_exists?(*args)
681
- @base.foreign_key_exists?(name, *args)
779
+ def foreign_key_exists?(*args, **options)
780
+ @base.foreign_key_exists?(name, *args, **options)
781
+ end
782
+
783
+ # Adds a check constraint.
784
+ #
785
+ # t.check_constraint("price > 0", name: "price_check")
786
+ #
787
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
788
+ def check_constraint(*args)
789
+ @base.add_check_constraint(name, *args)
790
+ end
791
+
792
+ # Removes the given check constraint from the table.
793
+ #
794
+ # t.remove_check_constraint(name: "price_check")
795
+ #
796
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
797
+ def remove_check_constraint(*args)
798
+ @base.remove_check_constraint(name, *args)
682
799
  end
683
800
  end
684
801
  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