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
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/connection_helper"
5
+
6
+ class ConnectionTest < ActiveRecord::AbstractMysqlTestCase
7
+ include ConnectionHelper
8
+
9
+ def setup
10
+ super
11
+ @subscriber = SQLSubscriber.new
12
+ @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", @subscriber)
13
+ @connection = ActiveRecord::Base.lease_connection
14
+ end
15
+
16
+ def teardown
17
+ ActiveSupport::Notifications.unsubscribe(@subscription)
18
+ super
19
+ end
20
+
21
+ def test_bad_connection
22
+ assert_raise ActiveRecord::NoDatabaseError do
23
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
24
+ configuration = db_config.configuration_hash.merge(database: "inexistent_activerecord_unittest")
25
+ connection = if current_adapter?(:Mysql2Adapter)
26
+ ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(configuration)
27
+ else
28
+ ActiveRecord::ConnectionAdapters::TrilogyAdapter.new(configuration)
29
+ end
30
+ connection.drop_table "ex", if_exists: true
31
+ end
32
+ end
33
+
34
+ def test_no_automatic_reconnection_after_timeout
35
+ assert_predicate @connection, :active?
36
+ cause_server_side_disconnect
37
+ assert_not_predicate @connection, :active?
38
+ ensure
39
+ # Repair all fixture connections so other tests won't break.
40
+ @fixture_connection_pools.each { |p| p.lease_connection.verify! }
41
+ end
42
+
43
+ def test_successful_reconnection_after_timeout_with_manual_reconnect
44
+ assert_predicate @connection, :active?
45
+ cause_server_side_disconnect
46
+ @connection.reconnect!
47
+ assert_predicate @connection, :active?
48
+ end
49
+
50
+ def test_successful_reconnection_after_timeout_with_verify
51
+ assert_predicate @connection, :active?
52
+ cause_server_side_disconnect
53
+ @connection.verify!
54
+ assert_predicate @connection, :active?
55
+ end
56
+
57
+ def test_execute_after_disconnect_reconnects
58
+ @connection.disconnect!
59
+
60
+ assert_equal 3, @connection.select_value("SELECT 1+2")
61
+ end
62
+
63
+ def test_quote_after_disconnect_reconnects
64
+ @connection.disconnect!
65
+
66
+ assert_equal "'string'", @connection.quote("string")
67
+ end
68
+
69
+ def test_active_after_disconnect
70
+ @connection.disconnect!
71
+ assert_equal false, @connection.active?
72
+ end
73
+
74
+ def test_wait_timeout_as_string
75
+ run_without_connection do |orig_connection|
76
+ ActiveRecord::Base.establish_connection(orig_connection.merge(wait_timeout: "60"))
77
+ result = ActiveRecord::Base.lease_connection.select_value("SELECT @@SESSION.wait_timeout")
78
+ assert_equal 60, result
79
+ end
80
+ end
81
+
82
+ def test_wait_timeout_as_url
83
+ run_without_connection do |orig_connection|
84
+ ActiveRecord::Base.establish_connection(orig_connection.merge("url" => "#{orig_connection[:adapter]}:///?wait_timeout=60"))
85
+ result = ActiveRecord::Base.lease_connection.select_value("SELECT @@SESSION.wait_timeout")
86
+ assert_equal 60, result
87
+ end
88
+ end
89
+
90
+ def test_character_set_connection_is_configured
91
+ run_without_connection do |orig_connection|
92
+ configuration_hash = orig_connection.except(:encoding, :collation)
93
+ ActiveRecord::Base.establish_connection(configuration_hash.merge!(encoding: "cp932"))
94
+ connection = ActiveRecord::Base.lease_connection
95
+
96
+ assert_equal "cp932", connection.show_variable("character_set_client")
97
+ assert_equal "cp932", connection.show_variable("character_set_results")
98
+ assert_equal "cp932", connection.show_variable("character_set_connection")
99
+ assert_equal "cp932_japanese_ci", connection.show_variable("collation_connection")
100
+
101
+ expected = "こんにちは".encode(Encoding::CP932)
102
+ assert_equal expected, connection.query_value("SELECT 'こんにちは'")
103
+ end
104
+ end
105
+
106
+ def test_collation_connection_is_configured
107
+ assert_equal "utf8mb4_unicode_ci", @connection.show_variable("collation_connection")
108
+ assert_equal 1, @connection.query_value("SELECT 'こんにちは' = 'コンニチハ'")
109
+
110
+ assert_equal "utf8mb4_general_ci", ARUnit2Model.lease_connection.show_variable("collation_connection")
111
+ assert_equal 0, ARUnit2Model.lease_connection.query_value("SELECT 'こんにちは' = 'コンニチハ'")
112
+ end
113
+
114
+ def test_mysql_default_in_strict_mode
115
+ result = @connection.select_value("SELECT @@SESSION.sql_mode")
116
+ assert_match %r(STRICT_ALL_TABLES), result
117
+ end
118
+
119
+ def test_mysql_strict_mode_disabled
120
+ run_without_connection do |orig_connection|
121
+ ActiveRecord::Base.establish_connection(orig_connection.merge(strict: false))
122
+ result = ActiveRecord::Base.lease_connection.select_value("SELECT @@SESSION.sql_mode")
123
+ assert_no_match %r(STRICT_ALL_TABLES), result
124
+ end
125
+ end
126
+
127
+ def test_mysql_strict_mode_specified_default
128
+ run_without_connection do |orig_connection|
129
+ ActiveRecord::Base.establish_connection(orig_connection.merge(strict: :default))
130
+ global_sql_mode = ActiveRecord::Base.lease_connection.select_value("SELECT @@GLOBAL.sql_mode")
131
+ session_sql_mode = ActiveRecord::Base.lease_connection.select_value("SELECT @@SESSION.sql_mode")
132
+ assert_equal global_sql_mode, session_sql_mode
133
+ end
134
+ end
135
+
136
+ def test_mysql_sql_mode_variable_overrides_strict_mode
137
+ run_without_connection do |orig_connection|
138
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { "sql_mode" => "ansi" }))
139
+ result = ActiveRecord::Base.lease_connection.select_value("SELECT @@SESSION.sql_mode")
140
+ assert_no_match %r(STRICT_ALL_TABLES), result
141
+ end
142
+ end
143
+
144
+ unless current_adapter?(:TrilogyAdapter)
145
+ def test_passing_arbitrary_flags_to_adapter
146
+ run_without_connection do |orig_connection|
147
+ ActiveRecord::Base.establish_connection(orig_connection.merge(flags: Mysql2::Client::COMPRESS))
148
+ assert_equal (Mysql2::Client::COMPRESS | Mysql2::Client::FOUND_ROWS), ActiveRecord::Base.lease_connection.raw_connection.query_options[:flags]
149
+ end
150
+ end
151
+
152
+ def test_passing_flags_by_array_to_adapter
153
+ run_without_connection do |orig_connection|
154
+ ActiveRecord::Base.establish_connection(orig_connection.merge(flags: ["COMPRESS"]))
155
+ assert_equal ["COMPRESS", "FOUND_ROWS"], ActiveRecord::Base.lease_connection.raw_connection.query_options[:flags]
156
+ end
157
+ end
158
+ end
159
+
160
+ def test_mysql_set_session_variable
161
+ run_without_connection do |orig_connection|
162
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { default_week_format: 3 }))
163
+ session_mode = ActiveRecord::Base.lease_connection.exec_query "SELECT @@SESSION.DEFAULT_WEEK_FORMAT"
164
+ assert_equal 3, session_mode.rows.first.first.to_i
165
+ end
166
+ end
167
+
168
+ def test_mysql_set_session_variable_to_default
169
+ run_without_connection do |orig_connection|
170
+ ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { default_week_format: :default }))
171
+ global_mode = ActiveRecord::Base.lease_connection.exec_query "SELECT @@GLOBAL.DEFAULT_WEEK_FORMAT"
172
+ session_mode = ActiveRecord::Base.lease_connection.exec_query "SELECT @@SESSION.DEFAULT_WEEK_FORMAT"
173
+ assert_equal global_mode.rows, session_mode.rows
174
+ end
175
+ end
176
+
177
+ def test_logs_name_show_variable
178
+ ActiveRecord::Base.lease_connection.materialize_transactions
179
+ @subscriber.logged.clear
180
+ @connection.show_variable "foo"
181
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
182
+ end
183
+
184
+ def test_logs_name_rename_column_for_alter
185
+ @connection.execute "CREATE TABLE `bar_baz` (`foo` varchar(255))"
186
+ @subscriber.logged.clear
187
+ @connection.send(:rename_column_for_alter, "bar_baz", "foo", "foo2")
188
+ if @connection.send(:supports_rename_column?)
189
+ assert_empty @subscriber.logged
190
+ else
191
+ assert_equal "SCHEMA", @subscriber.logged[0][1]
192
+ end
193
+ ensure
194
+ @connection.execute "DROP TABLE `bar_baz`"
195
+ end
196
+
197
+ def test_get_and_release_advisory_lock
198
+ lock_name = "test lock'n'name"
199
+
200
+ got_lock = @connection.get_advisory_lock(lock_name)
201
+ assert got_lock, "get_advisory_lock should have returned true but it didn't"
202
+
203
+ assert_equal false, test_lock_free(lock_name),
204
+ "expected the test advisory lock to be held but it wasn't"
205
+
206
+ released_lock = @connection.release_advisory_lock(lock_name)
207
+ assert released_lock, "expected release_advisory_lock to return true but it didn't"
208
+
209
+ assert test_lock_free(lock_name), "expected the test lock to be available after releasing"
210
+ end
211
+
212
+ def test_release_non_existent_advisory_lock
213
+ lock_name = "fake lock'n'name"
214
+ released_non_existent_lock = @connection.release_advisory_lock(lock_name)
215
+ assert_equal false, released_non_existent_lock,
216
+ "expected release_advisory_lock to return false when there was no lock to release"
217
+ end
218
+
219
+ def test_version_string
220
+ @connection.stub(:get_full_version, "8.0.35-0ubuntu0.22.04.1") do
221
+ assert_equal "8.0.35", @connection.get_database_version.to_s
222
+ end
223
+
224
+ @connection.stub(:get_full_version, "5.7.0") do
225
+ assert_equal "5.7.0", @connection.get_database_version.to_s
226
+ end
227
+ end
228
+
229
+ def test_version_string_with_mariadb
230
+ @connection.stub(:get_full_version, "5.5.5-10.6.5-MariaDB-1:10.6.5+maria~focal") do
231
+ assert_equal "10.6.5", @connection.get_database_version.to_s
232
+ end
233
+ end
234
+
235
+ def test_version_string_invalid
236
+ @connection.stub(:get_full_version, "some-database-proxy") do
237
+ error = assert_raises(ActiveRecord::DatabaseVersionError) do
238
+ @connection.get_database_version
239
+ end
240
+ assert_equal "Unable to parse MySQL version from \"some-database-proxy\"", error.message
241
+ end
242
+
243
+ @connection.stub(:get_full_version, "") do
244
+ error = assert_raises(ActiveRecord::DatabaseVersionError) do
245
+ @connection.get_database_version
246
+ end
247
+ assert_equal "Unable to parse MySQL version from \"\"", error.message
248
+ end
249
+
250
+ @connection.stub(:get_full_version, nil) do
251
+ error = assert_raises(ActiveRecord::DatabaseVersionError) do
252
+ @connection.get_database_version
253
+ end
254
+ assert_equal "Unable to parse MySQL version from nil", error.message
255
+ end
256
+ end
257
+
258
+ private
259
+ def cause_server_side_disconnect
260
+ @connection.update("set @@wait_timeout=1")
261
+ sleep 2
262
+ end
263
+
264
+ def test_lock_free(lock_name)
265
+ @connection.select_value("SELECT IS_FREE_LOCK(#{@connection.quote(lock_name)})") == 1
266
+ end
267
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/connection_helper"
5
+ require "models/author"
6
+ require "models/bulb"
7
+ require "models/car"
8
+
9
+ module ActiveRecord
10
+ class CountDeletedRowsWithLockTest < ActiveRecord::AbstractMysqlTestCase
11
+ test "delete and create in different threads synchronize correctly" do
12
+ Bulb.unscoped.delete_all
13
+ Bulb.create!(name: "Jimmy", color: "blue")
14
+
15
+ delete_thread = Thread.new do
16
+ Bulb.unscoped.delete_all
17
+ end
18
+
19
+ create_thread = Thread.new do
20
+ Author.create!(name: "Tommy")
21
+ end
22
+
23
+ delete_thread.join
24
+ create_thread.join
25
+
26
+ assert_equal 1, delete_thread.value
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "cases/json_shared_test_cases"
5
+
6
+ if ActiveRecord::Base.lease_connection.supports_json?
7
+ class JSONTest < ActiveRecord::AbstractMysqlTestCase
8
+ include JSONSharedTestCases
9
+ self.use_transactional_tests = false
10
+
11
+ def setup
12
+ super
13
+ @connection.create_table("json_data_type") do |t|
14
+ t.json "payload"
15
+ t.json "settings"
16
+ end
17
+ end
18
+
19
+ private
20
+ def column_type
21
+ :json
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ class MySQLBooleanTest < ActiveRecord::AbstractMysqlTestCase
6
+ self.use_transactional_tests = false
7
+
8
+ class BooleanType < ActiveRecord::Base
9
+ self.table_name = "mysql_booleans"
10
+ end
11
+
12
+ setup do
13
+ @connection = ActiveRecord::Base.lease_connection
14
+ @connection.clear_cache!
15
+ @connection.create_table("mysql_booleans") do |t|
16
+ t.boolean "archived"
17
+ t.string "published", limit: 1
18
+ end
19
+ BooleanType.reset_column_information
20
+
21
+ @emulate_booleans = @connection.class.emulate_booleans
22
+ end
23
+
24
+ teardown do
25
+ emulate_booleans @emulate_booleans
26
+ @connection.drop_table "mysql_booleans"
27
+ end
28
+
29
+ test "column type with emulated booleans" do
30
+ emulate_booleans true
31
+
32
+ assert_equal :boolean, boolean_column.type
33
+ assert_equal :string, string_column.type
34
+ end
35
+
36
+ test "column type without emulated booleans" do
37
+ emulate_booleans false
38
+
39
+ assert_equal :integer, boolean_column.type
40
+ assert_equal :string, string_column.type
41
+ end
42
+
43
+ test "type casting with emulated booleans" do
44
+ emulate_booleans true
45
+
46
+ boolean = BooleanType.create!(archived: true, published: true)
47
+ attributes = boolean.reload.attributes_before_type_cast
48
+ assert_equal 1, attributes["archived"]
49
+ assert_equal "1", attributes["published"]
50
+
51
+ boolean = BooleanType.create!(archived: false, published: false)
52
+ attributes = boolean.reload.attributes_before_type_cast
53
+ assert_equal 0, attributes["archived"]
54
+ assert_equal "0", attributes["published"]
55
+
56
+ assert_equal 1, @connection.type_cast(true)
57
+ assert_equal 0, @connection.type_cast(false)
58
+ end
59
+
60
+ test "type casting without emulated booleans" do
61
+ emulate_booleans false
62
+
63
+ boolean = BooleanType.create!(archived: true, published: true)
64
+ attributes = boolean.reload.attributes_before_type_cast
65
+ assert_equal 1, attributes["archived"]
66
+ assert_equal "1", attributes["published"]
67
+
68
+ boolean = BooleanType.create!(archived: false, published: false)
69
+ attributes = boolean.reload.attributes_before_type_cast
70
+ assert_equal 0, attributes["archived"]
71
+ assert_equal "0", attributes["published"]
72
+
73
+ assert_equal 1, @connection.type_cast(true)
74
+ assert_equal 0, @connection.type_cast(false)
75
+ end
76
+
77
+ test "with booleans stored as 1 and 0" do
78
+ @connection.execute "INSERT INTO mysql_booleans(archived, published) VALUES(1, '1')"
79
+ boolean = BooleanType.first
80
+ assert_equal true, boolean.archived
81
+ assert_equal "1", boolean.published
82
+ end
83
+
84
+ test "with booleans stored as t" do
85
+ @connection.execute "INSERT INTO mysql_booleans(published) VALUES('t')"
86
+ boolean = BooleanType.first
87
+ assert_equal "t", boolean.published
88
+ end
89
+
90
+ def boolean_column
91
+ BooleanType.columns.find { |c| c.name == "archived" }
92
+ end
93
+
94
+ def string_column
95
+ BooleanType.columns.find { |c| c.name == "published" }
96
+ end
97
+
98
+ def emulate_booleans(value)
99
+ @connection.class.emulate_booleans = value
100
+ BooleanType.reset_column_information
101
+ end
102
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/schema_dumping_helper"
5
+
6
+ class MySQLEnumTest < ActiveRecord::AbstractMysqlTestCase
7
+ self.use_transactional_tests = false
8
+
9
+ include SchemaDumpingHelper
10
+
11
+ class EnumTest < ActiveRecord::Base
12
+ attribute :state, :integer
13
+
14
+ enum :state, {
15
+ start: 0,
16
+ middle: 1,
17
+ finish: 2
18
+ }
19
+ end
20
+
21
+ def setup
22
+ EnumTest.lease_connection.create_table :enum_tests, id: false, force: true do |t|
23
+ t.column :enum_column, "enum('text','blob','tiny','medium','long','unsigned','bigint')"
24
+ t.column :state, "TINYINT(1)"
25
+ end
26
+ end
27
+
28
+ def test_should_not_be_unsigned
29
+ column = EnumTest.columns_hash["enum_column"]
30
+ assert_not_predicate column, :unsigned?
31
+ end
32
+
33
+ def test_should_not_be_bigint
34
+ column = EnumTest.columns_hash["enum_column"]
35
+ assert_not_predicate column, :bigint?
36
+ end
37
+
38
+ def test_schema_dumping
39
+ schema = dump_table_schema "enum_tests"
40
+ assert_match %r{t\.column "enum_column", "enum\('text','blob','tiny','medium','long','unsigned','bigint'\)"$}, schema
41
+ end
42
+
43
+ def test_enum_with_attribute
44
+ enum_test = EnumTest.create!(state: :middle)
45
+ assert_equal "middle", enum_test.state
46
+ end
47
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+ require "models/post"
6
+
7
+ class MySQLExplainTest < ActiveRecord::AbstractMysqlTestCase
8
+ fixtures :authors, :author_addresses
9
+
10
+ def test_explain_for_one_query
11
+ explain = Author.where(id: 1).explain.inspect
12
+ assert_match %(EXPLAIN SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
13
+ assert_match %r(authors), explain
14
+ end
15
+
16
+ def test_explain_with_eager_loading
17
+ explain = Author.where(id: 1).includes(:posts).explain.inspect
18
+ assert_match %(EXPLAIN SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
19
+ assert_match %r(authors), explain
20
+ assert_match %(EXPLAIN SELECT `posts`.* FROM `posts` WHERE `posts`.`author_id` = 1), explain
21
+ assert_match %r(posts), explain
22
+ end
23
+
24
+ def test_explain_with_options_as_symbol
25
+ explain = Author.where(id: 1).explain(explain_option).inspect
26
+ assert_match %(#{expected_analyze_clause} SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
27
+ end
28
+
29
+ def test_explain_with_options_as_strings
30
+ explain = Author.where(id: 1).explain(explain_option.to_s.upcase).inspect
31
+ assert_match %(#{expected_analyze_clause} SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
32
+ end
33
+
34
+ def test_explain_options_with_eager_loading
35
+ explain = Author.where(id: 1).includes(:posts).explain(explain_option).inspect
36
+ assert_match %(#{expected_analyze_clause} SELECT `authors`.* FROM `authors` WHERE `authors`.`id` = 1), explain
37
+ assert_match %(#{expected_analyze_clause} SELECT `posts`.* FROM `posts` WHERE `posts`.`author_id` = 1), explain
38
+ end
39
+
40
+ private
41
+ def explain_option
42
+ supports_analyze? || supports_explain_analyze? ? :analyze : :extended
43
+ end
44
+
45
+ def expected_analyze_clause
46
+ if supports_analyze?
47
+ "ANALYZE"
48
+ elsif supports_explain_analyze?
49
+ "EXPLAIN ANALYZE"
50
+ else
51
+ "EXPLAIN EXTENDED"
52
+ end
53
+ end
54
+
55
+ def supports_explain_analyze?
56
+ if conn.mariadb?
57
+ conn.database_version <= "10.0"
58
+ else
59
+ conn.database_version >= "6.0"
60
+ end
61
+ end
62
+
63
+ # https://mariadb.com/kb/en/analyze-statement/
64
+ def supports_analyze?
65
+ conn.mariadb? && conn.database_version >= "10.1.0"
66
+ end
67
+
68
+ def conn
69
+ ActiveRecord::Base.lease_connection
70
+ end
71
+ end