activerecord 5.0.7.2 → 6.1.1

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

Potentially problematic release.


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

Files changed (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  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 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,4 +1,6 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
4
6
  # This is a thread locals registry for Active Record. For example:
@@ -12,9 +14,9 @@ module ActiveRecord
12
14
  class RuntimeRegistry # :nodoc:
13
15
  extend ActiveSupport::PerThreadRegistry
14
16
 
15
- attr_accessor :connection_handler, :sql_runtime, :connection_id
17
+ attr_accessor :sql_runtime
16
18
 
17
- [:connection_handler, :sql_runtime, :connection_id].each do |val|
19
+ [:sql_runtime].each do |val|
18
20
  class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
19
21
  class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
20
22
  end
@@ -1,17 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Sanitization
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  module ClassMethods
6
- # Used to sanitize objects before they're used in an SQL SELECT statement.
7
- # Delegates to {connection.quote}[rdoc-ref:ConnectionAdapters::Quoting#quote].
8
- def sanitize(object) # :nodoc:
9
- connection.quote(object)
10
- end
11
- alias_method :quote_value, :sanitize
12
-
13
- protected
14
-
15
8
  # Accepts an array or string of SQL conditions and sanitizes
16
9
  # them into a valid SQL fragment for a WHERE clause.
17
10
  #
@@ -34,8 +27,7 @@ module ActiveRecord
34
27
  else condition
35
28
  end
36
29
  end
37
- alias_method :sanitize_sql, :sanitize_sql_for_conditions
38
- alias_method :sanitize_conditions, :sanitize_sql
30
+ alias :sanitize_sql :sanitize_sql_for_conditions
39
31
 
40
32
  # Accepts an array, hash, or string of SQL conditions and sanitizes
41
33
  # them into a valid SQL fragment for a SET clause.
@@ -46,12 +38,12 @@ module ActiveRecord
46
38
  # sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
47
39
  # # => "name=NULL and group_id=4"
48
40
  #
49
- # Post.send(:sanitize_sql_for_assignment, { name: nil, group_id: 4 })
41
+ # Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
50
42
  # # => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
51
43
  #
52
44
  # sanitize_sql_for_assignment("name=NULL and group_id='4'")
53
45
  # # => "name=NULL and group_id='4'"
54
- def sanitize_sql_for_assignment(assignments, default_table_name = self.table_name)
46
+ def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
55
47
  case assignments
56
48
  when Array; sanitize_sql_array(assignments)
57
49
  when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name)
@@ -68,47 +60,24 @@ module ActiveRecord
68
60
  # sanitize_sql_for_order("id ASC")
69
61
  # # => "id ASC"
70
62
  def sanitize_sql_for_order(condition)
71
- if condition.is_a?(Array) && condition.first.to_s.include?('?')
72
- sanitize_sql_array(condition)
63
+ if condition.is_a?(Array) && condition.first.to_s.include?("?")
64
+ disallow_raw_sql!(
65
+ [condition.first],
66
+ permit: connection.column_name_with_order_matcher
67
+ )
68
+
69
+ # Ensure we aren't dealing with a subclass of String that might
70
+ # override methods we use (e.g. Arel::Nodes::SqlLiteral).
71
+ if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
72
+ condition = [String.new(condition.first), *condition[1..-1]]
73
+ end
74
+
75
+ Arel.sql(sanitize_sql_array(condition))
73
76
  else
74
77
  condition
75
78
  end
76
79
  end
77
80
 
78
- # Accepts a hash of SQL conditions and replaces those attributes
79
- # that correspond to a {#composed_of}[rdoc-ref:Aggregations::ClassMethods#composed_of]
80
- # relationship with their expanded aggregate attribute values.
81
- #
82
- # Given:
83
- #
84
- # class Person < ActiveRecord::Base
85
- # composed_of :address, class_name: "Address",
86
- # mapping: [%w(address_street street), %w(address_city city)]
87
- # end
88
- #
89
- # Then:
90
- #
91
- # { address: Address.new("813 abc st.", "chicago") }
92
- # # => { address_street: "813 abc st.", address_city: "chicago" }
93
- def expand_hash_conditions_for_aggregates(attrs)
94
- expanded_attrs = {}
95
- attrs.each do |attr, value|
96
- if aggregation = reflect_on_aggregation(attr.to_sym)
97
- mapping = aggregation.mapping
98
- mapping.each do |field_attr, aggregate_attr|
99
- if mapping.size == 1 && !value.respond_to?(aggregate_attr)
100
- expanded_attrs[field_attr] = value
101
- else
102
- expanded_attrs[field_attr] = value.send(aggregate_attr)
103
- end
104
- end
105
- else
106
- expanded_attrs[attr] = value
107
- end
108
- end
109
- expanded_attrs
110
- end
111
-
112
81
  # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
