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
@@ -14,10 +14,10 @@ class DefaultTest < ActiveRecord::TestCase
14
14
  end
15
15
  end
16
16
 
17
- if current_adapter?(:PostgreSQLAdapter)
17
+ if current_adapter?(:PostgreSQLAdapter) || current_adapter?(:SQLite3Adapter)
18
18
  def test_multiline_default_text
19
19
  record = Default.new
20
- # older postgres versions represent the default with escapes ("\\012" for a newline)
20
+ # older PostgreSQL versions represent the default with escapes ("\\012" for a newline)
21
21
  assert("--- []\n\n" == record.multiline_default || "--- []\\012\\012" == record.multiline_default)
22
22
  end
23
23
  end
@@ -27,7 +27,7 @@ class DefaultNumbersTest < ActiveRecord::TestCase
27
27
  class DefaultNumber < ActiveRecord::Base; end
28
28
 
29
29
  setup do
30
- @connection = ActiveRecord::Base.connection
30
+ @connection = ActiveRecord::Base.lease_connection
31
31
  @connection.create_table :default_numbers do |t|
32
32
  t.integer :positive_integer, default: 7
33
33
  t.integer :negative_integer, default: -5
@@ -62,7 +62,7 @@ class DefaultStringsTest < ActiveRecord::TestCase
62
62
  class DefaultString < ActiveRecord::Base; end
63
63
 
64
64
  setup do
65
- @connection = ActiveRecord::Base.connection
65
+ @connection = ActiveRecord::Base.lease_connection
66
66
  @connection.create_table :default_strings do |t|
67
67
  t.string :string_col, default: "Smith"
68
68
  t.string :string_col_with_quotes, default: "O'Connor"
@@ -83,12 +83,45 @@ class DefaultStringsTest < ActiveRecord::TestCase
83
83
  end
84
84
  end
85
85
 
86
- if supports_text_column_with_default?
87
- class DefaultTextTest < ActiveRecord::TestCase
86
+ class DefaultBinaryTest < ActiveRecord::TestCase
87
+ if current_adapter?(:SQLite3Adapter, :PostgreSQLAdapter)
88
+ class DefaultBinary < ActiveRecord::Base; end
89
+
90
+ setup do
91
+ @connection = ActiveRecord::Base.lease_connection
92
+ @connection.create_table :default_binaries do |t|
93
+ t.binary :varbinary_col, null: false, limit: 64, default: "varbinary_default"
94
+ t.binary :varbinary_col_hex_looking, null: false, limit: 64, default: "0xDEADBEEF"
95
+ end
96
+ DefaultBinary.reset_column_information
97
+ end
98
+
99
+ def test_default_varbinary_string
100
+ assert_equal "varbinary_default", DefaultBinary.new.varbinary_col
101
+ end
102
+
103
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter) && !ActiveRecord::Base.lease_connection.mariadb?
104
+ def test_default_binary_string
105
+ assert_equal "binary_default", DefaultBinary.new.binary_col
106
+ end
107
+ end
108
+
109
+ def test_default_varbinary_string_that_looks_like_hex
110
+ assert_equal "0xDEADBEEF", DefaultBinary.new.varbinary_col_hex_looking
111
+ end
112
+
113
+ teardown do
114
+ @connection.drop_table :default_binaries
115
+ end
116
+ end
117
+ end
118
+
119
+ class DefaultTextTest < ActiveRecord::TestCase
120
+ if supports_text_column_with_default?
88
121
  class DefaultText < ActiveRecord::Base; end
89
122
 
90
123
  setup do
91
- @connection = ActiveRecord::Base.connection
124
+ @connection = ActiveRecord::Base.lease_connection
92
125
  @connection.create_table :default_texts do |t|
93
126
  t.text :text_col, default: "Smith"
94
127
  t.text :text_col_with_quotes, default: "O'Connor"
@@ -110,18 +143,22 @@ if supports_text_column_with_default?
110
143
  end
