activerecord 5.0.7.2 → 6.0.3.4

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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +708 -2040
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -22
  8. data/lib/active_record/advisory_lock_base.rb +18 -0
  9. data/lib/active_record/aggregations.rb +249 -247
  10. data/lib/active_record/association_relation.rb +18 -14
  11. data/lib/active_record/associations.rb +1603 -1592
  12. data/lib/active_record/associations/alias_tracker.rb +24 -34
  13. data/lib/active_record/associations/association.rb +114 -55
  14. data/lib/active_record/associations/association_scope.rb +94 -94
  15. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  16. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  17. data/lib/active_record/associations/builder/association.rb +18 -25
  18. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  19. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  20. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  21. data/lib/active_record/associations/builder/has_many.rb +4 -0
  22. data/lib/active_record/associations/builder/has_one.rb +37 -1
  23. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  24. data/lib/active_record/associations/collection_association.rb +86 -254
  25. data/lib/active_record/associations/collection_proxy.rb +158 -122
  26. data/lib/active_record/associations/foreign_association.rb +9 -0
  27. data/lib/active_record/associations/has_many_association.rb +23 -30
  28. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  29. data/lib/active_record/associations/has_one_association.rb +59 -54
  30. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  31. data/lib/active_record/associations/join_dependency.rb +143 -176
  32. data/lib/active_record/associations/join_dependency/join_association.rb +38 -87
  33. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  34. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  35. data/lib/active_record/associations/preloader.rb +90 -103
  36. data/lib/active_record/associations/preloader/association.rb +86 -100
  37. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  38. data/lib/active_record/associations/singular_association.rb +12 -45
  39. data/lib/active_record/associations/through_association.rb +26 -14
  40. data/lib/active_record/attribute_assignment.rb +54 -61
  41. data/lib/active_record/attribute_decorators.rb +38 -17
  42. data/lib/active_record/attribute_methods.rb +66 -106
  43. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  44. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  45. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  46. data/lib/active_record/attribute_methods/query.rb +4 -3
  47. data/lib/active_record/attribute_methods/read.rb +20 -49
  48. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  50. data/lib/active_record/attribute_methods/write.rb +34 -33
  51. data/lib/active_record/attributes.rb +38 -25
  52. data/lib/active_record/autosave_association.rb +54 -35
  53. data/lib/active_record/base.rb +27 -24
  54. data/lib/active_record/callbacks.rb +64 -35
  55. data/lib/active_record/coders/json.rb +2 -0
  56. data/lib/active_record/coders/yaml_column.rb +11 -12
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +552 -323
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +228 -147
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -202
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +396 -562
  70. data/lib/active_record/connection_adapters/column.rb +41 -13
  71. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  73. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  101. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -31
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  118. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  120. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  121. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  122. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  123. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  124. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  127. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +259 -266
  128. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  129. data/lib/active_record/connection_handling.rb +143 -40
  130. data/lib/active_record/core.rb +201 -163
  131. data/lib/active_record/counter_cache.rb +60 -28
  132. data/lib/active_record/database_configurations.rb +233 -0
  133. data/lib/active_record/database_configurations/database_config.rb +37 -0
  134. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  135. data/lib/active_record/database_configurations/url_config.rb +78 -0
  136. data/lib/active_record/define_callbacks.rb +22 -0
  137. data/lib/active_record/dynamic_matchers.rb +87 -87
  138. data/lib/active_record/enum.rb +60 -23
  139. data/lib/active_record/errors.rb +114 -18
  140. data/lib/active_record/explain.rb +4 -4
  141. data/lib/active_record/explain_registry.rb +3 -1
  142. data/lib/active_record/explain_subscriber.rb +9 -4
  143. data/lib/active_record/fixture_set/file.rb +13 -8
  144. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  145. data/lib/active_record/fixture_set/render_context.rb +17 -0
  146. data/lib/active_record/fixture_set/table_row.rb +152 -0
  147. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  148. data/lib/active_record/fixtures.rb +194 -504
  149. data/lib/active_record/gem_version.rb +5 -3
  150. data/lib/active_record/inheritance.rb +150 -99
  151. data/lib/active_record/insert_all.rb +179 -0
  152. data/lib/active_record/integration.rb +116 -25
  153. data/lib/active_record/internal_metadata.rb +16 -19
  154. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  155. data/lib/active_record/locking/optimistic.rb +77 -87
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +48 -29
  158. data/lib/active_record/middleware/database_selector.rb +74 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +369 -302
  162. data/lib/active_record/migration/command_recorder.rb +134 -100
  163. data/lib/active_record/migration/compatibility.rb +174 -56
  164. data/lib/active_record/migration/join_table.rb +8 -7
  165. data/lib/active_record/model_schema.rb +131 -127
  166. data/lib/active_record/nested_attributes.rb +213 -202
  167. data/lib/active_record/no_touching.rb +12 -3
  168. data/lib/active_record/null_relation.rb +12 -34
  169. data/lib/active_record/persistence.rb +446 -77
  170. data/lib/active_record/query_cache.rb +13 -12
  171. data/lib/active_record/querying.rb +37 -24
  172. data/lib/active_record/railtie.rb +128 -36
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +312 -177
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +214 -252
  179. data/lib/active_record/relation.rb +440 -318
  180. data/lib/active_record/relation/batches.rb +98 -52
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  182. data/lib/active_record/relation/calculations.rb +212 -173
  183. data/lib/active_record/relation/delegation.rb +72 -69
  184. data/lib/active_record/relation/finder_methods.rb +207 -247
  185. data/lib/active_record/relation/from_clause.rb +6 -8
  186. data/lib/active_record/relation/merger.rb +78 -62
  187. data/lib/active_record/relation/predicate_builder.rb +83 -105
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  195. data/lib/active_record/relation/query_attribute.rb +33 -2
  196. data/lib/active_record/relation/query_methods.rb +476 -334
  197. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  198. data/lib/active_record/relation/spawn_methods.rb +8 -8
  199. data/lib/active_record/relation/where_clause.rb +111 -96
  200. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  201. data/lib/active_record/result.rb +69 -40
  202. data/lib/active_record/runtime_registry.rb +5 -3
  203. data/lib/active_record/sanitization.rb +83 -99
  204. data/lib/active_record/schema.rb +7 -14
  205. data/lib/active_record/schema_dumper.rb +71 -69
  206. data/lib/active_record/schema_migration.rb +16 -6
  207. data/lib/active_record/scoping.rb +20 -20
  208. data/lib/active_record/scoping/default.rb +92 -95
  209. data/lib/active_record/scoping/named.rb +47 -27
  210. data/lib/active_record/secure_token.rb +4 -2
  211. data/lib/active_record/serialization.rb +2 -0
  212. data/lib/active_record/statement_cache.rb +63 -28
  213. data/lib/active_record/store.rb +121 -41
  214. data/lib/active_record/suppressor.rb +6 -3
  215. data/lib/active_record/table_metadata.rb +39 -18
  216. data/lib/active_record/tasks/database_tasks.rb +271 -81
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +70 -36
  223. data/lib/active_record/touch_later.rb +8 -6
  224. data/lib/active_record/transactions.rb +141 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +23 -18
  227. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  228. data/lib/active_record/type/date.rb +2 -0
  229. data/lib/active_record/type/date_time.rb +2 -0
  230. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  232. data/lib/active_record/type/internal/timezone.rb +2 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +16 -9
  235. data/lib/active_record/type/text.rb +11 -0
  236. data/lib/active_record/type/time.rb +2 -1
  237. data/lib/active_record/type/type_map.rb +14 -17
  238. data/lib/active_record/type/unsigned_integer.rb +16 -0
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/type_caster/connection.rb +17 -12
  241. data/lib/active_record/type_caster/map.rb +5 -4
  242. data/lib/active_record/validations.rb +7 -5
  243. data/lib/active_record/validations/absence.rb +2 -0
  244. data/lib/active_record/validations/associated.rb +4 -3
  245. data/lib/active_record/validations/length.rb +2 -0
  246. data/lib/active_record/validations/presence.rb +4 -2
  247. data/lib/active_record/validations/uniqueness.rb +29 -42
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +62 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +203 -0
  317. data/lib/arel/visitors/dot.rb +296 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +156 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +158 -0
  323. data/lib/arel/visitors/oracle12.rb +65 -0
  324. data/lib/arel/visitors/postgresql.rb +109 -0
  325. data/lib/arel/visitors/sqlite.rb +38 -0
  326. data/lib/arel/visitors/to_sql.rb +888 -0
  327. data/lib/arel/visitors/visitor.rb +45 -0
  328. data/lib/arel/visitors/where_sql.rb +22 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  333. data/lib/rails/generators/active_record/migration.rb +17 -3
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  335. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  338. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +137 -52
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  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/postgresql/oid/rails_5_1_point.rb +0 -50
  355. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  356. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  357. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  358. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  359. 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 :connection_handler, :sql_runtime
