activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  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 +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  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/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -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/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  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.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  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 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/extract"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters
3
7
  module PostgreSQL
@@ -13,13 +17,13 @@ module ActiveRecord
13
17
  end
14
18
 
15
19
  def run(records)
16
- nodes = records.reject { |row| @store.key? row['oid'].to_i }
17
- mapped, nodes = nodes.partition { |row| @store.key? row['typname'] }
18
- ranges, nodes = nodes.partition { |row| row['typtype'] == 'r'.freeze }
19
- enums, nodes = nodes.partition { |row| row['typtype'] == 'e'.freeze }
20
- domains, nodes = nodes.partition { |row| row['typtype'] == 'd'.freeze }
21
- arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in'.freeze }
22
- composites, nodes = nodes.partition { |row| row['typelem'].to_i != 0 }
20
+ nodes = records.reject { |row| @store.key? row["oid"].to_i }
21
+ mapped = nodes.extract! { |row| @store.key? row["typname"] }
22
+ ranges = nodes.extract! { |row| row["typtype"] == "r" }
23
+ enums = nodes.extract! { |row| row["typtype"] == "e" }
24
+ domains = nodes.extract! { |row| row["typtype"] == "d" }
25
+ arrays = nodes.extract! { |row| row["typinput"] == "array_in" }
26
+ composites = nodes.extract! { |row| row["typelem"].to_i != 0 }
23
27
 
24
28
  mapped.each { |row| register_mapped_type(row) }
25
29
  enums.each { |row| register_enum_type(row) }
@@ -29,10 +33,10 @@ module ActiveRecord
29
33
  composites.each { |row| register_composite_type(row) }
30
34
  end
31
35
 
32
- def query_conditions_for_initial_load(type_map)
33
- known_type_names = type_map.keys.map { |n| "'#{n}'" }
36
+ def query_conditions_for_initial_load
37
+ known_type_names = @store.keys.map { |n| "'#{n}'" }
34
38
  known_type_types = %w('r' 'e' 'd')
35
- <<-SQL % [known_type_names.join(", "), known_type_types.join(", ")]
39
+ <<~SQL % [known_type_names.join(", "), known_type_types.join(", ")]
36
40
  WHERE
37
41
  t.typname IN (%s)
38
42
  OR t.typtype IN (%s)
@@ -42,66 +46,66 @@ module ActiveRecord
42
46
  end
43
47
 
44
48
  private
45
- def register_mapped_type(row)
46
- alias_type row['oid'], row['typname']
47
- end
49
+ def register_mapped_type(row)
50
+ alias_type row["oid"], row["typname"]
51
+ end
48
52
 
49
- def register_enum_type(row)
50
- register row['oid'], OID::Enum.new
51
- end
53
+ def register_enum_type(row)
54
+ register row["oid"], OID::Enum.new
55
+ end
52
56
 
53
- def register_array_type(row)
54
- register_with_subtype(row['oid'], row['typelem'].to_i) do |subtype|
55
- OID::Array.new(subtype, row['typdelim'])
57
+ def register_array_type(row)
58
+ register_with_subtype(row["oid"], row["typelem"].to_i) do |subtype|
59
+ OID::Array.new(subtype, row["typdelim"])
60
+ end
56
61
  end
57
- end
58
62
 
59
- def register_range_type(row)
60
- register_with_subtype(row['oid'], row['rngsubtype'].to_i) do |subtype|
61
- OID::Range.new(subtype, row['typname'].to_sym)
63
+ def register_range_type(row)
64
+ register_with_subtype(row["oid"], row["rngsubtype"].to_i) do |subtype|
65
+ OID::Range.new(subtype, row["typname"].to_sym)
66
+ end
62
67
  end
63
- end
64
68
 
