activerecord 4.2.0 → 6.0.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 (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -971
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -248
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +135 -56
  11. data/lib/active_record/associations/association_scope.rb +103 -131
  12. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +27 -40
  15. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  16. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
  18. data/lib/active_record/associations/builder/has_many.rb +8 -4
  19. data/lib/active_record/associations/builder/has_one.rb +46 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +138 -274
  22. data/lib/active_record/associations/collection_proxy.rb +252 -151
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -83
  25. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  26. data/lib/active_record/associations/has_one_association.rb +62 -49
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +138 -162
  32. data/lib/active_record/associations/preloader/association.rb +90 -119
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +92 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1737 -1596
  38. data/lib/active_record/attribute_assignment.rb +56 -183
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  42. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  43. data/lib/active_record/attribute_methods/query.rb +6 -5
  44. data/lib/active_record/attribute_methods/read.rb +20 -76
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +33 -55
  48. data/lib/active_record/attribute_methods.rb +124 -143
  49. data/lib/active_record/attributes.rb +214 -74
  50. data/lib/active_record/autosave_association.rb +115 -46
  51. data/lib/active_record/base.rb +60 -49
  52. data/lib/active_record/callbacks.rb +100 -74
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
  68. data/lib/active_record/connection_adapters/column.rb +56 -43
  69. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  98. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
  116. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +288 -359
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +176 -41
  128. data/lib/active_record/core.rb +266 -233
  129. data/lib/active_record/counter_cache.rb +68 -50
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -105
  136. data/lib/active_record/enum.rb +164 -88
  137. data/lib/active_record/errors.rb +189 -53
  138. data/lib/active_record/explain.rb +23 -11
  139. data/lib/active_record/explain_registry.rb +4 -2
  140. data/lib/active_record/explain_subscriber.rb +11 -6
  141. data/lib/active_record/fixture_set/file.rb +35 -9
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +226 -495
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +158 -112
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +123 -29
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +3 -2
  154. data/lib/active_record/locking/optimistic.rb +91 -98
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +76 -33
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +177 -90
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +8 -6
  163. data/lib/active_record/migration.rb +634 -288
  164. data/lib/active_record/model_schema.rb +314 -112
  165. data/lib/active_record/nested_attributes.rb +266 -214
  166. data/lib/active_record/no_touching.rb +15 -2
  167. data/lib/active_record/null_relation.rb +24 -37
  168. data/lib/active_record/persistence.rb +559 -124
  169. data/lib/active_record/query_cache.rb +19 -23
  170. data/lib/active_record/querying.rb +43 -29
  171. data/lib/active_record/railtie.rb +148 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +338 -202
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +460 -299
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +207 -55
  180. data/lib/active_record/relation/calculations.rb +269 -248
  181. data/lib/active_record/relation/delegation.rb +70 -80
  182. data/lib/active_record/relation/finder_methods.rb +279 -255
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +83 -69
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  192. data/lib/active_record/relation/predicate_builder.rb +116 -92
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +574 -391
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +18 -16
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +518 -340
  200. data/lib/active_record/result.rb +79 -42
  201. data/lib/active_record/runtime_registry.rb +6 -4
  202. data/lib/active_record/sanitization.rb +144 -121
  203. data/lib/active_record/schema.rb +21 -24
  204. data/lib/active_record/schema_dumper.rb +112 -93
  205. data/lib/active_record/schema_migration.rb +24 -20
  206. data/lib/active_record/scoping/default.rb +101 -84
  207. data/lib/active_record/scoping/named.rb +86 -33
  208. data/lib/active_record/scoping.rb +45 -26
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +5 -5
  211. data/lib/active_record/statement_cache.rb +73 -36
  212. data/lib/active_record/store.rb +127 -42
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +309 -99
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +86 -40
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +215 -139
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +4 -41
  227. data/lib/active_record/type/date_time.rb +4 -38
  228. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  229. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +30 -15
  233. data/lib/active_record/type/text.rb +2 -2
  234. data/lib/active_record/type/time.rb +11 -16
  235. data/lib/active_record/type/type_map.rb +15 -17
  236. data/lib/active_record/type/unsigned_integer.rb +9 -7
  237. data/lib/active_record/type.rb +78 -23
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +13 -4
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +14 -13
  245. data/lib/active_record/validations/uniqueness.rb +43 -46
  246. data/lib/active_record/validations.rb +39 -35
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +43 -21
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +257 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  335. data/lib/rails/generators/active_record/migration.rb +31 -1
  336. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +166 -60
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_set/builder.rb +0 -86
  349. data/lib/active_record/attribute_set.rb +0 -77
  350. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  351. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  352. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  353. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  354. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  355. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  356. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  357. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  358. data/lib/active_record/type/big_integer.rb +0 -13
  359. data/lib/active_record/type/binary.rb +0 -50
  360. data/lib/active_record/type/boolean.rb +0 -30
  361. data/lib/active_record/type/decimal.rb +0 -40
  362. data/lib/active_record/type/decorator.rb +0 -14
  363. data/lib/active_record/type/float.rb +0 -19
  364. data/lib/active_record/type/integer.rb +0 -55
  365. data/lib/active_record/type/mutable.rb +0 -16
  366. data/lib/active_record/type/numeric.rb +0 -36
  367. data/lib/active_record/type/string.rb +0 -36
  368. data/lib/active_record/type/time_value.rb +0 -38
  369. data/lib/active_record/type/value.rb +0 -101
  370. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  371. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  372. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,31 +1,77 @@
1
- require 'date'
2
- require 'set'
3
- require 'bigdecimal'
4
- require 'bigdecimal/util'
1
+ # frozen_string_literal: true
5
2
 
6
3
  module ActiveRecord
7
4
  module ConnectionAdapters #:nodoc:
8
5
  # Abstract representation of an index definition on a table. Instances of
9
6
  # this type are typically created and returned by methods in database
10
- # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
11
- class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using) #:nodoc:
7
+ # adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
8
+ class IndexDefinition # :nodoc:
9
+ attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
10
+
11
+ def initialize(
12
+ table, name,
13
+ unique = false,
14
+ columns = [],
15
+ lengths: {},
16
+ orders: {},
17
+ opclasses: {},
18
+ where: nil,
19
+ type: nil,
20
+ using: nil,
21
+ comment: nil
22
+ )
23
+ @table = table
24
+ @name = name
25
+ @unique = unique
26
+ @columns = columns
27
+ @lengths = concise_options(lengths)
28
+ @orders = concise_options(orders)
29
+ @opclasses = concise_options(opclasses)
30
+ @where = where
31
+ @type = type
32
+ @using = using
33
+ @comment = comment
34
+ end
35
+
36
+ private
37
+ def concise_options(options)
38
+ if columns.size == options.size && options.values.uniq.size == 1
39
+ options.values.first
40
+ else
41
+ options
42
+ end
43
+ end
12
44
  end