16
18
 
17
- [:connection_handler, :sql_runtime, :connection_id].each do |val|
19
+ [:connection_handler, :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 (eg. 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,81 @@ 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
144
+ return unless unexpected
145
+
146
+ if allow_unsafe_raw_sql == :deprecated
147
+ ActiveSupport::Deprecation.warn(
148
+ "Dangerous query method (method whose arguments are used as raw " \
149
+ "SQL) called with non-attribute argument(s): " \
150
+ "#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
151
+ "arguments will be disallowed in Rails 6.1. This method should " \
152
+ "not be called with user-provided values, such as request " \
153
+ "parameters or model attributes. Known-safe values can be passed " \
154
+ "by wrapping them in Arel.sql()."
155
+ )
189
156
  else
190
- quote_bound_value(value, c)
157
+ raise(ActiveRecord::UnknownAttributeReference,
158
+ "Query method called with non-attribute argument(s): " +
159
+ unexpected.map(&:inspect).join(", ")
160
+ )
191
161
  end
192
162
  end
193
163
 
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}"
164
+ private
165
+ def replace_bind_variables(statement, values)
166
+ raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
167
+ bound = values.dup
168
+ c = connection
169
+ statement.gsub(/\?/) do
170
+ replace_bind_variable(bound.shift, c)
202
171
  end
203
172
  end
204
- end
205
173
 
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)
174
+ def replace_bind_variable(value, c = connection)
175
+ if ActiveRecord::Relation === value
176
+ value.to_sql
210
177
  else
