ibm_db 5.6.1 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
@@ -8,34 +8,43 @@ class SchemaDumperTest < ActiveRecord::TestCase
8
8
  self.use_transactional_tests = false
9
9
 
10
10
  setup do
11
- ActiveRecord::SchemaMigration.create_table
12
- end
11
+ @schema_migration = ActiveRecord::Base.connection_pool.schema_migration
12
+ @schema_migration.create_table
13
13
 
14
- def standard_dump
15
- @@standard_dump ||= perform_schema_dump
14
+ ARUnit2Model.connection_pool.schema_migration.create_table
16
15
  end
17
16
 
18
- def perform_schema_dump
19
- dump_all_table_schema []
17
+ def standard_dump
18
+ @@standard_dump ||= dump_all_table_schema
20
19
  end
21
20
 
22
21
  def test_dump_schema_information_with_empty_versions
23
- ActiveRecord::SchemaMigration.delete_all
24
- schema_info = ActiveRecord::Base.connection.dump_schema_information
22
+ @schema_migration.delete_all_versions
23
+ schema_info = ActiveRecord::Base.lease_connection.dump_schema_information
25
24
  assert_no_match(/INSERT INTO/, schema_info)
26
25
  end
27
26
 
28
- def test_dump_schema_information_outputs_lexically_ordered_versions
27
+ def test_dump_schema_information_outputs_lexically_reverse_ordered_versions_regardless_of_database_order
29
28
  versions = %w{ 20100101010101 20100201010101 20100301010101 }
30
- versions.reverse_each do |v|
31
- ActiveRecord::SchemaMigration.create!(version: v)
32
- end
33
-
34
- schema_info = ActiveRecord::Base.connection.dump_schema_information
35
- assert_match(/20100201010101.*20100301010101/m, schema_info)
36
- assert_includes schema_info, "20100101010101"
29
+ versions.shuffle.each do |v|
30
+ @schema_migration.create_version(v)
31
+ end
32
+
33
+ schema_info = ActiveRecord::Base.lease_connection.dump_schema_information
34
+ expected = <<~STR
35
+ INSERT INTO #{quote_table_name("schema_migrations")} (version) VALUES
36
+ ('20100301010101'),
37
+ ('20100201010101'),
38
+ ('20100101010101');
39
+ STR
40
+ assert_equal expected.strip, schema_info
37
41
  ensure
38
- ActiveRecord::SchemaMigration.delete_all
42
+ @schema_migration.delete_all_versions
43
+ end
44
+
45
+ def test_schema_dump_include_migration_version
46
+ output = standard_dump
47
+ assert_match %r{ActiveRecord::Schema\[#{ActiveRecord::Migration.current_version}\]\.define}, output
39
48
  end
40
49
 
41
50
  def test_schema_dump
@@ -59,6 +68,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
59
68
 
60
69
  def test_schema_dump_includes_camelcase_table_name
61
70
  output = standard_dump
71
+ skip "CamelCase table not supported on IBM_DBAdapter" if current_adapter?(:IBM_DBAdapter)
62
72
  assert_match %r{create_table "CamelCase"}, output
63
73
  end
64
74
 
@@ -113,10 +123,10 @@ class SchemaDumperTest < ActiveRecord::TestCase
113
123
  assert_match %r{c_int_1.*limit: 2}, output
114
124
  assert_match %r{c_int_2.*limit: 2}, output
115
125
 
116
- # int 3 is 4 bytes in postgresql
126
+ # int 3 is 4 bytes in PostgreSQL
117
127
  assert_match %r{"c_int_3"(?!.*limit)}, output
118
128
  assert_match %r{"c_int_4"(?!.*limit)}, output
119
- elsif current_adapter?(:Mysql2Adapter)
129
+ elsif current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
120
130
  assert_match %r{c_int_1.*limit: 1}, output
121
131
  assert_match %r{c_int_2.*limit: 2}, output
122
132
  assert_match %r{c_int_3.*limit: 3}, output
@@ -129,11 +139,16 @@ class SchemaDumperTest < ActiveRecord::TestCase
129
139
  assert_match %r{c_int_4.*limit: 4}, output
130
140
  end
131
141
 
132
- if current_adapter?(:SQLite3Adapter, :OracleAdapter)
142
+ if current_adapter?(:SQLite3Adapter)
133
143
  assert_match %r{c_int_5.*limit: 5}, output
134
144
  assert_match %r{c_int_6.*limit: 6}, output
135
145
  assert_match %r{c_int_7.*limit: 7}, output
136
146
  assert_match %r{c_int_8.*limit: 8}, output
147
+ elsif current_adapter?(:IBM_DBAdapter)
148
+ assert_match %r{t\.integer\s+"c_int_5"$}, output
149
+ assert_match %r{t\.integer\s+"c_int_6"$}, output
150
+ assert_match %r{t\.integer\s+"c_int_7"$}, output
151
+ assert_match %r{t\.integer\s+"c_int_8"$}, output
137
152
  else
138
153
  assert_match %r{t\.bigint\s+"c_int_5"$}, output
139
154
  assert_match %r{t\.bigint\s+"c_int_6"$}, output
@@ -143,7 +158,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
143
158
  end
144
159
 
145
160
  def test_schema_dump_with_string_ignored_table
146
- output = dump_all_table_schema(["accounts"])
161
+ output = dump_table_schema("authors")
147
162
  assert_no_match %r{create_table "accounts"}, output
148
163
  assert_match %r{create_table "authors"}, output
149
164
  assert_no_match %r{create_table "schema_migrations"}, output
@@ -151,22 +166,22 @@ class SchemaDumperTest < ActiveRecord::TestCase
151
166
  end
152
167
 
153
168
  def test_schema_dump_with_regexp_ignored_table
154
- output = dump_all_table_schema([/^account/])
155
- assert_no_match %r{create_table "accounts"}, output
156
- assert_match %r{create_table "authors"}, output
169
+ output = dump_all_table_schema([/^courses/], pool: ARUnit2Model.connection_pool)
170
+ assert_no_match %r{create_table "courses"}, output
171
+ assert_match %r{create_table "colleges"}, output
157
172
  assert_no_match %r{create_table "schema_migrations"}, output
158
173
  assert_no_match %r{create_table "ar_internal_metadata"}, output
159
174
  end
160
175
 
161
176
  def test_schema_dumps_index_columns_in_right_order
162
177
  index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_index/).first.strip
163
- if current_adapter?(:Mysql2Adapter)
164
- if ActiveRecord::Base.connection.supports_index_sort_order?
178
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
179
+ if ActiveRecord::Base.lease_connection.supports_index_sort_order?
165
180
  assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", length: { type: 10 }, order: { rating: :desc }', index_definition
166
181
  else
167
182
  assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", length: { type: 10 }', index_definition
168
183
  end
169
- elsif ActiveRecord::Base.connection.supports_index_sort_order?
184
+ elsif ActiveRecord::Base.lease_connection.supports_index_sort_order?
170
185
  assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index", order: { rating: :desc }', index_definition
171
186
  else
172
187
  assert_equal 't.index ["firm_id", "type", "rating"], name: "company_index"', index_definition
@@ -175,16 +190,31 @@ class SchemaDumperTest < ActiveRecord::TestCase
175
190
 
176
191
  def test_schema_dumps_partial_indices
177
192
  index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_partial_index/).first.strip
