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
@@ -1,16 +1,62 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "cases/helper"
2
- require 'models/topic'
3
- require 'models/task'
4
- require 'models/category'
5
- require 'models/post'
6
- require 'rack'
4
+ require "models/topic"
5
+ require "models/task"
6
+ require "models/category"
7
+ require "models/post"
8
+ require "rack"
7
9
 
8
10
  class QueryCacheTest < ActiveRecord::TestCase
11
+ self.use_transactional_tests = false
12
+
9
13
  fixtures :tasks, :topics, :categories, :posts, :categories_posts
10
14
 
11
- teardown do
15
+ class ShouldNotHaveExceptionsLogger < ActiveRecord::LogSubscriber
16
+ attr_reader :logger, :events
17
+
18
+ def initialize
19
+ super
20
+ @logger = ::Logger.new File::NULL
21
+ @exception = false
22
+ @events = []
23
+ end
24
+
25
+ def exception?
26
+ @exception
27
+ end
28
+
29
+ def sql(event)
30
+ @events << event
31
+ super
32
+ rescue
33
+ @exception = true
34
+ end
35
+ end
36
+
37
+ def teardown
12
38
  Task.connection.clear_query_cache
13
39
  ActiveRecord::Base.connection.disable_query_cache!
40
+ super
41
+ end
42
+
43
+ def test_writes_should_always_clear_cache
44
+ assert_cache :off
45
+
46
+ mw = middleware { |env|
47
+ Post.first
48
+ query_cache = ActiveRecord::Base.connection.query_cache
49
+ assert_equal 1, query_cache.length, query_cache.keys
50
+ Post.connection.uncached do
51
+ # should clear the cache
52
+ Post.create!(title: "a new post", body: "and a body")
53
+ end
54
+ query_cache = ActiveRecord::Base.connection.query_cache
55
+ assert_equal 0, query_cache.length, query_cache.keys
56
+ }
57
+ mw.call({})
58
+
59
+ assert_cache :off
14
60
  end
15
61
 
16
62
  def test_exceptional_middleware_clears_and_disables_cache_on_error
@@ -19,7 +65,8 @@ class QueryCacheTest < ActiveRecord::TestCase
19
65
  mw = middleware { |env|
20
66
  Task.find 1
21
67
  Task.find 1
22
- assert_equal 1, ActiveRecord::Base.connection.query_cache.length
68
+ query_cache = ActiveRecord::Base.connection.query_cache
69
+ assert_equal 1, query_cache.length, query_cache.keys
23
70
  raise "lol borked"
24
71
  }
25
72
  assert_raises(RuntimeError) { mw.call({}) }
@@ -27,101 +74,249 @@ class QueryCacheTest < ActiveRecord::TestCase
27
74
  assert_cache :off
28
75
  end
29
76
 
30
- private def with_temporary_connection_pool
31
- old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
32
- new_pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new ActiveRecord::Base.connection_pool.spec
33
- ActiveRecord::Base.connection_handler.send(:owner_to_pool)["primary"] = new_pool
77
+ def test_query_cache_is_applied_to_legacy_connections_in_all_handlers
78
+ old_value = ActiveRecord::Base.legacy_connection_handling
79
+ ActiveRecord::Base.legacy_connection_handling = true
80
+
81
+ ActiveRecord::Base.connection_handlers = {
82
+ writing: ActiveRecord::Base.default_connection_handler,
83
+ reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
84
+ }
34
85
 
35
- yield
86
+ ActiveRecord::Base.connected_to(role: :reading) do
87
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
88
+ ActiveRecord::Base.establish_connection(db_config)
89
+ end
90
+
91
+ mw = middleware { |env|
92
+ reading_handler = ActiveRecord::Base.connection_handlers[:reading]
93
+ ro_pool = reading_handler.connection_pool_list
94
+ ro_conn = ro_pool.first.connection
95
+ assert_predicate ActiveRecord::Base.connection, :query_cache_enabled
96
+ assert_predicate ro_conn, :query_cache_enabled
97
+ }
98
+
99
+ mw.call({})
36
100
  ensure
37
- ActiveRecord::Base.connection_handler.send(:owner_to_pool)["primary"] = old_pool
101
+ clean_up_legacy_connection_handlers
102
+ ActiveRecord::Base.legacy_connection_handling = old_value
38
103
  end
39
104
 