211
- value.map { |v| c.quote(v) }.join(',')
178
+ quote_bound_value(value, c)
212
179
  end
213
- else
214
- c.quote(value)
215
180
  end
216
- end
217
181
 
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}"
182
+ def replace_named_bind_variables(statement, bind_vars)
183
+ statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
184
+ if $1 == ":" # skip postgresql casts
185
+ match # return the whole match
186
+ elsif bind_vars.include?(match = $2.to_sym)
187
+ replace_bind_variable(bind_vars[match])
188
+ else
189
+ raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
190
+ end
191
+ end
221
192
  end
222
- end
223
- end
224
193
 
225
- # TODO: Deprecate this
226
- def quoted_id # :nodoc:
227
- self.class.quote_value(@attributes[self.class.primary_key].value_for_database)
194
+ def quote_bound_value(value, c = connection)
195
+ if value.respond_to?(:map) && !value.acts_like?(:string)
196
+ quoted = value.map { |v| c.quote(v) }
197
+ if quoted.empty?
198
+ c.quote(nil)
199
+ else
200
+ quoted.join(",")
201
+ end
202
+ else
203
+ c.quote(value)
204
+ end
205
+ end
206
+
207
+ def raise_if_bind_arity_mismatch(statement, expected, provided)
208
+ unless expected == provided
209
+ raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
210
+ end
211
+ end
228
212
  end
