activerecord 5.2.8.1 → 6.1.0

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 +849 -630
  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 +5 -4
  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 +95 -42
  10. data/lib/active_record/associations/association_scope.rb +21 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +50 -46
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -5
  13. data/lib/active_record/associations/builder/association.rb +23 -21
  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 +41 -20
  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 +133 -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 +45 -8
  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 +2 -15
  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 +203 -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 +381 -146
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -98
  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 +31 -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 +44 -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 +14 -6
  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 +63 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +43 -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/money.rb +2 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  95. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  97. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  98. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  100. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +222 -112
  108. data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
  110. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  113. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  114. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  115. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  116. data/lib/active_record/connection_adapters.rb +50 -0
  117. data/lib/active_record/connection_handling.rb +285 -33
  118. data/lib/active_record/core.rb +304 -106
  119. data/lib/active_record/counter_cache.rb +8 -30
  120. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  121. data/lib/active_record/database_configurations/database_config.rb +80 -0
  122. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  123. data/lib/active_record/database_configurations/url_config.rb +53 -0
  124. data/lib/active_record/database_configurations.rb +272 -0
  125. data/lib/active_record/delegated_type.rb +209 -0
  126. data/lib/active_record/destroy_association_async_job.rb +36 -0
  127. data/lib/active_record/dynamic_matchers.rb +3 -4
  128. data/lib/active_record/enum.rb +71 -17
  129. data/lib/active_record/errors.rb +62 -19
  130. data/lib/active_record/explain.rb +10 -6
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/file.rb +10 -17
  133. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  134. data/lib/active_record/fixture_set/render_context.rb +17 -0
  135. data/lib/active_record/fixture_set/table_row.rb +152 -0
  136. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  137. data/lib/active_record/fixtures.rb +197 -481
  138. data/lib/active_record/gem_version.rb +4 -4
  139. data/lib/active_record/inheritance.rb +53 -24
  140. data/lib/active_record/insert_all.rb +208 -0
  141. data/lib/active_record/integration.rb +67 -17
  142. data/lib/active_record/internal_metadata.rb +26 -9
  143. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  144. data/lib/active_record/locking/optimistic.rb +26 -22
  145. data/lib/active_record/locking/pessimistic.rb +9 -5
  146. data/lib/active_record/log_subscriber.rb +34 -35
  147. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  148. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  149. data/lib/active_record/middleware/database_selector.rb +77 -0
  150. data/lib/active_record/migration/command_recorder.rb +96 -44
  151. data/lib/active_record/migration/compatibility.rb +141 -64
  152. data/lib/active_record/migration/join_table.rb +0 -1
  153. data/lib/active_record/migration.rb +205 -156
  154. data/lib/active_record/model_schema.rb +148 -22
  155. data/lib/active_record/nested_attributes.rb +4 -7
  156. data/lib/active_record/no_touching.rb +8 -1
  157. data/lib/active_record/null_relation.rb +0 -1
  158. data/lib/active_record/persistence.rb +267 -59
  159. data/lib/active_record/query_cache.rb +21 -4
  160. data/lib/active_record/querying.rb +40 -23
  161. data/lib/active_record/railtie.rb +113 -74
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +402 -78
  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 +153 -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 +4 -7
  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 +58 -40
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +472 -186
  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 +108 -58
  185. data/lib/active_record/relation.rb +375 -104
  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 -6
  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 +39 -43
  202. data/lib/active_record/tasks/database_tasks.rb +276 -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 +246 -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 +58 -116
  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 +72 -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 +120 -35
  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
@@ -69,6 +77,8 @@ module ActiveRecord
69
77
 
70
78
  ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
71
79
 
80
+ CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
81
+
72
82
  PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
73
83
 
74
84
  ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
@@ -101,13 +111,14 @@ module ActiveRecord
101
111
  end
102
112
  alias validated? validate?
103
113
 
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
114
+ def export_name_on_schema_dump?
115
+ !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
116
+ end
117
+
118
+ def defined_for?(to_table: nil, validate: nil, **options)
119
+ (to_table.nil? || to_table.to_s == self.to_table) &&
120
+ (validate.nil? || validate == options.fetch(:validate, validate)) &&
121
+ options.all? { |k, v| self.options[k].to_s == v.to_s }
111
122
  end