40
- def test_query_cache_across_threads
41
- with_temporary_connection_pool do
42
- begin
43
- if in_memory_db?
44
- # Separate connections to an in-memory database create an entirely new database,
45
- # with an empty schema etc, so we just stub out this schema on the fly.
46
- ActiveRecord::Base.connection_pool.with_connection do |connection|
47
- connection.create_table :tasks do |t|
48
- t.datetime :starting
49
- t.datetime :ending
50
- end
51
- end
52
- ActiveRecord::FixtureSet.create_fixtures(self.class.fixture_path, ["tasks"], {}, ActiveRecord::Base)
53
- end
105
+ def test_query_cache_is_applied_to_all_connections
106
+ ActiveRecord::Base.connected_to(role: :reading) do
107
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
108
+ ActiveRecord::Base.establish_connection(db_config)
109
+ end
54
110
 
55
- ActiveRecord::Base.connection_pool.connections.each do |conn|
56
- assert_cache :off, conn
57
- end
111
+ mw = middleware { |env|
112
+ rw_conn = ActiveRecord::Base.connection_handler.connection_pool_list(:writing).first.connection
113
+ assert_predicate rw_conn, :query_cache_enabled
58
114
 
59
- assert !ActiveRecord::Base.connection.nil?
60
- assert_cache :off
115
+ ro_conn = ActiveRecord::Base.connection_handler.connection_pool_list(:reading).first.connection
116
+ assert_predicate ActiveRecord::Base.connection, :query_cache_enabled
117
+ assert_predicate ro_conn, :query_cache_enabled
118
+ }
61
119
 