229
213
  end
230
214
  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,19 @@ 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}$/
18
25
 
19
26
  class << self
20
- def dump(connection=ActiveRecord::Base.connection, stream=STDOUT, config = ActiveRecord::Base)
21
- new(connection, generate_options(config)).dump(stream)
27
+ def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
28
+ connection.create_schema_dumper(generate_options(config)).dump(stream)
22
29
  stream
23
30
  end
24
31
 
@@ -40,26 +47,36 @@ module ActiveRecord
40
47
  end
41
48
 
42
49
  private
50
+ attr_accessor :table_name
43
51
 
44
52
  def initialize(connection, options = {})
45
53
  @connection = connection
46
- @version = Migrator::current_version rescue nil
54
+ @version = connection.migration_context.current_version rescue nil
47
55
  @options = options
48
56
  end
49
57
 
50
- def header(stream)
51
- define_params = @version ? "version: #{@version}" : ""
58
+ # turns 20170404131909 into "2017_04_04_131909"
59
+ def formatted_version
60
+ stringified = @version.to_s
61
+ return stringified unless stringified.length == 14
62
+ stringified.insert(4, "_").insert(7, "_").insert(10, "_")
63
+ end
64
+
65
+ def define_params
66
+ @version ? "version: #{formatted_version}" : ""
67
+ end
52
68
 
69
+ def header(stream)
53
70
  stream.puts <<HEADER
54
71
  # This file is auto-generated from the current state of the database. Instead
55
72
  # of editing this file, please use the migrations feature of Active Record to
56
73
  # incrementally modify your database, and then regenerate this schema definition.
57
74
  #
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).
75
+ # This file is the source Rails uses to define your schema when running `rails
76
+ # db:schema:load`. When creating a new database, `rails db:schema:load` tends to
77
+ # be faster and is potentially less error prone than running all of your
78
+ # migrations from scratch. Old migrations may fail to apply correctly if those
79
+ # migrations use external dependencies or application code.
63
80
  #
64
81
  # It's strongly recommended that you check this file into your version control system.
65
82
 
@@ -72,20 +89,12 @@ HEADER
72
89
  stream.puts "end"
73
90
  end
74
91
 
92
+ # extensions are only supported by PostgreSQL
75
93
  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
94
  end
86
95
 
87
96
  def tables(stream)
88
- sorted_tables = @connection.data_sources.sort - @connection.views
97
+ sorted_tables = @connection.tables.sort
89
98
 
90
99
  sorted_tables.each do |table_name|
91
100
  table(table_name, stream) unless ignored?(table_name)
@@ -102,6 +111,8 @@ HEADER
102
111
  def table(table, stream)
103
112
  columns = @connection.columns(table)
104
113
  begin
114
+ self.table_name = table
115
+
105
116
  tbl = StringIO.new
106
117
 
107
118
  # first dump primary key column
@@ -111,60 +122,36 @@ HEADER
111
122
 
112
123
  case pk
113
124
  when String
114
- tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id'
125
+ tbl.print ", primary_key: #{pk.inspect}" unless pk == "id"
115
126
  pkcol = columns.detect { |c| c.name == pk }
116
- pkcolspec = @connection.column_spec_for_primary_key(pkcol)
127
+ pkcolspec = column_spec_for_primary_key(pkcol)
117
128
  if pkcolspec.present?
118
- pkcolspec.each do |key, value|
119
- tbl.print ", #{key}: #{value}"
120
- end
129
+ tbl.print ", #{format_colspec(pkcolspec)}"
121
130
  end
122
131
  when Array
123
132
  tbl.print ", primary_key: #{pk.inspect}"
124
133
  else
125
134
  tbl.print ", id: false"
