ibm_db 5.6.1 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionHandling
5
+ def fake_legacy_connection(config)
6
+ ConnectionAdapters::FakeLegacyAdapter.new nil, logger
7
+ end
8
+ end
9
+
10
+ module ConnectionAdapters
11
+ class FakeLegacyAdapter < AbstractAdapter
12
+ def active?
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ class FakeMisleadingLegacyAdapter < AbstractAdapter
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ class UndefinedConstantAsync < ActiveRecord::Base
6
+ self.destroy_association_async_job = "UndefinedConstantJob"
7
+ end
8
+
9
+ autoload :UnloadableBaseJob, "activejob/unloadable_base_job"
10
+ class UnloadableBaseAsync < ActiveRecord::Base
11
+ self.destroy_association_async_job = "UnloadableBaseJob"
12
+ end
13
+
14
+ class UnusedBelongsToAsync < ActiveRecord::Base
15
+ self.destroy_association_async_job = nil
16
+ end
17
+
18
+ class UnusedHasOneAsync < ActiveRecord::Base
19
+ self.destroy_association_async_job = nil
20
+ end
21
+
22
+ class UnusedHasManyAsync < ActiveRecord::Base
23
+ self.destroy_association_async_job = nil
24
+ end
25
+
26
+
27
+ class DestroyAssociationAsyncJobTest < ActiveRecord::TestCase
28
+ test "destroy_association_async_job requires valid job class" do
29
+ error = assert_raises NameError do
30
+ UndefinedConstantAsync.belongs_to :essay_destroy_async, dependent: :destroy_async
31
+ end
32
+ assert_match %r/destroy_association_async_job: uninitialized constant UndefinedConstantJob/, error.message
33
+ end
34
+
35
+ test "destroy_association_async_job error shows a missing parent job class, as if ActiveJob were missing" do
36
+ error = assert_raises NameError do
37
+ UnloadableBaseAsync.belongs_to :essay_destroy_async, dependent: :destroy_async
38
+ end
39
+ assert_match %r/destroy_association_async_job: uninitialized constant PretendActiveJobIsNotPresent/, error.message
40
+ end
41
+
42
+ test "belongs_to dependent destroy_async requires destroy_association_async_job" do
43
+ error = assert_raises ActiveRecord::ConfigurationError do
44
+ UnusedBelongsToAsync.belongs_to :essay_destroy_async, dependent: :destroy_async
45
+ end
46
+ assert_match %r/destroy_association_async_job/, error.message
47
+ end
48
+
49
+ test "has_one dependent destroy_async requires destroy_association_async_job" do
50
+ error = assert_raises ActiveRecord::ConfigurationError do
51
+ UnusedHasOneAsync.has_one :essay_destroy_async, dependent: :destroy_async
52
+ end
53
+ assert_match %r/destroy_association_async_job/, error.message
54
+ end
55
+
56
+ test "has_many dependent destroy_async requires destroy_association_async_job" do
57
+ error = assert_raises ActiveRecord::ConfigurationError do
58
+ UnusedHasManyAsync.has_many :essay_destroy_asyncs, dependent: :destroy_async
59
+ end
60
+ assert_match %r/destroy_association_async_job/, error.message
61
+ end
62
+ end
@@ -6,6 +6,7 @@ require "models/book_destroy_async"
6
6
  require "models/essay_destroy_async"
7
7
  require "models/tag"
8
8
  require "models/tagging"
9
+ require "models/author"
9
10
  require "models/essay"
10
11
  require "models/category"
11
12
  require "models/post"
@@ -18,10 +19,16 @@ require "models/dl_keyed_has_one"
18
19
  require "models/dl_keyed_join"
19
20
  require "models/dl_keyed_has_many"
20
21
  require "models/dl_keyed_has_many_through"
22
+ require "models/sharded/blog_post_destroy_async"
23
+ require "models/sharded/comment_destroy_async"
24
+ require "models/sharded/tag"
25
+ require "models/sharded/blog_post"
26
+ require "models/sharded/blog_post_tag"
27
+ require "models/sharded/blog"
28
+ require "models/cpk/book_destroy_async"
29
+ require "models/cpk/chapter_destroy_async"
21
30
 