62
- middleware {
63
- assert_cache :clean
120
+ mw.call({})
121
+ ensure
122
+ clean_up_connection_handler
123
+ end
64
124
 
65
- Task.find 1
66
- assert_cache :dirty
125
+ if Process.respond_to?(:fork) && !in_memory_db?
126
+ def test_query_cache_with_multiple_handlers_and_forked_processes_legacy_handling
127
+ old_value = ActiveRecord::Base.legacy_connection_handling
128
+ ActiveRecord::Base.legacy_connection_handling = true
129
+ ActiveRecord::Base.connection_handlers = {
130
+ writing: ActiveRecord::Base.default_connection_handler,
131
+ reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
132
+ }
133
+
134
+ ActiveRecord::Base.connected_to(role: :reading) do
135
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
136
+ ActiveRecord::Base.establish_connection(db_config)
137
+ end
67
138
 
68
- thread_1_connection = ActiveRecord::Base.connection
69
- ActiveRecord::Base.clear_active_connections!
70
- assert_cache :off, thread_1_connection
139
+ rd, wr = IO.pipe
140
+ rd.binmode
141
+ wr.binmode
71
142
 
72
- started = Concurrent::Event.new
73
- checked = Concurrent::Event.new
143
+ pid = fork {
144
+ rd.close
145
+ status = 0
74
146
 
75
- thread_2_connection = nil
76
- thread = Thread.new {
77
- thread_2_connection = ActiveRecord::Base.connection
147
+ middleware { |env|
148
+ begin
149
+ assert_cache :clean
78
150
 
79
- assert_equal thread_2_connection, thread_1_connection
80
- assert_cache :off
151
+ # first request dirties cache
152
+ ActiveRecord::Base.connected_to(role: :reading) do
153
+ Post.first
154
+ assert_cache :dirty
155
+ end
81
156
 
82
- middleware {
157
+ # should clear the cache
158
+ Post.create!(title: "a new post", body: "and a body")
159
+
160
+ # fails because cache is still dirty
161
+ ActiveRecord::Base.connected_to(role: :reading) do
83
162
  assert_cache :clean
163
+ Post.first
164
+ end
84
165
 
85
- Task.find 1
86
- assert_cache :dirty
166
+ rescue Minitest::Assertion => e
167
+ wr.write Marshal.dump e
168
+ status = 1
169
+ end
170
+ }.call({})
171
+
172
+ wr.close
173
+ exit!(status)
174
+ }
175
+
176
+ wr.close
177
+
178
+ Process.waitpid pid
179
+ if !$?.success?
180
+ raise Marshal.load(rd.read)
181
+ else
182
+ assert_predicate $?, :success?
183
+ end
87
184
 
88
- started.set
89
- checked.wait
185
+ rd.close
186
+ ensure
187
+ clean_up_legacy_connection_handlers
188
+ ActiveRecord::Base.legacy_connection_handling = old_value
189
+ end
190
+
191
+ def test_query_cache_with_forked_processes
192
+ ActiveRecord::Base.connected_to(role: :reading) do
193
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
194
+ ActiveRecord::Base.establish_connection(db_config)
195
+ end
90
196
 
91
- ActiveRecord::Base.clear_active_connections!
92
- }.call({})
93
- }
197
+ rd, wr = IO.pipe
198
+ rd.binmode
199
+ wr.binmode
94
200
 
95
- started.wait
201
+ pid = fork {
202
+ rd.close
203
+ status = 0
204
+
205
+ middleware { |env|
206
+ begin
207
+ assert_cache :clean
208
+
209
+ # first request dirties cache
210
+ ActiveRecord::Base.connected_to(role: :reading) do
211
+ Post.first
212
+ assert_cache :dirty
213
+ end
96
214
 
97
- thread_1_connection = ActiveRecord::Base.connection
98
- assert_not_equal thread_1_connection, thread_2_connection
99
- assert_cache :dirty, thread_2_connection
100
- checked.set
101
- thread.join
215
+ # should clear the cache
216
+ Post.create!(title: "a new post", body: "and a body")
102
217
 
103
- assert_cache :off, thread_2_connection
218
+ # fails because cache is still dirty
219
+ ActiveRecord::Base.connected_to(role: :reading) do
220
+ assert_cache :clean
221
+ Post.first
222
+ end
223
+
224
+ rescue Minitest::Assertion => e
225
+ wr.write Marshal.dump e
226
+ status = 1
227
+ end
104
228
  }.call({})
105
229
 
106
- ActiveRecord::Base.connection_pool.connections.each do |conn|
107
- assert_cache :off, conn
108
- end
109
- ensure
110
- ActiveRecord::Base.clear_all_connections!
230
+ wr.close
231
+ exit!(status)
232
+ }
233
+
234
+ wr.close
235
+
236
+ Process.waitpid pid
237
+ if !$?.success?
238
+ raise Marshal.load(rd.read)
239
+ else
240
+ assert_predicate $?, :success?
111
241
  end
242
+
243
+ rd.close
244
+ ensure
245
+ clean_up_connection_handler
112
246
  end
113
247
  end
114
248
 
115
- def test_exceptional_middleware_assigns_original_connection_id_on_error
116
- connection_id = ActiveRecord::Base.connection_id
249
+ def test_query_cache_across_threads
250
+ with_temporary_connection_pool do
251
+ if in_memory_db?
252
+ # Separate connections to an in-memory database create an entirely new database,
253
+ # with an empty schema etc, so we just stub out this schema on the fly.
254
+ ActiveRecord::Base.connection_pool.with_connection do |connection|
255
+ connection.create_table :tasks do |t|
256
+ t.datetime :starting
257
+ t.datetime :ending
258
+ end
259
+ end
260
+ ActiveRecord::FixtureSet.create_fixtures(self.class.fixture_path, ["tasks"], {}, ActiveRecord::Base)
261
+ end
117
262
 
118
- mw = middleware { |env|
119
- ActiveRecord::Base.connection_id = self.object_id
120
- raise "lol borked"
121
- }
122
- assert_raises(RuntimeError) { mw.call({}) }
263
+ ActiveRecord::Base.connection_pool.connections.each do |conn|
264
+ assert_cache :off, conn
265
+ end
266
+
267
+ assert_not_predicate ActiveRecord::Base.connection, :nil?
268
+ assert_cache :off
269
+
270
+ middleware {
271
+ assert_cache :clean
272
+
273
+ Task.find 1
274
+ assert_cache :dirty
275
+
276
+ thread_1_connection = ActiveRecord::Base.connection
277
+ ActiveRecord::Base.clear_active_connections!
278
+ assert_cache :off, thread_1_connection
279
+
280
+ started = Concurrent::Event.new
281
+ checked = Concurrent::Event.new
123
282
 
124
- assert_equal connection_id, ActiveRecord::Base.connection_id
283
+ thread_2_connection = nil
284
+ thread = Thread.new {
285
+ thread_2_connection = ActiveRecord::Base.connection
286
+
287
+ assert_equal thread_2_connection, thread_1_connection
288
+ assert_cache :off
289
+
290
+ middleware {
291
+ assert_cache :clean
292
+
293
+ Task.find 1
294
+ assert_cache :dirty
295
+
296
+ started.set
297
+ checked.wait
298
+
299
+ ActiveRecord::Base.clear_active_connections!
300
+ }.call({})
301
+ }
302
+
303
+ started.wait
304
+
305
+ thread_1_connection = ActiveRecord::Base.connection
306
+ assert_not_equal thread_1_connection, thread_2_connection
307
+ assert_cache :dirty, thread_2_connection
308
+ checked.set
309
+ thread.join
310
+
311
+ assert_cache :off, thread_2_connection
312
+ }.call({})
313
+
314
+ ActiveRecord::Base.connection_pool.connections.each do |conn|
315
+ assert_cache :off, conn
316
+ end
317
+ ensure
318
+ ActiveRecord::Base.connection_pool.disconnect!
319
+ end
125
320
  end
126
321
 
127
322
  def test_middleware_delegates
@@ -131,14 +326,15 @@ class QueryCacheTest < ActiveRecord::TestCase
131
326
  [200, {}, nil]
132
327
  }