178
- if ActiveRecord::Base.connection.supports_partial_index?
193
+ if ActiveRecord::Base.lease_connection.supports_partial_index?
179
194
  assert_equal 't.index ["firm_id", "type"], name: "company_partial_index", where: "(rating > 10)"', index_definition
180
195
  else
181
196
  assert_equal 't.index ["firm_id", "type"], name: "company_partial_index"', index_definition
182
197
  end
183
198
  end
184
199
 
200
+ def test_schema_dumps_nulls_not_distinct
201
+ index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_nulls_not_distinct/).first.strip
202
+ if supports_nulls_not_distinct?
203
+ assert_equal 't.index ["firm_id"], name: "company_nulls_not_distinct", nulls_not_distinct: true', index_definition
204
+ else
205
+ assert_equal 't.index ["firm_id"], name: "company_nulls_not_distinct"', index_definition
206
+ end
207
+ end
208
+
185
209
  def test_schema_dumps_index_sort_order
186
- index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*_name_and_rating/).first.strip
187
- if ActiveRecord::Base.connection.supports_index_sort_order?
210
+ index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*_name_and_rating/).first
211
+ if current_adapter?(:IBM_DBAdapter)
212
+ assert_not_nil index_definition
213
+ return
214
+ end
215
+
216
+ index_definition = index_definition.strip
217
+ if ActiveRecord::Base.lease_connection.supports_index_sort_order?
188
218
  assert_equal 't.index ["name", "rating"], name: "index_companies_on_name_and_rating", order: :desc', index_definition
189
219
  else
190
220
  assert_equal 't.index ["name", "rating"], name: "index_companies_on_name_and_rating"', index_definition
@@ -193,17 +223,18 @@ class SchemaDumperTest < ActiveRecord::TestCase
193
223
 
194
224
  def test_schema_dumps_index_length
195
225
  index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*_name_and_description/).first.strip
196
- if current_adapter?(:Mysql2Adapter)
226
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
197
227
  assert_equal 't.index ["name", "description"], name: "index_companies_on_name_and_description", length: 10', index_definition
198
228
  else
199
229
  assert_equal 't.index ["name", "description"], name: "index_companies_on_name_and_description"', index_definition
200
230
  end
201
231
  end
202
232
 
203
- if ActiveRecord::Base.connection.supports_check_constraints?
233
+ if ActiveRecord::Base.lease_connection.supports_check_constraints? && !current_adapter?(:IBM_DBAdapter)
204
234
  def test_schema_dumps_check_constraints
235
+ skip "Not supported on IBM_DBAdapter" if current_adapter?(:IBM_DBAdapter)
205
236
  constraint_definition = dump_table_schema("products").split(/\n/).grep(/t.check_constraint.*products_price_check/).first.strip
206
- if current_adapter?(:Mysql2Adapter)
237
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
207
238
  assert_equal 't.check_constraint "`price` > `discounted_price`", name: "products_price_check"', constraint_definition
208
239
  else
209
240
  assert_equal 't.check_constraint "price > discounted_price", name: "products_price_check"', constraint_definition
@@ -211,6 +242,44 @@ class SchemaDumperTest < ActiveRecord::TestCase
211
242
  end
212
243
  end
213
244
 
