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
@@ -21,21 +21,20 @@ module ActiveRecord
21
21
  super
22
22
  end
23
23
 
24
- unless current_adapter?(:OracleAdapter)
25
- def test_rename_table_should_work_with_reserved_words
26
- renamed = false
24
+ def test_rename_table_should_work_with_reserved_words
25
+ renamed = false
27
26
 
28
- add_column :test_models, :url, :string
29
- connection.rename_table :references, :old_references
30
- connection.rename_table :test_models, :references
27
+ connection.rename_table :references, :old_references
28
+ connection.rename_table :test_models, :references
31
29
 
32
- renamed = true
30
+ renamed = true
33
31
 
34
- # Using explicit id in insert for compatibility across all databases
35
- connection.execute "INSERT INTO 'references' (url, created_at, updated_at) VALUES ('http://rubyonrails.com', 0, 0)"
36
- assert_equal "http://rubyonrails.com", connection.select_value("SELECT url FROM 'references' WHERE id=1")
37
- ensure
38
- return unless renamed
32
+ # Using explicit id in insert for compatibility across all databases
33
+ table_name = connection.quote_table_name("references")
34
+ connection.execute "INSERT INTO #{table_name} (id, url) VALUES (123, 'http://rubyonrails.com')"
35
+ assert_equal "http://rubyonrails.com", connection.select_value("SELECT url FROM #{table_name} WHERE id=123")
36
+ ensure
37
+ if renamed
39
38
  connection.rename_table :references, :test_models
40
39
  connection.rename_table :old_references, :references
41
40
  end
@@ -49,6 +48,22 @@ module ActiveRecord
49
48
  assert_equal "http://www.foreverflying.com/octopus-black7.jpg", connection.select_value("SELECT url FROM octopi WHERE id=1")
50
49
  end
51
50
 
51
+ def test_rename_table_raises_for_long_table_names
52
+ name_limit = connection.table_name_length
53
+ long_name = "a" * (name_limit + 1)
54
+ short_name = "a" * name_limit
55
+
56
+ error = assert_raises(ArgumentError) do
57
+ connection.rename_table :test_models, long_name
58
+ end
59
+ assert_equal "Table name '#{long_name}' is too long; the limit is #{name_limit} characters", error.message
60
+
61
+ connection.rename_table :test_models, short_name
62
+ assert connection.table_exists?(short_name)
63
+ ensure
64
+ connection.drop_table short_name, if_exists: true
65
+ end
66
+
52
67
  def test_rename_table_with_an_index
53
68
  add_index :test_models, :url
54
69
 
@@ -62,54 +77,24 @@ module ActiveRecord
62
77
  assert_equal "index_octopi_on_url", index.name
63
78
  end
64
79
 
65
- def test_rename_table_does_not_rename_custom_named_index
66
- add_index :test_models, :url, name: "special_url_idx"
80
+ def test_rename_table_with_long_table_name_and_index
81
+ long_name = "a" * connection.table_name_length
67
82
 
68
- rename_table :test_models, :octopi
83
+ add_index :test_models, :url
84
+ rename_table :test_models, long_name
69
85
 
70
- assert_equal ["special_url_idx"], connection.indexes(:octopi).map(&:name)
86
+ index = connection.indexes(long_name).first
87
+ assert_includes index.columns, "url"
88
+ ensure
89
+ rename_table long_name, :test_models
71
90
  end
72
91
 
73
- if current_adapter?(:PostgreSQLAdapter)
74
- def test_rename_table_for_postgresql_should_also_rename_default_sequence
75
- rename_table :test_models, :octopi
76
-
77
- pk, seq = connection.pk_and_sequence_for("octopi")
78
-
79
- assert_equal ConnectionAdapters::PostgreSQL::Name.new("public", "octopi_#{pk}_seq"), seq
80
- end
92
+ def test_rename_table_does_not_rename_custom_named_index
93
+ add_index :test_models, :url, name: "special_url_idx"
81
94
 