133
328
  mw.call({})
134
- assert called, 'middleware should delegate'
329
+ assert called, "middleware should delegate"
135
330
  end
136
331
 
137
332
  def test_middleware_caches
138
333
  mw = middleware { |env|
139
334
  Task.find 1
140
335
  Task.find 1
141
- assert_equal 1, ActiveRecord::Base.connection.query_cache.length
336
+ query_cache = ActiveRecord::Base.connection.query_cache
337
+ assert_equal 1, query_cache.length, query_cache.keys
142
338
  [200, {}, nil]
143
339
  }
144
340
  mw.call({})
@@ -183,7 +379,7 @@ class QueryCacheTest < ActiveRecord::TestCase
183
379
  Task.cache do
184
380
  assert_queries(2) { Task.find(1); Task.find(2) }
185
381
  end
186
- assert_queries(0) { Task.find(1); Task.find(1); Task.find(2) }
382
+ assert_no_queries { Task.find(1); Task.find(1); Task.find(2) }
187
383
  end
188
384
  end
189
385
 
@@ -193,6 +389,52 @@ class QueryCacheTest < ActiveRecord::TestCase
193
389
  end
194
390
  end
195
391
 
392
+ def test_exists_queries_with_cache
393
+ Post.cache do
394
+ assert_queries(1) { Post.exists?; Post.exists? }
395
+ end
396
+ end
397
+
398
+ def test_select_all_with_cache
399
+ Post.cache do
400
+ assert_queries(1) do
401
+ 2.times { Post.connection.select_all(Post.all) }
402
+ end
403
+ end
404
+ end
405
+
406
+ def test_select_one_with_cache
407
+ Post.cache do
408
+ assert_queries(1) do
409
+ 2.times { Post.connection.select_one(Post.all) }
410
+ end
411
+ end
412
+ end
413
+
414
+ def test_select_value_with_cache
415
+ Post.cache do
416
+ assert_queries(1) do
417
+ 2.times { Post.connection.select_value(Post.all) }
418
+ end
419
+ end
420
+ end
421
+
422
+ def test_select_values_with_cache
423
+ Post.cache do
424
+ assert_queries(1) do
425
+ 2.times { Post.connection.select_values(Post.all) }
426
+ end
427
+ end
428
+ end
429
+
430
+ def test_select_rows_with_cache
431
+ Post.cache do
432
+ assert_queries(1) do
433
+ 2.times { Post.connection.select_rows(Post.all) }
434
+ end
435
+ end
436
+ end
437
+
196
438
  def test_query_cache_dups_results_correctly
197
439
  Task.cache do
198
440
  now = Time.now.utc
@@ -204,9 +446,55 @@ class QueryCacheTest < ActiveRecord::TestCase
204
446
  end
205
447
  end
206
448
 