245
+ if ActiveRecord::Base.lease_connection.supports_exclusion_constraints? && !current_adapter?(:IBM_DBAdapter)
246
+ def test_schema_dumps_exclusion_constraints
247
+ skip "Not supported on IBM_DBAdapter" if current_adapter?(:IBM_DBAdapter)
248
+ output = dump_table_schema("test_exclusion_constraints")
249
+ constraint_definitions = output.split(/\n/).grep(/test_exclusion_constraints_.*_overlap/)
250
+
251
+ assert_equal 3, constraint_definitions.size
252
+ assert_match 't.exclusion_constraint "daterange(start_date, end_date) WITH &&", where: "(start_date IS NOT NULL) AND (end_date IS NOT NULL)", using: :gist, name: "test_exclusion_constraints_date_overlap"', output
253
+ assert_match 't.exclusion_constraint "daterange(valid_from, valid_to) WITH &&", where: "(valid_from IS NOT NULL) AND (valid_to IS NOT NULL)", using: :gist, deferrable: :immediate, name: "test_exclusion_constraints_valid_overlap"', output
254
+ assert_match 't.exclusion_constraint "daterange(transaction_from, transaction_to) WITH &&", where: "(transaction_from IS NOT NULL) AND (transaction_to IS NOT NULL)", using: :gist, deferrable: :deferred, name: "test_exclusion_constraints_transaction_overlap"', output
255
+ end
256
+ end
257
+
258
+ if ActiveRecord::Base.lease_connection.supports_unique_constraints?
259
+ def test_schema_dumps_unique_constraints
260
+ output = dump_table_schema("test_unique_constraints")
261
+ constraint_definitions = output.split(/\n/).grep(/t\.unique_constraint/)
262
+
263
+ if current_adapter?(:IBM_DBAdapter)
264
+ assert_equal 0, constraint_definitions.size
265
+ return
266
+ end
267
+
268
+ assert_equal 4, constraint_definitions.size
269
+ assert_match 't.unique_constraint ["position_1"], name: "test_unique_constraints_position_deferrable_false"', output
270
+ assert_match 't.unique_constraint ["position_2"], deferrable: :immediate, name: "test_unique_constraints_position_deferrable_immediate"', output
271
+ assert_match 't.unique_constraint ["position_3"], deferrable: :deferred, name: "test_unique_constraints_position_deferrable_deferred"', output
272
+ assert_match 't.unique_constraint ["position_4"], nulls_not_distinct: true, name: "test_unique_constraints_position_nulls_not_distinct"', output
273
+ end
274
+
275
+ def test_schema_does_not_dump_unique_constraints_as_indexes
276
+ output = dump_table_schema("test_unique_constraints")
277
+ unique_index_definitions = output.split(/\n/).grep(/t\.index.*unique: true/)
278
+
279
+ assert_equal 0, unique_index_definitions.size
280
+ end
281
+ end
282
+
214
283
  def test_schema_dump_should_honor_nonstandard_primary_keys
215
284
  output = standard_dump
216
285
  match = output.match(%r{create_table "movies"(.*)do})
@@ -238,14 +307,20 @@ class SchemaDumperTest < ActiveRecord::TestCase
238
307
  assert_match %r{t\.float\s+"temperature"}, output
239
308
  end
240
309
 
241
- if ActiveRecord::Base.connection.supports_expression_index?
310
+ def test_schema_dump_aliased_types
311
+ output = standard_dump
312
+ assert_match %r{t\.binary\s+"blob_data"$}, output
313
+ assert_match %r{t\.decimal\s+"numeric_number"}, output
314
+ end
315
+
316
+ if ActiveRecord::Base.lease_connection.supports_expression_index?
242
317
  def test_schema_dump_expression_indices
243
318
  index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_expression_index/).first.strip
244
319
  index_definition.sub!(/, name: "company_expression_index"\z/, "")
245
320
 
246
321
  if current_adapter?(:PostgreSQLAdapter)
247
322
  assert_match %r{CASE.+lower\(\(name\)::text\).+END\) DESC"\z}i, index_definition
248
- elsif current_adapter?(:Mysql2Adapter)
323
+ elsif current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
249
324
  assert_match %r{CASE.+lower\(`name`\).+END\) DESC"\z}i, index_definition
250
325
  elsif current_adapter?(:SQLite3Adapter)
251
326
  assert_match %r{CASE.+lower\(name\).+END\) DESC"\z}i, index_definition
@@ -253,9 +328,18 @@ class SchemaDumperTest < ActiveRecord::TestCase
253
328
  assert false
254
329
  end
255
330
  end
331
+
332
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
333
+ def test_schema_dump_expression_indices_escaping
334
+ index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*full_name_index/).first.strip
335
+ index_definition.sub!(/, name: "full_name_index"\z/, "")
336
+
337
+ assert_match %r{concat_ws\(`firm_name`,`name`,_utf8mb4' '\)\)"\z}i, index_definition
338
+ end
339
+ end
256
340
  end
257
341
 
258
- if current_adapter?(:Mysql2Adapter)
342
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
259
343
  def test_schema_dump_includes_length_for_mysql_binary_fields
260
344
  output = dump_table_schema "binary_fields"
261
345
  assert_match %r{t\.binary\s+"var_binary",\s+limit: 255$}, output
@@ -305,7 +389,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
305
389
 
306
390
  def test_schema_dump_includes_limit_on_array_type
307
391
  output = dump_table_schema "bigint_array"