111
144
  end
112
145
 
113
- if current_adapter?(:PostgreSQLAdapter)
114
- class PostgresqlDefaultExpressionTest < ActiveRecord::TestCase
146
+ class PostgresqlDefaultExpressionTest < ActiveRecord::TestCase
147
+ if current_adapter?(:PostgreSQLAdapter)
115
148
  include SchemaDumpingHelper
116
149
 
117
150
  test "schema dump includes default expression" do
118
151
  output = dump_table_schema("defaults")
119
- if ActiveRecord::Base.connection.database_version >= 100000
152
+ if ActiveRecord::Base.lease_connection.database_version >= 100000
120
153
  assert_match %r/t\.date\s+"modified_date",\s+default: -> { "CURRENT_DATE" }/, output
121
154
  assert_match %r/t\.datetime\s+"modified_time",\s+default: -> { "CURRENT_TIMESTAMP" }/, output
155
+ assert_match %r/t\.datetime\s+"modified_time_without_precision",\s+precision: nil,\s+default: -> { "CURRENT_TIMESTAMP" }/, output
156
+ assert_match %r/t\.datetime\s+"modified_time_with_precision_0",\s+precision: 0,\s+default: -> { "CURRENT_TIMESTAMP" }/, output
122
157
  else
123
158
  assert_match %r/t\.date\s+"modified_date",\s+default: -> { "\('now'::text\)::date" }/, output
124
159
  assert_match %r/t\.datetime\s+"modified_time",\s+default: -> { "now\(\)" }/, output
160
+ assert_match %r/t\.datetime\s+"modified_time_without_precision",\s+precision: nil,\s+default: -> { "now\(\)" }/, output
161
+ assert_match %r/t\.datetime\s+"modified_time_with_precision_0",\s+precision: 0,\s+default: -> { "now\(\)" }/, output
125
162
  end
126
163
  assert_match %r/t\.date\s+"modified_date_function",\s+default: -> { "now\(\)" }/, output
127
164
  assert_match %r/t\.datetime\s+"modified_time_function",\s+default: -> { "now\(\)" }/, output
@@ -129,46 +166,61 @@ if current_adapter?(:PostgreSQLAdapter)
129
166
  end
130
167
  end
131
168
 
132
- if current_adapter?(:Mysql2Adapter)
133
- class MysqlDefaultExpressionTest < ActiveRecord::TestCase
169
+ class MysqlDefaultExpressionTest < ActiveRecord::TestCase
170
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
134
171
  include SchemaDumpingHelper
135
172
 
136
173
  if supports_default_expression?
137
174
  test "schema dump includes default expression" do
138
175
  output = dump_table_schema("defaults")
139
- assert_match %r/t\.binary\s+"uuid",\s+limit: 36,\s+default: -> { "\(uuid\(\)\)" }/i, output
176
+ assert_match %r/t\.binary\s+"uuid",\s+limit: 36,\s+default: -> { "\(?uuid\(\)\)?" }/i, output
140
177
  end
141
- end
142
178
 
143
- if supports_datetime_with_precision?
144
- test "schema dump datetime includes default expression" do
145
- output = dump_table_schema("datetime_defaults")
146
- assert_match %r/t\.datetime\s+"modified_datetime",\s+default: -> { "CURRENT_TIMESTAMP(?:\(\))?" }/i, output
179
+ test "schema dump includes default expression with single quotes reflected correctly" do
180
+ output = dump_table_schema("defaults")
181
+ assert_match %r/t\.string\s+"char2_concatenated",\s+default: -> { "\(?concat\(`char2`,(_utf8mb4)?'-'\)\)?" }/i, output
147
182
  end
183
+ end
148
184
 