449
+ def test_cache_notifications_can_be_overridden
450
+ logger = ShouldNotHaveExceptionsLogger.new
451
+ subscriber = ActiveSupport::Notifications.subscribe "sql.active_record", logger
452
+
453
+ connection = ActiveRecord::Base.connection.dup
454
+
455
+ def connection.cache_notification_info(sql, name, binds)
456
+ super.merge(neat: true)
457
+ end
458
+
459
+ connection.cache do
460
+ connection.select_all "select 1 from SYSIBM.DUAL"
461
+ connection.select_all "select 1 from SYSIBM.DUAL"
462
+ end
463
+
464
+ assert_equal true, logger.events.last.payload[:neat]
465
+ ensure
466
+ ActiveSupport::Notifications.unsubscribe subscriber
467
+ end
468
+
469
+ def test_cache_does_not_raise_exceptions
470
+ logger = ShouldNotHaveExceptionsLogger.new
471
+ subscriber = ActiveSupport::Notifications.subscribe "sql.active_record", logger
472
+
473
+ ActiveRecord::Base.cache do
474
+ assert_queries(1) { Task.find(1); Task.find(1) }
475
+ end
476
+
477
+ assert_not_predicate logger, :exception?
478
+ ensure
479
+ ActiveSupport::Notifications.unsubscribe subscriber
480
+ end
481
+
482
+ def test_query_cache_does_not_allow_sql_key_mutation
483
+ subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |_, _, _, _, payload|
484
+ payload[:sql].downcase!
485
+ end
486
+
487
+ assert_raises FrozenError do
488
+ ActiveRecord::Base.cache do
489
+ assert_queries(1) { Task.find(1); Task.find(1) }
490
+ end
491
+ end
492
+ ensure
493
+ ActiveSupport::Notifications.unsubscribe subscriber
494
+ end
495
+
207
496
  def test_cache_is_flat
208
497
  Task.cache do
209
- Topic.columns # don't count this query
210
498
  assert_queries(1) { Topic.find(1); Topic.find(1); }
211
499
  end
212
500
 
@@ -215,17 +503,9 @@ class QueryCacheTest < ActiveRecord::TestCase
215
503
  end
216
504
  end
217
505
 
218
- def test_cache_does_not_wrap_string_results_in_arrays
506
+ def test_cache_does_not_wrap_results_in_arrays
219
507
  Task.cache do
220
- # Oracle adapter returns count() as Integer or Float
221
- if current_adapter?(:OracleAdapter)
222
- assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
223
- elsif current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter)
224
- # Future versions of the sqlite3 adapter will return numeric
225
- assert_instance_of 0.class, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
226
- else
227
- assert_instance_of String, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
228
- end
508
+ assert_equal 2, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
229
509
  end
230
510
  end
231
511
 
@@ -250,20 +530,35 @@ class QueryCacheTest < ActiveRecord::TestCase
250
530
 
251
531
  def test_cache_is_available_when_using_a_not_connected_connection
252
532
  skip "In-Memory DB can't test for using a not connected connection" if in_memory_db?
253
- with_temporary_connection_pool do
254
- spec_name = Task.connection_specification_name
255
- resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(ActiveRecord::Base.configurations)
256
- ActiveRecord::Base.connection_handler.establish_connection(resolver.spec(:arunit, "test2"))
257
- Task.connection_specification_name = "test2"
258
- refute Task.connected?
533
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").dup
534
+ db_config.owner_name = "test2"
535
+ ActiveRecord::Base.connection_handler.establish_connection(db_config)
536
+ assert_not_predicate Task, :connected?
259
537
 
260
- Task.cache do
261
- begin
262
- assert_queries(1) { Task.find(1); Task.find(1) }
263
- ensure
264
- ActiveRecord::Base.connection_handler.remove_connection(Task.connection_specification_name)
265
- Task.connection_specification_name = spec_name
266
- end
538
+ Task.cache do
539
+ assert_queries(1) { Task.find(1); Task.find(1) }
540
+ ensure
541
+ ActiveRecord::Base.connection_handler.remove_connection_pool(db_config.owner_name)
542
+ end
543
+ end
544
+
545
+ def test_query_cache_executes_new_queries_within_block
546
+ ActiveRecord::Base.connection.enable_query_cache!
547
+
548
+ # Warm up the cache by running the query
549
+ assert_queries(1) do
550
+ assert_equal 0, Post.where(title: "test").to_a.count
551
+ end
552
+
553
+ # Check that if the same query is run again, no queries are executed
554
+ assert_no_queries do
555
+ assert_equal 0, Post.where(title: "test").to_a.count
556
+ end
557
+
558
+ ActiveRecord::Base.connection.uncached do
559
+ # Check that new query is executed, avoiding the cache
560
+ assert_queries(1) do
561
+ assert_equal 0, Post.where(title: "test").to_a.count
267
562
  end
268
563
  end
269
564
  end
@@ -273,75 +568,199 @@ class QueryCacheTest < ActiveRecord::TestCase
273
568
  post = Post.first
274
569
 