308
- assert_match %r{t\.bigint\s+"big_int_data_points\",\s+array: true}, output
392
+ assert_match %r{t\.bigint\s+"big_int_data_points",\s+array: true}, output
309
393
  end
310
394
 
311
395
  def test_schema_dump_allows_array_of_decimal_defaults
@@ -325,40 +409,68 @@ class SchemaDumperTest < ActiveRecord::TestCase
325
409
  end
326
410
 
327
411
  def test_schema_dump_includes_extensions
328
- connection = ActiveRecord::Base.connection
412
+ connection = ActiveRecord::Base.lease_connection
329
413
 
330
414
  connection.stub(:extensions, ["hstore"]) do
331
- output = perform_schema_dump
415
+ output = dump_all_table_schema(/./)
332
416
  assert_match "# These are extensions that must be enabled", output
333
417
  assert_match %r{enable_extension "hstore"}, output
334
418
  end
335
419
 
336
420
  connection.stub(:extensions, []) do
337
- output = perform_schema_dump
421
+ output = dump_all_table_schema(/./)
338
422
  assert_no_match "# These are extensions that must be enabled", output
339
423
  assert_no_match %r{enable_extension}, output
340
424
  end
341
425
  end
342
426
 
343
427
  def test_schema_dump_includes_extensions_in_alphabetic_order
344
- connection = ActiveRecord::Base.connection
428
+ connection = ActiveRecord::Base.lease_connection
345
429
 
346
430
  connection.stub(:extensions, ["hstore", "uuid-ossp", "xml2"]) do
347
- output = perform_schema_dump
431
+ output = dump_all_table_schema(/./)
348
432
  enabled_extensions = output.scan(%r{enable_extension "(.+)"}).flatten
349
433
  assert_equal ["hstore", "uuid-ossp", "xml2"], enabled_extensions
350
434
  end
351
435
 
352
436
  connection.stub(:extensions, ["uuid-ossp", "xml2", "hstore"]) do
353
- output = perform_schema_dump
437
+ output = dump_all_table_schema(/./)
354
438
  enabled_extensions = output.scan(%r{enable_extension "(.+)"}).flatten
355
439
  assert_equal ["hstore", "uuid-ossp", "xml2"], enabled_extensions
356
440
  end
357
441
  end
442
+
443
+ def test_schema_dump_include_limit_for_float4_field
444
+ output = dump_table_schema "numeric_data"
445
+ assert_match %r{t\.float\s+"temperature_with_limit",\s+limit: 24$}, output
446
+ end
447
+
448
+ def test_schema_dump_keeps_enum_intact_if_it_contains_comma
449
+ original, $stdout = $stdout, StringIO.new
450
+
451
+ migration = Class.new(ActiveRecord::Migration::Current) do
452
+ def up
453
+ create_enum "enum_with_comma", ["value1", "value,2", "value3"]
454
+ end
455
+
456
+ def down
457
+ drop_enum "enum_with_comma"
458
+ end
459
+ end
460
+
461
+ migration.migrate(:up)
462
+ output = dump_all_table_schema
463
+
464
+ assert_includes output, 'create_enum "enum_with_comma", ["value1", "value,2", "value3"]', output
465
+ ensure
466
+ migration.migrate(:down)
467
+ $stdout = original
468
+ end
358
469
  end
359
470
 
360
471
  def test_schema_dump_keeps_large_precision_integer_columns_as_decimal
361
472
  output = standard_dump
473
+
362
474
  # Oracle supports precision up to 38 and it identifies decimals with scale 0 as integers
363
475
  if current_adapter?(:OracleAdapter)
364
476
  assert_match %r{t\.integer\s+"atoms_in_universe",\s+precision: 38}, output
@@ -382,7 +494,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
382
494
  assert_match %r{create_table "string_key_objects", id: false}, output
383
495
  end
384
496
 
385
- if ActiveRecord::Base.connection.supports_foreign_keys?
497
+ if ActiveRecord::Base.lease_connection.supports_foreign_keys?
386
498
  def test_foreign_keys_are_dumped_at_the_bottom_to_circumvent_dependency_issues
387
499
  output = standard_dump
388
500
  assert_match(/^\s+add_foreign_key "fk_test_has_fk"[^\n]+\n\s+add_foreign_key "lessons_students"/, output)
@@ -392,41 +504,64 @@ class SchemaDumperTest < ActiveRecord::TestCase
392
504
  output = dump_table_schema "authors"
393
505
  assert_equal ["authors"], output.scan(/^\s*add_foreign_key "([^"]+)".+$/).flatten
394
506
  end
507
+
508
+ unless in_memory_db? || current_adapter?(:IBM_DBAdapter)
509
+ def test_do_not_dump_foreign_keys_when_bypassed_by_config
510
+ ActiveRecord::Base.establish_connection(
511
+ {
512
+ adapter: "sqlite3",
513
+ database: "test/storage/test.sqlite3",
514
+ foreign_keys: false,
515
+ }
516
+ )
517
+
518
+ output = dump_all_table_schema
519
+ assert_no_match(/^\s+add_foreign_key "fk_test_has_fk"[^\n]+\n\s+add_foreign_key "lessons_students"/, output)
520
+ ensure
521
+ ActiveRecord::Base.establish_connection(:arunit)
522
+ end
523
+ end
395
524
  end
396
525
 
397
- class CreateDogMigration < ActiveRecord::Migration::Current
526
+ class CreateCatMigration < ActiveRecord::Migration::Current
398
527
  def up
399
- create_table("dog_owners") do |t|
528
+ create_table("cat_owners") do |t|
400
529
  end
401
530
 
402
- create_table("dogs") do |t|
531
+ create_table("cats") do |t|
403
532
  t.column :name, :string
404
533
  t.references :owner
405
534
  t.index [:name]
406
- t.foreign_key :dog_owners, column: "owner_id"
535
+ t.foreign_key :cat_owners, column: "owner_id"
407
536
  end
408
537
  end
409
538
  def down
410
- drop_table("dogs")
411
- drop_table("dog_owners")
539
+ drop_table("cats")
540
+ drop_table("cat_owners")
412
541
  end
413
542
  end
414
543
 
415
544
  def test_schema_dump_with_table_name_prefix_and_suffix
545
+ ActiveRecord::Base.establish_connection(:arunit2) unless in_memory_db?
416
546
  original, $stdout = $stdout, StringIO.new