149
- test "schema dump datetime includes precise default expression" do
150
- output = dump_table_schema("datetime_defaults")
151
- assert_match %r/t\.datetime\s+"precise_datetime",.+default: -> { "CURRENT_TIMESTAMP\(6\)" }/i, output
152
- end
185
+ test "schema dump datetime includes default expression" do
186
+ output = dump_table_schema("datetime_defaults")
187
+ assert_match %r/t\.datetime\s+"modified_datetime",\s+precision: nil,\s+default: -> { "CURRENT_TIMESTAMP(?:\(\))?" }/i, output
188
+ end
153
189
 
154
- test "schema dump timestamp includes default expression" do
155
- output = dump_table_schema("timestamp_defaults")
156
- assert_match %r/t\.timestamp\s+"modified_timestamp",\s+default: -> { "CURRENT_TIMESTAMP(?:\(\))?" }/i, output
157
- end
190
+ test "schema dump datetime includes precise default expression" do
191
+ output = dump_table_schema("datetime_defaults")
192
+ assert_match %r/t\.datetime\s+"precise_datetime",\s+default: -> { "CURRENT_TIMESTAMP\(6\)" }/i, output
193
+ end
158
194
 
159
- test "schema dump timestamp includes precise default expression" do
160
- output = dump_table_schema("timestamp_defaults")
161
- assert_match %r/t\.timestamp\s+"precise_timestamp",.+default: -> { "CURRENT_TIMESTAMP\(6\)" }/i, output
162
- end
195
+ test "schema dump datetime includes precise default expression with on update" do
196
+ output = dump_table_schema("datetime_defaults")
197
+ assert_match %r/t\.datetime\s+"updated_datetime",\s+default: -> { "CURRENT_TIMESTAMP\(6\) ON UPDATE CURRENT_TIMESTAMP\(6\)" }/i, output
198
+ end
163
199
 
164
- test "schema dump timestamp without default expression" do
165
- output = dump_table_schema("timestamp_defaults")
166
- assert_match %r/t\.timestamp\s+"nullable_timestamp"$/, output
167
- end
200
+ test "schema dump timestamp includes default expression" do
201
+ output = dump_table_schema("timestamp_defaults")
202
+ assert_match %r/t\.timestamp\s+"modified_timestamp",\s+default: -> { "CURRENT_TIMESTAMP(?:\(\))?" }/i, output
203
+ end
204
+
205
+ test "schema dump timestamp includes precise default expression" do
206
+ output = dump_table_schema("timestamp_defaults")
207
+ assert_match %r/t\.timestamp\s+"precise_timestamp",.+default: -> { "CURRENT_TIMESTAMP\(6\)" }/i, output
208
+ end
209
+
210
+ test "schema dump timestamp includes precise default expression with on update" do
211
+ output = dump_table_schema("timestamp_defaults")
212
+ assert_match %r/t\.timestamp\s+"updated_timestamp",.+default: -> { "CURRENT_TIMESTAMP\(6\) ON UPDATE CURRENT_TIMESTAMP\(6\)" }/i, output
213
+ end
214
+
215
+ test "schema dump timestamp without default expression" do
216
+ output = dump_table_schema("timestamp_defaults")
217
+ assert_match %r/t\.timestamp\s+"nullable_timestamp"$/, output
168
218
  end
169
219
  end
220
+ end
170
221
 
171
- class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase
222
+ class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase
223
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
172
224
  # ActiveRecord::Base#create! (and #save and other related methods) will
173
225
  # open a new transaction. When in transactional tests mode, this will
174
226
  # cause Active Record to create a new savepoint. However, since MySQL doesn't
@@ -180,13 +232,12 @@ if current_adapter?(:Mysql2Adapter)
180
232
  self.use_transactional_tests = false
181
233
 
182
234
  def using_strict(strict)
183
- connection = ActiveRecord::Base.remove_connection
184
- conn_hash = connection.configuration_hash
235
+ db_config = ActiveRecord::Base.connection_pool.db_config
236
+ conn_hash = db_config.configuration_hash
185
237
  ActiveRecord::Base.establish_connection conn_hash.merge(strict: strict)
186
238
  yield
187
239
  ensure
