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
@@ -33,7 +33,7 @@ class JsonSerializationTest < ActiveRecord::TestCase
33
33
  avatar: "binarydata",
34
34
  created_at: Time.utc(2006, 8, 1),
35
35
  awesome: true,
36
- preferences: { shows: "anime" }
36
+ preferences: { "shows" => "anime" }
37
37
  )
38
38
  end
39
39
 
@@ -149,8 +149,8 @@ class JsonSerializationTest < ActiveRecord::TestCase
149
149
  @contact = ContactSti.new(@contact.attributes)
150
150
  assert_equal "ContactSti", @contact.type
151
151
 
152
- def @contact.serializable_hash(options = {})
153
- super({ except: %w(age) }.merge!(options))
152
+ def @contact.serializable_hash(options = nil)
153
+ super({ except: %w(age) }.merge!(options || {}))
154
154
  end
155
155
 
156
156
  json = @contact.to_json
@@ -268,7 +268,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
268
268
  authors = [@david, @mary]
269
269
  encoded = ActiveSupport::JSON.encode(authors, except: [
270
270
  :name, :author_address_id, :author_address_extra_id,
271
- :organization_id, :owned_essay_id
271
+ :organization_id, :owned_essay_id, :published_author_id
272
272
  ])
273
273
  assert_equal %([{"id":1},{"id":2}]), encoded
274
274
  end
@@ -301,7 +301,7 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
301
301
 
302
302
  def test_should_be_able_to_encode_relation
303
303
  set_include_root_in_json(true) do
304
- authors_relation = Author.where(id: [@david.id, @mary.id])
304
+ authors_relation = Author.where(id: [@david.id, @mary.id]).order(:id)
305
305
 
306
306
  json = ActiveSupport::JSON.encode authors_relation, only: :name
307
307
  assert_equal '[{"author":{"name":"David"}},{"author":{"name":"Mary"}}]', json
@@ -13,7 +13,7 @@ module JSONSharedTestCases
13
13
  end
14
14
 
15
15
  def setup
16
- @connection = ActiveRecord::Base.connection
16
+ @connection = ActiveRecord::Base.lease_connection
17
17
  end
18
18
 
19
19
  def teardown
@@ -220,7 +220,7 @@ module JSONSharedTestCases
220
220
 
221
221
  def test_not_compatible_with_serialize_json
222
222
  new_klass = Class.new(klass) do
223
- serialize :payload, JSON
223
+ serialize :payload, coder: JSON
224
224
  end
225
225
  assert_raises(ActiveRecord::AttributeMethods::Serialization::ColumnNotSerializableError) do
226
226
  new_klass.new
@@ -236,7 +236,7 @@ module JSONSharedTestCases
236
236
 
237
237
  def test_json_with_serialized_attributes
238
238
  new_klass = Class.new(klass) do
239
- serialize :settings, MySettings
239
+ serialize :settings, coder: MySettings
240
240
  end
241
241
 
242
242
  new_klass.create!(settings: MySettings.new("one" => "two"))
@@ -276,15 +276,11 @@ module JSONSharedTestCases
276
276
  end
277
277
 
278
278
  def assert_type_match(type, sql_type)