65
- def register_domain_type(row)
66
- if base_type = @store.lookup(row["typbasetype"].to_i)
67
- register row['oid'], base_type
68
- else
69
- warn "unknown base type (OID: #{row["typbasetype"]}) for domain #{row["typname"]}."
69
+ def register_domain_type(row)
70
+ if base_type = @store.lookup(row["typbasetype"].to_i)
71
+ register row["oid"], base_type
72
+ else
73
+ warn "unknown base type (OID: #{row["typbasetype"]}) for domain #{row["typname"]}."
74
+ end
70
75
  end
71
- end
72
76
 
73
- def register_composite_type(row)
74
- if subtype = @store.lookup(row['typelem'].to_i)
75
- register row['oid'], OID::Vector.new(row['typdelim'], subtype)
77
+ def register_composite_type(row)
78
+ if subtype = @store.lookup(row["typelem"].to_i)
79
+ register row["oid"], OID::Vector.new(row["typdelim"], subtype)
80
+ end
76
81
  end
77
- end
78
82
 
79
- def register(oid, oid_type = nil, &block)
80
- oid = assert_valid_registration(oid, oid_type || block)
81
- if block_given?
82
- @store.register_type(oid, &block)
83
- else
84
- @store.register_type(oid, oid_type)
83
+ def register(oid, oid_type = nil, &block)
84
+ oid = assert_valid_registration(oid, oid_type || block)
85
+ if block_given?
86
+ @store.register_type(oid, &block)
87
+ else
88
+ @store.register_type(oid, oid_type)
89
+ end
85
90
  end
86
- end
87
91
 
88
- def alias_type(oid, target)
89
- oid = assert_valid_registration(oid, target)
90
- @store.alias_type(oid, target)
91
- end
92
+ def alias_type(oid, target)
93
+ oid = assert_valid_registration(oid, target)
94
+ @store.alias_type(oid, target)
95
+ end
92
96
 
93
- def register_with_subtype(oid, target_oid)
94
- if @store.key?(target_oid)
95
- register(oid) do |_, *args|
96
- yield @store.lookup(target_oid, *args)
97
+ def register_with_subtype(oid, target_oid)
98
+ if @store.key?(target_oid)
99
+ register(oid) do |_, *args|
100
+ yield @store.lookup(target_oid, *args)
101
+ end
97
102
  end
98
103
  end
99
- end
100
104
 
101
- def assert_valid_registration(oid, oid_type)
102
- raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil?
103
- oid.to_i
104
- end
105
+ def assert_valid_registration(oid, oid_type)
106
+ raise ArgumentError, "can't register nil type for OID #{oid}" if oid_type.nil?
107
+ oid.to_i
108
+ end
105
109
  end
106
110
  end
107
111
  end
@@ -1,19 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module OID # :nodoc:
5
7
  class Uuid < Type::Value # :nodoc:
6
- ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x
8
+ ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
7
9
 
8
- alias_method :type_cast_for_database, :type_cast_from_database
10
+ alias :serialize :deserialize
9
11
 
10
12
  def type
11
13
  :uuid
12
14
  end
13
15
 
14
- def type_cast(value)
15
- value.to_s[ACCEPTABLE_UUID, 0]
16
+ def changed?(old_value, new_value, _new_value_before_type_cast)
17
+ old_value.class != new_value.class ||
18
+ new_value && old_value.casecmp(new_value) != 0
19
+ end
20
+
21
+ def changed_in_place?(raw_old_value, new_value)
22
+ raw_old_value.class != new_value.class ||
23
+ new_value && raw_old_value.casecmp(new_value) != 0
16
24
  end
25
+
26
+ private
27
+ def cast_value(value)
28
+ casted = value.to_s
29
+ casted if casted.match?(ACCEPTABLE_UUID)
30
+ end
17
31
  end
18
32
  end
19
33
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -16,7 +18,7 @@ module ActiveRecord
16
18
  # FIXME: this should probably split on +delim+ and use +subtype+
17
19
  # to cast the values. Unfortunately, the current Rails behavior
18
20
  # is to just return the string.
19
- def type_cast(value)
21
+ def cast(value)
20
22
  value
21
23
  end
22
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -7,7 +9,7 @@ module ActiveRecord
7
9
  :xml