188
- ActiveRecord::Base.remove_connection
189
- ActiveRecord::Base.establish_connection connection
240
+ ActiveRecord::Base.establish_connection db_config
190
241
  end
191
242
 
192
243
  # Strict mode controls how MySQL handles invalid or missing values
@@ -239,7 +290,7 @@ if current_adapter?(:Mysql2Adapter)
239
290
  def with_mysql_not_null_table
240
291
  klass = Class.new(ActiveRecord::Base)
241
292
  klass.table_name = "test_mysql_not_null_defaults"
242
- klass.connection.create_table klass.table_name do |t|
293
+ klass.lease_connection.create_table klass.table_name do |t|
243
294
  t.integer :non_null_integer, null: false
244
295
  t.string :non_null_string, null: false
245
296
  t.text :non_null_text, null: false
@@ -248,7 +299,22 @@ if current_adapter?(:Mysql2Adapter)
248
299
 
249
300
  yield klass
250
301
  ensure
251
- klass.connection.drop_table(klass.table_name) rescue nil
302
+ klass.lease_connection.drop_table(klass.table_name) rescue nil
303
+ end
304
+ end
305
+ end
306
+
307
+ class Sqlite3DefaultExpressionTest < ActiveRecord::TestCase
308
+ if current_adapter?(:SQLite3Adapter)
309
+ include SchemaDumpingHelper
310
+
311
+ test "schema dump includes default expression" do
312
+ output = dump_table_schema("defaults")
313
+ assert_match %r/t\.date\s+"modified_date",\s+default: -> { "CURRENT_DATE" }/, output
314
+ assert_match %r/t\.datetime\s+"modified_time",\s+default: -> { "CURRENT_TIMESTAMP" }/, output
315
+ assert_match %r/t\.datetime\s+"modified_time_without_precision",\s+precision: nil,\s+default: -> { "CURRENT_TIMESTAMP" }/, output
316
+ assert_match %r/t\.datetime\s+"modified_time_with_precision_0",\s+precision: 0,\s+default: -> { "CURRENT_TIMESTAMP" }/, output
317
+ assert_match %r/t\.integer\s+"random_number",\s+default: -> { "ABS\(RANDOM\(\)\)" }/, output
252
318
  end
253
319
  end
254
320
  end
@@ -1,16 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cases/helper"
4
+ require "models/account"
4
5
  require "models/entry"
5
6
  require "models/message"
7
+ require "models/recipient"
6
8
  require "models/comment"
9
+ require "models/uuid_entry"
10
+ require "models/uuid_message"
11
+ require "models/uuid_comment"
7
12
 
8
13
  class DelegatedTypeTest < ActiveRecord::TestCase
9
- fixtures :comments
14
+ fixtures :comments, :accounts, :posts
10
15
 
11
16
  setup do
12
- @entry_with_message = Entry.create! entryable: Message.new(subject: "Hello world!")
13
- @entry_with_comment = Entry.create! entryable: comments(:greetings)
17
+ @entry_with_message = Entry.create! entryable: Message.new(subject: "Hello world!"), account: accounts(:signals37)
18
+ @entry_with_comment = Entry.create! entryable: comments(:greetings), account: accounts(:signals37)
19
+ @entry_with_post = Entry.create! thing: posts(:welcome), account: accounts(:signals37)
20
+
21
+ if current_adapter?(:PostgreSQLAdapter)
22
+ @uuid_entry_with_message = UuidEntry.create! uuid: SecureRandom.uuid, entryable: UuidMessage.new(uuid: SecureRandom.uuid, subject: "Hello world!")
23
+ @uuid_entry_with_comment = UuidEntry.create! uuid: SecureRandom.uuid, entryable: UuidComment.new(uuid: SecureRandom.uuid, content: "comment")
24
+ end
25
+ end
26
+
27
+ test "delegated types" do
28
+ assert_equal ["Message", "Comment"], Entry.entryable_types
14
29
  end
15
30
 