279
- native_type = ActiveRecord::Base.connection.native_database_types[type][:name]
279
+ native_type = ActiveRecord::Base.lease_connection.native_database_types[type][:name]
280
280
  assert_match %r(\A#{native_type}\b), sql_type
281
281
  end
282
282
 
283
283
  def insert_statement_per_database(values)
284
- if current_adapter?(:OracleAdapter)
285
- "insert into json_data_type (id, payload) VALUES (json_data_type_seq.nextval, '#{values}')"
286
- else
287
- "insert into json_data_type (payload) VALUES ('#{values}')"
288
- end
284
+ "insert into json_data_type (payload) VALUES ('#{values}')"
289
285
  end
290
286
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "thread"
4
3
  require "cases/helper"
5
4
  require "models/person"
6
5
  require "models/job"
@@ -181,6 +180,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
181
180
  assert_equal 0, p1.lock_version
182
181
 
183
182
  p1.touch
183
+
184
184
  assert_equal 1, p1.lock_version
185
185
  assert_not_predicate p1, :changed?, "Changes should have been cleared"
186
186
  assert_predicate p1, :saved_changes?
@@ -291,7 +291,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
291
291
  end
292
292
 
293
293
  def test_touch_existing_lock_without_default_should_work_with_null_in_the_database
294
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
294
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
295
295
  t1 = LockWithoutDefault.last
296
296
 
297
297
  assert_equal 0, t1.lock_version
@@ -319,7 +319,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
319
319
  end
320
320
 
321
321
  def test_lock_without_default_should_work_with_null_in_the_database
322
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
322
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
323
323
  t1 = LockWithoutDefault.last
324
324
  t2 = LockWithoutDefault.find(t1.id)
325
325
 
@@ -341,7 +341,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
341
341
  end
342
342
 
343
343
  def test_update_with_lock_version_without_default_should_work_on_dirty_value_before_type_cast
344
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
344
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
345
345
  t1 = LockWithoutDefault.last
346
346
 
347
347
  assert_equal 0, t1.lock_version
@@ -358,7 +358,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
358
358
  end
359
359
 
360
360
  def test_destroy_with_lock_version_without_default_should_work_on_dirty_value_before_type_cast
361
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
361
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
362
362
  t1 = LockWithoutDefault.last
363
363
 
364
364
  assert_equal 0, t1.lock_version
@@ -379,7 +379,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
379
379
  assert_equal "title1", t1.title
380
380
  assert_equal 0, t1.lock_version
381
381
 
382
- assert_queries(1) { t1.update(title: "title2") }
382
+ assert_queries_count(3) { t1.update(title: "title2") }
383
383
 
384
384
  t1.reload
385
385
  assert_equal "title2", t1.title
@@ -387,7 +387,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
387
387
 
388
388
  t2 = LockWithoutDefault.new(title: "title1")
389
389
 
390
- assert_queries(1) { t2.save! }
390
+ assert_queries_count(3) { t2.save! }
391
391
 
392
392
  t2.reload
393
393
  assert_equal "title1", t2.title
@@ -408,7 +408,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
408
408
  end
409
409
 
410
410
  def test_lock_with_custom_column_without_default_should_work_with_null_in_the_database
411
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults_cust(title) VALUES('title1')")
411
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults_cust(title) VALUES('title1')")
412
412
 
413
413
  t1 = LockWithCustomColumnWithoutDefault.last
414
414
  t2 = LockWithCustomColumnWithoutDefault.find(t1.id)
@@ -436,7 +436,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
436
436
  assert_equal "title1", t1.title
437
437
  assert_equal 0, t1.custom_lock_version
438
438
 
439
- assert_queries(1) { t1.update(title: "title2") }
439
+ assert_queries_count(3) { t1.update(title: "title2") }
440
440
 
441
441
  t1.reload
442
442
  assert_equal "title2", t1.title
@@ -444,7 +444,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
444
444
 
445
445
  t2 = LockWithCustomColumnWithoutDefault.new(title: "title1")
446
446
 
447
- assert_queries(1) { t2.save! }
447
+ assert_queries_count(3) { t2.save! }
448
448
 
449
449
  t2.reload
450
450
  assert_equal "title1", t2.title
@@ -452,20 +452,22 @@ class OptimisticLockingTest < ActiveRecord::TestCase
452
452
  end
453
453
 
454
454
  def test_readonly_attributes
455
- assert_equal Set.new([ "name" ]), ReadonlyNameShip.readonly_attributes
455
+ assert_equal [ "name" ], ReadonlyNameShip.readonly_attributes
456
456
 
457
457
  s = ReadonlyNameShip.create(name: "unchangeable name")
458
458
  s.reload
459
459
  assert_equal "unchangeable name", s.name
460
460
 
461
- s.update(name: "changed name")
461
+ assert_raises(ActiveRecord::ReadonlyAttributeError) do
462
+ s.update(name: "changed name")
463
+ end
462
464
  s.reload
463
465
  assert_equal "unchangeable name", s.name
464
466
  end
465
467
 
466
- def test_quote_table_name
468
+ def test_quote_table_name_reserved_word_references
467
469
  ref = references(:michael_magician)
468
- ref.favourite = !ref.favourite
470
+ ref.favorite = !ref.favorite
469
471
  assert ref.save
470
472
  end
471
473
 
@@ -545,7 +547,7 @@ class OptimisticLockingTest < ActiveRecord::TestCase
545
547
  assert_not_empty p.treasures
546
548
  p.destroy
547
549
  assert_empty p.treasures
548
- assert_empty RichPerson.connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1")
550
+ assert_empty RichPerson.lease_connection.select_all("SELECT * FROM peoples_treasures WHERE rich_person_id = 1")
549
551
  end
550
552
 
551
553
  def test_yaml_dumping_with_lock_column
@@ -608,7 +610,7 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
608
610
  end
609
611
 
610
612
  def test_destroy_existing_object_with_locking_column_value_null_in_the_database
611
- ActiveRecord::Base.connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
613
+ ActiveRecord::Base.lease_connection.execute("INSERT INTO lock_without_defaults(title) VALUES('title1')")
612
614
  t1 = LockWithoutDefault.last
613
615
 
614
616
  assert_equal 0, t1.lock_version
@@ -634,12 +636,12 @@ class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
634
636
 
635
637
  private
636
638
  def add_counter_column_to(model, col = "test_count")
637
- model.connection.add_column model.table_name, col, :integer, null: false, default: 0
639
+ model.lease_connection.add_column model.table_name, col, :integer, null: false, default: 0
638
640
  model.reset_column_information
639
641
  end
640
642
 
641
643
  def remove_counter_column_from(model, col = :test_count)
642
- model.connection.remove_column model.table_name, col
644
+ model.lease_connection.remove_column model.table_name, col
643
645
  model.reset_column_information
644
646
  end
645
647
 
@@ -661,8 +663,8 @@ end
661
663
  # is so cumbersome. Will deadlock Ruby threads if the underlying db.execute
662
664
  # blocks, so separate script called by Kernel#system is needed.
663
665
  # (See exec vs. async_exec in the PostgreSQL adapter.)
664
- unless in_memory_db?
665
- class PessimisticLockingTest < ActiveRecord::TestCase
666
+ class PessimisticLockingTest < ActiveRecord::TestCase
667
+ unless in_memory_db?
666
668
  self.use_transactional_tests = false
667
669
  fixtures :people, :readers
668
670
 
@@ -673,7 +675,7 @@ unless in_memory_db?
673
675
  end
674
676
 
675
677
  # Test typical find.
676
- def test_sane_find_with_lock
678
+ def test_typical_find_with_lock
677
679
  assert_nothing_raised do
678
680
  Person.transaction do
679
681
  Person.lock.find(1)
@@ -703,23 +705,23 @@ unless in_memory_db?
703
705
  def test_lock_raises_when_the_record_is_dirty
704
706
  person = Person.find 1
705
707
  person.first_name = "fooman"
706
- assert_raises(RuntimeError) do
708
+ error = assert_raises(RuntimeError) do
707
709
  person.lock!
708
710
  end
711
+ assert_match(/Changed attributes: "first_name"/, error.message)
709
712
  end
710
713
 
711
714
  def test_locking_in_after_save_callback
712
715
  assert_nothing_raised do
713
716
  frog = ::Frog.create(name: "Old Frog")
714
717
  frog.name = "New Frog"
715
- assert_not_deprecated do
718
+ assert_not_deprecated(ActiveRecord.deprecator) do
716
719
  frog.save!
717
720
  end
718
721
  end
719
722
  end
720
723
 
721
724
  def test_with_lock_commits_transaction
722
- puts "Inside test_with_lock_commits_transaction"
723
725
  person = Person.find 1
724
726
  person.with_lock do
725
727
  person.first_name = "fooman"
@@ -739,15 +741,44 @@ unless in_memory_db?
739
741
  assert_equal old, person.reload.first_name
740
742
  end
741
743
 
744
+ def test_with_lock_configures_transaction
745
+ person = Person.find 1
746
+ Person.transaction do
747
+ outer_transaction = Person.lease_connection.transaction_manager.current_transaction
748
+ assert_equal true, outer_transaction.joinable?
749
+ person.with_lock(requires_new: true, joinable: false) do
750
+ current_transaction = Person.lease_connection.transaction_manager.current_transaction
751
+ assert_not_equal outer_transaction, current_transaction
752
+ assert_equal false, current_transaction.joinable?
753
+ end
754
+ end
755
+ end
756
+
742
757
  if current_adapter?(:PostgreSQLAdapter)
743
758
  def test_lock_sending_custom_lock_statement
744
759
  Person.transaction do
745
760
  person = Person.find(1)
746
- assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do
761
+ assert_queries_match(/LIMIT \$?\d FOR SHARE NOWAIT/) do
747
762
  person.lock!("FOR SHARE NOWAIT")
748
763
  end
749
764
  end
750
765
  end
766
+
767
+ def test_with_lock_sets_isolation
768
+ person = Person.find 1
769
+ person.with_lock(isolation: :read_uncommitted) do
770
+ current_transaction = Person.lease_connection.transaction_manager.current_transaction
771
+ assert_equal :read_uncommitted, current_transaction.isolation_level
772
+ end
773
+ end
774
+
775
+ def test_with_lock_locks_with_no_args
776
+ person = Person.find 1
777
+ assert_queries_match(/LIMIT \$?\d FOR UPDATE/i) do
778
+ person.with_lock do
779
+ end
780
+ end
781
+ end
751
782
  end
752
783
 
753
784
  def test_no_locks_no_wait
@@ -756,29 +787,34 @@ unless in_memory_db?
756
787
  end
757
788
 
758
789
  private
759
- def duel(zzz = 5)
790
+ def duel(&block)
760
791
  t0, t1, t2, t3 = nil, nil, nil, nil
761
792
 
793
+ a_wakeup = Concurrent::Event.new
794
+ b_wakeup = Concurrent::Event.new
795
+
762
796
  a = Thread.new do
763
797
  t0 = Time.now
764
- Person.transaction do
798
+ Person.transaction(joinable: false) do
765
799
  yield
766
- sleep zzz # block thread 2 for zzz seconds
800
+ b_wakeup.set
801
+ a_wakeup.wait
767
802
  end
768
803
  t1 = Time.now
769
804
  end
770
805
 
771
806
  b = Thread.new do
772
- sleep zzz / 2.0 # ensure thread 1 tx starts first
807
+ b_wakeup.wait
773
808
  t2 = Time.now
774
- Person.transaction { yield }
809
+ Person.transaction(&block)
810
+ a_wakeup.set
775
811
  t3 = Time.now
776
812
  end
777
813
 
778
814
  a.join
779
815
  b.join
780
816
 
781
- assert t1 > t0 + zzz
817
+ assert t1 > t0
782
818
  assert t2 > t0
783
819
  assert t3 > t2
784
820
  [t0.to_f..t1.to_f, t2.to_f..t3.to_f]
@@ -9,8 +9,8 @@ require "active_support/log_subscriber/test_helper"
9
9
  class LogSubscriberTest < ActiveRecord::TestCase
10
10
  include ActiveSupport::LogSubscriber::TestHelper
11
11
  include ActiveSupport::Logger::Severity
12
- REGEXP_CLEAR = Regexp.escape(ActiveRecord::LogSubscriber::CLEAR)
13
- REGEXP_BOLD = Regexp.escape(ActiveRecord::LogSubscriber::BOLD)
12
+ REGEXP_CLEAR = Regexp.escape("\e[#{ActiveRecord::LogSubscriber::MODES[:clear]}m")
13
+ REGEXP_BOLD = Regexp.escape("\e[#{ActiveRecord::LogSubscriber::MODES[:bold]}m")
14
14
  REGEXP_MAGENTA = Regexp.escape(ActiveRecord::LogSubscriber::MAGENTA)
15
15
  REGEXP_CYAN = Regexp.escape(ActiveRecord::LogSubscriber::CYAN)
16
16
  SQL_COLORINGS = {
@@ -44,7 +44,7 @@ class LogSubscriberTest < ActiveRecord::TestCase
44
44
  def setup
45
45
  @old_logger = ActiveRecord::Base.logger
46
46
  Developer.primary_key
47
- ActiveRecord::Base.connection.materialize_transactions
47
+ ActiveRecord::Base.lease_connection.materialize_transactions
48
48
  super
49
49
  ActiveRecord::LogSubscriber.attach_to(:active_record)
50
50
  end
@@ -133,6 +133,12 @@ class LogSubscriberTest < ActiveRecord::TestCase
133
133
  end
134
134
  end
135
135
 
136
+ def test_async_query
137
+ logger = TestDebugLogSubscriber.new
138
+ logger.sql(Event.new(0.9, sql: "SELECT * from models", name: "Model Load", async: true, lock_wait: 0.01))
139
+ assert_match(/ASYNC Model Load \(0\.0ms\) \(db time 0\.9ms\) SELECT/i, logger.debugs.last)
140
+ end
141
+
136
142
  def test_query_logging_coloration_with_nested_select
137
143
  logger = TestDebugLogSubscriber.new
138
144
  logger.colorize_logging = true
@@ -183,28 +189,28 @@ class LogSubscriberTest < ActiveRecord::TestCase
183
189
  assert_match(/SELECT .*?FROM .?developers.?/i, @logger.logged(:debug).last)
184
190
  end
185
191
 
186
- def test_vebose_query_logs
187
- ActiveRecord::Base.verbose_query_logs = true
192
+ def test_verbose_query_logs
193
+ ActiveRecord.verbose_query_logs = true
188
194
 
189
195
  logger = TestDebugLogSubscriber.new
190
196
  logger.sql(Event.new(0, sql: "hi mom!"))
191
197
  assert_equal 2, @logger.logged(:debug).size
192
198
  assert_match(/↳/, @logger.logged(:debug).last)
193
199
  ensure
194
- ActiveRecord::Base.verbose_query_logs = false
200
+ ActiveRecord.verbose_query_logs = false
195
201
  end
196
202
 
197
203
  def test_verbose_query_with_ignored_callstack
198
- ActiveRecord::Base.verbose_query_logs = true
204
+ ActiveRecord.verbose_query_logs = true
199
205
 
200
206
  logger = TestDebugLogSubscriber.new
201
- def logger.extract_query_source_location(*); nil; end
207
+ def logger.query_source_location; nil; end
202
208
 
203
209
  logger.sql(Event.new(0, sql: "hi mom!"))
204
210
  assert_equal 1, @logger.logged(:debug).size
205
211
  assert_no_match(/↳/, @logger.logged(:debug).last)
206
212
  ensure
207
- ActiveRecord::Base.verbose_query_logs = false
213
+ ActiveRecord.verbose_query_logs = false
208
214
  end
209
215
 
210
216
  def test_verbose_query_logs_disabled_by_default
@@ -241,11 +247,7 @@ class LogSubscriberTest < ActiveRecord::TestCase
241
247
  assert_equal 0, @logger.logged(:debug).size
242
248
  end
243
249
 
244
- def test_initializes_runtime
245
- Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join
246
- end
247
-
248
- if ActiveRecord::Base.connection.prepared_statements
250
+ if ActiveRecord::Base.lease_connection.prepared_statements
249
251
  def test_where_in_binds_logging_include_attribute_names
250
252
  Developer.where(id: [1, 2, 3, 4, 5]).load
251
253
  wait
@@ -261,7 +263,7 @@ class LogSubscriberTest < ActiveRecord::TestCase
261
263
  def test_binary_data_hash
262
264
  Binary.create(data: { a: 1 })
263
265
  wait
264
- assert_match(/<7 bytes of binary data>/, @logger.logged(:debug).join)
266
+ assert_match(/<(6|7) bytes of binary data>/, @logger.logged(:debug).join)
265
267
  end
266
268
  end
267
269
  end
@@ -7,8 +7,36 @@ require "models/reply"
7
7
  class MarshalSerializationTest < ActiveRecord::TestCase
8
8
  fixtures :topics
9
9
 
10
- def test_deserializing_rails_6_0_marshal_basic
11
- topic = Marshal.load(marshal_fixture("rails_6_0_topic"))
10
+ setup do
11
+ @previous_format_version = ActiveRecord::Marshalling.format_version
12
+ end
13
+
14
+ teardown do
15
+ ActiveRecord::Marshalling.format_version = @previous_format_version
16
+ end
17
+
18
+ def test_deserializing_rails_6_1_marshal_basic
19
+ topic = Marshal.load(marshal_fixture("rails_6_1_topic"))
20
+
21
+ assert_not_predicate topic, :new_record?
22
+ assert_equal 1, topic.id
23
+ assert_equal "The First Topic", topic.title
24
+ assert_equal "Have a nice day", topic.content
25
+ end
26
+
27
+ def test_deserializing_rails_6_1_marshal_with_loaded_association_cache
28
+ topic = Marshal.load(marshal_fixture("rails_6_1_topic_associations"))
29
+
30
+ assert_not_predicate topic, :new_record?
31
+ assert_equal 1, topic.id
32
+ assert_equal "The First Topic", topic.title
33
+ assert_equal "Have a nice day", topic.content
34
+ assert_predicate topic.association(:replies), :loaded?
35
+ assert_predicate topic.replies.first.association(:topic), :loaded?
36
+ end
37
+
38
+ def test_deserializing_rails_7_1_marshal_basic
39
+ topic = Marshal.load(marshal_fixture("rails_7_1_topic"))
12
40
 
13
41
  assert_not_predicate topic, :new_record?
14
42
  assert_equal 1, topic.id
@@ -16,13 +44,58 @@ class MarshalSerializationTest < ActiveRecord::TestCase
16
44
  assert_equal "Have a nice day", topic.content
17
45
  end
18
46
 
19
- def test_deserializing_rails_6_0_marshal_with_loaded_association_cache
20
- topic = Marshal.load(marshal_fixture("rails_6_0_topic_associations"))
47
+ def test_deserializing_rails_7_1_marshal_with_loaded_association_cache
48
+ topic = Marshal.load(marshal_fixture("rails_7_1_topic_associations"))
21
49
 
22
50
  assert_not_predicate topic, :new_record?
23
51
  assert_equal 1, topic.id
24
52
  assert_equal "The First Topic", topic.title
25
53
  assert_equal "Have a nice day", topic.content
54
+ assert_predicate topic.association(:replies), :loaded?
55
+ assert_predicate topic.replies.first.association(:topic), :loaded?
56
+ assert_same topic, topic.replies.first.topic
57
+ end
58
+
59
+ def test_rails_6_1_rountrip
60
+ topic = Topic.find(1)
61
+ topic.replies.to_a
62
+ topic = Marshal.load(Marshal.dump(topic))
63
+
64
+ assert_not_predicate topic, :new_record?
65
+ assert_equal 1, topic.id
66
+ assert_equal "The First Topic", topic.title
67
+ assert_equal "Have a nice day", topic.content
68
+ assert_predicate topic.association(:replies), :loaded?
69
+ end
70
+
71
+ def test_rails_7_1_rountrip
72
+ ActiveRecord::Marshalling.format_version = 7.1
73
+
74
+ topic = Topic.find(1)
75
+ topic.replies.each(&:topic)
76
+ assert_not_equal 0, topic.replies.size
77
+ topic.replies.each do |reply|
78
+ assert_same topic, reply.topic
79
+ end
80
+
81
+ topic.association(:open_replies)
82
+ assert_equal true, topic.association_cached?(:open_replies)
83
+ assert_not_predicate topic.association(:open_replies), :loaded?
84
+
85
+ topic = Marshal.load(Marshal.dump(topic))
86
+
87
+ assert_not_predicate topic, :new_record?
88
+ assert_equal 1, topic.id
89
+ assert_equal "The First Topic", topic.title
90
+ assert_equal "Have a nice day", topic.content
91
+ assert_predicate topic.association(:replies), :loaded?
92
+
93
+ assert_not_predicate topic.association(:open_replies), :loaded?
94
+
95
+ assert_not_equal 0, topic.replies.size
96
+ topic.replies.each do |reply|
97
+ assert_same topic, reply.topic
98
+ end
26
99
  end
27
100
 
28
101
  private
@@ -32,7 +105,7 @@ class MarshalSerializationTest < ActiveRecord::TestCase
32
105
 
33
106
  def marshal_fixture_path(file_name)
34
107
  File.expand_path(
35
- "support/marshal_compatibility_fixtures/#{ActiveRecord::Base.connection.adapter_name}/#{file_name}.dump",
108
+ "support/marshal_compatibility_fixtures/#{ActiveRecord::Base.lease_connection.adapter_name}/#{file_name}.dump",
36
109
  TEST_ROOT
37
110
  )
38
111
  end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+ require "models/binary"
6
+ require "models/comment"
7
+ require "models/post"
8
+ require "active_support/message_pack"
9
+ require "active_record/message_pack"
10
+
11
+ class ActiveRecordMessagePackTest < ActiveRecord::TestCase
12
+ fixtures :posts, :comments, :authors, :author_addresses
13
+
14
+ test "enshrines type IDs" do
15
+ expected = {
16
+ 119 => ActiveModel::Type::Binary::Data,
17
+ 120 => ActiveRecord::Base,
18
+ }
19
+
20
+ factory = ::MessagePack::Factory.new
21
+ ActiveRecord::MessagePack::Extensions.install(factory)
22
+ actual = factory.registered_types.to_h do |entry|
23
+ [entry[:type], entry[:class]]
24
+ end
25
+
26
+ assert_equal expected, actual
27
+ end
28
+
29
+ test "roundtrips record and cached associations" do
30
+ post = Post.create!(title: "A Title", body: "A body.")
31
+ post.create_author!(name: "An Author")
32
+ post.comments.create!(body: "A comment.")
33
+ post.comments.create!(body: "Another comment.", author: post.author)
34
+ post.comments.load
35
+
36
+ assert_no_queries do
37
+ roundtripped_post = roundtrip(post)
38
+
39
+ assert_equal post, roundtripped_post
40
+ assert_equal post.author, roundtripped_post.author
41
+ assert_equal post.comments.to_a, roundtripped_post.comments.to_a
42
+ assert_equal post.comments.map(&:author), roundtripped_post.comments.map(&:author)
43
+
44
+ assert_same roundtripped_post, roundtripped_post.comments[0].post
45
+ assert_same roundtripped_post, roundtripped_post.comments[1].post
46
+ assert_same roundtripped_post.author, roundtripped_post.comments[1].author
47
+ end
48
+ end
49
+
50
+ test "roundtrips new_record? status" do
51
+ post = Post.new(title: "A Title", body: "A body.")
52
+ post.create_author!(name: "An Author")
53
+
54
+ assert_no_queries do
55
+ roundtripped_post = roundtrip(post)
56
+
57
+ assert_equal post.attributes, roundtripped_post.attributes
58
+ assert_equal post.new_record?, roundtripped_post.new_record?
59
+ assert_equal post.author, roundtripped_post.author
60
+ assert_equal post.author.new_record?, roundtripped_post.author.new_record?
61
+ end
62
+ end
63
+
64
+ test "roundtrips binary attribute" do
65
+ binary = Binary.new(data: Marshal.dump("data"))
66
+ assert_equal binary.attributes, roundtrip(binary).attributes
67
+ end
68
+
69
+ test "raises ActiveSupport::MessagePack::MissingClassError if record class no longer exists" do
70
+ klass = Class.new(Post)
71
+ def klass.name; "SomeLegacyClass"; end
72
+ dumped = serializer.dump(klass.new(title: "A Title", body: "A body."))
73
+
74
+ assert_raises ActiveSupport::MessagePack::MissingClassError do
75
+ serializer.load(dumped)
76
+ end
77
+ end
78
+
79
+ private
80
+ def serializer
81
+ @serializer ||= ::MessagePack::Factory.new.tap do |factory|
82
+ ActiveRecord::MessagePack::Extensions.install(factory)
83
+ ActiveSupport::MessagePack::Extensions.install(factory)
84
+ ActiveSupport::MessagePack::Extensions.install_unregistered_type_error(factory)
85
+ end
86
+ end
87
+
88
+ def roundtrip(input)
89
+ serializer.load(serializer.dump(input))
90
+ end
91
+ end