113
82
  #
114
83
  # sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
@@ -116,19 +85,10 @@ module ActiveRecord
116
85
  def sanitize_sql_hash_for_assignment(attrs, table)
117
86
  c = connection
118
87
  attrs.map do |attr, value|
119
- if value.is_a?(Base)
120
- require "active_support/core_ext/string/filters"
121
- ActiveSupport::Deprecation.warn(<<-WARNING.squish)
122
- Passing `ActiveRecord::Base` objects to
123
- `sanitize_sql_hash_for_assignment` (or methods which call it,
124
- such as `update_all`) is deprecated. Please pass the id directly,
125
- instead.
126
- WARNING
127
- else
128
- value = type_for_attribute(attr.to_s).serialize(value)
129
- end
88
+ type = type_for_attribute(attr)
89
+ value = type.serialize(type.cast(value))
130
90
  "#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
131
- end.join(', ')
91
+ end.join(", ")
132
92
  end
133
93
 
134
94
  # Sanitizes a +string+ so that it is safe to use within an SQL
@@ -163,9 +123,9 @@ module ActiveRecord
163
123
  # # => "name='foo''bar' and group_id='4'"
164
124
  def sanitize_sql_array(ary)
165
125
  statement, *values = ary
166
- if values.first.is_a?(Hash) && statement =~ /:\w+/
126
+ if values.first.is_a?(Hash) && /:\w+/.match?(statement)
167
127
  replace_named_bind_variables(statement, values.first)
168
- elsif statement.include?('?')
128
+ elsif statement.include?("?")
169
129
  replace_bind_variables(statement, values)
170
130
  elsif statement.blank?
171
131
  statement
@@ -174,57 +134,70 @@ module ActiveRecord
174
134
  end
175
135
  end
176
136
 
177
- def replace_bind_variables(statement, values) # :nodoc:
178
- raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
179
- bound = values.dup
180
- c = connection
181
- statement.gsub(/\?/) do
182
- replace_bind_variable(bound.shift, c)
137
+ def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
138
+ unexpected = nil
139
+ args.each do |arg|
140
+ next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
141
+ (unexpected ||= []) << arg
183
142
  end
184
- end
185
143
 
186
- def replace_bind_variable(value, c = connection) # :nodoc:
187
- if ActiveRecord::Relation === value
188
- value.to_sql
189
- else
190
- quote_bound_value(value, c)
144
+ if unexpected
145
+ raise(ActiveRecord::UnknownAttributeReference,
146
+ "Query method called with non-attribute argument(s): " +
147
+ unexpected.map(&:inspect).join(", ")
148
+ )
191
149
  end
192
150
  end
193
151
 
194
- def replace_named_bind_variables(statement, bind_vars) # :nodoc:
195
- statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
196
- if $1 == ':' # skip postgresql casts
197
- match # return the whole match
198
- elsif bind_vars.include?(match = $2.to_sym)
199
- replace_bind_variable(bind_vars[match])
200
- else
201
- raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
152
+ private
153
+ def replace_bind_variables(statement, values)
154
+ raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
155
+ bound = values.dup
156
+ c = connection
157
+ statement.gsub(/\?/) do
158
+ replace_bind_variable(bound.shift, c)
202
159
  end
203
160
  end
204
- end
205
161
 
206
- def quote_bound_value(value, c = connection) # :nodoc:
207
- if value.respond_to?(:map) && !value.acts_like?(:string)
208
- if value.respond_to?(:empty?) && value.empty?
209
- c.quote(nil)
162
+ def replace_bind_variable(value, c = connection)
163
+ if ActiveRecord::Relation === value
164
+ value.to_sql
210
165
  else
211
- value.map { |v| c.quote(v) }.join(',')
166
+ quote_bound_value(value, c)
212
167
  end
213
- else
214
- c.quote(value)
215
168
  end
216
- end
217
169
 