16
31
  test "delegated class" do
@@ -18,25 +33,41 @@ class DelegatedTypeTest < ActiveRecord::TestCase
18
33
  assert_equal Comment, @entry_with_comment.entryable_class
19
34
  end
20
35
 
36
+ test "delegated class with custom foreign_type" do
37
+ assert_equal Message, @entry_with_message.thing_class
38
+ assert_equal Comment, @entry_with_comment.thing_class
39
+ assert_equal Post, @entry_with_post.thing_class
40
+ end
41
+
21
42
  test "delegated type name" do
22
43
  assert_equal "message", @entry_with_message.entryable_name
23
- assert @entry_with_message.entryable_name.message?
44
+ assert_predicate @entry_with_message.entryable_name, :message?
24
45
 
25
46
  assert_equal "comment", @entry_with_comment.entryable_name
26
- assert @entry_with_comment.entryable_name.comment?
47
+ assert_predicate @entry_with_comment.entryable_name, :comment?
27
48
  end
28
49
 
29
50
  test "delegated type predicates" do
30
- assert @entry_with_message.message?
51
+ assert_predicate @entry_with_message, :message?
31
52
  assert_not @entry_with_message.comment?
32
53
 
33
- assert @entry_with_comment.comment?
54
+ assert_predicate @entry_with_comment, :comment?
34
55
  assert_not @entry_with_comment.message?
35
56
  end
36
57
 
58
+ test "delegated type predicates with custom foreign_type" do
59
+ assert_predicate @entry_with_post, :post?
60
+ assert_not @entry_with_message.post?
61
+ assert_not @entry_with_comment.post?
62
+ end
63
+
37
64
  test "scope" do
38
- assert Entry.messages.first.message?
39
- assert Entry.comments.first.comment?
65
+ assert_predicate Entry.messages.first, :message?
66
+ assert_predicate Entry.comments.first, :comment?
67
+ end
68
+
69
+ test "scope with custom foreign_type" do
70
+ assert_predicate Entry.posts.first, :post?
40
71
  end
41
72
 
42
73
  test "accessor" do
@@ -54,4 +85,33 @@ class DelegatedTypeTest < ActiveRecord::TestCase
54
85
  assert_equal @entry_with_comment.entryable_id, @entry_with_comment.comment_id
55
86
  assert_nil @entry_with_comment.message_id
56
87
  end
88
+
89
+ test "association uuid" do
90
+ skip unless current_adapter?(:PostgreSQLAdapter)
91
+
92
+ assert_equal @uuid_entry_with_message.entryable_uuid, @uuid_entry_with_message.uuid_message_uuid
93
+ assert_nil @uuid_entry_with_message.uuid_comment_uuid
94
+
95
+ assert_equal @uuid_entry_with_comment.entryable_uuid, @uuid_entry_with_comment.uuid_comment_uuid
96
+ assert_nil @uuid_entry_with_comment.uuid_message_uuid
97
+ end
98
+
99
+ test "touch account" do
100
+ previous_account_updated_at = @entry_with_message.account.updated_at
101
+ previous_entry_updated_at = @entry_with_message.updated_at
102
+ previous_message_updated_at = @entry_with_message.entryable.updated_at
103
+
104
+ travel 5.seconds do
105
+ Recipient.create! message: @entry_with_message.entryable, email_address: "test@test.com"
106
+ end
107
+
108
+ assert_not_equal @entry_with_message.reload.account.updated_at, previous_account_updated_at
109
+ assert_not_equal @entry_with_message.reload.updated_at, previous_entry_updated_at
110
+ assert_not_equal @entry_with_message.reload.entryable.updated_at, previous_message_updated_at
111
+ end
112
+
113
+ test "builder method" do
114
+ assert_respond_to Entry.new, :build_entryable
115
+ assert_equal Message, Entry.new(entryable_type: "Message").build_entryable.class
116
+ end
57
117
  end