112
123
 
113
124
  private
@@ -116,6 +127,21 @@ module ActiveRecord
116
127
  end
117
128
  end
118
129
 
130
+ CheckConstraintDefinition = Struct.new(:table_name, :expression, :options) do
131
+ def name
132
+ options[:name]
133
+ end
134
+
135
+ def validate?
136
+ options.fetch(:validate, true)
137
+ end
138
+ alias validated? validate?
139
+
140
+ def export_name_on_schema_dump?
141
+ !ActiveRecord::SchemaDumper.chk_ignore_pattern.match?(name) if name
142
+ end
143
+ end
144
+
119
145
  class ReferenceDefinition # :nodoc:
120
146
  def initialize(
121
147
  name,
@@ -138,26 +164,21 @@ module ActiveRecord
138
164
  end
139
165
 
140
166
  def add_to(table)
141
- columns.each do |column_options|
142
- table.column(*column_options)
167
+ columns.each do |name, type, options|
168
+ table.column(name, type, **options)
143
169
  end
144
170
 
145
171
  if index
146
- table.index(column_names, index_options)
172
+ table.index(column_names, **index_options(table.name))
147
173
  end
148
174
 
149
175
  if foreign_key
150
- table.foreign_key(foreign_table_name, foreign_key_options)
176
+ table.foreign_key(foreign_table_name, **foreign_key_options)
151
177
  end
152
178
  end
153
179
 
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
180
  private
181
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
161
182
 
162
183
  def as_options(value)
163
184
  value.is_a?(Hash) ? value : {}
@@ -167,8 +188,14 @@ module ActiveRecord
167
188
  as_options(polymorphic).merge(options.slice(:null, :first, :after))
168
189
  end
169
190
 
170
- def index_options
171
- as_options(index)
191
+ def polymorphic_index_name(table_name)
192
+ "index_#{table_name}_on_#{name}"
193
+ end
194
+
195
+ def index_options(table_name)
196
+ index_options = as_options(index)
197
+ index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
198
+ index_options
172
199
  end
173
200
 
174
201
  def foreign_key_options
@@ -199,41 +226,45 @@ module ActiveRecord
199
226
  end
200
227
 
201
228
  module ColumnMethods
229
+ extend ActiveSupport::Concern
230
+
202
231
  # Appends a primary key definition to the table definition.
203
232
  # Can be called multiple times, but this is probably not a good idea.
204
233
  def primary_key(name, type = :primary_key, **options)
205
- column(name, type, options.merge(primary_key: true))
234
+ column(name, type, **options.merge(primary_key: true))
206
235
  end
207
236
 
237
+ ##
238
+ # :method: column
239
+ # :call-seq: column(name, type, **options)
240
+ #
208
241
  # Appends a column or columns of a specified type.
209
242
  #
210
243
  # t.string(:goat)
211
244
  # t.string(:goat, :sheep)
212
245
  #
213
246
  # 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) }
247
+
248
+ included do
249
+ define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
250
+ :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
251
+
252
+ alias :numeric :decimal
253
+ end
254
+
255
+ class_methods do
256
+ def define_column_methods(*column_types) # :nodoc:
257
+ column_types.each do |column_type|
258
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
259
+ def #{column_type}(*names, **options)
260
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
261
+ names.each { |name| column(name, :#{column_type}, **options) }
262
+ end
263
+ RUBY
233
264
  end
234
- CODE
265
+ end
266
+ private :define_column_methods
235
267
  end
236
- alias_method :numeric, :decimal
237
268
  end
238
269
 
239
270
  # Represents the schema of an SQL table in an abstract way. This class
@@ -242,7 +273,7 @@ module ActiveRecord
242
273
  # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
243
274
  # is actually of this type:
244
275
  #
245
- # class SomeMigration < ActiveRecord::Migration[5.0]
276
+ # class SomeMigration < ActiveRecord::Migration[6.0]
246
277
  # def up
247
278
  # create_table :foo do |t|
248
279
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -257,15 +288,26 @@ module ActiveRecord
257
288
  class TableDefinition
258
289
  include ColumnMethods
259
290
 
260
- attr_accessor :indexes
261
- attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
291
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys, :check_constraints
262
292
 
263
- def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
293
+ def initialize(
294
+ conn,
295
+ name,
296
+ temporary: false,
297
+ if_not_exists: false,
298
+ options: nil,
299
+ as: nil,
300
+ comment: nil,
301
+ **
302
+ )
303
+ @conn = conn
264
304
  @columns_hash = {}
265
305
  @indexes = []
266
306
  @foreign_keys = []
267
307
  @primary_keys = nil
308
+ @check_constraints = []
268
309
  @temporary = temporary
310
+ @if_not_exists = if_not_exists
269
311
  @options = options
270
312
  @as = as
271
313
  @name = name
@@ -349,21 +391,28 @@ module ActiveRecord
349
391
  #
350
392
  # create_table :taggings do |t|
351
393
  # 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' }
394
+ # t.references :tagger, polymorphic: true
395
+ # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
354
396
  # end
355
- def column(name, type, options = {})
397
+ def column(name, type, index: nil, **options)
356
398
  name = name.to_s
357
399
  type = type.to_sym if type
358
- options = options.dup
359
400
 
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."
401
+ if @columns_hash[name]
402
+ if @columns_hash[name].primary_key?
403
+ raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
404
+ else
405
+ raise ArgumentError, "you can't define an already defined column '#{name}'."
406
+ end
407
+ end
408
+
409
+ @columns_hash[name] = new_column_definition(name, type, **options)
410
+
411
+ if index
412
+ index_options = index.is_a?(Hash) ? index : {}
413
+ index(name, **index_options)
362
414
  end
363
415
 
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
416
  self
368
417
  end
369
418
 
@@ -377,15 +426,16 @@ module ActiveRecord
377
426
  # This is primarily used to track indexes that need to be created after the table
378
427
  #
379
428
  # index(:account_id, name: 'index_projects_on_account_id')
380
- def index(column_name, options = {})
429
+ def index(column_name, **options)
381
430
  indexes << [column_name, options]
382
431
  end
383
432
 
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])
433
+ def foreign_key(table_name, **options) # :nodoc:
434
+ foreign_keys << [table_name, options]
435
+ end
436
+
437
+ def check_constraint(expression, **options)
438
+ check_constraints << [expression, options]
389
439
  end
390
440
 
391
441
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
@@ -395,19 +445,24 @@ module ActiveRecord
395
445
  def timestamps(**options)
396
446
  options[:null] = false if options[:null].nil?
397
447
 
398
- column(:created_at, :datetime, options)
399
- column(:updated_at, :datetime, options)
448
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
449
+ options[:precision] = 6
450
+ end
451
+
452
+ column(:created_at, :datetime, **options)
453
+ column(:updated_at, :datetime, **options)
400
454
  end
401
455
 
402
456
  # Adds a reference.
403
457
  #
404
458
  # t.references(:user)
405
459
  # t.belongs_to(:supplier, foreign_key: true)
460
+ # t.belongs_to(:supplier, foreign_key: true, type: :integer)
406
461
  #
407
462
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
408
463
  def references(*args, **options)
409
464
  args.each do |ref_name|
410
- ReferenceDefinition.new(ref_name, options).add_to(self)
465
+ ReferenceDefinition.new(ref_name, **options).add_to(self)
411
466
  end
412
467
  end
413
468
  alias :belongs_to :references
@@ -442,14 +497,16 @@ module ActiveRecord
442
497
 
443
498
  class AlterTable # :nodoc:
444
499
  attr_reader :adds
445
- attr_reader :foreign_key_adds
446
- attr_reader :foreign_key_drops
500
+ attr_reader :foreign_key_adds, :foreign_key_drops
501
+ attr_reader :check_constraint_adds, :check_constraint_drops
447
502
 
448
503
  def initialize(td)
449
504
  @td = td
450
505
  @adds = []
451
506
  @foreign_key_adds = []
452
507
  @foreign_key_drops = []
508
+ @check_constraint_adds = []
509
+ @check_constraint_drops = []
453
510
  end
454
511
 
455
512
  def name; @td.name; end
@@ -462,10 +519,18 @@ module ActiveRecord
462
519
  @foreign_key_drops << name
463
520
  end
464
521
 
465
- def add_column(name, type, options)
522
+ def add_check_constraint(expression, options)
523
+ @check_constraint_adds << CheckConstraintDefinition.new(name, expression, options)
524
+ end
525
+
526
+ def drop_check_constraint(constraint_name)
527
+ @check_constraint_drops << constraint_name
528
+ end
529
+
530
+ def add_column(name, type, **options)
466
531
  name = name.to_s
467
532
  type = type.to_sym
468
- @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
533
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
469
534
  end
470
535
  end
471
536
 
@@ -482,9 +547,11 @@ module ActiveRecord
482
547
  # t.timestamps
483
548
  # t.change
484
549
  # t.change_default
550
+ # t.change_null
485
551
  # t.rename
486
552
  # t.references
487
553
  # t.belongs_to
554
+ # t.check_constraint
488
555
  # t.string
489
556
  # t.text
490
557
  # t.integer
@@ -502,9 +569,11 @@ module ActiveRecord
502
569
  # t.json
503
570
  # t.virtual
504
571
  # t.remove
572
+ # t.remove_foreign_key
505
573
  # t.remove_references
506
574
  # t.remove_belongs_to
507
575
  # t.remove_index
576
+ # t.remove_check_constraint
508
577
  # t.remove_timestamps
509
578
  # end
510
579
  #
@@ -523,8 +592,12 @@ module ActiveRecord
523
592
  # t.column(:name, :string)
524
593
  #
525
594
  # 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)
595
+ def column(column_name, type, index: nil, **options)
596
+ @base.add_column(name, column_name, type, **options)
597
+ if index
598
+ index_options = index.is_a?(Hash) ? index : {}
599
+ index(column_name, **index_options)
600
+ end
528
601
  end
529
602
 
530
603
  # Checks to see if a column exists.
@@ -532,8 +605,8 @@ module ActiveRecord
532
605
  # t.string(:name) unless t.column_exists?(:name, :string)
533
606
  #
534
607
  # 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)
608
+ def column_exists?(column_name, type = nil, **options)
609
+ @base.column_exists?(name, column_name, type, **options)
537
610
  end
538
611
 
539
612
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
@@ -544,8 +617,8 @@ module ActiveRecord
544
617
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
545
618
  #
546
619
  # 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)
620
+ def index(column_name, **options)
621
+ @base.add_index(name, column_name, **options)
549
622
  end
550
623
 
551
624
  # Checks to see if an index exists.
@@ -573,8 +646,8 @@ module ActiveRecord
573
646
  # t.timestamps(null: false)
574
647
  #
575
648
  # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
576
- def timestamps(options = {})
577
- @base.add_timestamps(name, options)
649
+ def timestamps(**options)
650
+ @base.add_timestamps(name, **options)
578
651
  end
579
652
 
580
653
  # Changes the column's definition according to the new options.
@@ -583,8 +656,8 @@ module ActiveRecord
583
656
  # t.change(:description, :text)
584
657
  #
585
658
  # 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)
659
+ def change(column_name, type, **options)
660
+ @base.change_column(name, column_name, type, **options)
588
661
  end
589
662
 
590
663
  # Sets a new default value for a column.
@@ -598,14 +671,24 @@ module ActiveRecord
598
671
  @base.change_column_default(name, column_name, default_or_changes)
599
672
  end
600
673
 
674
+ # Sets or removes a NOT NULL constraint on a column.
675
+ #
676
+ # t.change_null(:qualification, true)
677
+ # t.change_null(:qualification, false, 0)
678
+ #
679
+ # See {connection.change_column_null}[rdoc-ref:SchemaStatements#change_column_null]
680
+ def change_null(column_name, null, default = nil)
681
+ @base.change_column_null(name, column_name, null, default)
682
+ end
683
+
601
684
  # Removes the column(s) from the table definition.
602
685
  #
603
686
  # t.remove(:qualification)
604
687
  # t.remove(:qualification, :experience)
605
688
  #
606
689
  # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
607
- def remove(*column_names)
608
- @base.remove_columns(name, *column_names)
690
+ def remove(*column_names, **options)
691
+ @base.remove_columns(name, *column_names, **options)
609
692
  end
610
693
 
611
694
  # Removes the given index from the table.
@@ -613,10 +696,11 @@ module ActiveRecord
613
696
  # t.remove_index(:branch_id)
614
697
  # t.remove_index(column: [:branch_id, :party_id])
615
698
  # t.remove_index(name: :by_branch_party)
699
+ # t.remove_index(:branch_id, name: :by_branch_party)
616
700
  #
617
701
  # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
618
- def remove_index(options = {})
619
- @base.remove_index(name, options)
702
+ def remove_index(column_name = nil, **options)
703
+ @base.remove_index(name, column_name, **options)
620
704
  end
621
705
 
622
706
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
@@ -624,8 +708,8 @@ module ActiveRecord
624
708
  # t.remove_timestamps
625
709
  #
626
710
  # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
627
- def remove_timestamps(options = {})
628
- @base.remove_timestamps(name, options)
711
+ def remove_timestamps(**options)
712
+ @base.remove_timestamps(name, **options)
629
713
  end
630
714
 
631
715
  # Renames a column.
@@ -645,7 +729,7 @@ module ActiveRecord
645
729
  # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
646
730
  def references(*args, **options)
647
731
  args.each do |ref_name|
648
- @base.add_reference(name, ref_name, options)
732
+ @base.add_reference(name, ref_name, **options)
649
733
  end
650
734
  end
651
735
  alias :belongs_to :references
@@ -658,18 +742,29 @@ module ActiveRecord
658
742
  # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
659
743
  def remove_references(*args, **options)
660
744
  args.each do |ref_name|
661
- @base.remove_reference(name, ref_name, options)
745
+ @base.remove_reference(name, ref_name, **options)
662
746
  end
663
747
  end
664
748
  alias :remove_belongs_to :remove_references
665
749
 
666
- # Adds a foreign key.
750
+ # Adds a foreign key to the table using a supplied table name.
667
751
  #
668
752
  # t.foreign_key(:authors)
753
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
669
754
  #
670
755
  # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
671
- def foreign_key(*args)
672
- @base.add_foreign_key(name, *args)
756
+ def foreign_key(*args, **options)
757
+ @base.add_foreign_key(name, *args, **options)
758
+ end
759
+
760
+ # Removes the given foreign key from the table.
761
+ #
762
+ # t.remove_foreign_key(:authors)
763
+ # t.remove_foreign_key(column: :author_id)
764
+ #
765
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
766
+ def remove_foreign_key(*args, **options)
767
+ @base.remove_foreign_key(name, *args, **options)
673
768
  end
674
769
 
675
770
  # Checks to see if a foreign key exists.
@@ -677,8 +772,26 @@ module ActiveRecord
677
772
  # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
678
773
  #
679
774
  # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
680
- def foreign_key_exists?(*args)
681
- @base.foreign_key_exists?(name, *args)
775
+ def foreign_key_exists?(*args, **options)
776
+ @base.foreign_key_exists?(name, *args, **options)
777
+ end
778
+
779
+ # Adds a check constraint.
780
+ #
781
+ # t.check_constraint("price > 0", name: "price_check")
782
+ #
783
+ # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
784
+ def check_constraint(*args)
785
+ @base.add_check_constraint(name, *args)
786
+ end
787
+
788
+ # Removes the given check constraint from the table.
789
+ #
790
+ # t.remove_check_constraint(name: "price_check")
791
+ #
792
+ # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
793
+ def remove_check_constraint(*args)
794
+ @base.remove_check_constraint(name, *args)
682
795
  end
683
796
  end
684
797
  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