8
10
  end
9
11
 
10
- def type_cast_for_database(value)
12
+ def serialize(value)
11
13
  return unless value
12
14
  Data.new(super)
13
15
  end
@@ -1,30 +1,30 @@
1
- require 'active_record/connection_adapters/postgresql/oid/infinity'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'active_record/connection_adapters/postgresql/oid/array'
4
- require 'active_record/connection_adapters/postgresql/oid/bit'
5
- require 'active_record/connection_adapters/postgresql/oid/bit_varying'
6
- require 'active_record/connection_adapters/postgresql/oid/bytea'
7
- require 'active_record/connection_adapters/postgresql/oid/cidr'
8
- require 'active_record/connection_adapters/postgresql/oid/date'
9
- require 'active_record/connection_adapters/postgresql/oid/date_time'
10
- require 'active_record/connection_adapters/postgresql/oid/decimal'
11
- require 'active_record/connection_adapters/postgresql/oid/enum'
12
- require 'active_record/connection_adapters/postgresql/oid/float'
13
- require 'active_record/connection_adapters/postgresql/oid/hstore'
14
- require 'active_record/connection_adapters/postgresql/oid/inet'
15
- require 'active_record/connection_adapters/postgresql/oid/integer'
16
- require 'active_record/connection_adapters/postgresql/oid/json'
17
- require 'active_record/connection_adapters/postgresql/oid/jsonb'
18
- require 'active_record/connection_adapters/postgresql/oid/money'
19
- require 'active_record/connection_adapters/postgresql/oid/point'
20
- require 'active_record/connection_adapters/postgresql/oid/range'
21
- require 'active_record/connection_adapters/postgresql/oid/specialized_string'
22
- require 'active_record/connection_adapters/postgresql/oid/time'
23
- require 'active_record/connection_adapters/postgresql/oid/uuid'
24
- require 'active_record/connection_adapters/postgresql/oid/vector'
25
- require 'active_record/connection_adapters/postgresql/oid/xml'
3
+ require "active_record/connection_adapters/postgresql/oid/array"
4
+ require "active_record/connection_adapters/postgresql/oid/bit"
5
+ require "active_record/connection_adapters/postgresql/oid/bit_varying"
6
+ require "active_record/connection_adapters/postgresql/oid/bytea"
7
+ require "active_record/connection_adapters/postgresql/oid/cidr"
8
+ require "active_record/connection_adapters/postgresql/oid/date"
9
+ require "active_record/connection_adapters/postgresql/oid/date_time"
10
+ require "active_record/connection_adapters/postgresql/oid/decimal"
11
+ require "active_record/connection_adapters/postgresql/oid/enum"
12
+ require "active_record/connection_adapters/postgresql/oid/hstore"
13
+ require "active_record/connection_adapters/postgresql/oid/inet"
14
+ require "active_record/connection_adapters/postgresql/oid/interval"
15
+ require "active_record/connection_adapters/postgresql/oid/jsonb"
16
+ require "active_record/connection_adapters/postgresql/oid/macaddr"
17
+ require "active_record/connection_adapters/postgresql/oid/money"
18
+ require "active_record/connection_adapters/postgresql/oid/oid"
19
+ require "active_record/connection_adapters/postgresql/oid/point"
20
+ require "active_record/connection_adapters/postgresql/oid/legacy_point"
21
+ require "active_record/connection_adapters/postgresql/oid/range"
22
+ require "active_record/connection_adapters/postgresql/oid/specialized_string"
23
+ require "active_record/connection_adapters/postgresql/oid/uuid"
24
+ require "active_record/connection_adapters/postgresql/oid/vector"
25
+ require "active_record/connection_adapters/postgresql/oid/xml"
26
26
 
27
- require 'active_record/connection_adapters/postgresql/oid/type_map_initializer'
27
+ require "active_record/connection_adapters/postgresql/oid/type_map_initializer"
28
28
 
29
29
  module ActiveRecord