@@ -362,7 +362,7 @@ class DirtyTest < ActiveRecord::TestCase
362
362
  old_updated_on = 1.hour.ago.beginning_of_day
363
363
 
364
364
  with_partial_writes Pirate, false do
365
- assert_queries(2) { 2.times { pirate.save! } }
365
+ assert_queries_count(6) { 2.times { pirate.save! } }
366
366
  Pirate.where(id: pirate.id).update_all(updated_on: old_updated_on)
367
367
  end
368
368
 
@@ -370,7 +370,7 @@ class DirtyTest < ActiveRecord::TestCase
370
370
  assert_no_queries { 2.times { pirate.save! } }
371
371
  assert_equal old_updated_on, pirate.reload.updated_on
372
372
 
373
- assert_queries(1) { pirate.catchphrase = "bar"; pirate.save! }
373
+ assert_queries_count(3) { pirate.catchphrase = "bar"; pirate.save! }
374
374
  assert_not_equal old_updated_on, pirate.reload.updated_on
375
375
  end
376
376
  end
@@ -379,7 +379,7 @@ class DirtyTest < ActiveRecord::TestCase
379
379
  person = Person.new(first_name: "foo")
380
380
 
381
381
  with_partial_writes Person, false do
382
- assert_queries(2) { 2.times { person.save! } }
382
+ assert_queries_count(6) { 2.times { person.save! } }
383
383
  Person.where(id: person.id).update_all(first_name: "baz")
384
384
  end
385
385
 
@@ -389,7 +389,7 @@ class DirtyTest < ActiveRecord::TestCase
389
389
  assert_no_queries { 2.times { person.save! } }
390
390
  assert_equal old_lock_version, person.reload.lock_version
391
391
 
392
- assert_queries(1) { person.first_name = "bar"; person.save! }
392
+ assert_queries_count(3) { person.first_name = "bar"; person.save! }
393
393
  assert_not_equal old_lock_version, person.reload.lock_version
394
394
  end
395
395
  end
@@ -460,44 +460,44 @@ class DirtyTest < ActiveRecord::TestCase
460
460
 
461
461
  def test_save_should_store_serialized_attributes_even_with_partial_writes
462
462
  with_partial_writes(Topic) do
463
- topic = Topic.create!(content: { a: "a" })
463
+ topic = Topic.create!(content: { "a" => "a" })
464
464
 
465
465
  assert_not_predicate topic, :changed?
466
466
 
467
- topic.content[:b] = "b"
467
+ topic.content["b"] = "b"
468
468
 
469
469
  assert_predicate topic, :changed?
470
470
 
471
471
  topic.save!
472
472
 
473
473
  assert_not_predicate topic, :changed?
474
- assert_equal "b", topic.content[:b]
474
+ assert_equal "b", topic.content["b"]
475
475
 
476
476
  topic.reload
477
477
 
478
- assert_equal "b", topic.content[:b]
478
+ assert_equal "b", topic.content["b"]
479
479
  end
480
480
  end
481
481
 
482
482
  def test_save_always_should_update_timestamps_when_serialized_attributes_are_present
483
483
  with_partial_writes(Topic) do
484
- topic = Topic.create!(content: { a: "a" })
484
+ topic = Topic.create!(content: { "a" => "a" })
485
485
  topic.save!
486
486
 
487
487
  updated_at = topic.updated_at
488
488
  travel(1.second) do
489
- topic.content[:hello] = "world"
489
+ topic.content["hello"] = "world"
490
490
  topic.save!
491
491
  end
492
492
 
493
493
  assert_not_equal updated_at, topic.updated_at
494
- assert_equal "world", topic.content[:hello]
494
+ assert_equal "world", topic.content["hello"]
495
495
  end
496
496
  end
497
497
 
498
498
  def test_save_should_not_save_serialized_attribute_with_partial_writes_if_not_present
499
499
  with_partial_writes(Topic) do