82
- def test_renaming_table_renames_primary_key
83
- connection.create_table :cats, id: :uuid, default: "uuid_generate_v4()"
84
- rename_table :cats, :felines
85
-
86
- assert connection.table_exists? :felines
87
- assert_not connection.table_exists? :cats
88
-
89
- primary_key_name = connection.select_values(<<~SQL, "SCHEMA")[0]
90
- SELECT c.relname
91
- FROM pg_class c
92
- JOIN pg_index i
93
- ON c.oid = i.indexrelid
94
- WHERE i.indisprimary
95
- AND i.indrelid = 'felines'::regclass
96
- SQL
97
-
98
- assert_equal "felines_pkey", primary_key_name
99
- ensure
100
- connection.drop_table :cats, if_exists: true
101
- connection.drop_table :felines, if_exists: true
102
- end
95
+ rename_table :test_models, :octopi
103
96
 
104
- def test_renaming_table_doesnt_attempt_to_rename_non_existent_sequences
105
- connection.create_table :cats, id: :uuid, default: "uuid_generate_v4()"
106
- assert_nothing_raised { rename_table :cats, :felines }
107
- assert connection.table_exists? :felines
108
- assert_not connection.table_exists? :cats
109
- ensure
110
- connection.drop_table :cats, if_exists: true
111
- connection.drop_table :felines, if_exists: true
112
- end
97
+ assert_equal ["special_url_idx"], connection.indexes(:octopi).map(&:name)
113
98
  end
114
99
  end
115
100
  end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ module ActiveRecord