275
570
  Post.transaction do
276
- post.update_attributes(title: 'rollback')
277
- assert_equal 1, Post.where(title: 'rollback').to_a.count
571
+ post.update(title: "rollback")
572
+ assert_equal 1, Post.where(title: "rollback").to_a.count
278
573
  raise ActiveRecord::Rollback
279
574
  end
280
575
 
281
- assert_equal 0, Post.where(title: 'rollback').to_a.count
576
+ assert_equal 0, Post.where(title: "rollback").to_a.count
282
577
 
283
578
  ActiveRecord::Base.connection.uncached do
284
- assert_equal 0, Post.where(title: 'rollback').to_a.count
579
+ assert_equal 0, Post.where(title: "rollback").to_a.count
285
580
  end
286
581
 
287
582
  begin
288
583
  Post.transaction do
289
- post.update_attributes(title: 'rollback')
290
- assert_equal 1, Post.where(title: 'rollback').to_a.count
291
- raise 'broken'
584
+ post.update(title: "rollback")
585
+ assert_equal 1, Post.where(title: "rollback").to_a.count
586
+ raise "broken"
292
587
  end
293
588
  rescue Exception
294
589
  end
295
590
 
296
- assert_equal 0, Post.where(title: 'rollback').to_a.count
591
+ assert_equal 0, Post.where(title: "rollback").to_a.count
297
592
 
298
593
  ActiveRecord::Base.connection.uncached do
299
- assert_equal 0, Post.where(title: 'rollback').to_a.count
594
+ assert_equal 0, Post.where(title: "rollback").to_a.count
300
595
  end
301
596
  end
302
597
 
303
- def test_query_cache_does_not_establish_connection_if_unconnected
304
- with_temporary_connection_pool do
305
- ActiveRecord::Base.clear_active_connections!
306
- refute ActiveRecord::Base.connection_handler.active_connections? # sanity check
598
+ def test_query_cached_even_when_types_are_reset
599
+ Task.cache do
600
+ # Warm the cache
601
+ Task.find(1)
307
602
 
308
- middleware {
309
- refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in setup"
310
- }.call({})
603
+ # Preload the type cache again (so we don't have those queries issued during our assertions)
604
+ Task.connection.send(:reload_type_map)
311
605
 
312
- refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in cleanup"
606
+ # Clear places where type information is cached
607
+ Task.reset_column_information
608
+ Task.initialize_find_by_cache
609
+ Task.define_attribute_methods
610
+
611
+ assert_no_queries do
612
+ Task.find(1)
613
+ end
313
614
  end
314
615
  end
315
616
 
617
+ def test_query_cache_does_not_establish_connection_if_unconnected
618
+ ActiveRecord::Base.clear_active_connections!
619
+ assert_not ActiveRecord::Base.connection_handler.active_connections? # sanity check
620
+
621
+ middleware {
622
+ assert_not ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in setup"
623
+ }.call({})
624
+
625
+ assert_not ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in cleanup"
626
+ end
627
+
316
628
  def test_query_cache_is_enabled_on_connections_established_after_middleware_runs
317
- with_temporary_connection_pool do
318
- ActiveRecord::Base.clear_active_connections!
319
- refute ActiveRecord::Base.connection_handler.active_connections? # sanity check
629
+ ActiveRecord::Base.clear_active_connections!
630
+ assert_not ActiveRecord::Base.connection_handler.active_connections? # sanity check
320
631
 
321
- middleware {
322
- assert ActiveRecord::Base.connection.query_cache_enabled, "QueryCache did not get lazily enabled"
323
- }.call({})
324
- end
632
+ middleware {
633
+ assert_predicate ActiveRecord::Base.connection, :query_cache_enabled
634
+ }.call({})
635
+ assert_not_predicate ActiveRecord::Base.connection, :query_cache_enabled
325
636
  end
326
637
 
327
638
  def test_query_caching_is_local_to_the_current_thread
328
- with_temporary_connection_pool do
329
- ActiveRecord::Base.clear_active_connections!
639
+ ActiveRecord::Base.clear_active_connections!
330
640
 