500
- topic = Topic.create!(author_name: "Bill", content: { a: "a" })
500
+ topic = Topic.create!(author_name: "Bill", content: { "a" => "a" })
501
501
  topic = Topic.select("id, author_name").find(topic.id)
502
502
  topic.update_columns author_name: "John"
503
503
  assert_not_nil topic.reload.content
@@ -505,11 +505,11 @@ class DirtyTest < ActiveRecord::TestCase
505
505
  end
506
506
 
507
507
  def test_changes_to_save_should_not_mutate_array_of_hashes
508
- topic = Topic.new(author_name: "Bill", content: [{ a: "a" }])
508
+ topic = Topic.new(author_name: "Bill", content: [{ "a" => "a" }])
509
509
 
510
510
  topic.changes_to_save
511
511
 
512
- assert_equal [{ a: "a" }], topic.content
512
+ assert_equal [{ "a" => "a" }], topic.content
513
513
  end
514
514
 
515
515
  def test_previous_changes
@@ -608,19 +608,18 @@ class DirtyTest < ActiveRecord::TestCase
608
608
 
609
609
  class Testings < ActiveRecord::Base; end
610
610
  def test_field_named_field
611
- ActiveRecord::Base.connection.create_table :testings do |t|
611
+ ActiveRecord::Base.lease_connection.create_table :testings do |t|
612
612
  t.string :field
613
613
  end
614
614
  assert_nothing_raised do
615
615
  Testings.new.attributes
616
616
  end
617
617
  ensure
618
- ActiveRecord::Base.connection.drop_table :testings rescue nil
618
+ ActiveRecord::Base.lease_connection.drop_table :testings rescue nil
619
619
  ActiveRecord::Base.clear_cache!
620
620
  end
621
621
 
622
622
  def test_datetime_attribute_can_be_updated_with_fractional_seconds
623
- skip "Fractional seconds are not supported" unless supports_datetime_with_precision?
624
623
  in_time_zone "Paris" do
625
624
  target = Class.new(ActiveRecord::Base)
626
625
  target.table_name = "topics"
@@ -630,7 +629,7 @@ class DirtyTest < ActiveRecord::TestCase
630
629
  topic = target.create(written_on: written_on)
631
630
  topic.written_on += 0.3
632
631
 
633
- assert topic.written_on_changed?, "Fractional second update not detected"
632
+ assert_predicate topic, :written_on_changed?, "Fractional second update not detected"
634
633
  end
635
634
  end
636
635
 
@@ -645,12 +644,12 @@ class DirtyTest < ActiveRecord::TestCase
645
644
  test "partial insert" do
646
645
  with_partial_writes Person do
647
646
  jon = nil
648
- assert_sql(/first_name/i) do
649
- jon = Person.create! first_name: "Jon"
647
+ assert_no_queries_match(/followers_count/) do
648
+ assert_queries_match(/first_name/) do
649
+ jon = Person.create! first_name: "Jon"
650
+ end
650
651
  end
651
652
 
652
- assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql.include?("followers_count") }
653
-
654
653
  jon.reload
655
654
  assert_equal "Jon", jon.first_name
656
655
  assert_equal 0, jon.followers_count
@@ -941,13 +940,71 @@ class DirtyTest < ActiveRecord::TestCase
941
940
  assert_not_predicate person, :changed?
942
941
  end
943
942
 