22
31
  class DestroyAssociationAsyncTest < ActiveRecord::TestCase
23
- self.use_transactional_tests = false
24
-
25
32
  include ActiveJob::TestHelper
26
33
 
27
34
  test "destroying a record destroys the has_many :through records using a job" do
@@ -31,7 +38,9 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
31
38
  book.tags << [tag, tag2]
32
39
  book.save!
33
40
 
34
- book.destroy
41
+ assert_enqueued_jobs 1, only: ActiveRecord::DestroyAssociationAsyncJob do
42
+ book.destroy
43
+ end
35
44
 
36
45
  assert_difference -> { Tag.count }, -2 do
37
46
  perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
@@ -41,6 +50,39 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
41
50
  BookDestroyAsync.delete_all
42
51
  end
43
52
 
53
+ test "destroying a record destroys has_many :through associated by composite primary key using a job" do
54
+ blog = Sharded::Blog.create!
55
+ blog_post = Sharded::BlogPostDestroyAsync.create!(blog_id: blog.id)
56
+
57
+ tag1 = Sharded::Tag.create!(name: "Short Read", blog_id: blog.id)
58
+ tag2 = Sharded::Tag.create!(name: "Science", blog_id: blog.id)
59
+
60
+ blog_post.tags << [tag1, tag2]
61
+
62
+ blog_post.save!
63
+
64
+ assert_enqueued_jobs 1, only: ActiveRecord::DestroyAssociationAsyncJob do
65
+ blog_post.destroy
66
+ end
67
+
68
+ sql = capture_sql do
69
+ assert_difference -> { Sharded::Tag.count }, -2 do
70
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
71
+ end
72
+ end
73
+
74
+ delete_sqls = sql.select { |sql| sql.start_with?("DELETE") }
75
+ assert_equal 2, delete_sqls.count
76
+
77
+ delete_sqls.each do |sql|
78
+ assert_match(/#{Regexp.escape(quote_table_name("sharded_tags.blog_id"))} =/, sql)
79
+ end
80
+ ensure
81
+ Sharded::Tag.delete_all
82
+ Sharded::BlogPostDestroyAsync.delete_all
83
+ Sharded::Blog.delete_all
84
+ end
85
+
44
86
  test "destroying a scoped has_many through only deletes within the scope deleted" do
45
87
  tag = Tag.create!(name: "Der be treasure")
46
88
  tag2 = Tag.create!(name: "Der be rum")
@@ -74,16 +116,43 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
74
116
  parent.destroy
75
117
 
76
118
  assert_difference -> { DlKeyedJoin.count }, -2 do
77
- assert_difference -> { DlKeyedHasManyThrough.count }, -2 do
78
- perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
119
+ assert_difference -> { DlKeyedHasManyThrough.count }, -2 do
120
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
121
+ end
79
122
  end
80
- end
81
123
  ensure
82
124
  DlKeyedHasManyThrough.delete_all
83
125
  DestroyAsyncParent.delete_all
84
126
  DlKeyedJoin.delete_all
85
127
  end
86
128
 
129
+ test "enqueues multiple jobs if count of dependent records to destroy is greater than batch size" do
130
+ ActiveRecord::Base.destroy_association_async_batch_size = 1
131
+
132
+ tag = Tag.create!(name: "Der be treasure")
133
+ tag2 = Tag.create!(name: "Der be rum")
134
+ book = BookDestroyAsync.create!
135
+ book.tags << [tag, tag2]
136
+ book.save!
137
+
138
+ job_1_args = ->(job_args) { job_args.first[:association_ids] == [tag.id] }
139
+ job_2_args = ->(job_args) { job_args.first[:association_ids] == [tag2.id] }
140
+
141
+ assert_enqueued_with(job: ActiveRecord::DestroyAssociationAsyncJob, args: job_1_args) do
142
+ assert_enqueued_with(job: ActiveRecord::DestroyAssociationAsyncJob, args: job_2_args) do
143
+ book.destroy
144
+ end
145
+ end
146
+
147
+ assert_difference -> { Tag.count }, -2 do
148
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
149
+ end
150
+ ensure
151
+ Tag.delete_all
152
+ BookDestroyAsync.delete_all
153
+ ActiveRecord::Base.destroy_association_async_batch_size = nil
154
+ end
155
+
87
156
  test "belongs to" do
88
157
  essay = EssayDestroyAsync.create!(name: "Der be treasure")
89
158
  book = BookDestroyAsync.create!(name: "Arr, matey!")
@@ -99,6 +168,33 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
99
168
  BookDestroyAsync.delete_all
100
169
  end
101
170
 
171
+ test "belongs to associated by composite primary key" do
172
+ blog = Sharded::Blog.create!
173
+ blog_post = Sharded::BlogPostDestroyAsync.create!(blog_id: blog.id)
174
+ comment = Sharded::CommentDestroyAsync.create!(body: "Great post! :clap:")
175
+
176
+ comment.blog_post = blog_post
177
+ comment.save!
178
+
179
+ assert_enqueued_jobs 1, only: ActiveRecord::DestroyAssociationAsyncJob do
180
+ comment.destroy
181
+ end
182
+
183
+ sql = capture_sql do
184
+ assert_difference -> { Sharded::BlogPostDestroyAsync.count }, -1 do
185
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
186
+ end
187
+ end
188
+
189
+ delete_sqls = sql.select { |sql| sql.start_with?("DELETE") }
190
+ assert_equal 1, delete_sqls.count
191
+ assert_match(/#{Regexp.escape(quote_table_name("sharded_blog_posts.blog_id"))} =/, delete_sqls.first)
192
+ ensure
193
+ Sharded::BlogPostDestroyAsync.delete_all
194
+ Sharded::CommentDestroyAsync.delete_all
195
+ Sharded::Blog.delete_all
196
+ end
197
+
102
198
  test "enqueues belongs_to to be deleted with custom primary key" do
103
199
  belongs = DlKeyedBelongsTo.create!
104
200
  parent = DestroyAsyncParent.create!
@@ -114,6 +210,20 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
114
210
  DestroyAsyncParent.delete_all
115
211
  end
116
212
 
213
+ test "polymorphic belongs_to" do
214
+ writer = Author.create(name: "David")
215
+ essay = EssayDestroyAsync.create!(name: "Der be treasure", writer: writer)
216
+
217
+ essay.destroy
218
+
219
+ assert_difference -> { Author.count }, -1 do
220
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
221
+ end
222
+ ensure
223
+ EssayDestroyAsync.delete_all
224
+ Author.delete_all
225
+ end
226
+
117
227
  test "has_one" do
118
228
  content = Content.create(title: "hello")
119
229
  book = BookDestroyAsync.create!(name: "Arr, matey!")
@@ -162,7 +272,7 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
162
272
  BookDestroyAsync.delete_all
163
273
  end
164
274
 
165
- test "has_many with sti parent class destroys all children class records" do
275
+ test "has_many with STI parent class destroys all children class records" do
166
276
  book = BookDestroyAsync.create!
167
277
  LongEssayDestroyAsync.create!(book: book)
168
278
  ShortEssayDestroyAsync.create!(book: book)
@@ -189,6 +299,32 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
189
299
  DestroyAsyncParent.delete_all
190
300
  end
191
301
 
302
+ test "has_many associated with composite primary key" do
303
+ book = Cpk::BookDestroyAsync.create!(id: [1, 1])
304
+ _chapter1 = book.chapters.create!(id: [1, 1], title: "Chapter 1")
305
+ _chapter2 = book.chapters.create!(id: [1, 2], title: "Chapter 2")
306
+
307
+ assert_enqueued_jobs 1, only: ActiveRecord::DestroyAssociationAsyncJob do
308
+ book.destroy
309
+ end
310
+
311
+ sql = capture_sql do
312
+ assert_difference -> { Cpk::ChapterDestroyAsync.count }, -2 do
313
+ perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
314
+ end
315
+ end
316
+
317
+ delete_sqls = sql.select { |sql| sql.start_with?("DELETE") }
318
+ assert_equal 2, delete_sqls.count
319
+
320
+ delete_sqls.each do |sql|
321
+ assert_match(/#{Regexp.escape(quote_table_name("cpk_chapters.author_id"))} =/, sql)
322
+ end
323
+ ensure
324
+ Cpk::ChapterDestroyAsync.delete_all
325
+ Cpk::BookDestroyAsync.delete_all
326
+ end
327
+
192
328
  test "not enqueue the job if transaction is not committed" do
193
329
  dl_keyed_has_many = DlKeyedHasMany.new
194
330
  parent = DestroyAsyncParent.create!
@@ -272,7 +408,7 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
272
408
 
273
409
  belongs.destroy
274
410
  perform_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
275
- assert parent.reload.deleted?
411
+ assert_predicate parent.reload, :deleted?
276
412
  ensure
277
413
  DlKeyedBelongsToSoftDelete.delete_all
278
414
  DestroyAsyncParentSoftDelete.delete_all
@@ -298,8 +434,8 @@ class DestroyAssociationAsyncTest < ActiveRecord::TestCase
298
434
  raise ActiveRecord::Rollback
299
435
  end
300
436
  assert_no_enqueued_jobs only: ActiveRecord::DestroyAssociationAsyncJob
437
+ ensure
438
+ Tag.delete_all
439
+ BookDestroyAsync.delete_all
301
440
  end
302
- ensure
303
- Tag.delete_all
304
- BookDestroyAsync.delete_all
305
441
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "activejob/helper"
4
+ require "active_record/railties/job_runtime"
5
+
6
+ class JobRuntimeTest < ActiveSupport::TestCase
7
+ class TestJob < ActiveJob::Base
8
+ include ActiveRecord::Railties::JobRuntime
9
+
10
+ def perform(*)
11
+ ActiveRecord::RuntimeRegistry.sql_runtime += 42.0
12
+ end
13
+ end
14
+
15
+ test "job notification payload includes db_runtime" do
16
+ ActiveRecord::RuntimeRegistry.sql_runtime = 0.0
17
+
18
+ assert_equal 42, notification_payload[:db_runtime]
19
+ end
20
+
21
+ test "db_runtime tracks database runtime for job only" do
22
+ ActiveRecord::RuntimeRegistry.sql_runtime = 100.0
23
+
24
+ assert_equal 42.0, notification_payload[:db_runtime]
25
+ assert_equal 142.0, ActiveRecord::RuntimeRegistry.sql_runtime
26
+ end
27
+
28
+ private
29
+ def notification_payload
30
+ payload = nil
31
+ subscriber = ActiveSupport::Notifications.subscribe("perform.active_job") do |*, _payload|
32
+ payload = _payload
33
+ end
34
+
35
+ TestJob.perform_now
36
+
37
+ ActiveSupport::Notifications.unsubscribe(subscriber)
38
+
39
+ payload
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UnloadableBaseJob < PretendActiveJobIsNotPresent; end
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ class ActiveRecordSchemaTest < ActiveRecord::TestCase
6
+ self.use_transactional_tests = false
7
+
8
+ setup do
9
+ @original_verbose = ActiveRecord::Migration.verbose
10
+ ActiveRecord::Migration.verbose = false
11
+ @connection = ActiveRecord::Base.lease_connection
12
+ @pool = ActiveRecord::Base.connection_pool
13
+ @schema_migration = @pool.schema_migration
14
+ @schema_migration.delete_all_versions
15
+ end
16
+
17
+ teardown do
18
+ @connection.drop_table :fruits rescue nil
19
+ @connection.drop_table :has_timestamps rescue nil
20
+ @connection.drop_table :multiple_indexes rescue nil
21
+ @schema_migration.delete_all_versions
22
+ ActiveRecord::Migration.verbose = @original_verbose
23
+ end
24
+
25
+ def test_has_primary_key
26
+ old_primary_key_prefix_type = ActiveRecord::Base.primary_key_prefix_type
27
+ ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
28
+ assert_equal "version", @schema_migration.primary_key
29
+
30
+ assert_difference "@schema_migration.count", 1 do
31
+ @schema_migration.create_version(12)
32
+ end
33
+ ensure
34
+ ActiveRecord::Base.primary_key_prefix_type = old_primary_key_prefix_type
35
+ end
36
+
37
+ def test_schema_without_version_is_the_current_version_schema
38
+ schema_class = ActiveRecord::Schema
39
+ assert schema_class < ActiveRecord::Migration[ActiveRecord::Migration.current_version]
40
+ assert_not schema_class < ActiveRecord::Migration[7.0]
41
+ assert schema_class < ActiveRecord::Schema::Definition
42
+ end
43
+
44
+ def test_schema_version_accessor
45
+ schema_class = ActiveRecord::Schema[6.1]
46
+ assert schema_class < ActiveRecord::Migration[6.1]
47
+ assert schema_class < ActiveRecord::Schema::Definition
48
+ end
49
+
50
+ def test_schema_define
51
+ ActiveRecord::Schema.define(version: 7) do
52
+ create_table :fruits do |t|
53
+ t.column :color, :string
54
+ t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle
55
+ t.column :texture, :string
56
+ t.column :flavor, :string
57
+ end
58
+ end
59
+
60
+ assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" }
61
+ assert_nothing_raised { @connection.select_all "SELECT * FROM schema_migrations" }
62
+ assert_equal 7, @connection.schema_version
63
+ end
64
+
65
+ def test_schema_define_with_table_name_prefix
66
+ old_table_name_prefix = ActiveRecord::Base.table_name_prefix
67
+ ActiveRecord::Base.table_name_prefix = "nep_"
68
+ ActiveRecord::Schema.define(version: 7) do
69
+ create_table :fruits do |t|
70
+ t.column :color, :string
71
+ t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle
72
+ t.column :texture, :string
73
+ t.column :flavor, :string
74
+ end
75
+ end
76
+ assert_equal 7, @pool.migration_context.current_version
77
+ ensure
78
+ ActiveRecord::Base.table_name_prefix = old_table_name_prefix
79
+ @connection.drop_table :nep_fruits
80
+ @connection.drop_table :nep_schema_migrations
81
+ @schema_migration.create_table
82
+ end
83
+
84
+ def test_schema_raises_an_error_for_invalid_column_type
85
+ assert_raise NoMethodError do
86
+ ActiveRecord::Schema.define(version: 8) do
87
+ create_table :vegetables do |t|
88
+ t.unknown :color
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ def test_schema_subclass
95
+ Class.new(ActiveRecord::Schema).define(version: 9) do
96
+ create_table :fruits
97
+ end
98
+ assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" }
99
+ end
100
+
101
+ def test_normalize_version
102
+ assert_equal "118", @schema_migration.normalize_migration_number("0000118")
103
+ assert_equal "002", @schema_migration.normalize_migration_number("2")
104
+ assert_equal "017", @schema_migration.normalize_migration_number("0017")
105
+ assert_equal "20131219224947", @schema_migration.normalize_migration_number("20131219224947")
106
+ end
107
+
108
+ def test_schema_load_with_multiple_indexes_for_column_of_different_names
109
+ ibm_db_adapter = current_adapter?(:IBM_DBAdapter)
110
+
111
+ ActiveRecord::Schema.define do
112
+ create_table :multiple_indexes do |t|
113
+ t.string "foo"
114
+ t.index ["foo"], name: "multiple_indexes_foo_1"
115
+ t.index ["foo"], name: "multiple_indexes_foo_2" unless ibm_db_adapter
116
+ end
117
+ end
118
+
119
+ indexes = @connection.indexes("multiple_indexes")
120
+
121
+ if ibm_db_adapter
122
+ assert_equal 1, indexes.length
123
+ assert_equal ["multiple_indexes_foo_1"], indexes.collect(&:name).sort
124
+ else
125
+ assert_equal 2, indexes.length
126
+ assert_equal ["multiple_indexes_foo_1", "multiple_indexes_foo_2"], indexes.collect(&:name).sort
127
+ end
128
+ end
129
+
130
+ if current_adapter?(:PostgreSQLAdapter)
131
+ def test_timestamps_with_and_without_zones
132
+ ActiveRecord::Schema.define do
133
+ create_table :has_timestamps do |t|
134
+ t.datetime "default_format"
135
+ t.datetime "without_time_zone"
136
+ t.timestamp "also_without_time_zone"
137
+ t.timestamptz "with_time_zone"
138
+ end
139
+ end
140
+
141
+ assert @connection.column_exists?(:has_timestamps, :default_format, :datetime)
142
+ assert @connection.column_exists?(:has_timestamps, :without_time_zone, :datetime)
143
+ assert @connection.column_exists?(:has_timestamps, :also_without_time_zone, :datetime)
144
+ assert @connection.column_exists?(:has_timestamps, :with_time_zone, :timestamptz)
145
+ end
146
+ end
147
+
148
+ def test_timestamps_with_implicit_default_on_create_table
149
+ ActiveRecord::Schema.define do
150
+ create_table :has_timestamps do |t|
151
+ t.timestamps
152
+ end
153
+ end
154
+
155
+ assert @connection.column_exists?(:has_timestamps, :created_at, precision: 6, null: false)
156
+ assert @connection.column_exists?(:has_timestamps, :updated_at, precision: 6, null: false)
157
+ end
158
+
159
+ def test_timestamps_with_implicit_default_on_change_table
160
+ ActiveRecord::Schema.define do
161
+ create_table :has_timestamps
162
+
163
+ change_table :has_timestamps do |t|
164
+ t.timestamps default: Time.now
165
+ end
166
+ end
167
+
168
+ assert @connection.column_exists?(:has_timestamps, :created_at, precision: 6, null: false)
169
+ assert @connection.column_exists?(:has_timestamps, :updated_at, precision: 6, null: false)
170
+ end
171
+
172
+ if ActiveRecord::Base.lease_connection.supports_bulk_alter?
173
+ def test_timestamps_with_implicit_default_on_change_table_with_bulk
174
+ ActiveRecord::Schema.define do
175
+ create_table :has_timestamps
176
+
177
+ change_table :has_timestamps, bulk: true do |t|
178
+ t.timestamps default: Time.now
179
+ end
180
+ end
181
+
182
+ assert @connection.column_exists?(:has_timestamps, :created_at, precision: 6, null: false)
183
+ assert @connection.column_exists?(:has_timestamps, :updated_at, precision: 6, null: false)
184
+ end
185
+ end
186
+
187
+ def test_timestamps_with_implicit_default_on_add_timestamps
188
+ ActiveRecord::Schema.define do
189
+ create_table :has_timestamps
190
+ add_timestamps :has_timestamps, default: Time.now
191
+ end
192
+
193
+ assert @connection.column_exists?(:has_timestamps, :created_at, precision: 6, null: false)
194
+ assert @connection.column_exists?(:has_timestamps, :updated_at, precision: 6, null: false)
195
+ end
196
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "rack"
5
+
6
+ class ActiveRecordTest < ActiveRecord::TestCase
7
+ self.use_transactional_tests = false
8
+
9
+ unless in_memory_db?
10
+ test ".disconnect_all! closes all connections" do
11
+ ActiveRecord::Base.lease_connection.connect!
12
+ assert_predicate ActiveRecord::Base, :connected?
13
+
14
+ ActiveRecord.disconnect_all!
15
+ assert_not_predicate ActiveRecord::Base, :connected?
16
+
17
+ ActiveRecord::Base.lease_connection.connect!
18
+ assert_predicate ActiveRecord::Base, :connected?
19
+ end
20
+ end
21
+ end