417
547
  ActiveRecord::Base.table_name_prefix = "foo_"
418
548
  ActiveRecord::Base.table_name_suffix = "_bar"
419
549
 
420
- migration = CreateDogMigration.new
550
+ migration = CreateCatMigration.new
421
551
  migration.migrate(:up)
422
552
 
423
- output = perform_schema_dump
553
+ output = dump_table_schema("foo_cat_owners_bar", "foo_cats_bar")
554
+
555
+ assert_match %r{create_table "cat_owners"}, output
556
+ assert_match %r{create_table "cats"}, output
557
+ assert_match %r{t\.index \["name"\], name: "index_foo_cats_bar_on_name"}, output
424
558
  assert_no_match %r{create_table "foo_.+_bar"}, output
425
559
  assert_no_match %r{add_index "foo_.+_bar"}, output
426
560
  assert_no_match %r{create_table "schema_migrations"}, output
427
561
  assert_no_match %r{create_table "ar_internal_metadata"}, output
428
562
 
429
- if ActiveRecord::Base.connection.supports_foreign_keys?
563
+ if ActiveRecord::Base.lease_connection.supports_foreign_keys?
564
+ assert_match %r{add_foreign_key "cats", "cat_owners", column: "owner_id"}, output
430
565
  assert_no_match %r{add_foreign_key "foo_.+_bar"}, output
431
566
  assert_no_match %r{add_foreign_key "[^"]+", "foo_.+_bar"}, output
432
567
  end
@@ -435,23 +570,30 @@ class SchemaDumperTest < ActiveRecord::TestCase
435
570
 
436
571
  ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = ""
437
572
  $stdout = original
573
+ ActiveRecord::Base.establish_connection(:arunit)
438
574
  end
439
575
 
440
576
  def test_schema_dump_with_table_name_prefix_and_suffix_regexp_escape
577
+ ActiveRecord::Base.establish_connection(:arunit2) unless in_memory_db?
441
578
  original, $stdout = $stdout, StringIO.new
442
579
  ActiveRecord::Base.table_name_prefix = "foo$"
443
580
  ActiveRecord::Base.table_name_suffix = "$bar"
444
581
 
445
- migration = CreateDogMigration.new
582
+ migration = CreateCatMigration.new
446
583
  migration.migrate(:up)
447
584
 
448
- output = perform_schema_dump
585
+ output = dump_table_schema("foo$cat_owners$bar", "foo$cat$bar")
586
+
587
+ assert_match %r{create_table "cat_owners"}, output
588
+ assert_match %r{create_table "cats"}, output
589
+ assert_match %r{t\.index \["name"\], name: "index_foo\$cats\$bar_on_name"}, output unless current_adapter?(:IBM_DBAdapter)
449
590
  assert_no_match %r{create_table "foo\$.+\$bar"}, output
450
591
  assert_no_match %r{add_index "foo\$.+\$bar"}, output
451
592
  assert_no_match %r{create_table "schema_migrations"}, output
452
593
  assert_no_match %r{create_table "ar_internal_metadata"}, output
453
594
 
454
- if ActiveRecord::Base.connection.supports_foreign_keys?
595
+ if ActiveRecord::Base.lease_connection.supports_foreign_keys?
596
+ assert_match %r{add_foreign_key "cats", "cat_owners", column: "owner_id"}, output unless current_adapter?(:IBM_DBAdapter)
455
597
  assert_no_match %r{add_foreign_key "foo\$.+\$bar"}, output
456
598
  assert_no_match %r{add_foreign_key "[^"]+", "foo\$.+\$bar"}, output
457
599
  end
@@ -460,10 +602,12 @@ class SchemaDumperTest < ActiveRecord::TestCase
460
602
 
461
603
  ActiveRecord::Base.table_name_suffix = ActiveRecord::Base.table_name_prefix = ""
462
604
  $stdout = original
605
+ ActiveRecord::Base.establish_connection(:arunit)
463
606
  end
464
607
 
465
608
  def test_schema_dump_with_table_name_prefix_and_ignoring_tables
466
609
  original, $stdout = $stdout, StringIO.new
610
+ ActiveRecord::Base.establish_connection(:arunit2) unless in_memory_db?
467
611
 
468
612
  create_cat_migration = Class.new(ActiveRecord::Migration::Current) do
469
613
  def change
@@ -482,7 +626,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
482
626
  migration.migrate(:up)
483
627
 
484
628
  stream = StringIO.new
485
- output = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream).string
629
+ output = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection_pool, stream).string
486
630
 
487
631
  assert_match %r{create_table "omg_cats"}, output
488
632
  assert_no_match %r{create_table "cats"}, output
@@ -492,6 +636,311 @@ class SchemaDumperTest < ActiveRecord::TestCase
492
636
  ActiveRecord::SchemaDumper.ignore_tables = original_schema_dumper_ignore_tables
493
637
 
494
638
  $stdout = original