30
30
  module ConnectionAdapters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -16,7 +18,7 @@ module ActiveRecord
16
18
 
17
19
  # Quotes strings for use in SQL input.
18
20
  def quote_string(s) #:nodoc:
19
- @connection.escape(s)
21
+ PG::Connection.escape(s)
20
22
  end
21
23
 
22
24
  # Checks the following cases:
@@ -27,8 +29,13 @@ module ActiveRecord
27
29
  # - schema_name."table.name"
28
30
  # - "schema.name".table_name
29
31
  # - "schema.name"."table.name"
30
- def quote_table_name(name)
31
- Utils.extract_schema_qualified_name(name.to_s).quoted
32
+ def quote_table_name(name) # :nodoc:
33
+ self.class.quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted.freeze
34
+ end
35
+
36
+ # Quotes schema names for use in SQL queries.
37
+ def quote_schema_name(name)
38
+ PG::Connection.quote_ident(name)
32
39
  end
33
40
 
34
41
  def quote_table_name_for_assignment(table, attr)
@@ -36,72 +43,162 @@ module ActiveRecord
36
43
  end
37
44
 
38
45
  # Quotes column names for use in SQL queries.
39
- def quote_column_name(name) #:nodoc:
40
- PGconn.quote_ident(name.to_s)
46
+ def quote_column_name(name) # :nodoc:
47
+ self.class.quoted_column_names[name] ||= PG::Connection.quote_ident(super).freeze
41
48
  end
42
49
 
43
- # Quote date/time values for use in SQL input. Includes microseconds
44
- # if the value is a Time responding to usec.
50
+ # Quote date/time values for use in SQL input.
45
51
  def quoted_date(value) #:nodoc:
46
- result = super
47
- if value.acts_like?(:time) && value.respond_to?(:usec)
48
- result = "#{result}.#{sprintf("%06d", value.usec)}"
49
- end
50
-
51
52
  if value.year <= 0
52
53
  bce_year = format("%04d", -value.year + 1)
53
- result = result.sub(/^-?\d+/, bce_year) + " BC"
54
+ super.sub(/^-?\d+/, bce_year) + " BC"
55
+ else
56
+ super
54
57
  end
55
- result
56
58
  end
57
59
 
58
- # Does not quote function default values for UUID columns
59
- def quote_default_value(value, column) #:nodoc:
60
- if column.type == :uuid && value =~ /\(\)/
61
- value
60
+ def quoted_binary(value) # :nodoc:
61
+ "'#{escape_bytea(value.to_s)}'"
62
+ end
63
+
64
+ def quote_default_expression(value, column) # :nodoc:
65
+ if value.is_a?(Proc)
66
+ value.call
67
+ elsif column.type == :uuid && value.is_a?(String) && /\(\)/.match?(value)
68
+ value # Does not quote function default values for UUID columns
69
+ elsif column.respond_to?(:array?)
70
+ type = lookup_cast_type_from_column(column)
71
+ quote(type.serialize(value))
62
72
  else
63
- quote(value, column)
73
+ super
64
74
  end
65
75
  end
66
76
 
77
+ def lookup_cast_type_from_column(column) # :nodoc:
78
+ type_map.lookup(column.oid, column.fmod, column.sql_type)
79
+ end
80
+
81
+ def column_name_matcher
82
+ COLUMN_NAME
83
+ end
84
+
85
+ def column_name_with_order_matcher
86
+ COLUMN_NAME_WITH_ORDER
87
+ end
88
+
89
+ COLUMN_NAME = /
90
+ \A
91
+ (
92
+ (?:
93
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
94
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
95
+ )
96
+ (?:(?:\s+AS)?\s+(?:\w+|"\w+"))?
97
+ )
98
+ (?:\s*,\s*\g<1>)*
99
+ \z
100
+ /ix
101
+
102
+ COLUMN_NAME_WITH_ORDER = /
103
+ \A
104
+ (
105
+ (?:
106
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
107
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
108
+ )
109
+ (?:\s+ASC|\s+DESC)?
110
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
111
+ )
112
+ (?:\s*,\s*\g<1>)*
113
+ \z
114
+ /ix
115
+
116
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
117
+
67
118
  private