218
- def raise_if_bind_arity_mismatch(statement, expected, provided) # :nodoc:
219
- unless expected == provided
220
- raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
170
+ def replace_named_bind_variables(statement, bind_vars)
171
+ statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
172
+ if $1 == ":" # skip postgresql casts
173
+ match # return the whole match
174
+ elsif bind_vars.include?(match = $2.to_sym)
175
+ replace_bind_variable(bind_vars[match])
176
+ else
177
+ raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
178
+ end
179
+ end
180
+ end
181
+
182
+ def quote_bound_value(value, c = connection)
183
+ if value.respond_to?(:map) && !value.acts_like?(:string)
184
+ values = value.map { |v| v.respond_to?(:id_for_database) ? v.id_for_database : v }
185
+ if values.empty?
186
+ c.quote(nil)
187
+ else
188
+ values.map! { |v| c.quote(v) }.join(",")
189
+ end
190
+ else
191
+ value = value.id_for_database if value.respond_to?(:id_for_database)
192
+ c.quote(value)
193
+ end
221
194
  end
222
- end
223
- end
224
195
 
225
- # TODO: Deprecate this
226
- def quoted_id # :nodoc:
227
- self.class.quote_value(@attributes[self.class.primary_key].value_for_database)
196
+ def raise_if_bind_arity_mismatch(statement, expected, provided)
197
+ unless expected == provided
198
+ raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
199
+ end
200
+ end
228
201
  end
229
202
  end
230
203
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record \Schema
3
5
  #
@@ -37,10 +39,10 @@ module ActiveRecord
37
39
  # The +info+ hash is optional, and if given is used to define metadata
38
40
  # about the current schema (currently, only the schema's version):
39
41
  #
40
- # ActiveRecord::Schema.define(version: 20380119000001) do
42
+ # ActiveRecord::Schema.define(version: 2038_01_19_000001) do
41
43
  # ...
42
44
  # end
43
- def self.define(info={}, &block)
45
+ def self.define(info = {}, &block)
44
46
  new.define(info, &block)
45
47
  end
46
48
 
@@ -48,21 +50,12 @@ module ActiveRecord
48
50
  instance_eval(&block)
49
51
 
50
52
  if info[:version].present?
51
- initialize_schema_migrations_table
52
- connection.assume_migrated_upto_version(info[:version], migrations_paths)
53
+ connection.schema_migration.create_table
54
+ connection.assume_migrated_upto_version(info[:version])
53
55
  end
54
56
 
55
57
  ActiveRecord::InternalMetadata.create_table
56
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
58
+ ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
57
59
  end
58
-
59
- private
60
- # Returns the migrations paths.
61
- #
62
- # ActiveRecord::Schema.new.migrations_paths
63
- # # => ["db/migrate"] # Rails migration path by default.
64
- def migrations_paths # :nodoc:
65
- ActiveRecord::Migrator.migrations_paths
66
- end
67
60
  end
68
61
  end
@@ -1,4 +1,6 @@
1
- require 'stringio'
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
2
4
 
3
5
  module ActiveRecord
4
6
  # = Active Record Schema Dumper
@@ -11,14 +13,25 @@ module ActiveRecord
11
13
  ##
12
14
  # :singleton-method:
13
15
  # A list of tables which should not be dumped to the schema.
14
- # Acceptable values are strings as well as regexp.
15
- # This setting is only used if ActiveRecord::Base.schema_format == :ruby
16
- cattr_accessor :ignore_tables
17
- @@ignore_tables = []
16
+ # Acceptable values are strings as well as regexp if ActiveRecord::Base.schema_format == :ruby.
17
+ # Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
18
+ cattr_accessor :ignore_tables, default: []
19
+
20
+ ##
21
+ # :singleton-method:
22
+ # Specify a custom regular expression matching foreign keys which name
23
+ # should not be dumped to db/schema.rb.
24
+ cattr_accessor :fk_ignore_pattern, default: /^fk_rails_[0-9a-f]{10}$/
25
+
26
+ ##
27
+ # :singleton-method:
28
+ # Specify a custom regular expression matching check constraints which name
29
+ # should not be dumped to db/schema.rb.
30
+ cattr_accessor :chk_ignore_pattern, default: /^chk_rails_[0-9a-f]{10}$/
18
31
 
19
32
  class << self
20
- def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
21
- new(connection, generate_options(config)).dump(stream)
33
+ def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
34
+ connection.create_schema_dumper(generate_options(config)).dump(stream)
22
35
  stream
23
36
  end
24
37
 
@@ -40,26 +53,36 @@ module ActiveRecord
40
53
  end
41
54
 
42
55
  private
56
+ attr_accessor :table_name
43
57
 
44
58
  def initialize(connection, options = {})
45
59
  @connection = connection
46
- @version = Migrator::current_version rescue nil
60
+ @version = connection.migration_context.current_version rescue nil
47
61
  @options = options
48
62
  end
49
63
 