639
+ ActiveRecord::Base.establish_connection(:arunit)
640
+ end
641
+
642
+ if current_adapter?(:PostgreSQLAdapter)
643
+ def test_schema_dump_with_correct_timestamp_types_via_create_table_and_t_column
644
+ original, $stdout = $stdout, StringIO.new
645
+
646
+ migration = Class.new(ActiveRecord::Migration::Current) do
647
+ def up
648
+ create_table("timestamps") do |t|
649
+ t.datetime :this_should_remain_datetime
650
+ t.timestamp :this_is_an_alias_of_datetime
651
+ t.column :without_time_zone, :timestamp
652
+ t.column :with_time_zone, :timestamptz
653
+ end
654
+ end
655
+ def down
656
+ drop_table("timestamps")
657
+ end
658
+ end
659
+ migration.migrate(:up)
660
+
661
+ output = dump_table_schema("timestamps")
662
+ assert output.include?('t.datetime "this_should_remain_datetime"')
663
+ assert output.include?('t.datetime "this_is_an_alias_of_datetime"')
664
+ assert output.include?('t.datetime "without_time_zone"')
665
+ assert output.include?('t.timestamptz "with_time_zone"')
666
+ ensure
667
+ migration.migrate(:down)
668
+ $stdout = original
669
+ end
670
+
671
+ def test_schema_dump_with_timestamptz_datetime_format
672
+ migration, original, $stdout = nil, $stdout, StringIO.new
673
+
674
+ with_postgresql_datetime_type(:timestamptz) do
675
+ migration = Class.new(ActiveRecord::Migration::Current) do
676
+ def up
677
+ create_table("timestamps") do |t|
678
+ t.datetime :this_should_remain_datetime
679
+ t.timestamptz :this_is_an_alias_of_datetime
680
+ t.column :without_time_zone, :timestamp
681
+ t.column :with_time_zone, :timestamptz
682
+ end
683
+ end
684
+ def down
685
+ drop_table("timestamps")
686
+ end
687
+ end
688
+ migration.migrate(:up)
689
+
690
+ output = dump_table_schema("timestamps")
691
+ assert output.include?('t.datetime "this_should_remain_datetime"')
692
+ assert output.include?('t.datetime "this_is_an_alias_of_datetime"')
693
+ assert output.include?('t.timestamp "without_time_zone"')
694
+ assert output.include?('t.datetime "with_time_zone"')
695
+ end
696
+ ensure
697
+ migration.migrate(:down)
698
+ $stdout = original
699
+ end
700
+
701
+ def test_timestamps_schema_dump_before_rails_7
702
+ migration, original, $stdout = nil, $stdout, StringIO.new
703
+
704
+ migration = Class.new(ActiveRecord::Migration[6.1]) do
705
+ def up
706
+ create_table("timestamps") do |t|
707
+ t.datetime :this_should_remain_datetime
708
+ t.timestamp :this_is_an_alias_of_datetime
709
+ t.column :this_is_also_an_alias_of_datetime, :timestamp
710
+ end
711
+ end
712
+ def down
713
+ drop_table("timestamps")
714
+ end
715
+ end
716
+ migration.migrate(:up)
717
+
718
+ output = dump_table_schema("timestamps")
719
+ assert output.include?('t.datetime "this_should_remain_datetime"')
720
+ assert output.include?('t.datetime "this_is_an_alias_of_datetime"')
721
+ assert output.include?('t.datetime "this_is_also_an_alias_of_datetime"')
722
+ ensure
723
+ migration.migrate(:down)
724
+ $stdout = original
725
+ end
726
+
727
+ def test_timestamps_schema_dump_before_rails_7_with_timestamptz_setting
728
+ migration, original, $stdout = nil, $stdout, StringIO.new
729
+
730
+ with_postgresql_datetime_type(:timestamptz) do
731
+ migration = Class.new(ActiveRecord::Migration[6.1]) do
732
+ def up
733
+ create_table("timestamps") do |t|
734
+ t.datetime :this_should_change_to_timestamp
735
+ t.timestamp :this_should_stay_as_timestamp
736
+ t.column :this_should_also_stay_as_timestamp, :timestamp
737
+ end
738
+ end
739
+ def down
740
+ drop_table("timestamps")
741
+ end
742
+ end
743
+ migration.migrate(:up)
744
+
745
+ output = dump_table_schema("timestamps")
746
+ # Normally we'd write `t.datetime` here. But because you've changed the `datetime_type`
747
+ # to something else, `t.datetime` now means `:timestamptz`. To ensure that old columns
748
+ # are still created as a `:timestamp` we need to change what is written to the schema dump.
749
+ #
750
+ # Typically in Rails we handle this through Migration versioning (`ActiveRecord::Migration::Compatibility`)
751
+ # but that doesn't work here because the schema dumper is not aware of which migration
752
+ # a column was added in.
753
+ assert output.include?('t.timestamp "this_should_change_to_timestamp"')
754
+ assert output.include?('t.timestamp "this_should_stay_as_timestamp"')
755
+ assert output.include?('t.timestamp "this_should_also_stay_as_timestamp"')
756
+ end
757
+ ensure
758
+ migration.migrate(:down)
759
+ $stdout = original
760
+ end
761
+
762
+ def test_schema_dump_when_changing_datetime_type_for_an_existing_app
763
+ original, $stdout = $stdout, StringIO.new
764
+
765
+ migration = Class.new(ActiveRecord::Migration::Current) do
766
+ def up
767
+ create_table("timestamps") do |t|
768
+ t.datetime :default_format
769
+ t.column :without_time_zone, :timestamp
770
+ t.column :with_time_zone, :timestamptz
771
+ end
772
+ end
773
+ def down
774
+ drop_table("timestamps")
775
+ end
776
+ end
777
+ migration.migrate(:up)
778
+
779
+ output = dump_table_schema("timestamps")
780
+ assert output.include?('t.datetime "default_format"')
781
+ assert output.include?('t.datetime "without_time_zone"')
782
+ assert output.include?('t.timestamptz "with_time_zone"')
783
+
784
+ datetime_type_was = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type
785
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :timestamptz
786
+
787
+ output = dump_table_schema("timestamps")
788
+ assert output.include?('t.timestamp "default_format"')
789
+ assert output.include?('t.timestamp "without_time_zone"')
790
+ assert output.include?('t.datetime "with_time_zone"')
791
+ ensure
792
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = datetime_type_was
793
+ migration.migrate(:down)
794
+ $stdout = original
795
+ end
796
+
797
+ def test_schema_dump_with_correct_timestamp_types_via_create_table_and_t_timestamptz
798
+ original, $stdout = $stdout, StringIO.new
799
+
800
+ migration = Class.new(ActiveRecord::Migration::Current) do
801
+ def up
802
+ create_table("timestamps") do |t|
803
+ t.datetime :default_format
804
+ t.datetime :without_time_zone
805
+ t.timestamp :also_without_time_zone
806
+ t.timestamptz :with_time_zone
807
+ end
808
+ end
809
+ def down
810
+ drop_table("timestamps")
811
+ end
812
+ end
813
+ migration.migrate(:up)
814
+
815
+ output = dump_table_schema("timestamps")
816
+ assert output.include?('t.datetime "default_format"')
817
+ assert output.include?('t.datetime "without_time_zone"')
818
+ assert output.include?('t.datetime "also_without_time_zone"')
819
+ assert output.include?('t.timestamptz "with_time_zone"')
820
+ ensure
821
+ migration.migrate(:down)
822
+ $stdout = original
823
+ end
824
+
825
+ def test_schema_dump_with_correct_timestamp_types_via_add_column
826
+ original, $stdout = $stdout, StringIO.new
827
+
828
+ migration = Class.new(ActiveRecord::Migration::Current) do
829
+ def up
830
+ create_table("timestamps")
831
+
832
+ add_column :timestamps, :default_format, :datetime
833
+ add_column :timestamps, :without_time_zone, :datetime
834
+ add_column :timestamps, :also_without_time_zone, :timestamp
835
+ add_column :timestamps, :with_time_zone, :timestamptz
836
+ end
837
+ def down
838
+ drop_table("timestamps")
839
+ end
840
+ end
841
+ migration.migrate(:up)
842
+
843
+ output = dump_table_schema("timestamps")
844
+ assert output.include?('t.datetime "default_format"')
845
+ assert output.include?('t.datetime "without_time_zone"')
846
+ assert output.include?('t.datetime "also_without_time_zone"')
847
+ assert output.include?('t.timestamptz "with_time_zone"')
848
+ ensure
849
+ migration.migrate(:down)
850
+ $stdout = original
851
+ end
852
+
853
+ def test_schema_dump_with_correct_timestamp_types_via_add_column_before_rails_7
854
+ original, $stdout = $stdout, StringIO.new
855
+
856
+ migration = Class.new(ActiveRecord::Migration[6.1]) do
857
+ def up
858
+ create_table("timestamps")
859
+
860
+ add_column :timestamps, :default_format, :datetime
861
+ add_column :timestamps, :without_time_zone, :datetime
862
+ add_column :timestamps, :also_without_time_zone, :timestamp
863
+ end
864
+ def down
865
+ drop_table("timestamps")
866
+ end
867
+ end
868
+ migration.migrate(:up)
869
+
870
+ output = dump_table_schema("timestamps")
871
+ assert output.include?('t.datetime "default_format"')
872
+ assert output.include?('t.datetime "without_time_zone"')
873
+ assert output.include?('t.datetime "also_without_time_zone"')
874
+ ensure
875
+ migration.migrate(:down)
876
+ $stdout = original
877
+ end
878
+
879
+ def test_schema_dump_with_correct_timestamp_types_via_add_column_before_rails_7_with_timestamptz_setting
880
+ migration, original, $stdout = nil, $stdout, StringIO.new
881
+
882
+ with_postgresql_datetime_type(:timestamptz) do
883
+ migration = Class.new(ActiveRecord::Migration[6.1]) do
884
+ def up
885
+ create_table("timestamps")
886
+
887
+ add_column :timestamps, :this_should_change_to_timestamp, :datetime
888
+ add_column :timestamps, :this_should_stay_as_timestamp, :timestamp
889
+ end
890
+ def down
891
+ drop_table("timestamps")
892
+ end
893
+ end
894
+ migration.migrate(:up)
895
+
896
+ output = dump_table_schema("timestamps")
897
+ # Normally we'd write `t.datetime` here. But because you've changed the `datetime_type`
898
+ # to something else, `t.datetime` now means `:timestamptz`. To ensure that old columns
899
+ # are still created as a `:timestamp` we need to change what is written to the schema dump.
900
+ #
901
+ # Typically in Rails we handle this through Migration versioning (`ActiveRecord::Migration::Compatibility`)
902
+ # but that doesn't work here because the schema dumper is not aware of which migration
903
+ # a column was added in.
904
+ assert output.include?('t.timestamp "this_should_change_to_timestamp"')
905
+ assert output.include?('t.timestamp "this_should_stay_as_timestamp"')
906
+ end
907
+ ensure
908
+ migration.migrate(:down)
909
+ $stdout = original
910
+ end
911
+
912
+ def test_schema_dump_with_correct_timestamp_types_via_add_column_with_type_as_string
913
+ migration, original, $stdout = nil, $stdout, StringIO.new
914
+
915
+ with_postgresql_datetime_type(:timestamptz) do
916
+ migration = Class.new(ActiveRecord::Migration[6.1]) do
917
+ def up
918
+ create_table("timestamps")
919
+
920
+ add_column :timestamps, :this_should_change_to_timestamp, "datetime"
921
+ add_column :timestamps, :this_should_stay_as_timestamp, "timestamp"
922
+ end
923
+ def down
924
+ drop_table("timestamps")
925
+ end
926
+ end
927
+ migration.migrate(:up)
928
+
929
+ output = dump_table_schema("timestamps")
930
+ # Normally we'd write `t.datetime` here. But because you've changed the `datetime_type`
931
+ # to something else, `t.datetime` now means `:timestamptz`. To ensure that old columns
932
+ # are still created as a `:timestamp` we need to change what is written to the schema dump.
933
+ #
934
+ # Typically in Rails we handle this through Migration versioning (`ActiveRecord::Migration::Compatibility`)
935
+ # but that doesn't work here because the schema dumper is not aware of which migration
936
+ # a column was added in.
937
+ assert output.include?('t.timestamp "this_should_change_to_timestamp"')
938
+ assert output.include?('t.timestamp "this_should_stay_as_timestamp"')
939
+ end
940
+ ensure
941
+ migration.migrate(:down)
942
+ $stdout = original
943
+ end
495
944
  end