6
+ class Migration
7
+ class SchemaDefinitionsTest < ActiveRecord::TestCase
8
+ attr_reader :connection
9
+
10
+ def setup
11
+ @connection = ActiveRecord::Base.lease_connection
12
+ end
13
+
14
+ def test_build_create_table_definition_with_block
15
+ td = connection.build_create_table_definition :test do |t|
16
+ t.column :foo, :string
17
+ end
18
+
19
+ id_column = td.columns.find { |col| col.name == "id" }
20
+ assert_predicate id_column, :present?
21
+
22
+ foo_column = td.columns.find { |col| col.name == "foo" }
23
+ assert_predicate foo_column, :present?
24
+ end
25
+
26
+ def test_build_create_table_definition_without_block
27
+ td = connection.build_create_table_definition(:test)
28
+
29
+ id_column = td.columns.find { |col| col.name == "id" }
30
+ assert_predicate id_column, :present?
31
+ end
32
+
33
+ def test_build_create_join_table_definition_with_block
34
+ assert connection.table_exists?(:posts)
35
+ assert connection.table_exists?(:comments)
36
+
37
+ join_td = connection.build_create_join_table_definition(:posts, :comments) do |t|
38
+ t.column :another_col, :string
39
+ end
40
+
41
+ assert_equal :comments_posts, join_td.name
42
+ assert_equal ["another_col", "comment_id", "post_id"], join_td.columns.map(&:name).sort
43
+ end
44
+
45
+ def test_build_create_join_table_definition_without_block
46
+ assert connection.table_exists?(:posts)
47
+ assert connection.table_exists?(:comments)
48
+
49
+ join_td = connection.build_create_join_table_definition(:posts, :comments)
50
+
51
+ assert_equal :comments_posts, join_td.name
52
+ assert_equal ["comment_id", "post_id"], join_td.columns.map(&:name).sort
53
+ end
54
+
55
+ def test_build_create_index_definition
56
+ connection.create_table(:test) do |t|
57
+ t.column :foo, :string
58
+ end
59
+ create_index = connection.build_create_index_definition(:test, :foo)
60
+
61
+ assert_equal "index_test_on_foo", create_index.index.name
62
+ ensure
63
+ connection.drop_table(:test) if connection.table_exists?(:test)
64
+ end
65
+
66
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
67
+ def test_build_create_index_definition_for_existing_index
68
+ connection.create_table(:test) do |t|
69
+ t.column :foo, :string
70
+ end
71
+ connection.add_index(:test, :foo)
72
+
73
+ create_index = connection.build_create_index_definition(:test, :foo, if_not_exists: true)
74
+ assert_nil create_index
75
+ ensure
76
+ connection.drop_table(:test) if connection.table_exists?(:test)
77
+ end
78
+ end
79
+
80
+ unless current_adapter?(:SQLite3Adapter)
81
+ def test_build_change_column_definition
82
+ connection.create_table(:test) do |t|
83
+ t.column :foo, :string
84
+ end
85
+
86
+ change_cd = connection.build_change_column_definition(:test, :foo, :integer)
87
+ change_col = change_cd.column
88
+ assert_equal "foo", change_col.name.to_s
89
+ ensure
90
+ connection.drop_table(:test) if connection.table_exists?(:test)
91
+ end
92
+
93
+ def test_build_change_column_default_definition
94
+ connection.create_table(:test) do |t|
95
+ t.column :foo, :string
96
+ end
97
+
98
+ change_default_cd = connection.build_change_column_default_definition(:test, :foo, "new")
99
+ assert_equal "new", change_default_cd.default
100
+
101
+ change_col = change_default_cd.column
102
+ assert_equal "foo", change_col.name.to_s
103
+ ensure
104
+ connection.drop_table(:test) if connection.table_exists?(:test)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/schema_dumping_helper"
5
+
6
+ if ActiveRecord::Base.lease_connection.supports_unique_constraints?
7
+ module ActiveRecord
8
+ class Migration
9
+ class UniqueConstraintTest < ActiveRecord::TestCase
10
+ include SchemaDumpingHelper
11
+
12
+ class Section < ActiveRecord::Base
13
+ end
14
+
15
+ setup do
16
+ @connection = ActiveRecord::Base.lease_connection
17
+ @connection.create_table "sections", force: true do |t|
18
+ t.integer "position", null: false
19
+ end
20
+ end
21
+
22
+ teardown do
23
+ @connection.drop_table "sections", if_exists: true
24
+ end
25
+
26
+ def test_unique_constraints
27
+ skip "DB2 does not provide PostgreSQL-style unique constraint metadata fixtures" if current_adapter?(:IBM_DBAdapter)
28
+
29
+ unique_constraints = @connection.unique_constraints("test_unique_constraints")
30
+
31
+ expected_constraints = [
32
+ {
33
+ name: "test_unique_constraints_position_deferrable_false",
34
+ deferrable: false,
35
+ column: ["position_1"]
36
+ }, {
37
+ name: "test_unique_constraints_position_deferrable_immediate",
38
+ deferrable: :immediate,
39
+ column: ["position_2"]
40
+ }, {
41
+ name: "test_unique_constraints_position_deferrable_deferred",
42
+ deferrable: :deferred,
43
+ column: ["position_3"]
44
+ }, {
45
+ name: "test_unique_constraints_position_nulls_not_distinct",
46
+ nulls_not_distinct: true,
47
+ column: ["position_4"]
48
+ }
49
+ ]
50
+
51
+ assert_equal expected_constraints.size, unique_constraints.size
52
+
53
+ expected_nulls_not_distinct = expected_constraints.pop
54
+
55
+ expected_constraints.each do |expected_constraint|
56
+ constraint = unique_constraints.find { |constraint| constraint.name == expected_constraint[:name] }
57
+ assert_equal "test_unique_constraints", constraint.table_name
58
+ assert_equal expected_constraint[:name], constraint.name
59
+ assert_equal expected_constraint[:column], constraint.column
60
+ assert_equal expected_constraint[:deferrable], constraint.deferrable
61
+ end
62
+
63
+ if supports_nulls_not_distinct?
64
+ constraint = unique_constraints.find { |constraint| constraint.name == expected_nulls_not_distinct[:name] }
65
+ assert_equal "test_unique_constraints", constraint.table_name
66
+ assert_equal expected_nulls_not_distinct[:name], constraint.name
67
+ assert_equal expected_nulls_not_distinct[:column], constraint.column
68
+ assert_equal expected_nulls_not_distinct[:nulls_not_distinct], constraint.nulls_not_distinct
69
+ end
70
+ end
71
+
72
+ def test_unique_constraints_scoped_to_schemas
73
+ skip "DB2 CREATE SCHEMA requires privileges not available for this test user" if current_adapter?(:IBM_DBAdapter)
74
+
75
+ @connection.add_unique_constraint :sections, [:position]
76
+
77
+ assert_no_changes -> { @connection.unique_constraints("sections").size } do
78
+ @connection.create_schema "test_schema"
79
+ @connection.create_table "test_schema.sections" do |t|
80
+ t.integer :position
81
+ end
82
+ @connection.add_unique_constraint "test_schema.sections", [:position]
83
+ end
84
+ ensure
85
+ @connection.drop_schema "test_schema"
86
+ end
87
+
88
+ def test_add_unique_constraint_without_deferrable
89
+ @connection.add_unique_constraint :sections, [:position]
90
+
91
+ unique_constraints = @connection.unique_constraints("sections")
92
+ assert_equal 1, unique_constraints.size
93
+
94
+ constraint = unique_constraints.first
95
+ assert_equal "sections", constraint.table_name
96
+ assert_equal "uniq_rails_1e07660b77", constraint.name
97
+ assert_equal false, constraint.deferrable
98
+ end
99
+
100
+ def test_add_unique_constraint_with_deferrable_false
101
+ @connection.add_unique_constraint :sections, [:position], deferrable: false
102
+
103
+ unique_constraints = @connection.unique_constraints("sections")
104
+ assert_equal 1, unique_constraints.size
105
+
106
+ constraint = unique_constraints.first
107
+ assert_equal "sections", constraint.table_name
108
+ assert_equal "uniq_rails_1e07660b77", constraint.name
109
+ assert_equal false, constraint.deferrable
110
+ end
111
+
112
+ def test_add_unique_constraint_with_deferrable_immediate
113
+ skip "DB2 adapter does not expose deferrable state for unique constraints" if current_adapter?(:IBM_DBAdapter)
114
+
115
+ @connection.add_unique_constraint :sections, [:position], deferrable: :immediate
116
+
117
+ unique_constraints = @connection.unique_constraints("sections")
118
+ assert_equal 1, unique_constraints.size
119
+
120
+ constraint = unique_constraints.first
121
+ assert_equal "sections", constraint.table_name
122
+ assert_equal "uniq_rails_1e07660b77", constraint.name
123
+ assert_equal :immediate, constraint.deferrable
124
+ end
125
+
126
+ def test_add_unique_constraint_with_deferrable_deferred
127
+ skip "DB2 adapter does not expose deferrable state for unique constraints" if current_adapter?(:IBM_DBAdapter)
128
+
129
+ @connection.add_unique_constraint :sections, [:position], deferrable: :deferred
130
+
131
+ unique_constraints = @connection.unique_constraints("sections")
132
+ assert_equal 1, unique_constraints.size
133
+
134
+ constraint = unique_constraints.first
135
+ assert_equal "sections", constraint.table_name
136
+ assert_equal "uniq_rails_1e07660b77", constraint.name
137
+ assert_equal :deferred, constraint.deferrable
138
+ end
139
+
140
+ def test_add_unique_constraint_with_deferrable_invalid
141
+ error = assert_raises(ArgumentError) do
142
+ @connection.add_unique_constraint :sections, [:position], deferrable: true
143
+ end
144
+
145
+ assert_equal "deferrable must be `:immediate` or `:deferred`, got: `true`", error.message
146
+ end
147
+
148
+ def test_added_deferrable_initially_immediate_unique_constraint
149
+ skip "DB2 CLI driver reports function-sequence errors for deferred unique-constraint checks" if current_adapter?(:IBM_DBAdapter)
150
+
151
+ @connection.add_unique_constraint :sections, [:position], deferrable: :immediate, name: "unique_section_position"
152
+
153
+ section = Section.create!(position: 1)
154
+
155
+ assert_raises(ActiveRecord::StatementInvalid) do
156
+ Section.transaction(requires_new: true) do
157
+ Section.create!(position: 1)
158
+ section.update!(position: 2)
159
+ end
160
+ end
161
+
162
+ assert_nothing_raised do
163
+ Section.transaction(requires_new: true) do
164
+ Section.lease_connection.exec_query("SET CONSTRAINTS unique_section_position DEFERRED")
165
+ Section.create!(position: 1)
166
+ section.update!(position: 2)
167
+
168
+ # NOTE: Clear `SET CONSTRAINTS` statement at the end of transaction.
169
+ raise ActiveRecord::Rollback
170
+ end
171
+ end
172
+ end
173
+
174
+ def test_add_unique_constraint_with_name_and_using_index
175
+ skip "DB2 does not support ADD UNIQUE CONSTRAINT ... USING INDEX syntax" if current_adapter?(:IBM_DBAdapter)
176
+
177
+ @connection.add_index :sections, [:position], name: "unique_index", unique: true
178
+ @connection.add_unique_constraint :sections, name: "unique_constraint", deferrable: :immediate, using_index: "unique_index"
179
+
180
+ unique_constraints = @connection.unique_constraints("sections")
181
+ assert_equal 1, unique_constraints.size
182
+
183
+ constraint = unique_constraints.first
184
+ assert_equal "sections", constraint.table_name
185
+ assert_equal "unique_constraint", constraint.name
186
+ assert_equal ["position"], constraint.column
187
+ assert_equal :immediate, constraint.deferrable
188
+ end
189
+
190
+ def test_add_unique_constraint_with_only_using_index
191
+ skip "DB2 does not support ADD UNIQUE CONSTRAINT ... USING INDEX syntax" if current_adapter?(:IBM_DBAdapter)
192
+
193
+ @connection.add_index :sections, [:position], name: "unique_index", unique: true
194
+ @connection.add_unique_constraint :sections, using_index: "unique_index"
195
+
196
+ unique_constraints = @connection.unique_constraints("sections")
197
+ assert_equal 1, unique_constraints.size
198
+
199
+ constraint = unique_constraints.first
200
+ assert_equal "sections", constraint.table_name
201
+ assert_equal "uniq_rails_79b901ffb4", constraint.name
202
+ assert_equal ["position"], constraint.column
203
+ assert_equal false, constraint.deferrable
204
+ end
205
+
206
+ def test_add_unique_constraint_with_columns_and_using_index
207
+ @connection.add_index :sections, [:position], name: "unique_index", unique: true
208
+
209
+ assert_raises(ArgumentError) do
210
+ @connection.add_unique_constraint :sections, [:position], using_index: "unique_index"
211
+ end
212
+ end
213
+
214
+ def test_remove_unique_constraint
215
+ @connection.add_unique_constraint :sections, [:position], name: :unique_section_position
216
+ assert_equal 1, @connection.unique_constraints("sections").size
217
+ @connection.remove_unique_constraint :sections, name: :unique_section_position
218
+ assert_empty @connection.unique_constraints("sections")
219
+ end
220
+
221
+ def test_remove_unique_constraint_by_column
222
+ @connection.add_unique_constraint :sections, [:position]
223
+ assert_equal 1, @connection.unique_constraints("sections").size
224
+ @connection.remove_unique_constraint :sections, [:position]
225
+ assert_empty @connection.unique_constraints("sections")
226
+ end
227
+
228
+ def test_remove_non_existing_unique_constraint
229
+ assert_raises(ArgumentError, match: /Table 'sections' has no unique constraint/) do
230
+ @connection.remove_unique_constraint :sections, name: "nonexistent"
231
+ end
232
+ end
233
+
234
+ def test_renamed_unique_constraint
235
+ @connection.add_unique_constraint :sections, [:position]
236
+ @connection.rename_column :sections, :position, :new_position
237
+
238
+ unique_constraints = @connection.unique_constraints("sections")
239
+ assert_equal 1, unique_constraints.size
240
+
241
+ constraint = unique_constraints.first
242
+ assert_equal "sections", constraint.table_name
243
+ assert_equal ["new_position"], constraint.column
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end