331
- middleware {
332
- assert ActiveRecord::Base.connection_pool.query_cache_enabled
333
- assert ActiveRecord::Base.connection.query_cache_enabled
641
+ middleware {
642
+ assert ActiveRecord::Base.connection_pool.query_cache_enabled
643
+ assert ActiveRecord::Base.connection.query_cache_enabled
334
644
 
335
- Thread.new {
336
- refute ActiveRecord::Base.connection_pool.query_cache_enabled
337
- refute ActiveRecord::Base.connection.query_cache_enabled
338
- }.join
339
- }.call({})
645
+ Thread.new {
646
+ assert_not ActiveRecord::Base.connection_pool.query_cache_enabled
647
+ assert_not ActiveRecord::Base.connection.query_cache_enabled
648
+ }.join
649
+ }.call({})
650
+ end
651
+
652
+ def test_query_cache_is_enabled_on_all_connection_pools
653
+ middleware {
654
+ ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
655
+ assert pool.query_cache_enabled
656
+ assert pool.connection.query_cache_enabled
657
+ end
658
+ }.call({})
659
+ end
340
660
 
661
+ def test_clear_query_cache_is_called_on_all_legacy_connections
662
+ skip "with in memory db, reading role won't be able to see database on writing role" if in_memory_db?
663
+ old_value = ActiveRecord::Base.legacy_connection_handling
664
+ ActiveRecord::Base.legacy_connection_handling = true
665
+
666
+ ActiveRecord::Base.connection_handlers = {
667
+ writing: ActiveRecord::Base.default_connection_handler,
668
+ reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
669
+ }
670
+
671
+ ActiveRecord::Base.connected_to(role: :reading) do
672
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
673
+ ActiveRecord::Base.establish_connection(db_config)
341
674
  end
675
+
676
+ mw = middleware { |env|
677
+ ActiveRecord::Base.connected_to(role: :reading) do
678
+ @topic = Topic.first
679
+ end
680
+
681
+ assert @topic
682
+
683
+ ActiveRecord::Base.connected_to(role: :writing) do
684
+ @topic.title = "It doesn't have to be crazy at work"
685
+ @topic.save!
686
+ end
687
+
688
+ assert_equal "It doesn't have to be crazy at work", @topic.title
689
+
690
+ ActiveRecord::Base.connected_to(role: :reading) do
691
+ @topic = Topic.first
692
+ assert_equal "It doesn't have to be crazy at work", @topic.title
693
+ end
694
+ }
695
+
696
+ mw.call({})
697
+ ensure
698
+ unless in_memory_db?
699
+ clean_up_legacy_connection_handlers
700
+ ActiveRecord::Base.legacy_connection_handling = old_value
701
+ end
702
+ end
703
+
704
+ def test_clear_query_cache_is_called_on_all_connections
705
+ skip "with in memory db, reading role won't be able to see database on writing role" if in_memory_db?
706
+
707
+ ActiveRecord::Base.connected_to(role: :reading) do
708
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
709
+ ActiveRecord::Base.establish_connection(db_config)
710
+ end
711
+
712
+ mw = middleware { |env|
713
+ ActiveRecord::Base.connected_to(role: :reading) do
714
+ @topic = Topic.first
715
+ end
716
+
717
+ assert @topic
718
+
719
+ ActiveRecord::Base.connected_to(role: :writing) do
720
+ @topic.title = "It doesn't have to be crazy at work"
721
+ @topic.save!
722
+ end
723
+
724
+ assert_equal "It doesn't have to be crazy at work", @topic.title
725
+
726
+ ActiveRecord::Base.connected_to(role: :reading) do
727
+ @topic = Topic.first
728
+ assert_equal "It doesn't have to be crazy at work", @topic.title
729
+ end
730
+ }
731
+
732
+ mw.call({})
733
+ ensure
734
+ clean_up_connection_handler
735
+ end
736
+
737
+ test "query cache is enabled in threads with shared connection" do
738
+ ActiveRecord::Base.connection_pool.lock_thread = true
739
+
740
+ assert_cache :off
741
+
742
+ thread_a = Thread.new do
743
+ middleware { |env|
744
+ assert_cache :clean
745
+ [200, {}, nil]
746
+ }.call({})
747
+ end
748
+
749
+ thread_a.join
750
+
751
+ ActiveRecord::Base.connection_pool.lock_thread = false
342
752
  end
343
753
 
344
754
  private
755
+ def with_temporary_connection_pool
756
+ pool_config = ActiveRecord::Base.connection_handler.send(:owner_to_pool_manager).fetch("ActiveRecord::Base").get_pool_config(ActiveRecord::Base.writing_role, :default)
757
+ new_pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(pool_config)
758
+
759
+ pool_config.stub(:pool, new_pool) do
760
+ yield
761
+ end
762
+ end
763
+
345
764
  def middleware(&app)