126
135
  end
127
- tbl.print ", force: :cascade"
128
136
 
129
137
  table_options = @connection.table_options(table)
130
138
  if table_options.present?
131
139
  tbl.print ", #{format_options(table_options)}"
132
140
  end
133
141
 
134
- tbl.puts " do |t|"
142
+ tbl.puts ", force: :cascade do |t|"
135
143
 
136
144
  # then dump all non-primary key columns
137
- column_specs = columns.map do |column|
145
+ columns.each do |column|
138
146
  raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
139
147
  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*$/, ''))
148
+ type, colspec = column_spec(column)
149
+ if type.is_a?(Symbol)
150
+ tbl.print " t.#{type} #{column.name.inspect}"
151
+ else
152
+ tbl.print " t.column #{column.name.inspect}, #{type.inspect}"
153
+ end
154
+ tbl.print ", #{format_colspec(colspec)}" if colspec.present?
168
155
  tbl.puts
169
156
  end
170
157
 
@@ -179,9 +166,9 @@ HEADER
179
166
  stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
180
167
  stream.puts "# #{e.message}"
181
168
  stream.puts
169
+ ensure
170
+ self.table_name = nil
182
171
  end
183
-
184
- stream
185
172
  end
186
173
 
187
174
  # Keep it for indexing materialized views
@@ -189,7 +176,7 @@ HEADER
189
176
  if (indexes = @connection.indexes(table)).any?
190
177
  add_index_statements = indexes.map do |index|
191
178
  table_name = remove_prefix_and_suffix(index.table).inspect
192
- " add_index #{([table_name]+index_parts(index)).join(', ')}"
179
+ " add_index #{([table_name] + index_parts(index)).join(', ')}"
193
180
  end
194
181
 
195
182
  stream.puts add_index_statements.sort.join("\n")
@@ -212,10 +199,11 @@ HEADER
212
199
  "name: #{index.name.inspect}",
213
200
  ]
214
201
  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?
202
+ index_parts << "length: #{format_index_parts(index.lengths)}" if index.lengths.present?
203
+ index_parts << "order: #{format_index_parts(index.orders)}" if index.orders.present?
204
+ index_parts << "opclass: #{format_index_parts(index.opclasses)}" if index.opclasses.present?
217
205
  index_parts << "where: #{index.where.inspect}" if index.where
218
- index_parts << "using: #{index.using.inspect}" if index.using
206
+ index_parts << "using: #{index.using.inspect}" if !@connection.default_index_type?(index)
219
207
  index_parts << "type: #{index.type.inspect}" if index.type
220
208
  index_parts << "comment: #{index.comment.inspect}" if index.comment
221
209
  index_parts
@@ -237,7 +225,7 @@ HEADER
237
225
  parts << "primary_key: #{foreign_key.primary_key.inspect}"
238
226
  end
239
227
 
240
- if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
228
+ if foreign_key.export_name_on_schema_dump?
241
229
  parts << "name: #{foreign_key.name.inspect}"
242
230
  end
243
231
 
@@ -251,12 +239,26 @@ HEADER
251
239
  end
252
240
  end
253
241
 
242
+ def format_colspec(colspec)
243
+ colspec.map { |key, value| "#{key}: #{value}" }.join(", ")
244
+ end
245
+
254
246
  def format_options(options)
255
247
  options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
256
248
  end
257
249
 
250
+ def format_index_parts(options)
251
+ if options.is_a?(Hash)
252
+ "{ #{format_options(options)} }"
253
+ else
254
+ options.inspect
255
+ end
256
+ end
257
+
258
258
  def remove_prefix_and_suffix(table)
259
- table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
259
+ prefix = Regexp.escape(@options[:table_name_prefix].to_s)
260
+ suffix = Regexp.escape(@options[:table_name_suffix].to_s)
261
+ table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
260
262
  end
261
263
 
262
264
  def ignored?(table_name)