ibm_db 5.1.0-x86-mingw32 → 5.3.2-x86-mingw32

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 (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/ddl_helper"
5
+
6
+ class Mysql2AdapterPreventWritesTest < ActiveRecord::Mysql2TestCase
7
+ include DdlHelper
8
+
9
+ def setup
10
+ @conn = ActiveRecord::Base.connection
11
+ end
12
+
13
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
14
+ assert_raises(ActiveRecord::ReadOnlyError) do
15
+ ActiveRecord::Base.while_preventing_writes 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
+ assert_raises(ActiveRecord::ReadOnlyError) do
25
+ ActiveRecord::Base.while_preventing_writes 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
+ assert_raises(ActiveRecord::ReadOnlyError) do
35
+ ActiveRecord::Base.while_preventing_writes 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
+ assert_raises(ActiveRecord::ReadOnlyError) do
45
+ ActiveRecord::Base.while_preventing_writes 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_nil @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_nil @conn.execute("USE #{db_name}")
95
+ end
96
+ end
97
+
98
+ private
99
+ def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
100
+ super(@conn, "ex", definition, &block)
101
+ end
102
+ end
103
+
104
+ class Mysql2AdapterPreventWritesLegacyTest < ActiveRecord::Mysql2TestCase
105
+ include DdlHelper
106
+
107
+ def setup
108
+ @old_value = ActiveRecord::Base.legacy_connection_handling
109
+ ActiveRecord::Base.legacy_connection_handling = true
110
+
111
+ @conn = ActiveRecord::Base.connection
112
+ @connection_handler = ActiveRecord::Base.connection_handler
113
+ end
114
+
115
+ def teardown
116
+ ActiveRecord::Base.legacy_connection_handling = @old_value
117
+ end
118
+
119
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
120
+ assert_raises(ActiveRecord::ReadOnlyError) do
121
+ @connection_handler.while_preventing_writes do
122
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
123
+ end
124
+ end
125
+ end
126
+
127
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
128
+ @conn.insert("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
129
+
130
+ assert_raises(ActiveRecord::ReadOnlyError) do
131
+ @connection_handler.while_preventing_writes do
132
+ @conn.update("UPDATE `engines` SET `engines`.`car_id` = '9989' WHERE `engines`.`car_id` = '138853948594'")
133
+ end
134
+ end
135
+ end
136
+
137
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
138
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
139
+
140
+ assert_raises(ActiveRecord::ReadOnlyError) do
141
+ @connection_handler.while_preventing_writes do
142
+ @conn.execute("DELETE FROM `engines` where `engines`.`car_id` = '138853948594'")
143
+ end
144
+ end
145
+ end
146
+
147
+ def test_errors_when_a_replace_query_is_called_while_preventing_writes
148
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
149
+
150
+ assert_raises(ActiveRecord::ReadOnlyError) do
151
+ @connection_handler.while_preventing_writes do
152
+ @conn.execute("REPLACE INTO `engines` SET `engines`.`car_id` = '249823948'")
153
+ end
154
+ end
155
+ end
156
+
157
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
158
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
159
+
160
+ @connection_handler.while_preventing_writes do
161
+ assert_equal 1, @conn.execute("SELECT `engines`.* FROM `engines` WHERE `engines`.`car_id` = '138853948594'").entries.count
162
+ end
163
+ end
164
+
165
+ def test_doesnt_error_when_a_show_query_is_called_while_preventing_writes
166
+ @connection_handler.while_preventing_writes do
167
+ assert_equal 2, @conn.execute("SHOW FULL FIELDS FROM `engines`").entries.count
168
+ end
169
+ end
170
+
171
+ def test_doesnt_error_when_a_set_query_is_called_while_preventing_writes
172
+ @connection_handler.while_preventing_writes do
173
+ assert_nil @conn.execute("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci")
174
+ end
175
+ end
176
+
177
+ def test_doesnt_error_when_a_describe_query_is_called_while_preventing_writes
178
+ @connection_handler.while_preventing_writes do
179
+ assert_equal 2, @conn.execute("DESCRIBE engines").entries.count
180
+ end
181
+ end
182
+
183
+ def test_doesnt_error_when_a_desc_query_is_called_while_preventing_writes
184
+ @connection_handler.while_preventing_writes do
185
+ assert_equal 2, @conn.execute("DESC engines").entries.count
186
+ end
187
+ end
188
+
189
+ def test_doesnt_error_when_a_read_query_with_leading_chars_is_called_while_preventing_writes
190
+ @conn.execute("INSERT INTO `engines` (`car_id`) VALUES ('138853948594')")
191
+
192
+ @connection_handler.while_preventing_writes do
193
+ assert_equal 1, @conn.execute("/*action:index*/(\n( SELECT `engines`.* FROM `engines` WHERE `engines`.`car_id` = '138853948594' ) )").entries.count
194
+ end
195
+ end
196
+
197
+ def test_doesnt_error_when_a_use_query_is_called_while_preventing_writes
198
+ @connection_handler.while_preventing_writes do
199
+ db_name = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").database
200
+ assert_nil @conn.execute("USE #{db_name}")
201
+ end
202
+ end
203
+
204
+ private
205
+ def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
206
+ super(@conn, "ex", definition, &block)
207
+ end
208
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
4
  require "support/ddl_helper"
3
5
 
@@ -6,26 +8,58 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
6
8
 
7
9
  def setup
8
10
  @conn = ActiveRecord::Base.connection
11
+ @connection_handler = ActiveRecord::Base.connection_handler
12
+ end
13
+
14
+ def test_connection_error
15
+ assert_raises ActiveRecord::ConnectionNotEstablished do
16
+ ActiveRecord::Base.mysql2_connection(socket: File::NULL)
17
+ end
18
+ end
19
+
20
+ def test_reconnection_error
21
+ fake_connection = Class.new do
22
+ def query_options
23
+ {}
24
+ end
25
+
26
+ def query(*)
27
+ end
28
+
29
+ def close
30
+ end
31
+ end.new
32
+ @conn = ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(
33
+ fake_connection,
34
+ ActiveRecord::Base.logger,
35
+ nil,
36
+ { socket: File::NULL }
37
+ )
38
+ assert_raises ActiveRecord::ConnectionNotEstablished do
39
+ @conn.reconnect!
40
+ end
9
41
  end
10
42
 
11
43
  def test_exec_query_nothing_raises_with_no_result_queries
12
44
  assert_nothing_raised do
13
45
  with_example_table do
14
- @conn.exec_query('INSERT INTO ex (number) VALUES (1)')
15
- @conn.exec_query('DELETE FROM ex WHERE number = 1')
46
+ @conn.exec_query("INSERT INTO ex (number) VALUES (1)")
47
+ @conn.exec_query("DELETE FROM ex WHERE number = 1")
16
48
  end
17
49
  end
18
50
  end
19
51
 
20
- def test_valid_column
21
- with_example_table do
22
- column = @conn.columns('ex').find { |col| col.name == 'id' }
23
- assert @conn.valid_type?(column.type)
24
- end
52
+ def test_database_exists_returns_false_if_database_does_not_exist
53
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
54
+ config = db_config.configuration_hash.merge(database: "inexistent_activerecord_unittest")
55
+ assert_not ActiveRecord::ConnectionAdapters::Mysql2Adapter.database_exists?(config),
56
+ "expected database to not exist"
25
57
  end
26
58
 
27
- def test_invalid_column
28
- assert_not @conn.valid_type?(:foobar)
59
+ def test_database_exists_returns_true_when_the_database_exists
60
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
61
+ assert ActiveRecord::ConnectionAdapters::Mysql2Adapter.database_exists?(db_config.configuration_hash),
62
+ "expected database #{db_config.database} to exist"
29
63
  end
30
64
 
31
65
  def test_columns_for_distinct_zero_orders
@@ -34,50 +68,171 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
34
68
  end
35
69
 
36
70
  def test_columns_for_distinct_one_order
37
- assert_equal "posts.id, posts.created_at AS alias_0",
71
+ assert_equal "posts.created_at AS alias_0, posts.id",
38
72
  @conn.columns_for_distinct("posts.id", ["posts.created_at desc"])
39
73
  end
40
74
 
41
75
  def test_columns_for_distinct_few_orders
42
- assert_equal "posts.id, posts.created_at AS alias_0, posts.position AS alias_1",
76
+ assert_equal "posts.created_at AS alias_0, posts.position AS alias_1, posts.id",
43
77
  @conn.columns_for_distinct("posts.id", ["posts.created_at desc", "posts.position asc"])
44
78
  end
45
79
 
46
80
  def test_columns_for_distinct_with_case
47
81
  assert_equal(
48
- 'posts.id, CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0',
49
- @conn.columns_for_distinct('posts.id',
82
+ "CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END AS alias_0, posts.id",
83
+ @conn.columns_for_distinct("posts.id",
50
84
  ["CASE WHEN author.is_active THEN UPPER(author.name) ELSE UPPER(author.email) END"])
51
85
  )
52
86
  end
53
87
 
54
88
  def test_columns_for_distinct_blank_not_nil_orders
55
- assert_equal "posts.id, posts.created_at AS alias_0",
89
+ assert_equal "posts.created_at AS alias_0, posts.id",
56
90
  @conn.columns_for_distinct("posts.id", ["posts.created_at desc", "", " "])
57
91
  end
58
92
 
59
93
  def test_columns_for_distinct_with_arel_order
60
- order = Object.new
61
- def order.to_sql
62
- "posts.created_at desc"
63
- end
64
- assert_equal "posts.id, posts.created_at AS alias_0",
94
+ Arel::Table.engine = nil # should not rely on the global Arel::Table.engine
95
+
96
+ order = Arel.sql("posts.created_at").desc
97
+ assert_equal "posts.created_at AS alias_0, posts.id",
65
98
  @conn.columns_for_distinct("posts.id", [order])
99
+ ensure
100
+ Arel::Table.engine = ActiveRecord::Base
66
101
  end
67
102
 
68
- def test_table_exists_acts_upon_current_database
69
- previous_db = @conn.select_value("SELECT DATABASE()")
103
+ def test_errors_for_bigint_fks_on_integer_pk_table_in_alter_table
104
+ # table old_cars has primary key of integer
105
+
106
+ error = assert_raises(ActiveRecord::MismatchedForeignKey) do
107
+ @conn.add_reference :engines, :old_car
108
+ @conn.add_foreign_key :engines, :old_cars
109
+ end
70
110
 
71
- assert @conn.table_exists?("accounts")
72
- @conn.execute("USE activerecord_unittest2")
73
- assert_not @conn.table_exists?("accounts")
111
+ assert_match(
112
+ %r/Column `old_car_id` on table `engines` does not match column `id` on `old_cars`, which has type `int(\(11\))?`\./,
113
+ error.message
114
+ )
115
+ assert_match(
116
+ %r/To resolve this issue, change the type of the `old_car_id` column on `engines` to be :integer\. \(For example `t.integer :old_car_id`\)\./,
117
+ error.message
118
+ )
119
+ assert_not_nil error.cause
74
120
  ensure
75
- @conn.execute("USE #{previous_db}")
121
+ @conn.execute("ALTER TABLE engines DROP COLUMN old_car_id") rescue nil
76
122
  end
77
123
 
78
- private
124
+ def test_errors_for_bigint_fks_on_integer_pk_table_in_create_table
125
+ # table old_cars has primary key of integer
79
126
 
80
- def with_example_table(definition = 'id int auto_increment primary key, number int, data varchar(255)', &block)
81
- super(@conn, 'ex', definition, &block)
127
+ error = assert_raises(ActiveRecord::MismatchedForeignKey) do
128
+ @conn.execute(<<~SQL)
129
+ CREATE TABLE activerecord_unittest.foos (
130
+ id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY,
131
+ old_car_id bigint,
132
+ INDEX index_foos_on_old_car_id (old_car_id),
133
+ CONSTRAINT fk_rails_ff771f3c96 FOREIGN KEY (old_car_id) REFERENCES old_cars (id)
134
+ )
135
+ SQL
136
+ end
137
+
138
+ assert_match(
139
+ %r/Column `old_car_id` on table `foos` does not match column `id` on `old_cars`, which has type `int(\(11\))?`\./,
140
+ error.message
141
+ )
142
+ assert_match(
143
+ %r/To resolve this issue, change the type of the `old_car_id` column on `foos` to be :integer\. \(For example `t.integer :old_car_id`\)\./,
144
+ error.message
145
+ )
146
+ assert_not_nil error.cause
147
+ ensure
148
+ @conn.drop_table :foos, if_exists: true
82
149
  end
150
+
151
+ def test_errors_for_integer_fks_on_bigint_pk_table_in_create_table
152
+ # table old_cars has primary key of bigint
153
+
154
+ error = assert_raises(ActiveRecord::MismatchedForeignKey) do
155
+ @conn.execute(<<~SQL)
156
+ CREATE TABLE activerecord_unittest.foos (
157
+ id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY,
158
+ car_id int,
159
+ INDEX index_foos_on_car_id (car_id),
160
+ CONSTRAINT fk_rails_ff771f3c96 FOREIGN KEY (car_id) REFERENCES cars (id)
161
+ )
162
+ SQL
163
+ end
164
+
165
+ assert_match(
166
+ %r/Column `car_id` on table `foos` does not match column `id` on `cars`, which has type `bigint(\(20\))?`\./,
167
+ error.message
168
+ )
169
+ assert_match(
170
+ %r/To resolve this issue, change the type of the `car_id` column on `foos` to be :bigint\. \(For example `t.bigint :car_id`\)\./,
171
+ error.message
172
+ )
173
+ assert_not_nil error.cause
174
+ ensure
175
+ @conn.drop_table :foos, if_exists: true
176
+ end
177
+
178
+ def test_errors_for_bigint_fks_on_string_pk_table_in_create_table
179
+ # table old_cars has primary key of string
180
+
181
+ error = assert_raises(ActiveRecord::MismatchedForeignKey) do
182
+ @conn.execute(<<~SQL)
183
+ CREATE TABLE activerecord_unittest.foos (
184
+ id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY,
185
+ subscriber_id bigint,
186
+ INDEX index_foos_on_subscriber_id (subscriber_id),
187
+ CONSTRAINT fk_rails_ff771f3c96 FOREIGN KEY (subscriber_id) REFERENCES subscribers (nick)
188
+ )
189
+ SQL
190
+ end
191
+
192
+ assert_includes error.message, <<~MSG.squish
193
+ Column `subscriber_id` on table `foos` does not match column `nick` on `subscribers`,
194
+ which has type `varchar(255)`. To resolve this issue, change the type of the `subscriber_id`
195
+ column on `foos` to be :string. (For example `t.string :subscriber_id`).
196
+ MSG
197
+ assert_not_nil error.cause
198
+ ensure
199
+ @conn.drop_table :foos, if_exists: true
200
+ end
201
+
202
+ def test_read_timeout_exception
203
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
204
+
205
+ ActiveRecord::Base.establish_connection(
206
+ db_config.configuration_hash.merge("read_timeout" => 1)
207
+ )
208
+
209
+ error = assert_raises(ActiveRecord::AdapterTimeout) do
210
+ ActiveRecord::Base.connection.execute("SELECT SLEEP(2)")
211
+ end
212
+ assert_kind_of ActiveRecord::QueryAborted, error
213
+
214
+ assert_equal Mysql2::Error::TimeoutError, error.cause.class
215
+ ensure
216
+ ActiveRecord::Base.establish_connection :arunit
217
+ end
218
+
219
+ def test_statement_timeout_error_codes
220
+ raw_conn = @conn.raw_connection
221
+ assert_raises(ActiveRecord::StatementTimeout) do
222
+ raw_conn.stub(:query, ->(_sql) { raise Mysql2::Error.new("fail", 50700, ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::ER_FILSORT_ABORT) }) {
223
+ @conn.execute("SELECT 1")
224
+ }
225
+ end
226
+
227
+ assert_raises(ActiveRecord::StatementTimeout) do
228
+ raw_conn.stub(:query, ->(_sql) { raise Mysql2::Error.new("fail", 50700, ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::ER_QUERY_TIMEOUT) }) {
229
+ @conn.execute("SELECT 1")
230
+ }
231
+ end
232
+ end
233
+
234
+ private
235
+ def with_example_table(definition = "id int auto_increment primary key, number int, data varchar(255)", &block)
236
+ super(@conn, "ex", definition, &block)
237
+ end
83
238
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "support/connection_helper"
5
+
6
+ module ActiveRecord
7
+ class Mysql2NestedDeadlockTest < ActiveRecord::Mysql2TestCase
8
+ self.use_transactional_tests = false
9
+
10
+ class Sample < ActiveRecord::Base
11
+ self.table_name = "samples"
12
+ end
13
+
14
+ setup do
15
+ @abort, Thread.abort_on_exception = Thread.abort_on_exception, false
16
+ Thread.report_on_exception, @original_report_on_exception = false, Thread.report_on_exception
17
+
18
+ connection = ActiveRecord::Base.connection
19
+ connection.clear_cache!
20
+
21
+ connection.create_table("samples", force: true) do |t|
22
+ t.integer "value"
23
+ end
24
+
25
+ Sample.reset_column_information
26
+ end
27
+
28
+ teardown do
29
+ ActiveRecord::Base.clear_active_connections!
30
+ ActiveRecord::Base.connection.drop_table "samples", if_exists: true
31
+
32
+ Thread.abort_on_exception = @abort
33
+ Thread.report_on_exception = @original_report_on_exception
34
+ end
35
+
36
+ test "deadlock correctly raises Deadlocked inside nested SavepointTransaction" do
37
+ assert_raises(ActiveRecord::Deadlocked) do
38
+ barrier = Concurrent::CyclicBarrier.new(2)
39
+
40
+ s1 = Sample.create value: 1
41
+ s2 = Sample.create value: 2
42
+
43
+ begin
44
+ thread = Thread.new do
45
+ Sample.transaction(requires_new: false) do
46
+ Sample.transaction(requires_new: true) do
47
+ s1.lock!
48
+ barrier.wait
49
+ s2.update value: 1
50
+ end
51
+ end
52
+ end
53
+
54
+ begin
55
+ Sample.transaction(requires_new: false) do
56
+ Sample.transaction(requires_new: true) do
57
+ s2.lock!
58
+ barrier.wait
59
+ s1.update value: 2
60
+ end
61
+ end
62
+ ensure
63
+ thread.join
64
+ end
65
+ rescue ActiveRecord::StatementInvalid => e
66
+ if /SAVEPOINT active_record_. does not exist/ =~ e.to_s
67
+ flunk "ROLLBACK TO SAVEPOINT query issued for savepoint that no longer exists due to deadlock: #{e}"
68
+ else
69
+ raise e
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/post"
5
+
6
+ if supports_optimizer_hints?
7
+ class Mysql2OptimzerHintsTest < ActiveRecord::Mysql2TestCase
8
+ fixtures :posts
9
+
10
+ def test_optimizer_hints
11
+ assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
12
+ posts = Post.optimizer_hints("NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id)")
13
+ posts = posts.select(:id).where(author_id: [0, 1])
14
+ assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
15
+ end
16
+ end
17
+
18
+ def test_optimizer_hints_with_count_subquery
19
+ assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
20
+ posts = Post.optimizer_hints("NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id)")
21
+ posts = posts.select(:id).where(author_id: [0, 1]).limit(5)
22
+ assert_equal 5, posts.count
23
+ end
24
+ end
25
+
26
+ def test_optimizer_hints_is_sanitized
27
+ assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
28
+ posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
29
+ posts = posts.select(:id).where(author_id: [0, 1])
30
+ assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
31
+ end
32
+
33
+ assert_sql(%r{\ASELECT /\*\+ `posts`\.\*, \*/}) do
34
+ posts = Post.optimizer_hints("**// `posts`.*, //**")
35
+ posts = posts.select(:id).where(author_id: [0, 1])
36
+ assert_equal({ "id" => 1 }, posts.first.as_json)
37
+ end
38
+ end
39
+
40
+ def test_optimizer_hints_with_unscope
41
+ assert_sql(%r{\ASELECT `posts`\.`id`}) do
42
+ posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
43
+ posts = posts.select(:id).where(author_id: [0, 1])
44
+ posts.unscope(:optimizer_hints).load
45
+ end
46
+ end
47
+
48
+ def test_optimizer_hints_with_or
49
+ assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
50
+ Post.optimizer_hints("NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id)")
51
+ .or(Post.all).load
52
+ end
53
+
54
+ queries = capture_sql do
55
+ Post.optimizer_hints("NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id)")
56
+ .or(Post.optimizer_hints("NO_ICP(posts)")).load
57
+ end
58
+ assert_equal 1, queries.length
59
+ assert_includes queries.first, "NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id)"
60
+ assert_not_includes queries.first, "NO_ICP(posts)"
61
+
62
+ queries = capture_sql do
63
+ Post.all.or(Post.optimizer_hints("NO_ICP(posts)")).load
64
+ end
65
+ assert_equal 1, queries.length
66
+ assert_not_includes queries.first, "NO_ICP(posts)"
67
+ end
68
+ end
69
+ end