119
+ def lookup_cast_type(sql_type)
120
+ super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
121
+ end
68
122
 
69
- def _quote(value)
70
- case value
71
- when Type::Binary::Data
72
- "'#{escape_bytea(value.to_s)}'"
73
- when OID::Xml::Data
74
- "xml '#{quote_string(value.to_s)}'"
75
- when OID::Bit::Data
76
- if value.binary?
77
- "B'#{value}'"
78
- elsif value.hex?
79
- "X'#{value}'"
123
+ def _quote(value)
124
+ case value
125
+ when OID::Xml::Data
126
+ "xml '#{quote_string(value.to_s)}'"
127
+ when OID::Bit::Data
128
+ if value.binary?
129
+ "B'#{value}'"
130
+ elsif value.hex?
131
+ "X'#{value}'"
132
+ end
133
+ when Numeric
134
+ if value.finite?
135
+ super
136
+ else
137
+ "'#{value}'"
138
+ end
139
+ when OID::Array::Data
140
+ _quote(encode_array(value))
141
+ when Range
142
+ _quote(encode_range(value))
143
+ else
144
+ super
80
145
  end
81
- when Float
82
- if value.infinite? || value.nan?
83
- "'#{value}'"
146
+ end
147
+
148
+ def _type_cast(value)
149
+ case value
150
+ when Type::Binary::Data
151
+ # Return a bind param hash with format as binary.
152
+ # See https://deveiate.org/code/pg/PG/Connection.html#method-i-exec_prepared-doc
153
+ # for more information
154
+ { value: value.to_s, format: 1 }
155
+ when OID::Xml::Data, OID::Bit::Data
156
+ value.to_s
157
+ when OID::Array::Data
158
+ encode_array(value)
159
+ when Range
160
+ encode_range(value)
84
161
  else
85
162
  super
86
163
  end
87
- else
88
- super
89
164
  end
90
- end
91
165
 
92
- def _type_cast(value)
93
- case value
94
- when Type::Binary::Data
95
- # Return a bind param hash with format as binary.
96
- # See http://deveiate.org/code/pg/PGconn.html#method-i-exec_prepared-doc
97
- # for more information
98
- { value: value.to_s, format: 1 }
99
- when OID::Xml::Data, OID::Bit::Data
100
- value.to_s
101
- else
102
- super
166
+ def encode_array(array_data)
167
+ encoder = array_data.encoder
168
+ values = type_cast_array(array_data.values)
169
+
170
+ result = encoder.encode(values)
171
+ if encoding = determine_encoding_of_strings_in_array(values)
172
+ result.force_encoding(encoding)
173
+ end
174
+ result
175
+ end
176
+
177
+ def encode_range(range)
178
+ "[#{type_cast_range_value(range.begin)},#{type_cast_range_value(range.end)}#{range.exclude_end? ? ')' : ']'}"
179
+ end
180
+
181
+ def determine_encoding_of_strings_in_array(value)
182
+ case value
183
+ when ::Array then determine_encoding_of_strings_in_array(value.first)
184
+ when ::String then value.encoding
185
+ end
186
+ end
187
+
188
+ def type_cast_array(values)
189
+ case values
190
+ when ::Array then values.map { |item| type_cast_array(item) }
191
+ else _type_cast(values)
192
+ end
193
+ end
194
+
195
+ def type_cast_range_value(value)
196
+ infinity?(value) ? "" : type_cast(value)
197
+ end
198
+
199
+ def infinity?(value)
200
+ value.respond_to?(:infinite?) && value.infinite?
103
201
  end
104
- end
105
202
  end
106
203
  end
107
204
  end
@@ -1,27 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module ReferentialIntegrity # :nodoc:
5
- def supports_disable_referential_integrity? # :nodoc:
6
- true
7
- end
8
-
9
7
  def disable_referential_integrity # :nodoc:
10
- if supports_disable_referential_integrity?
11
- begin
8
+ original_exception = nil
9
+
10
+ begin
11
+ transaction(requires_new: true) do
12
12
  execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
13
- rescue
14
- execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER USER" }.join(";"))
15
13
  end
14
+ rescue ActiveRecord::ActiveRecordError => e
15
+ original_exception = e
16
+ end
17
+
18
+ begin
19
+ yield
20
+ rescue ActiveRecord::InvalidForeignKey => e
21
+ warn <<-WARNING
22
+ WARNING: Rails was not able to disable referential integrity.
23
+
24
+ This is most likely caused due to missing permissions.
25
+ Rails needs superuser privileges to disable referential integrity.
26
+
27
+ cause: #{original_exception&.message}
28
+
29
+ WARNING
30
+ raise e
16
31
  end
17
- yield
18
- ensure
19
- if supports_disable_referential_integrity?
20
- begin
32
+
33
+ begin
34
+ transaction(requires_new: true) do
21
35
  execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
22
- rescue
23
- execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER USER" }.join(";"))
24
36
  end
37
+ rescue ActiveRecord::ActiveRecordError
25
38
  end
26
39
  end
27
40
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ module PostgreSQL
6
+ class SchemaCreation < SchemaCreation # :nodoc:
7
+ private
8
+ def visit_AlterTable(o)
9
+ super << o.constraint_validations.map { |fk| visit_ValidateConstraint fk }.join(" ")
10
+ end
11
+
12
+ def visit_AddForeignKey(o)
13
+ super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
14
+ end
15
+
16
+ def visit_CheckConstraintDefinition(o)
17
+ super.dup.tap { |sql| sql << " NOT VALID" unless o.validate? }
18
+ end
19
+
20
+ def visit_ValidateConstraint(name)
21
+ "VALIDATE CONSTRAINT #{quote_column_name(name)}"
22
+ end
23
+
24
+ def visit_ChangeColumnDefinition(o)
25
+ column = o.column
26
+ column.sql_type = type_to_sql(column.type, **column.options)
27
+ quoted_column_name = quote_column_name(o.name)
28
+
29
+ change_column_sql = +"ALTER COLUMN #{quoted_column_name} TYPE #{column.sql_type}"
30
+
31
+ options = column_options(column)
32
+
33
+ if options[:collation]
34
+ change_column_sql << " COLLATE \"#{options[:collation]}\""
35
+ end
36
+
37
+ if options[:using]
38
+ change_column_sql << " USING #{options[:using]}"
39
+ elsif options[:cast_as]
40
+ cast_as_type = type_to_sql(options[:cast_as], **options)
41
+ change_column_sql << " USING CAST(#{quoted_column_name} AS #{cast_as_type})"
42
+ end
43
+
44
+ if options.key?(:default)
45
+ if options[:default].nil?
46
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} DROP DEFAULT"
47
+ else
48
+ quoted_default = quote_default_expression(options[:default], column)
49
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} SET DEFAULT #{quoted_default}"
50
+ end
51
+ end
52
+
53
+ if options.key?(:null)
54
+ change_column_sql << ", ALTER COLUMN #{quoted_column_name} #{options[:null] ? 'DROP' : 'SET'} NOT NULL"
55
+ end
56
+
57
+ change_column_sql
58
+ end
59
+
60
+ def add_column_options!(sql, options)
61
+ if options[:collation]
62
+ sql << " COLLATE \"#{options[:collation]}\""
63
+ end
64
+ super
65
+ end
66
+
67
+ # Returns any SQL string to go between CREATE and TABLE. May be nil.
68
+ def table_modifier_in_create(o)
69
+ # A table cannot be both TEMPORARY and UNLOGGED, since all TEMPORARY
70
+ # tables are already UNLOGGED.
71
+ if o.temporary
72
+ " TEMPORARY"
73
+ elsif o.unlogged
74
+ " UNLOGGED"
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end