50
- def header(stream)
51
- define_params = @version ? "version: #{@version}" : ""
64
+ # turns 20170404131909 into "2017_04_04_131909"
65
+ def formatted_version
66
+ stringified = @version.to_s
67
+ return stringified unless stringified.length == 14
68
+ stringified.insert(4, "_").insert(7, "_").insert(10, "_")
69
+ end
70
+
71
+ def define_params
72
+ @version ? "version: #{formatted_version}" : ""
73
+ end
52
74
 
75
+ def header(stream)
53
76
  stream.puts <<HEADER
54
77
  # This file is auto-generated from the current state of the database. Instead
55
78
  # of editing this file, please use the migrations feature of Active Record to
56
79
  # incrementally modify your database, and then regenerate this schema definition.
57
80
  #
58
- # Note that this schema.rb definition is the authoritative source for your
59
- # database schema. If you need to create the application database on another
60
- # system, you should be using db:schema:load, not running all the migrations
61
- # from scratch. The latter is a flawed and unsustainable approach (the more migrations
62
- # you'll amass, the slower it'll run and the greater likelihood for issues).
81
+ # This file is the source Rails uses to define your schema when running `bin/rails
82
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
83
+ # be faster and is potentially less error prone than running all of your
84
+ # migrations from scratch. Old migrations may fail to apply correctly if those
85
+ # migrations use external dependencies or application code.
63
86
  #
64
87
  # It's strongly recommended that you check this file into your version control system.
65
88
 
@@ -72,20 +95,12 @@ HEADER
72
95
  stream.puts "end"
73
96
  end
74
97
 
98
+ # extensions are only supported by PostgreSQL
75
99
  def extensions(stream)
76
- return unless @connection.supports_extensions?
77
- extensions = @connection.extensions
78
- if extensions.any?
79
- stream.puts " # These are extensions that must be enabled in order to support this database"
80
- extensions.each do |extension|
81
- stream.puts " enable_extension #{extension.inspect}"
82
- end
83
- stream.puts
84
- end
85
100
  end
86
101
 
87
102
  def tables(stream)
88
- sorted_tables = @connection.data_sources.sort - @connection.views
103
+ sorted_tables = @connection.tables.sort
89
104
 
90
105
  sorted_tables.each do |table_name|
91
106
  table(table_name, stream) unless ignored?(table_name)
@@ -102,6 +117,8 @@ HEADER
102
117
  def table(table, stream)
103
118
  columns = @connection.columns(table)
104
119
  begin
120
+ self.table_name = table
121
+
105
122
  tbl = StringIO.new
106
123
 
107
124
  # first dump primary key column
@@ -111,64 +128,44 @@ HEADER
111
128
 
112
129
  case pk
113
130
  when String
114
- tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
131
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
115
132
  pkcol = columns.detect { |c| c.name == pk }
116
- pkcolspec = @connection.column_spec_for_primary_key(pkcol)
117
- if pkcolspec.present?
118
- pkcolspec.each do |key, value|
119
- tbl.print ", #{key}: #{value}"
133
+ pkcolspec = column_spec_for_primary_key(pkcol)
134
+ unless pkcolspec.empty?
135
+ if pkcolspec != pkcolspec.slice(:id, :default)
136
+ pkcolspec = { id: { type: pkcolspec.delete(:id), **pkcolspec }.compact }
120
137
  end
138
+ tbl.print ", #{format_colspec(pkcolspec)}"
121
139
  end
122
140
  when Array
123
141
  tbl.print ", primary_key: #{pk.inspect}"
124
142
  else
125
143
  tbl.print ", id: false"
126
144
  end
127
- tbl.print ", force: :cascade"
128
145
 
129
146
  table_options = @connection.table_options(table)
130
147
  if table_options.present?
131
148
  tbl.print ", #{format_options(table_options)}"
132
149
  end
133
150
 
134
- tbl.puts " do |t|"
151
+ tbl.puts ", force: :cascade do |t|"
135
152
 
136
153
  # then dump all non-primary key columns
137
- column_specs = columns.map do |column|
154
+ columns.each do |column|
138
155
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
139
156
  next if column.name == pk
