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,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/connection_helper"
5
+
6
+ class ActiveSchemaTest < ActiveRecord::AbstractMysqlTestCase
7
+ include ConnectionHelper
8
+
9
+ def setup
10
+ ActiveRecord::Base.lease_connection.send(:default_row_format)
11
+ ActiveRecord::Base.lease_connection.singleton_class.class_eval do
12
+ alias_method :execute_without_stub, :execute
13
+ def execute(sql, name = nil)
14
+ ActiveSupport::Notifications.instrumenter.instrument(
15
+ "sql.active_record",
16
+ sql: sql,
17
+ name: name,
18
+ connection: self) do
19
+ sql
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ teardown do
26
+ reset_connection
27
+ end
28
+
29
+ def test_add_index
30
+ expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`)"
31
+ assert_equal expected, add_index(:people, :last_name, length: nil)
32
+
33
+ expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`(10))"
34
+ assert_equal expected, add_index(:people, :last_name, length: 10)
35
+
36
+ expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(15))"
37
+ assert_equal expected, add_index(:people, [:last_name, :first_name], length: 15)
38
+ assert_equal expected, add_index(:people, ["last_name", "first_name"], length: 15)
39
+
40
+ expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`)"
41
+ assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15 })
42
+ assert_equal expected, add_index(:people, ["last_name", "first_name"], length: { last_name: 15 })
43
+
44
+ expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(10))"
45
+ assert_equal expected, add_index(:people, [:last_name, :first_name], length: { last_name: 15, first_name: 10 })
46
+ assert_equal expected, add_index(:people, ["last_name", :first_name], length: { last_name: 15, "first_name" => 10 })
47
+
48
+ %w(SPATIAL FULLTEXT UNIQUE).each do |type|
49
+ expected = "CREATE #{type} INDEX `index_people_on_last_name` ON `people` (`last_name`)"
50
+ assert_equal expected, add_index(:people, :last_name, type: type)
51
+ end
52
+
53
+ %w(btree hash).each do |using|
54
+ expected = "CREATE INDEX `index_people_on_last_name` USING #{using} ON `people` (`last_name`)"
55
+ assert_equal expected, add_index(:people, :last_name, using: using)
56
+ end
57
+
58
+ expected = "CREATE INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10))"
59
+ assert_equal expected, add_index(:people, :last_name, length: 10, using: :btree)
60
+
61
+ %i(default copy inplace instant).each do |algorithm|
62
+ expected = "CREATE INDEX `index_people_on_last_name` USING btree ON `people` (`last_name`(10)) ALGORITHM = #{algorithm.upcase}"
63
+ assert_equal expected, add_index(:people, :last_name, length: 10, using: :btree, algorithm: algorithm)
64
+ end
65
+
66
+ with_real_execute do
67
+ add_index(:people, :first_name)
68
+ assert index_exists?(:people, :first_name)
69
+
70
+ assert_nothing_raised do
71
+ add_index(:people, :first_name, if_not_exists: true)
72
+ end
73
+ end
74
+
75
+ assert_raise ArgumentError do
76
+ add_index(:people, :last_name, algorithm: :coyp)
77
+ end
78
+
79
+ expected = "CREATE INDEX `index_people_on_last_name_and_first_name` USING btree ON `people` (`last_name`(15), `first_name`(15))"
80
+ assert_equal expected, add_index(:people, [:last_name, :first_name], length: 15, using: :btree)
81
+ end
82
+
83
+ def test_index_in_create
84
+ %w(SPATIAL FULLTEXT UNIQUE).each do |type|
85
+ expected = /\ACREATE TABLE `people` \(#{type} INDEX `index_people_on_last_name` \(`last_name`\)\)/
86
+ actual = ActiveRecord::Base.lease_connection.create_table(:people, id: false) do |t|
87
+ t.index :last_name, type: type
88
+ end
89
+ assert_match expected, actual
90
+ end
91
+
92
+ expected = /\ACREATE TABLE `people` \(INDEX `index_people_on_last_name` USING btree \(`last_name`\(10\)\)\)/
93
+ actual = ActiveRecord::Base.lease_connection.create_table(:people, id: false) do |t|
94
+ t.index :last_name, length: 10, using: :btree
95
+ end
96
+ assert_match expected, actual
97
+ end
98
+
99
+ def test_index_in_bulk_change
100
+ %w(SPATIAL FULLTEXT UNIQUE).each do |type|
101
+ expected = "ALTER TABLE `people` ADD #{type} INDEX `index_people_on_last_name` (`last_name`)"
102
+ assert_queries_match(expected) do
103
+ ActiveRecord::Base.lease_connection.change_table(:people, bulk: true) do |t|
104
+ t.index :last_name, type: type
105
+ end
106
+ end
107
+ end
108
+
109
+ expected = "ALTER TABLE `people` ADD INDEX `index_people_on_last_name` USING btree (`last_name`(10)), ALGORITHM = COPY"
110
+ assert_queries_match(expected) do
111
+ ActiveRecord::Base.lease_connection.change_table(:people, bulk: true) do |t|
112
+ t.index :last_name, length: 10, using: :btree, algorithm: :copy
113
+ end
114
+ end
115
+ end
116
+
117
+ def test_drop_table
118
+ assert_equal "DROP TABLE `people`", drop_table(:people)
119
+ end
120
+
121
+ def test_drop_tables
122
+ assert_equal "DROP TABLE `people`, `sobrinho`", drop_table(:people, :sobrinho)
123
+ end
124
+
125
+ def test_create_mysql_database_with_encoding
126
+ if ActiveRecord::Base.lease_connection.send(:row_format_dynamic_by_default?)
127
+ assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8mb4`", create_database(:matt)
128
+ else
129
+ error = assert_raises(RuntimeError) { create_database(:matt) }
130
+ expected = "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
131
+ assert_equal expected, error.message
132
+ end
133
+ assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, charset: "latin1")
134
+ assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT COLLATE `utf8mb4_bin`", create_database(:matt_aimonetti, collation: "utf8mb4_bin")
135
+ end
136
+
137
+ def test_recreate_mysql_database_with_encoding
138
+ create_database(:luca, charset: "latin1")
139
+ assert_equal "CREATE DATABASE `luca` DEFAULT CHARACTER SET `latin1`", recreate_database(:luca, charset: "latin1")
140
+ end
141
+
142
+ def test_add_column
143
+ assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string)
144
+ end
145
+
146
+ def test_add_column_with_limit
147
+ assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, limit: 32)
148
+ end
149
+
150
+ def test_drop_table_with_specific_database
151
+ assert_equal "DROP TABLE `otherdb`.`people`", drop_table("otherdb.people")
152
+ end
153
+
154
+ def test_drop_tables_with_specific_database
155
+ assert_equal "DROP TABLE `otherdb`.`people`, `otherdb`.`sobrinho`", drop_table("otherdb.people", "otherdb.sobrinho")
156
+ end
157
+
158
+ def test_add_timestamps
159
+ with_real_execute do
160
+ ActiveRecord::Base.lease_connection.create_table :delete_me
161
+ ActiveRecord::Base.lease_connection.add_timestamps :delete_me, null: true
162
+ assert column_exists?("delete_me", "updated_at", "datetime")
163
+ assert column_exists?("delete_me", "created_at", "datetime")
164
+ ensure
165
+ ActiveRecord::Base.lease_connection.drop_table :delete_me rescue nil
166
+ end
167
+ end
168
+
169
+ def test_remove_timestamps
170
+ with_real_execute do
171
+ ActiveRecord::Base.lease_connection.create_table :delete_me do |t|
172
+ t.timestamps null: true
173
+ end
174
+ ActiveRecord::Base.lease_connection.remove_timestamps :delete_me, null: true
175
+ assert_not column_exists?("delete_me", "updated_at", "datetime")
176
+ assert_not column_exists?("delete_me", "created_at", "datetime")
177
+ ensure
178
+ ActiveRecord::Base.lease_connection.drop_table :delete_me rescue nil
179
+ end
180
+ end
181
+
182
+ def test_indexes_in_create
183
+ expected = /\ACREATE TEMPORARY TABLE `temp` \(INDEX `index_temp_on_zip` \(`zip`\)\)(?: ROW_FORMAT=DYNAMIC)? AS SELECT id, name, zip FROM a_really_complicated_query/
184
+ actual = ActiveRecord::Base.lease_connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t|
185
+ t.index :zip
186
+ end
187
+
188
+ assert_match expected, actual
189
+ end
190
+
191
+ private
192
+ def with_real_execute
193
+ ActiveRecord::Base.lease_connection.singleton_class.class_eval do
194
+ alias_method :execute_with_stub, :execute
195
+ remove_method :execute
196
+ alias_method :execute, :execute_without_stub
197
+ end
198
+
199
+ yield
200
+ ensure
201
+ ActiveRecord::Base.lease_connection.singleton_class.class_eval do
202
+ remove_method :execute
203
+ alias_method :execute, :execute_with_stub
204
+ end
205
+ end
206
+
207
+ def method_missing(...)
208
+ ActiveRecord::Base.lease_connection.public_send(...)
209
+ end
210
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/ddl_helper"
5
+
6
+ class AdapterPreventWritesTest < ActiveRecord::AbstractMysqlTestCase
7
+ include DdlHelper
8
+
9
+ def setup
10
+ @conn = ActiveRecord::Base.lease_connection
11
+ end
12
+
13
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
14
+ ActiveRecord::Base.while_preventing_writes do
15
+ assert_raises(ActiveRecord::ReadOnlyError) do
16
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
22
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
23
+
24
+ ActiveRecord::Base.while_preventing_writes do
25
+ assert_raises(ActiveRecord::ReadOnlyError) do
26
+ @conn.update("UPDATE `engines` SET `engines`.`car_id` = '9989' WHERE `engines`.`car_id` = '138853948594'")
27
+ end
28
+ end
29
+ end
30
+
31
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
32
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
33
+
34
+ ActiveRecord::Base.while_preventing_writes do
35
+ assert_raises(ActiveRecord::ReadOnlyError) do
36
+ @conn.execute("DELETE FROM `engines` where `engines`.`car_id` = '138853948594'")
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_errors_when_a_replace_query_is_called_while_preventing_writes
42
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
43
+
44
+ ActiveRecord::Base.while_preventing_writes do
45
+ assert_raises(ActiveRecord::ReadOnlyError) do
46
+ @conn.execute("REPLACE INTO `engines` SET `engines`.`car_id` = '249823948'")
47
+ end
48
+ end
49
+ end
50
+
51
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
52
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
53
+
54
+ ActiveRecord::Base.while_preventing_writes do
55
+ assert_equal 1, @conn.execute("SELECT `engines`.* FROM `engines` WHERE `engines`.`car_id` = '138853948594'").entries.count
56
+ end
57
+ end
58
+
59
+ def test_doesnt_error_when_a_show_query_is_called_while_preventing_writes
60
+ ActiveRecord::Base.while_preventing_writes do
61
+ assert_equal 2, @conn.execute("SHOW FULL FIELDS FROM `engines`").entries.count
62
+ end
63
+ end
64
+
65
+ def test_doesnt_error_when_a_set_query_is_called_while_preventing_writes
66
+ ActiveRecord::Base.while_preventing_writes do
67
+ assert_nothing_raised { @conn.execute("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci") }
68
+ end
69
+ end
70
+
71
+ def test_doesnt_error_when_a_describe_query_is_called_while_preventing_writes
72
+ ActiveRecord::Base.while_preventing_writes do
73
+ assert_equal 2, @conn.execute("DESCRIBE engines").entries.count
74
+ end
75
+ end
76
+
77
+ def test_doesnt_error_when_a_desc_query_is_called_while_preventing_writes
78
+ ActiveRecord::Base.while_preventing_writes do
79
+ assert_equal 2, @conn.execute("DESC engines").entries.count
80
+ end
81
+ end
82
+
83
+ def test_doesnt_error_when_a_read_query_with_leading_chars_is_called_while_preventing_writes
84
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
85
+
86
+ ActiveRecord::Base.while_preventing_writes do
87
+ assert_equal 1, @conn.execute("/*action:index*/(\n( SELECT `engines`.* FROM `engines` WHERE `engines`.`car_id` = '138853948594' ) )").entries.count
88
+ end
89
+ end
90
+
91
+ def test_doesnt_error_when_a_use_query_is_called_while_preventing_writes
92
+ ActiveRecord::Base.while_preventing_writes do
93
+ db_name = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").database
94
+ assert_nothing_raised { @conn.execute("USE #{db_name}") }
95
+ end
96
+ end
97
+
98
+ def test_doesnt_error_when_a_kill_query_is_called_while_preventing_writes
99
+ ActiveRecord::Base.while_preventing_writes do
100
+ conn_id = @conn.execute("SELECT CONNECTION_ID() as connection_id").to_a[0][0]
101
+ assert_raises(ActiveRecord::QueryCanceled) do
102
+ @conn.execute("KILL QUERY #{conn_id}")
103
+ end
104
+ end
105
+ end
106
+
107
+ private
108
+ def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
109
+ super(@conn, "ex", definition, &block)
110
+ end
111
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/schema_dumping_helper"
5
+
6
+ class AutoIncrementTest < ActiveRecord::AbstractMysqlTestCase
7
+ include SchemaDumpingHelper
8
+
9
+ def setup
10
+ @connection = ActiveRecord::Base.lease_connection
11
+ end
12
+
13
+ def teardown
14
+ @connection.drop_table :auto_increments, if_exists: true
15
+ end
16
+
17
+ def test_auto_increment_without_primary_key
18
+ @connection.create_table :auto_increments, id: false, force: true do |t|
19
+ t.integer :id, null: false, auto_increment: true
20
+ t.index :id
21
+ end
22
+ output = dump_table_schema("auto_increments")
23
+ assert_match(/t\.integer\s+"id",\s+null: false,\s+auto_increment: true$/, output)
24
+ end
25
+
26
+ def test_auto_increment_with_composite_primary_key
27
+ @connection.create_table :auto_increments, primary_key: [:id, :created_at], force: true do |t|
28
+ t.integer :id, null: false, auto_increment: true
29
+ t.datetime :created_at, null: false
30
+ end
31
+ output = dump_table_schema("auto_increments")
32
+ assert_match(/t\.integer\s+"id",\s+null: false,\s+auto_increment: true$/, output)
33
+ end
34
+
35
+ def test_auto_increment_false_with_custom_primary_key
36
+ @connection.create_table :auto_increments, id: false, force: :cascade do |t|
37
+ t.primary_key :id, auto_increment: false
38
+ end
39
+
40
+ assert_not_predicate @connection.columns(:auto_increments).first, :auto_increment?
41
+ end
42
+
43
+ def test_auto_increment_false_with_create_table
44
+ @connection.create_table :auto_increments, auto_increment: false, force: :cascade
45
+
46
+ assert_not_predicate @connection.columns(:auto_increments).first, :auto_increment?
47
+ end
48
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/topic"
5
+ require "models/post"
6
+
7
+ module ActiveRecord
8
+ module ConnectionAdapters
9
+ class AbstractMysqlAdapter
10
+ class BindParameterTest < ActiveRecord::AbstractMysqlTestCase
11
+ fixtures :topics, :posts
12
+
13
+ def test_update_question_marks
14
+ str = "foo?bar"
15
+ x = Topic.first
16
+ x.title = str
17
+ x.content = str
18
+ x.save!
19
+ x.reload
20
+ assert_equal str, x.title
21
+ assert_equal str, x.content
22
+ end
23
+
24
+ def test_create_question_marks
25
+ str = "foo?bar"
26
+ x = Topic.create!(title: str, content: str)
27
+ x.reload
28
+ assert_equal str, x.title
29
+ assert_equal str, x.content
30
+ end
31
+
32
+ def test_update_null_bytes
33
+ str = "foo\0bar"
34
+ x = Topic.first
35
+ x.title = str
36
+ x.content = str
37
+ x.save!
38
+ x.reload
39
+ assert_equal str, x.title
40
+ assert_equal str, x.content
41
+ end
42
+
43
+ def test_create_null_bytes
44
+ str = "foo\0bar"
45
+ x = Topic.create!(title: str, content: str)
46
+ x.reload
47
+ assert_equal str, x.title
48
+ assert_equal str, x.content
49
+ end
50
+
51
+ def test_where_with_string_for_string_column_using_bind_parameters
52
+ assert_quoted_as "'Welcome to the weblog'", "Welcome to the weblog", match: 1
53
+ end
54
+
55
+ def test_where_with_integer_for_string_column_using_bind_parameters
56
+ assert_quoted_as "'0'", 0
57
+ end
58
+
59
+ def test_where_with_float_for_string_column_using_bind_parameters
60
+ assert_quoted_as "'0.0'", 0.0
61
+ end
62
+
63
+ def test_where_with_boolean_for_string_column_using_bind_parameters
64
+ assert_quoted_as "'0'", false
65
+ end
66
+
67
+ def test_where_with_decimal_for_string_column_using_bind_parameters
68
+ assert_quoted_as "'0.0'", BigDecimal(0)
69
+ end
70
+
71
+ def test_where_with_rational_for_string_column_using_bind_parameters
72
+ assert_quoted_as "'0.0'", Rational(0)
73
+ end
74
+
75
+ private
76
+ def assert_quoted_as(expected, value, match: 0)
77
+ relation = Post.where("title = ?", value)
78
+ assert_equal(
79
+ %{SELECT `posts`.* FROM `posts` WHERE (title = #{expected})},
80
+ relation.to_sql,
81
+ )
82
+ if match == 0
83
+ assert_empty relation.to_a
84
+ else
85
+ assert_equal match, relation.count
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ class CaseSensitivityTest < ActiveRecord::AbstractMysqlTestCase
6
+ class CollationTest < ActiveRecord::Base
7
+ end
8
+
9
+ repair_validations(CollationTest)
10
+
11
+ def test_columns_include_collation_different_from_table
12
+ assert_equal "utf8mb4_bin", CollationTest.columns_hash["string_cs_column"].collation
13
+ assert_equal "utf8mb4_general_ci", CollationTest.columns_hash["string_ci_column"].collation
14
+ end
15
+
16
+ def test_case_sensitive
17
+ assert_not_predicate CollationTest.columns_hash["string_ci_column"], :case_sensitive?
18
+ assert_predicate CollationTest.columns_hash["string_cs_column"], :case_sensitive?
19
+ end
20
+
21
+ def test_case_insensitive_comparison_for_ci_column
22
+ CollationTest.validates_uniqueness_of(:string_ci_column, case_sensitive: false)
23
+ CollationTest.create!(string_ci_column: "A")
24
+ invalid = CollationTest.new(string_ci_column: "a")
25
+ queries = capture_sql { invalid.save }
26
+ ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) }
27
+ assert_no_match(/lower/i, ci_uniqueness_query)
28
+ end
29
+
30
+ def test_case_insensitive_comparison_for_cs_column
31
+ CollationTest.validates_uniqueness_of(:string_cs_column, case_sensitive: false)
32
+ CollationTest.create!(string_cs_column: "A")
33
+ invalid = CollationTest.new(string_cs_column: "a")
34
+ queries = capture_sql { invalid.save }
35
+ cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) }
36
+ assert_match(/lower/i, cs_uniqueness_query)
37
+ end
38
+
39
+ def test_case_sensitive_comparison_for_ci_column
40
+ CollationTest.validates_uniqueness_of(:string_ci_column, case_sensitive: true)
41
+ CollationTest.create!(string_ci_column: "A")
42
+ invalid = CollationTest.new(string_ci_column: "A")
43
+ queries = capture_sql { invalid.save }
44
+ ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) }
45
+ assert_match(/binary/i, ci_uniqueness_query)
46
+ end
47
+
48
+ def test_case_sensitive_comparison_for_cs_column
49
+ CollationTest.validates_uniqueness_of(:string_cs_column, case_sensitive: true)
50
+ CollationTest.create!(string_cs_column: "A")
51
+ invalid = CollationTest.new(string_cs_column: "A")
52
+ queries = capture_sql { invalid.save }
53
+ cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) }
54
+ assert_no_match(/binary/i, cs_uniqueness_query)
55
+ end
56
+
57
+ def test_case_sensitive_comparison_for_binary_column
58
+ CollationTest.validates_uniqueness_of(:binary_column, case_sensitive: true)
59
+ CollationTest.create!(binary_column: "A")
60
+ invalid = CollationTest.new(binary_column: "A")
61
+ queries = capture_sql { invalid.save }
62
+ bin_uniqueness_query = queries.detect { |q| q.match(/binary_column/) }
63
+ assert_no_match(/\bBINARY\b/, bin_uniqueness_query)
64
+ end
65
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/schema_dumping_helper"
5
+
6
+ class CharsetCollationTest < ActiveRecord::AbstractMysqlTestCase
7
+ include SchemaDumpingHelper
8
+
9
+ setup do
10
+ @connection = ActiveRecord::Base.lease_connection
11
+ @connection.create_table :charset_collations, id: { type: :string, collation: "utf8mb4_bin" }, force: true do |t|
12
+ t.string :string_ascii_bin, charset: "ascii", collation: "ascii_bin"
13
+ t.text :text_ucs2_unicode_ci, charset: "ucs2", collation: "ucs2_unicode_ci"
14
+ end
15
+ end
16
+
17
+ teardown do
18
+ @connection.drop_table :charset_collations, if_exists: true
19
+ end
20
+
21
+ test "string column with charset and collation" do
22
+ column = @connection.columns(:charset_collations).find { |c| c.name == "string_ascii_bin" }
23
+ assert_equal :string, column.type
24
+ assert_equal "ascii_bin", column.collation
25
+ end
26
+
27
+ test "text column with charset and collation" do
28
+ column = @connection.columns(:charset_collations).find { |c| c.name == "text_ucs2_unicode_ci" }
29
+ assert_equal :text, column.type
30
+ assert_equal "ucs2_unicode_ci", column.collation
31
+ end
32
+
33
+ test "add column with charset and collation" do
34
+ @connection.add_column :charset_collations, :title, :string, charset: "utf8mb4", collation: "utf8mb4_bin"
35
+
36
+ column = @connection.columns(:charset_collations).find { |c| c.name == "title" }
37
+ assert_equal :string, column.type
38
+ assert_equal "utf8mb4_bin", column.collation
39
+ end
40
+
41
+ test "change column with charset and collation" do
42
+ @connection.add_column :charset_collations, :description, :string, charset: "utf8mb4", collation: "utf8mb4_unicode_ci"
43
+ @connection.change_column :charset_collations, :description, :text, charset: "utf8mb4", collation: "utf8mb4_general_ci"
44
+
45
+ column = @connection.columns(:charset_collations).find { |c| c.name == "description" }
46
+ assert_equal :text, column.type
47
+ assert_equal "utf8mb4_general_ci", column.collation
48
+ end
49
+
50
+ test "change column doesn't preserve collation for string to binary types" do
51
+ @connection.add_column :charset_collations, :description, :string, charset: "utf8mb4", collation: "utf8mb4_unicode_ci"
52
+ @connection.change_column :charset_collations, :description, :binary
53
+
54
+ column = @connection.columns(:charset_collations).find { |c| c.name == "description" }
55
+
56
+ assert_equal :binary, column.type
57
+ assert_nil column.collation
58
+ end
59
+
60
+ test "change column doesn't preserve collation for string to non-string types" do
61
+ @connection.add_column :charset_collations, :description, :string, charset: "utf8mb4", collation: "utf8mb4_unicode_ci"
62
+ @connection.change_column :charset_collations, :description, :int
63
+
64
+ column = @connection.columns(:charset_collations).find { |c| c.name == "description" }
65
+
66
+ assert_equal :integer, column.type
67
+ assert_nil column.collation
68
+ end
69
+
70
+ test "change column preserves collation for string to text" do
71
+ @connection.add_column :charset_collations, :description, :string, charset: "utf8mb4", collation: "utf8mb4_unicode_ci"
72
+ @connection.change_column :charset_collations, :description, :text
73
+
74
+ column = @connection.columns(:charset_collations).find { |c| c.name == "description" }
75
+ assert_equal :text, column.type
76
+ assert_equal "utf8mb4_unicode_ci", column.collation
77
+ end
78
+
79
+ test "schema dump includes collation" do
80
+ output = dump_table_schema("charset_collations")
81
+ assert_match %r/create_table "charset_collations", id: { type: :string, collation: "utf8mb4_bin" }/, output
82
+ assert_match %r{t\.string\s+"string_ascii_bin",\s+collation: "ascii_bin"$}, output
83
+ assert_match %r{t\.text\s+"text_ucs2_unicode_ci",\s+collation: "ucs2_unicode_ci"$}, output
84
+ end
85
+ end