13
45
 
14
46
  # Abstract representation of a column definition. Instances of this type
15
47
  # are typically created by methods in TableDefinition, and added to the
16
48
  # +columns+ attribute of said TableDefinition object, in order to be used
17
49
  # for generating a number of table creation or table changing SQL statements.
18
- class ColumnDefinition < Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :primary_key, :sql_type, :cast_type) #:nodoc:
19
-
50
+ ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
20
51
  def primary_key?
21
- primary_key || type.to_sym == :primary_key
52
+ options[:primary_key]
22
53
  end
23
- end
24
54
 
25
- class ChangeColumnDefinition < Struct.new(:column, :type, :options) #:nodoc:
55
+ [:limit, :precision, :scale, :default, :null, :collation, :comment].each do |option_name|
56
+ module_eval <<-CODE, __FILE__, __LINE__ + 1
57
+ def #{option_name}
58
+ options[:#{option_name}]
59
+ end
60
+
61
+ def #{option_name}=(value)
62
+ options[:#{option_name}] = value
63
+ end
64
+ CODE
65
+ end
26
66
  end
27
67
 
28
- class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc:
68
+ AddColumnDefinition = Struct.new(:column) # :nodoc:
69
+
70
+ ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
71
+
72
+ PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
73
+
74
+ ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
29
75
  def name
30
76
  options[:name]
31
77
  end
@@ -50,31 +96,151 @@ module ActiveRecord
50
96
  options[:primary_key] != default_primary_key
51
97
  end
52
98
 
99
+ def validate?
100
+ options.fetch(:validate, true)
101
+ end
102
+ alias validated? validate?
103
+
104
+ def export_name_on_schema_dump?
105
+ !ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
106
+ end
107
+
108
+ def defined_for?(to_table: nil, **options)
109
+ (to_table.nil? || to_table.to_s == self.to_table) &&
110
+ options.all? { |k, v| self.options[k].to_s == v.to_s }
111
+ end
112
+
53
113
  private
54
- def default_primary_key
55
- "id"
114
+ def default_primary_key
115
+ "id"
116
+ end
117
+ end
118
+
119
+ class ReferenceDefinition # :nodoc:
120
+ def initialize(
121
+ name,
122
+ polymorphic: false,
123
+ index: true,
124
+ foreign_key: false,
125
+ type: :bigint,
126
+ **options
127
+ )
128
+ @name = name
129
+ @polymorphic = polymorphic
130
+ @index = index
131
+ @foreign_key = foreign_key
132
+ @type = type
133
+ @options = options
134
+
135
+ if polymorphic && foreign_key
136
+ raise ArgumentError, "Cannot add a foreign key to a polymorphic relation"
137
+ end
56
138
  end
139
+
140
+ def add_to(table)
141
+ columns.each do |column_options|
142
+ table.column(*column_options)
143
+ end
144
+
145
+ if index
146
+ table.index(column_names, index_options)
147
+ end
148
+
149
+ if foreign_key
150
+ table.foreign_key(foreign_table_name, foreign_key_options)
151
+ end
152
+ end
153
+
154
+ private
155
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
156
+
157
+ def as_options(value)
158
+ value.is_a?(Hash) ? value : {}
159
+ end
160
+
161
+ def polymorphic_options
162
+ as_options(polymorphic).merge(options.slice(:null, :first, :after))
163
+ end
164
+
165
+ def index_options
166
+ as_options(index)
167
+ end
168
+
169
+ def foreign_key_options
170
+ as_options(foreign_key).merge(column: column_name)
171
+ end
172
+
173
+ def columns
174
+ result = [[column_name, type, options]]
175
+ if polymorphic
176
+ result.unshift(["#{name}_type", :string, polymorphic_options])
177
+ end
178
+ result
179
+ end
180
+
181
+ def column_name
182
+ "#{name}_id"
183
+ end
184
+
185
+ def column_names
186
+ columns.map(&:first)
187
+ end
188
+
189
+ def foreign_table_name
190
+ foreign_key_options.fetch(:to_table) do
191
+ Base.pluralize_table_names ? name.to_s.pluralize : name
192
+ end
193
+ end
57
194
  end
58
195
 
59
- module TimestampDefaultDeprecation # :nodoc:
60
- def emit_warning_if_null_unspecified(options)
61
- return if options.key?(:null)
196
+ module ColumnMethods
197
+ extend ActiveSupport::Concern
62
198
 
63
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
64
- `#timestamp` was called without specifying an option for `null`. In Rails 5,
65
- this behavior will change to `null: false`. You should manually specify
66
- `null: true` to prevent the behavior of your existing migrations from changing.
67
- MSG
199
+ # Appends a primary key definition to the table definition.
200
+ # Can be called multiple times, but this is probably not a good idea.
201
+ def primary_key(name, type = :primary_key, **options)
202
+ column(name, type, options.merge(primary_key: true))
203
+ end
204
+
205
+ ##
206
+ # :method: column
207
+ # :call-seq: column(name, type, **options)
208
+ #
209
+ # Appends a column or columns of a specified type.
210
+ #
211
+ # t.string(:goat)
212
+ # t.string(:goat, :sheep)
213
+ #
214
+ # See TableDefinition#column
215
+
216
+ included do
217
+ define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
218
+ :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
219
+
220
+ alias :numeric :decimal
221
+ end
222
+
223
+ class_methods do
224
+ private def define_column_methods(*column_types) # :nodoc:
225
+ column_types.each do |column_type|
226
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
227
+ def #{column_type}(*names, **options)
228
+ raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
229
+ names.each { |name| column(name, :#{column_type}, options) }
230
+ end
231
+ RUBY
232
+ end
233
+ end
68
234
  end
69
235
  end
70
236
 
71
237
  # Represents the schema of an SQL table in an abstract way. This class
72
238
  # provides methods for manipulating the schema representation.
73
239
  #
74
- # Inside migration files, the +t+ object in +create_table+
240
+ # Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
75
241
  # is actually of this type:
76
242
  #
77
- # class SomeMigration < ActiveRecord::Migration
243
+ # class SomeMigration < ActiveRecord::Migration[5.0]
78
244
  # def up
79
245
  # create_table :foo do |t|
80
246
  # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
@@ -86,124 +252,65 @@ module ActiveRecord
86
252
  # end
87
253
  # end
88
254
  #
89
- # The table definitions
90
- # The Columns are stored as a ColumnDefinition in the +columns+ attribute.
91
255
  class TableDefinition
92
- include TimestampDefaultDeprecation
93
-
94
- # An array of ColumnDefinition objects, representing the column changes
95
- # that have been defined.
96
- attr_accessor :indexes
97
- attr_reader :name, :temporary, :options, :as
98
-
99
- def initialize(types, name, temporary, options, as = nil)
256
+ include ColumnMethods
257
+
258
+ attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
259
+
260
+ def initialize(
261
+ conn,
262
+ name,
263
+ temporary: false,
264
+ if_not_exists: false,
265
+ options: nil,
266
+ as: nil,
267
+ comment: nil,
268
+ **
269
+ )
270
+ @conn = conn
100
271
  @columns_hash = {}
101
- @indexes = {}
102
- @native = types
272
+ @indexes = []
273
+ @foreign_keys = []
274
+ @primary_keys = nil
103
275
  @temporary = temporary
276
+ @if_not_exists = if_not_exists
104
277
  @options = options
105
278
  @as = as
106
279
  @name = name
280
+ @comment = comment
107
281
  end
108
282
 
109
- def columns; @columns_hash.values; end
110
-
111
- # Appends a primary key definition to the table definition.
112
- # Can be called multiple times, but this is probably not a good idea.
113
- def primary_key(name, type = :primary_key, options = {})
114
- column(name, type, options.merge(:primary_key => true))
283
+ def primary_keys(name = nil) # :nodoc:
284
+ @primary_keys = PrimaryKeyDefinition.new(name) if name
285
+ @primary_keys
115
286
  end
116
287
 
288
+ # Returns an array of ColumnDefinition objects for the columns of the table.
289
+ def columns; @columns_hash.values; end
290
+
117
291
  # Returns a ColumnDefinition for the column with name +name+.
118
292
  def [](name)
119
293
  @columns_hash[name.to_s]
120
294
  end
121
295
 
122
296
  # Instantiates a new column for the table.
123
- # The +type+ parameter is normally one of the migrations native types,
124
- # which is one of the following:
125
- # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
126
- # <tt>:integer</tt>, <tt>:float</tt>, <tt>:decimal</tt>,
127
- # <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
128
- # <tt>:binary</tt>, <tt>:boolean</tt>.
129
- #
130
- # You may use a type not in this list as long as it is supported by your
131
- # database (for example, "polygon" in MySQL), but this will not be database
132
- # agnostic and should usually be avoided.
133
- #
134
- # Available options are (none of these exists by default):
135
- # * <tt>:limit</tt> -
136
- # Requests a maximum column length. This is number of characters for <tt>:string</tt> and
137
- # <tt>:text</tt> columns and number of bytes for <tt>:binary</tt> and <tt>:integer</tt> columns.
138
- # * <tt>:default</tt> -
139
- # The column's default value. Use nil for NULL.
140
- # * <tt>:null</tt> -
141
- # Allows or disallows +NULL+ values in the column. This option could
142
- # have been named <tt>:null_allowed</tt>.
143
- # * <tt>:precision</tt> -
144
- # Specifies the precision for a <tt>:decimal</tt> column.
145
- # * <tt>:scale</tt> -
146
- # Specifies the scale for a <tt>:decimal</tt> column.
297
+ # See {connection.add_column}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_column]
298
+ # for available options.
299
+ #
300
+ # Additional options are:
147
301
  # * <tt>:index</tt> -
148
302
  # Create an index for the column. Can be either <tt>true</tt> or an options hash.
149
303
  #
150
- # Note: The precision is the total number of significant digits
151
- # and the scale is the number of digits that can be stored following
152
- # the decimal point. For example, the number 123.45 has a precision of 5
153
- # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
154
- # range from -999.99 to 999.99.
155
- #
156
- # Please be aware of different RDBMS implementations behavior with
157
- # <tt>:decimal</tt> columns:
158
- # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
159
- # <tt>:precision</tt>, and makes no comments about the requirements of
160
- # <tt>:precision</tt>.
161
- # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
162
- # Default is (10,0).
163
- # * PostgreSQL: <tt>:precision</tt> [1..infinity],
164
- # <tt>:scale</tt> [0..infinity]. No default.
165
- # * SQLite2: Any <tt>:precision</tt> and <tt>:scale</tt> may be used.
166
- # Internal storage as strings. No default.
167
- # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
168
- # but the maximum supported <tt>:precision</tt> is 16. No default.
169
- # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
170
- # Default is (38,0).
171
- # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
172
- # Default unknown.
173
- # * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
174
- # Default (38,0).
175
- #
176
304
  # This method returns <tt>self</tt>.
177
305
  #
178
306
  # == Examples
179
- # # Assuming +td+ is an instance of TableDefinition
180
- # td.column(:granted, :boolean)
181
- # # granted BOOLEAN
182
- #
183
- # td.column(:picture, :binary, limit: 2.megabytes)
184
- # # => picture BLOB(2097152)
185
307
  #
186
- # td.column(:sales_stage, :string, limit: 20, default: 'new', null: false)
187
- # # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
188
- #
189
- # td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
190
- # # => bill_gates_money DECIMAL(15,2)
191
- #
192
- # td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
193
- # # => sensor_reading DECIMAL(30,20)
194
- #
195
- # # While <tt>:scale</tt> defaults to zero on most databases, it
196
- # # probably wouldn't hurt to include it.
197
- # td.column(:huge_integer, :decimal, precision: 30)
198
- # # => huge_integer DECIMAL(30)
199
- #
200
- # # Defines a column with a database-specific type.
201
- # td.column(:foo, 'polygon')
202
- # # => foo polygon
308
+ # # Assuming +td+ is an instance of TableDefinition
309
+ # td.column(:granted, :boolean, index: true)
203
310
  #
204
311
  # == Short-hand examples
205
312
  #
206
- # Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types.
313
+ # Instead of calling #column directly, you can also work with the short-hand definitions for the default types.
207
314
  # They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
208
315
  # in a single statement.
209
316
  #
@@ -235,7 +342,8 @@ module ActiveRecord
235
342
  # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
236
343
  # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
237
344
  # options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option
238
- # will also create an index, similar to calling <tt>add_index</tt>. So what can be written like this:
345
+ # will also create an index, similar to calling {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
346
+ # So what can be written like this:
239
347
  #
240
348
  # create_table :taggings do |t|
241
349
  # t.integer :tag_id, :tagger_id, :taggable_id
@@ -249,15 +357,20 @@ module ActiveRecord
249
357
  #
250
358
  # create_table :taggings do |t|
251
359
  # t.references :tag, index: { name: 'index_taggings_on_tag_id' }
252
- # t.references :tagger, polymorphic: true, index: true
253
- # t.references :taggable, polymorphic: { default: 'Photo' }
360
+ # t.references :tagger, polymorphic: true
361
+ # t.references :taggable, polymorphic: { default: 'Photo' }, index: false
254
362
  # end
255
- def column(name, type, options = {})
363
+ def column(name, type, **options)
256
364
  name = name.to_s
257
- type = type.to_sym
258
-
259
- if @columns_hash[name] && @columns_hash[name].primary_key?
260
- raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
365
+ type = type.to_sym if type
366
+ options = options.dup
367
+
368
+ if @columns_hash[name]
369
+ if @columns_hash[name].primary_key?
370
+ raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
371
+ else
372
+ raise ArgumentError, "you can't define an already defined column '#{name}'."
373
+ end
261
374
  end
262
375
 
263
376
  index_options = options.delete(:index)
@@ -266,89 +379,79 @@ module ActiveRecord
266
379
  self
267
380
  end
268
381
 
382
+ # remove the column +name+ from the table.
383
+ # remove_column(:account_id)
269
384
  def remove_column(name)
270
385
  @columns_hash.delete name.to_s
271
386
  end
272
387
 
273
- [:string, :text, :integer, :bigint, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
274
- define_method column_type do |*args|
275
- options = args.extract_options!
276
- column_names = args
277
- column_names.each { |name| column(name, column_type, options) }
278
- end
279
- end
280
-
281
388
  # Adds index options to the indexes hash, keyed by column name
282
389
  # This is primarily used to track indexes that need to be created after the table
283
390
  #
284
391
  # index(:account_id, name: 'index_projects_on_account_id')
285
392
  def index(column_name, options = {})
286
- indexes[column_name] = options
393
+ indexes << [column_name, options]
394
+ end
395
+
396
+ def foreign_key(table_name, options = {}) # :nodoc:
397
+ foreign_keys << [table_name, options]
287
398
  end
288
399
 
289
400
  # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
290
- # <tt>:updated_at</tt> to the table. See SchemaStatements#add_timestamps
401
+ # <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
291
402
  #
292
403
  # t.timestamps null: false
293
- def timestamps(*args)
294
- options = args.extract_options!
295
- emit_warning_if_null_unspecified(options)
404
+ def timestamps(**options)
405
+ options[:null] = false if options[:null].nil?
406
+
407
+ if !options.key?(:precision) && @conn.supports_datetime_with_precision?
408
+ options[:precision] = 6
409
+ end
410
+
296
411
  column(:created_at, :datetime, options)
297
412
  column(:updated_at, :datetime, options)
298
413
  end
299
414
 
300
- # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
301
- # <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
302
- # by default, the <tt>:type</tt> option can be used to specify a different type.
415
+ # Adds a reference.
303
416
  #
304
417
  # t.references(:user)
305
- # t.references(:user, type: "string")
306
- # t.belongs_to(:supplier, polymorphic: true)
418
+ # t.belongs_to(:supplier, foreign_key: true)
419
+ # t.belongs_to(:supplier, foreign_key: true, type: :integer)
307
420
  #
308
- # See SchemaStatements#add_reference
309
- def references(*args)
310
- options = args.extract_options!
311
- polymorphic = options.delete(:polymorphic)
312
- index_options = options.delete(:index)
313
- type = options.delete(:type) || :integer
314
- args.each do |col|
315
- column("#{col}_id", type, options)
316
- column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
317
- index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
421
+ # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
422
+ def references(*args, **options)
423
+ args.each do |ref_name|
424
+ ReferenceDefinition.new(ref_name, options).add_to(self)
318
425
  end
319
426
  end
320
427
  alias :belongs_to :references
321
428
 
322
- def new_column_definition(name, type, options) # :nodoc:
323
- type = aliased_types(type.to_s, type)
324
- column = create_column_definition name, type
325
- limit = options.fetch(:limit) do
326
- native[type][:limit] if native[type].is_a?(Hash)
429
+ def new_column_definition(name, type, **options) # :nodoc:
430
+ if integer_like_primary_key?(type, options)
431
+ type = integer_like_primary_key_type(type, options)
327
432
  end
328
-
329
- column.limit = limit
330
- column.precision = options[:precision]
331
- column.scale = options[:scale]
332
- column.default = options[:default]
333
- column.null = options[:null]
334
- column.first = options[:first]
335
- column.after = options[:after]
336
- column.primary_key = type == :primary_key || options[:primary_key]
337
- column
433
+ type = aliased_types(type.to_s, type)
434
+ options[:primary_key] ||= type == :primary_key
435
+ options[:null] = false if options[:primary_key]
436
+ create_column_definition(name, type, options)
338
437
  end
339
438
 
340
439
  private
341
- def create_column_definition(name, type)
342
- ColumnDefinition.new name, type
343
- end
440
+ def create_column_definition(name, type, options)
441
+ ColumnDefinition.new(name, type, options)
442
+ end
344
443
 
345
- def native
346
- @native
347
- end
444
+ def aliased_types(name, fallback)
445
+ "timestamp" == name ? :datetime : fallback
446
+ end
348
447
 
349
- def aliased_types(name, fallback)
350
- 'timestamp' == name ? :datetime : fallback
351
- end
448
+ def integer_like_primary_key?(type, options)
449
+ options[:primary_key] && [:integer, :bigint].include?(type) && !options.key?(:default)
450
+ end
451
+
452
+ def integer_like_primary_key_type(type, options)
453
+ type
454
+ end
352
455
  end
353
456
 
354
457
  class AlterTable # :nodoc:
@@ -376,16 +479,17 @@ module ActiveRecord
376
479
  def add_column(name, type, options)
377
480
  name = name.to_s
378
481
  type = type.to_sym
379
- @adds << @td.new_column_definition(name, type, options)
482
+ @adds << AddColumnDefinition.new(@td.new_column_definition(name, type, options))
380
483
  end
381
484
  end
382
485
 
383
486
  # Represents an SQL table in an abstract way for updating a table.
384
- # Also see TableDefinition and SchemaStatements#create_table
487
+ # Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
385
488
  #
386
489
  # Available transformations are:
387
490
  #
388
491
  # change_table :table do |t|
492
+ # t.primary_key
389
493
  # t.column
390
494
  # t.index
391
495
  # t.rename_index
@@ -398,15 +502,21 @@ module ActiveRecord
398
502
  # t.string
399
503
  # t.text
400
504
  # t.integer
505
+ # t.bigint
401
506
  # t.float
402
507
  # t.decimal
508
+ # t.numeric
403
509
  # t.datetime
404
510
  # t.timestamp
405
511
  # t.time
406
512
  # t.date
407
513
  # t.binary
408
514
  # t.boolean
515
+ # t.foreign_key
516
+ # t.json
517
+ # t.virtual
409
518
  # t.remove
519
+ # t.remove_foreign_key
410
520
  # t.remove_references
411
521
  # t.remove_belongs_to
412
522
  # t.remove_index
@@ -414,6 +524,8 @@ module ActiveRecord
414
524
  # end
415
525
  #
416
526
  class Table
527
+ include ColumnMethods
528
+
417
529
  attr_reader :name
418
530
 
419
531
  def initialize(table_name, base)
@@ -422,33 +534,44 @@ module ActiveRecord
422
534
  end
423
535
 
424
536
  # Adds a new column to the named table.
425
- # See TableDefinition#column for details of the options you can use.
426
537
  #
427
- # ====== Creating a simple column
428
538
  # t.column(:name, :string)
429
- def column(column_name, type, options = {})
539
+ #
540
+ # See TableDefinition#column for details of the options you can use.
541
+ def column(column_name, type, **options)
542
+ index_options = options.delete(:index)
430
543
  @base.add_column(name, column_name, type, options)
544
+ index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
431
545
  end
432
546
 
433
- # Checks to see if a column exists. See SchemaStatements#column_exists?
547
+ # Checks to see if a column exists.
548
+ #
549
+ # t.string(:name) unless t.column_exists?(:name, :string)
550
+ #
551
+ # See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
434
552
  def column_exists?(column_name, type = nil, options = {})
435
553
  @base.column_exists?(name, column_name, type, options)
436
554
  end
437
555
 
438
556
  # Adds a new index to the table. +column_name+ can be a single Symbol, or
439
- # an Array of Symbols. See SchemaStatements#add_index
557
+ # an Array of Symbols.
440
558
  #
441
- # ====== Creating a simple index
442
559
  # t.index(:name)
443
- # ====== Creating a unique index
444
560
  # t.index([:branch_id, :party_id], unique: true)
445
- # ====== Creating a named index
446
561
  # t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
562
+ #
563
+ # See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
447
564
  def index(column_name, options = {})
448
565
  @base.add_index(name, column_name, options)
449
566
  end
450
567
 
451
- # Checks to see if an index exists. See SchemaStatements#index_exists?
568
+ # Checks to see if an index exists.
569
+ #
570
+ # unless t.index_exists?(:branch_id)
571
+ # t.index(:branch_id)
572
+ # end
573
+ #
574
+ # See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
452
575
  def index_exists?(column_name, options = {})
453
576
  @base.index_exists?(name, column_name, options)
454
577
  end
@@ -456,52 +579,59 @@ module ActiveRecord
456
579
  # Renames the given index on the table.
457
580
  #
458
581
  # t.rename_index(:user_id, :account_id)
582
+ #
583
+ # See {connection.rename_index}[rdoc-ref:SchemaStatements#rename_index]
459
584
  def rename_index(index_name, new_index_name)
460
585
  @base.rename_index(name, index_name, new_index_name)
461
586
  end
462
587
 
463
- # Adds timestamps (+created_at+ and +updated_at+) columns to the table. See SchemaStatements#add_timestamps
588
+ # Adds timestamps (+created_at+ and +updated_at+) columns to the table.
589
+ #
590
+ # t.timestamps(null: false)
464
591
  #
465
- # t.timestamps null: false
592
+ # See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
466
593
  def timestamps(options = {})
467
594
  @base.add_timestamps(name, options)
468
595
  end
469
596
 
470
597
  # Changes the column's definition according to the new options.
471
- # See TableDefinition#column for details of the options you can use.
472
598
  #
473
599
  # t.change(:name, :string, limit: 80)
474
600
  # t.change(:description, :text)
601
+ #
602
+ # See TableDefinition#column for details of the options you can use.
475
603
  def change(column_name, type, options = {})
476
604
  @base.change_column(name, column_name, type, options)
477
605
  end
478
606
 
479
- # Sets a new default value for a column. See SchemaStatements#change_column_default
607
+ # Sets a new default value for a column.
480
608
  #
481
609
  # t.change_default(:qualification, 'new')
482
610
  # t.change_default(:authorized, 1)
483
- def change_default(column_name, default)
484
- @base.change_column_default(name, column_name, default)
611
+ # t.change_default(:status, from: nil, to: "draft")
612
+ #
613
+ # See {connection.change_column_default}[rdoc-ref:SchemaStatements#change_column_default]
614
+ def change_default(column_name, default_or_changes)
615
+ @base.change_column_default(name, column_name, default_or_changes)
485
616
  end
486
617
 
487
618
  # Removes the column(s) from the table definition.
488
619
  #
489
620
  # t.remove(:qualification)
490
621
  # t.remove(:qualification, :experience)
622
+ #
623
+ # See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
491
624
  def remove(*column_names)
492
625
  @base.remove_columns(name, *column_names)
493
626
  end
494
627
 
495
628
  # Removes the given index from the table.
496
629
  #
497
- # ====== Remove the index_table_name_on_column in the table_name table
498
- # t.remove_index :column
499
- # ====== Remove the index named index_table_name_on_branch_id in the table_name table
500
- # t.remove_index column: :branch_id
501
- # ====== Remove the index named index_table_name_on_branch_id_and_party_id in the table_name table
502
- # t.remove_index column: [:branch_id, :party_id]
503
- # ====== Remove the index named by_branch_party in the table_name table
504
- # t.remove_index name: :by_branch_party
630
+ # t.remove_index(:branch_id)
631
+ # t.remove_index(column: [:branch_id, :party_id])
632
+ # t.remove_index(name: :by_branch_party)
633
+ #
634
+ # See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
505
635
  def remove_index(options = {})
506
636
  @base.remove_index(name, options)
507
637
  end
@@ -509,6 +639,8 @@ module ActiveRecord
509
639
  # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
510
640
  #
511
641
  # t.remove_timestamps
642
+ #
643
+ # See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
512
644
  def remove_timestamps(options = {})
513
645
  @base.remove_timestamps(name, options)
514
646
  end
@@ -516,21 +648,19 @@ module ActiveRecord
516
648
  # Renames a column.
517
649
  #
518
650
  # t.rename(:description, :name)
651
+ #
652
+ # See {connection.rename_column}[rdoc-ref:SchemaStatements#rename_column]
519
653
  def rename(column_name, new_column_name)
520
654
  @base.rename_column(name, column_name, new_column_name)
521
655
  end
522
656
 
523
- # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
524
- # <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
525
- # by default, the <tt>:type</tt> option can be used to specify a different type.
657
+ # Adds a reference.
526
658
  #
527
659
  # t.references(:user)
528
- # t.references(:user, type: "string")
529
- # t.belongs_to(:supplier, polymorphic: true)
660
+ # t.belongs_to(:supplier, foreign_key: true)
530
661
  #
531
- # See SchemaStatements#add_reference
532
- def references(*args)
533
- options = args.extract_options!
662
+ # See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
663
+ def references(*args, **options)
534
664
  args.each do |ref_name|
535
665
  @base.add_reference(name, ref_name, options)
536
666
  end
@@ -538,37 +668,46 @@ module ActiveRecord
538
668
  alias :belongs_to :references
539
669
 
540
670
  # Removes a reference. Optionally removes a +type+ column.
541
- # <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
542
671
  #
543
672
  # t.remove_references(:user)
544
673
  # t.remove_belongs_to(:supplier, polymorphic: true)
545
674
  #
546
- # See SchemaStatements#remove_reference
547
- def remove_references(*args)
548
- options = args.extract_options!
675
+ # See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
676
+ def remove_references(*args, **options)
549
677
  args.each do |ref_name|
550
678
  @base.remove_reference(name, ref_name, options)
551
679
  end
552
680
  end
553
681
  alias :remove_belongs_to :remove_references
554
682
 
555
- # Adds a column or columns of a specified type
683
+ # Adds a foreign key to the table using a supplied table name.
556
684
  #
557
- # t.string(:goat)
558
- # t.string(:goat, :sheep)
559
- [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
560
- define_method column_type do |*args|
561
- options = args.extract_options!
562
- args.each do |column_name|
563
- @base.add_column(name, column_name, column_type, options)
564
- end
565
- end
685
+ # t.foreign_key(:authors)
686
+ # t.foreign_key(:authors, column: :author_id, primary_key: "id")
687
+ #
688
+ # See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
689
+ def foreign_key(*args)
690
+ @base.add_foreign_key(name, *args)
566
691
  end
567
692
 
568
- private
569
- def native
570
- @base.native_database_types
571
- end
693
+ # Removes the given foreign key from the table.
694
+ #
695
+ # t.remove_foreign_key(:authors)
696
+ # t.remove_foreign_key(column: :author_id)
697
+ #
698
+ # See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
699
+ def remove_foreign_key(*args)
700
+ @base.remove_foreign_key(name, *args)
701
+ end
702
+
703
+ # Checks to see if a foreign key exists.
704
+ #
705
+ # t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
706
+ #
707
+ # See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
708
+ def foreign_key_exists?(*args)
709
+ @base.foreign_key_exists?(name, *args)
710
+ end
572
711
  end
573
712
  end
574
713
  end