496
945
  end
497
946
 
@@ -499,14 +948,24 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
499
948
  include SchemaDumpingHelper
500
949
 
501
950
  setup do
502
- @connection = ActiveRecord::Base.connection
951
+ @connection = ActiveRecord::Base.lease_connection
503
952
  @connection.create_table :dump_defaults, force: true do |t|
504
953
  t.string :string_with_default, default: "Hello!"
505
954
  t.date :date_with_default, default: "2014-06-05"
506
955
  t.datetime :datetime_with_default, default: "2014-06-05 07:17:04"
507
956
  t.time :time_with_default, default: "07:17:04"
508
957
  t.decimal :decimal_with_default, default: "1234567890.0123456789", precision: 20, scale: 10
509
- t.text :text_with_default, default: "John' Doe" if supports_text_column_with_default?
958
+
959
+ if supports_text_column_with_default?
960
+ t.text :text_with_default, default: "John' Doe"
961
+
962
+ if current_adapter?(:PostgreSQLAdapter)
963
+ t.text :uuid, default: -> { "gen_random_uuid()" }
964
+ elsif !current_adapter?(:IBM_DBAdapter)
965
+ # IBM_DB does not support uuid() function
966
+ t.text :uuid, default: -> { "uuid()" }
967
+ end
968
+ end
510
969
  end