140
- @connection.column_spec(column)
141
- end.compact
142
-
143
- # find all migration keys used in this table
144
- keys = @connection.migration_keys
145
-
146
- # figure out the lengths for each column based on above keys
147
- lengths = keys.map { |key|
148
- column_specs.map { |spec|
149
- spec[key] ? spec[key].length + 2 : 0
150
- }.max
151
- }
152
-
153
- # the string we're going to sprintf our values against, with standardized column widths
154
- format_string = lengths.map{ |len| "%-#{len}s" }
155
-
156
- # find the max length for the 'type' column, which is special
157
- type_length = column_specs.map{ |column| column[:type].length }.max
158
-
159
- # add column type definition to our format string
160
- format_string.unshift " t.%-#{type_length}s "
161
-
162
- format_string *= ''
163
-
164
- column_specs.each do |colspec|
165
- values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
166
- values.unshift colspec[:type]
167
- tbl.print((format_string % values).gsub(/,\s*$/, ''))
157
+ type, colspec = column_spec(column)
158
+ if type.is_a?(Symbol)
159
+ tbl.print " t.#{type} #{column.name.inspect}"
160
+ else
161
+ tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
162
+ end
163
+ tbl.print ", #{format_colspec(colspec)}" if colspec.present?
168
164
  tbl.puts
169
165
  end
170
166
 
171
167
  indexes_in_create(table, tbl)
168
+ check_constraints_in_create(table, tbl) if @connection.supports_check_constraints?
172
169
 
173
170
  tbl.puts " end"
174
171
  tbl.puts
@@ -179,9 +176,9 @@ HEADER
179
176
  stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
180
177
  stream.puts "# #{e.message}"
181
178
  stream.puts
179
+ ensure
180
+ self.table_name = nil
182
181
  end
183
-
184
- stream
185
182
  end
186
183
 
187
184
  # Keep it for indexing materialized views
@@ -189,7 +186,7 @@ HEADER
189
186
  if (indexes = @connection.indexes(table)).any?
190
187
  add_index_statements = indexes.map do |index|
191
188
  table_name = remove_prefix_and_suffix(index.table).inspect
192
- " add_index #{([table_name]+index_parts(index)).join(', ')}"
189
+ " add_index #{([table_name] + index_parts(index)).join(', ')}"
193
190
  end
194
191
 
195
192
  stream.puts add_index_statements.sort.join("\n")
@@ -212,15 +209,34 @@ HEADER
212
209
  "name: #{index.name.inspect}",
213
210
  ]
214
211
  index_parts << "unique: true" if index.unique
215
- index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
216
- index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
212
+ index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
213
+ index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
214
+ index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
217
215
  index_parts << "where: #{index.where.inspect}" if index.where
218
- index_parts << "using: #{index.using.inspect}" if index.using
216
+ index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
219
217
  index_parts << "type: #{index.type.inspect}" if index.type
220
218
  index_parts << "comment: #{index.comment.inspect}" if index.comment
221
219
  index_parts
222
220
  end
223
221
 
222
+ def check_constraints_in_create(table, stream)
223
+ if (check_constraints = @connection.check_constraints(table)).any?
224
+ add_check_constraint_statements = check_constraints.map do |check_constraint|
225
+ parts = [
226
+ "t.check_constraint #{check_constraint.expression.inspect}"
227
+ ]
228
+
229
+ if check_constraint.export_name_on_schema_dump?
230
+ parts << "name: #{check_constraint.name.inspect}"
231
+ end
232
+
233
+ " #{parts.join(', ')}"
234
+ end
235
+
236
+ stream.puts add_check_constraint_statements.sort.join("\n")
237
+ end
238
+ end
239
+
224
240
  def foreign_keys(table, stream)
225
241
  if (foreign_keys = @connection.foreign_keys(table)).any?
226
242
  add_foreign_key_statements = foreign_keys.map do |foreign_key|
@@ -237,7 +253,7 @@ HEADER
237
253
  parts << "primary_key: #{foreign_key.primary_key.inspect}"
238
254
  end
239
255
 
240
- if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
256
+ if foreign_key.export_name_on_schema_dump?
241
257
  parts << "name: #{foreign_key.name.inspect}"
242
258
  end
243
259
 
@@ -251,12 +267,28 @@ HEADER
251
267
  end
252
268
  end
253
269
 
270
+ def format_colspec(colspec)
271
+ colspec.map do |key, value|
272
+ "#{key}: #{ value.is_a?(Hash) ? "{ #{format_colspec(value)} }" : value }"
273
+ end.join(", ")
274
+ end
275
+
254
276
  def format_options(options)
255
277
  options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
256
278
  end
257
279
 
280
+ def format_index_parts(options)
281
+ if options.is_a?(Hash)
282
+ "{ #{format_options(options)} }"
283
+ else
284
+ options.inspect
285
+ end
286
+ end
287
+
258
288
  def remove_prefix_and_suffix(table)
259
- table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
289
+ prefix = Regexp.escape(@options[:table_name_prefix].to_s)
290
+ suffix = Regexp.escape(@options[:table_name_suffix].to_s)
291
+ table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
260
292
  end
261
293
 
262
294
  def ignored?(table_name)