346
765
  executor = Class.new(ActiveSupport::Executor)
347
766
  ActiveRecord::QueryCache.install_executor_hooks executor
@@ -351,14 +770,14 @@ class QueryCacheTest < ActiveRecord::TestCase
351
770
  def assert_cache(state, connection = ActiveRecord::Base.connection)
352
771
  case state
353
772
  when :off
354
- assert !connection.query_cache_enabled, "cache should be off"
773
+ assert_not connection.query_cache_enabled, "cache should be off"
355
774
  assert connection.query_cache.empty?, "cache should be empty"
356
775
  when :clean
357
776
  assert connection.query_cache_enabled, "cache should be on"
358
777
  assert connection.query_cache.empty?, "cache should be empty"
359
778
  when :dirty
360
779
  assert connection.query_cache_enabled, "cache should be on"
361
- assert !connection.query_cache.empty?, "cache should be dirty"
780
+ assert_not connection.query_cache.empty?, "cache should be dirty"
362
781
  else
363
782
  raise "unknown state"
364
783
  end
@@ -368,6 +787,10 @@ end
368
787
  class QueryCacheExpiryTest < ActiveRecord::TestCase
369
788
  fixtures :tasks, :posts, :categories, :categories_posts
370
789
 
790
+ def teardown
791
+ Task.connection.clear_query_cache
792
+ end
793
+
371
794
  def test_cache_gets_cleared_after_migration
372
795
  # warm the cache
373
796
  Post.find(1)
@@ -382,19 +805,19 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
382
805
 
383
806
  def test_find
384
807
  assert_called(Task.connection, :clear_query_cache) do
385
- assert !Task.connection.query_cache_enabled
808
+ assert_not Task.connection.query_cache_enabled
386
809
  Task.cache do
387
810
  assert Task.connection.query_cache_enabled
388
811
  Task.find(1)
389
812
 
390
813
  Task.uncached do
391
- assert !Task.connection.query_cache_enabled
814
+ assert_not Task.connection.query_cache_enabled
392
815
  Task.find(1)
393
816
  end
394
817
 
395
818
  assert Task.connection.query_cache_enabled
396
819
  end
397
- assert !Task.connection.query_cache_enabled
820
+ assert_not Task.connection.query_cache_enabled
398
821
  end
399
822
  end
400
823
 
@@ -424,6 +847,40 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
424
847
  end
425
848
  end
426
849
 
850
+ def test_insert_all
851
+ skip unless supports_insert_on_duplicate_skip?
852
+
853
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
854
+ Task.cache { Task.insert({ starting: Time.now }) }
855
+ end
856
+
857
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
858
+ Task.cache { Task.insert_all([{ starting: Time.now }]) }
859
+ end
860
+ end
861
+
862
+ def test_insert_all_bang
863
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
864
+ Task.cache { Task.insert!({ starting: Time.now }) }
865
+ end
866
+
867
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
868
+ Task.cache { Task.insert_all!([{ starting: Time.now }]) }
869
+ end
870
+ end
871
+
872
+ def test_upsert_all
873
+ skip unless supports_insert_on_duplicate_update?
874
+
875
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
876
+ Task.cache { Task.upsert({ starting: Time.now }) }
877
+ end
878
+
879
+ assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
880
+ Task.cache { Task.upsert_all([{ starting: Time.now }]) }
881
+ end
882
+ end
883
+
427
884
  def test_cache_is_expired_by_habtm_update
428
885
  assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
429
886
  ActiveRecord::Base.cache do
@@ -438,9 +895,21 @@ class QueryCacheExpiryTest < ActiveRecord::TestCase
438
895
  assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
439
896
  ActiveRecord::Base.cache do
440
897
  p = Post.find(1)
441
- assert p.categories.any?
898
+ assert_predicate p.categories, :any?
442
899
  p.categories.delete_all
443
900
  end
444
901
  end
445
902
  end
903
+
904
+ test "threads use the same connection" do
905
+ @connection_1 = ActiveRecord::Base.connection.object_id
906
+
907
+ thread_a = Thread.new do
908
+ @connection_2 = ActiveRecord::Base.connection.object_id
909
+ end
910
+
911
+ thread_a.join
912
+
913
+ assert_equal @connection_1, @connection_2
914
+ end
446
915
  end