511
970
 
512
971
  if current_adapter?(:PostgreSQLAdapter)
@@ -515,6 +974,8 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
515
974
  t.float :float_with_nan_default, default: Float::NAN
516
975
  t.datetime :beginning_of_time, default: "-infinity"
517
976
  t.datetime :end_of_time, default: "infinity"
977
+ t.date :date_with_neg_inf_default, default: -::Float::INFINITY
978
+ t.date :date_with_pos_inf_default, default: ::Float::INFINITY
518
979
  end
519
980
  end
520
981
  end
@@ -528,7 +989,11 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
528
989
 
529
990
  assert_match %r{t\.string\s+"string_with_default",.*?default: "Hello!"}, output
530
991
  assert_match %r{t\.date\s+"date_with_default",\s+default: "2014-06-05"}, output
531
- assert_match %r{t\.datetime\s+"datetime_with_default",\s+precision: 6,\s+default: "2014-06-05 07:17:04"}, output
992
+ if current_adapter?(:IBM_DBAdapter)
993
+ assert_match %r{t\.datetime\s+"datetime_with_default",\s+default: "2014-06-05 07:17:04"}, output
994
+ else
995
+ assert_match %r{t\.datetime\s+"datetime_with_default",\s+precision: 6,\s+default: "2014-06-05 07:17:04"}, output
996
+ end
532
997
  assert_match %r{t\.time\s+"time_with_default",\s+default: "2000-01-01 07:17:04"}, output
533
998
  assert_match %r{t\.decimal\s+"decimal_with_default",\s+precision: 20,\s+scale: 10,\s+default: "1234567890.0123456789"}, output
534
999
  end
@@ -537,14 +1002,22 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
537
1002
  output = dump_table_schema("dump_defaults")
538
1003
 
539
1004
  assert_match %r{t\.text\s+"text_with_default",.*?default: "John' Doe"}, output
1005
+
1006
+ if current_adapter?(:PostgreSQLAdapter)
1007
+ assert_match %r{t\.text\s+"uuid",.*?default: -> \{ "gen_random_uuid\(\)" \}}, output
1008
+ elsif !current_adapter?(:IBM_DBAdapter)
1009
+ # IBM_DB does not support uuid() function, so this column is not created
1010
+ assert_match %r{t\.text\s+"uuid",.*?default: -> \{ "uuid\(\)" \}}, output
1011
+ end
540
1012
  end if supports_text_column_with_default?
541
1013
 
542
1014
  def test_schema_dump_with_column_infinity_default
543
- skip unless current_adapter?(:PostgreSQLAdapter)
544
1015
  output = dump_table_schema("infinity_defaults")
545
1016
  assert_match %r{t\.float\s+"float_with_inf_default",\s+default: ::Float::INFINITY}, output
546
1017
  assert_match %r{t\.float\s+"float_with_nan_default",\s+default: ::Float::NAN}, output
547
1018
  assert_match %r{t\.datetime\s+"beginning_of_time",\s+default: -::Float::INFINITY}, output
548
1019
  assert_match %r{t\.datetime\s+"end_of_time",\s+default: ::Float::INFINITY}, output
549
- end
1020
+ assert_match %r{t\.date\s+"date_with_neg_inf_default",\s+default: -::Float::INFINITY}, output
1021
+ assert_match %r{t\.date\s+"date_with_pos_inf_default",\s+default: ::Float::INFINITY}, output
1022
+ end if current_adapter?(:PostgreSQLAdapter)
550
1023
  end