943
+ test "partial insert off with unchanged default function attribute" do
944
+ skip "IBM_DB/DB2: column DEFAULT expressions do not support timezone arithmetic; " \
945
+ "CURRENT_TIMESTAMP DEFAULT stores local time and cannot be adjusted to UTC." if current_adapter?(:IBM_DBAdapter)
946
+ with_partial_writes Aircraft, false do
947
+ aircraft = Aircraft.new(name: "Boeing")
948
+ assert_equal "Boeing", aircraft.name
949
+
950
+ aircraft.save!
951
+ aircraft.reload
952
+
953
+ assert_equal "Boeing", aircraft.name
954
+ assert_in_delta Time.now, aircraft.manufactured_at, 1.1
955
+ end
956
+ end
957
+
958
+ test "partial insert off with changed default function attribute" do
959
+ with_partial_writes Aircraft, false do
960
+ manufactured_at = 1.years.ago
961
+ aircraft = Aircraft.new(name: "Boeing2", manufactured_at: manufactured_at)
962
+
963
+ assert_equal "Boeing2", aircraft.name
964
+ assert_equal manufactured_at.to_i, aircraft.manufactured_at.to_i
965
+
966
+ aircraft.save!
967
+ aircraft.reload
968
+
969
+ assert_equal "Boeing2", aircraft.name
970
+ assert_equal manufactured_at.utc.strftime("%Y-%m-%d %H:%M:%S"), aircraft.manufactured_at.strftime("%Y-%m-%d %H:%M:%S")
971
+ end
972
+ end
973
+
974
+ if current_adapter?(:PostgreSQLAdapter) && supports_identity_columns?
975
+ test "partial insert off with changed composite identity primary key attribute" do
976
+ klass = Class.new(ActiveRecord::Base) do
977
+ self.table_name = "cpk_postgresql_identity_table"
978
+ end
979
+
980
+ with_partial_writes(klass, false) do
981
+ record = klass.create!(another_id: 10)
982
+ assert_equal 10, record.another_id
983
+ assert_not_nil record.id
984
+ end
985
+ end
986
+ end
987
+
988
+ test "attribute_changed? properly type casts enum values" do
989
+ parrot = LiveParrot.create!(name: "Scipio", breed: :african)
990
+
991
+ parrot.breed = :australian
992
+
993
+ assert parrot.breed_changed?(from: "african", to: "australian")
994
+ assert parrot.breed_changed?(from: :african, to: :australian)
995
+ assert parrot.breed_changed?(from: 0, to: 1)
996
+ end
997
+
944
998
  private
945
999
  def with_partial_writes(klass, on = true)
946
- old = klass.partial_writes?
947
- klass.partial_writes = on
1000
+ old_inserts = klass.partial_inserts?
1001
+ old_updates = klass.partial_updates?
1002
+ klass.partial_inserts = on
1003
+ klass.partial_updates = on
948
1004
  yield
949
1005
  ensure
950
- klass.partial_writes = old
1006
+ klass.partial_inserts = old_inserts
1007
+ klass.partial_updates = old_updates
951
1008
  end
952
1009
 
953
1010
  def check_pirate_after_save_failure(pirate)
@@ -6,25 +6,26 @@ class TestRecord < ActiveRecord::Base
6
6
  end
7
7
 
8
8
  class TestDisconnectedAdapter < ActiveRecord::TestCase
9
- self.use_transactional_tests = false
10
-
11
9
  def setup
12
- @connection = ActiveRecord::Base.connection
10
+ @connection = ActiveRecord::Base.lease_connection
13
11
  end
14
12
 
15
13
  teardown do
16
14
  return if in_memory_db?
17
- db_config = ActiveRecord::Base.connection_db_config
18
- ActiveRecord::Base.establish_connection(db_config)
19
15
  end
20
16
 
21
17
  unless in_memory_db?
22
- test "can't execute statements while disconnected" do
18
+ test "reconnects to execute statements when disconnected" do
23
19
  @connection.execute "SELECT count(*) from products"
20
+ first_connection = @connection.instance_variable_get(:@raw_connection).__id__
21
+
24
22
  @connection.disconnect!
25
- assert_raises(ActiveRecord::ConnectionNotEstablished) do
26
- @connection.execute "SELECT count(*) from products"
27
- end
23
+ assert_nil @connection.instance_variable_get(:@raw_connection)
24
+
25
+ @connection.execute "SELECT count(*) from products"
26
+ second_connection = @connection.instance_variable_get(:@raw_connection).__id__
27
+
28
+ assert_not_equal second_connection, first_connection
28
29
  end
29
30
  end
30
31
  end