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
@@ -12,19 +12,11 @@ module ActiveRecord
12
12
  end
13
13
 
14
14
  def test_url_invalid_adapter
15
- error = assert_raises(LoadError) do
16
- Base.connection_handler.establish_connection "ridiculous://foo?encoding=utf8"
17
- end
18
-
19
- assert_match "Could not load the 'ridiculous' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", error.message
20
- end
21
-
22
- def test_error_if_no_adapter_method
23
15
  error = assert_raises(AdapterNotFound) do
24
- Base.connection_handler.establish_connection "abstract://foo?encoding=utf8"
16
+ Base.connection_handler.establish_connection "ridiculous://foo?encoding=utf8"
25
17
  end
26
18
 
27
- assert_match "database configuration specifies nonexistent abstract adapter", error.message
19
+ assert_match "Database configuration specifies nonexistent 'ridiculous' adapter. Available adapters are: abstract, fake, ibm_db, mysql2, postgresql, sqlite3, trilogy. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile if it's not in the list of available adapters.", error.message
28
20
  end
29
21
 
30
22
  # The abstract adapter is used simply to bypass the bit of code that
@@ -62,6 +54,18 @@ module ActiveRecord
62
54
  }, pool_config.configuration_hash)
63
55
  end
64
56
 
57
+ def test_url_sub_key_merges_correctly_when_query_param
58
+ hash = { "url" => "abstract:///?user=user&password=passwd&dbname=app" }
59
+ pool_config = resolve_db_config :production, "production" => hash
60
+
61
+ assert_equal({
62
+ adapter: "abstract",
63
+ user: "user",
64
+ password: "passwd",
65
+ dbname: "app"
66
+ }, pool_config.configuration_hash)
67
+ end
68
+
65
69
  def test_url_host_no_db
66
70
  pool_config = resolve_db_config "abstract://foo?encoding=utf8"
67
71
  assert_equal({
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ module ActiveRecord
6
+ class DatabaseConfigurations
7
+ class UrlConfigTest < ActiveRecord::TestCase
8
+ def test_schema_dump_parsing
9
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?schema_dump=false", {})
10
+ assert_nil config.schema_dump
11
+
12
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?schema_dump=db/foo_schema.rb", {})
13
+ assert_equal "db/foo_schema.rb", config.schema_dump
14
+
15
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {})
16
+ assert_equal "schema.rb", config.schema_dump
17
+ end
18
+
19
+ def test_query_cache_parsing
20
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?query_cache=false", {})
21
+ assert_equal false, config.query_cache
22
+
23
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?query_cache=42", {})
24
+ assert_equal "42", config.query_cache
25
+ end
26
+
27
+ def test_replica_parsing
28
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {})
29
+ assert_nil config.replica?
30
+
31
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=true", {})
32
+ assert_equal true, config.replica?
33
+
34
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=false", {})
35
+ assert_equal false, config.replica?
36
+
37
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=random", {})
38
+ assert_equal true, config.replica?
39
+ end
40
+
41
+ def test_database_tasks_parsing
42
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {})
43
+ assert_equal true, config.database_tasks?
44
+
45
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?database_tasks=random", {})
46
+ assert_equal true, config.database_tasks?
47
+
48
+ config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?database_tasks=false", {})
49
+ assert_equal false, config.database_tasks?
50
+ end
51
+ end
52
+ end
53
+ end
@@ -14,7 +14,6 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
14
14
  assert_predicate ActiveRecord::Base.configurations, :blank?
15
15
  ensure
16
16
  ActiveRecord::Base.configurations = old_config
17
- ActiveRecord::Base.establish_connection :arunit
18
17
  end
19
18
  end
20
19
 
@@ -36,34 +35,37 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
36
35
  ENV["RAILS_ENV"] = previous_env
37
36
  end
38
37
 
39
- def test_configs_for_getter_with_env_and_name
40
- config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
38
+ def test_configs_for_with_name_symbol
39
+ previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "arunit2"
41
40
 
42
- assert_equal "arunit", config.env_name
41
+ config = ActiveRecord::Base.configurations.configs_for(name: :primary)
42
+
43
+ assert_equal "arunit2", config.env_name
43
44
  assert_equal "primary", config.name
45
+ ensure
46
+ ENV["RAILS_ENV"] = previous_env
44
47
  end
45
48
 
46
- def test_default_hash_returns_config_hash_from_default_env
47
- original_rails_env = ENV["RAILS_ENV"]
48
- ENV["RAILS_ENV"] = "arunit"
49
+ def test_configs_for_getter_with_env_and_name
50
+ config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
49
51
 
50
- assert_deprecated do
51
- assert_equal ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").configuration_hash, ActiveRecord::Base.configurations.default_hash
52
- end
53
- ensure
54
- ENV["RAILS_ENV"] = original_rails_env
52
+ assert_equal "arunit", config.env_name
53
+ assert_equal "primary", config.name
55
54
  end
56
55
 
57
56
  def test_find_db_config_returns_first_config_for_env
58
57
  config = ActiveRecord::DatabaseConfigurations.new({
59
58
  "test" => {
60
59
  "config_1" => {
60
+ "adapter" => "abstract",
61
61
  "database" => "db"
62
62
  },
63
63
  "config_2" => {
64
+ "adapter" => "abstract",
64
65
  "database" => "db"
65
66
  },
66
67
  "config_3" => {
68
+ "adapter" => "abstract",
67
69
  "database" => "db"
68
70
  },
69
71
  }
@@ -82,7 +84,7 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
82
84
  def test_find_db_config_prioritize_db_config_object_for_the_current_env
83
85
  config = ActiveRecord::DatabaseConfigurations.new({
84
86
  "primary" => {
85
- "adapter" => "randomadapter"
87
+ "adapter" => "abstract",
86
88
  },
87
89
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call => {
88
90
  "primary" => {
@@ -97,49 +99,90 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
97
99
  assert_equal ":memory:", config.database
98
100
  end
99
101
 
100
- def test_to_h_turns_db_config_object_back_into_a_hash_and_is_deprecated
101
- configs = ActiveRecord::Base.configurations
102
- assert_equal "ActiveRecord::DatabaseConfigurations", configs.class.name
103
- assert_deprecated do
104
- assert_equal "Hash", configs.to_h.class.name
105
- assert_equal ["arunit", "arunit2", "arunit_without_prepared_statements"], ActiveRecord::Base.configurations.to_h.keys.sort
102
+ class CustomHashConfig < ActiveRecord::DatabaseConfigurations::HashConfig
103
+ def sharded?
104
+ custom_config.fetch("sharded", false)
106
105
  end
106
+
107
+ private
108
+ def custom_config
109
+ configuration_hash.fetch(:custom_config)
110
+ end
107
111
  end
108
- end
109
112
 
110
- class LegacyDatabaseConfigurationsTest < ActiveRecord::TestCase
111
- def test_can_turn_configurations_into_a_hash_and_is_deprecated
112
- assert_deprecated do
113
- assert ActiveRecord::Base.configurations.to_h.is_a?(Hash), "expected to be a hash but was not."
114
- assert_equal ["arunit", "arunit2", "arunit_without_prepared_statements"].sort, ActiveRecord::Base.configurations.to_h.keys.sort
113
+ def test_registering_a_custom_config_object
114
+ previous_handlers = ActiveRecord::DatabaseConfigurations.db_config_handlers
115
+
116
+ ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, _, config|
117
+ next unless config.key?(:custom_config)
118
+ CustomHashConfig.new(env_name, name, config)
115
119
  end
116
- end
117
120
 
118
- def test_deprecated_config_method
119
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
121
+ configs = ActiveRecord::DatabaseConfigurations.new({
122
+ "test" => {
123
+ "config_1" => {
124
+ "adapter" => "abstract",
125
+ "database" => "db",
126
+ "custom_config" => {
127
+ "sharded" => 1
128
+ }
129
+ },
130
+ "config_2" => {
131
+ "adapter" => "abstract",
132
+ "database" => "db"
133
+ }
134
+ }
135
+ }).configurations
136
+
137
+ custom_config = configs.first
138
+ hash_config = configs.last
120
139
 
121
- assert_equal db_config.configuration_hash.stringify_keys, assert_deprecated { db_config.config }
122
- end
140
+ assert custom_config.is_a?(CustomHashConfig)
141
+ assert hash_config.is_a?(ActiveRecord::DatabaseConfigurations::HashConfig)
123
142
 
124
- def test_unsupported_method_raises
125
- assert_raises NoMethodError do
126
- ActiveRecord::Base.configurations.fetch(:foo)
127
- end
143
+ assert_predicate custom_config, :sharded?
144
+ ensure
145
+ ActiveRecord::DatabaseConfigurations.db_config_handlers = previous_handlers
128
146
  end
129
147
 
130
- def test_spec_name_in_configs_for_is_deprecated
131
- assert_deprecated do
132
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", spec_name: "primary")
148
+ def test_configs_for_with_custom_key
149
+ previous_handlers = ActiveRecord::DatabaseConfigurations.db_config_handlers
133
150
 
134
- assert_equal "primary", db_config.name
151
+ ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, _, config|
152
+ next unless config.key?(:custom_config)
153
+ CustomHashConfig.new(env_name, name, config)
135
154
  end
155
+
156
+ config = {
157
+ "default_env" => {
158
+ "primary" => { "adapter" => "sqlite3", "database" => "test/db/primary.sqlite3", "custom_config" => { "sharded" => 1 } },
159
+ "replica" => { "adapter" => "sqlite3", "database" => "test/db/hidden.sqlite3", "replica" => true, "custom_config" => { "sharded" => 1 } },
160
+ "secondary" => { "adapter" => "sqlite3", "database" => "test/db/secondary.sqlite3" }
161
+ }
162
+ }
163
+ prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
164
+
165
+ assert_equal 1, ActiveRecord::Base.configurations.configs_for(env_name: "default_env", config_key: :custom_config).count
166
+ assert_equal 2, ActiveRecord::Base.configurations.configs_for(env_name: "default_env", config_key: :custom_config, include_hidden: true).count
167
+ assert_equal 2, ActiveRecord::Base.configurations.configs_for(env_name: "default_env").count
168
+ ensure
169
+ ActiveRecord::DatabaseConfigurations.db_config_handlers = previous_handlers
170
+ ActiveRecord::Base.configurations = prev_configs
136
171
  end
137
172
 
138
- def test_spec_name_getter_is_deprecated
139
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
173
+ def test_configs_for_with_include_hidden
174
+ config = {
175
+ "default_env" => {
176
+ "readonly" => { "adapter" => "sqlite3", "database" => "test/db/readonly.sqlite3", "replica" => true },
177
+ "hidden" => { "adapter" => "sqlite3", "database" => "test/db/hidden.sqlite3", "database_tasks" => false },
178
+ "default" => { "adapter" => "sqlite3", "database" => "test/db/primary.sqlite3" }
179
+ }
180
+ }
181
+ prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
140
182
 
141
- assert_deprecated do
142
- assert_equal "primary", db_config.spec_name
143
- end
183
+ assert_equal 1, ActiveRecord::Base.configurations.configs_for(env_name: "default_env").count
184
+ assert_equal 3, ActiveRecord::Base.configurations.configs_for(env_name: "default_env", include_hidden: true).count
185
+ ensure
186
+ ActiveRecord::Base.configurations = prev_configs
144
187
  end
145
188
  end
@@ -62,15 +62,15 @@ module ActiveRecord
62
62
  called = true
63
63
 
64
64
  assert ActiveRecord::Base.connected_to?(role: :reading)
65
- assert_predicate ActiveRecord::Base.connection, :preventing_writes?
65
+ assert_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
66
66
 
67
67
  ActiveRecord::Base.connected_to(role: :writing, prevent_writes: false) do
68
68
  assert ActiveRecord::Base.connected_to?(role: :writing)
69
- assert_not_predicate ActiveRecord::Base.connection, :preventing_writes?
69
+ assert_not_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
70
70
  end
71
71
 
72
72
  assert ActiveRecord::Base.connected_to?(role: :reading)
73
- assert_predicate ActiveRecord::Base.connection, :preventing_writes?
73
+ assert_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
74
74
  end
75
75
  assert called
76
76
  end
@@ -202,12 +202,12 @@ module ActiveRecord
202
202
  write = false
203
203
  resolver.read do
204
204
  assert ActiveRecord::Base.connected_to?(role: :writing)
205
- assert_predicate ActiveRecord::Base.connection, :preventing_writes?
205
+ assert_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
206
206
  read = true
207
207
 
208
208
  resolver.write do
209
209
  assert ActiveRecord::Base.connected_to?(role: :writing)
210
- assert_not_predicate ActiveRecord::Base.connection, :preventing_writes?
210
+ assert_not_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
211
211
  write = true
212
212
  end
213
213
  end
@@ -227,7 +227,7 @@ module ActiveRecord
227
227
  resolver.read do
228
228
  inside_preventing.wait
229
229
  assert ActiveRecord::Base.connected_to?(role: :writing)
230
- assert_predicate ActiveRecord::Base.connection, :preventing_writes?
230
+ assert_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
231
231
  finished_checking.set
232
232
  end
233
233
  end
@@ -235,7 +235,7 @@ module ActiveRecord
235
235
  t2 = Thread.new do
236
236
  resolver.write do
237
237
  assert ActiveRecord::Base.connected_to?(role: :writing)
238
- assert_not_predicate ActiveRecord::Base.connection, :preventing_writes?
238
+ assert_not_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
239
239
  inside_preventing.set
240
240
  finished_checking.wait
241
241
  end
@@ -244,7 +244,7 @@ module ActiveRecord
244
244
  t3 = Thread.new do
245
245
  resolver.read do
246
246
  assert ActiveRecord::Base.connected_to?(role: :writing)
247
- assert_predicate ActiveRecord::Base.connection, :preventing_writes?
247
+ assert_predicate ActiveRecord::Base.lease_connection, :preventing_writes?
248
248
  end
249
249
  end
250
250
 
@@ -282,6 +282,8 @@ module ActiveRecord
282
282
  assert ActiveRecord::Base.connected_to?(role: :writing)
283
283
  [200, {}, ["body"]]
284
284
  })
285
+ cache = ActiveSupport::Cache::MemoryStore.new
286
+ middleware = ActionDispatch::Session::CacheStore.new(middleware, cache: cache, key: "_session_id")
285
287
  assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "POST")
286
288
  end
287
289
 
@@ -290,7 +292,27 @@ module ActiveRecord
290
292
  assert ActiveRecord::Base.connected_to?(role: :reading)
291
293
  [200, {}, ["body"]]
292
294
  })
295
+ cache = ActiveSupport::Cache::MemoryStore.new
296
+ middleware = ActionDispatch::Session::CacheStore.new(middleware, cache: cache, key: "_session_id")
297
+
293
298
  assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
294
299
  end
300
+
301
+ class ReadonlyResolver < ActiveRecord::Middleware::DatabaseSelector::Resolver
302
+ def reading_request?(request)
303
+ true
304
+ end
305
+ end
306
+
307
+ def test_the_middleware_chooses_reading_role_with_POST_request_if_resolver_tells_it_to
308
+ middleware = ActiveRecord::Middleware::DatabaseSelector.new(lambda { |env|
309
+ assert ActiveRecord::Base.connected_to?(role: :reading)
310
+ [200, {}, ["body"]]
311
+ }, ReadonlyResolver)
312
+
313
+ cache = ActiveSupport::Cache::MemoryStore.new
314
+ middleware = ActionDispatch::Session::CacheStore.new(middleware, cache: cache, key: "_session_id")
315
+ assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "POST")
316
+ end
295
317
  end
296
318
  end
@@ -4,14 +4,12 @@ require "cases/helper"
4
4
 
5
5
  class DatabaseStatementsTest < ActiveRecord::TestCase
6
6
  def setup
7
- @connection = ActiveRecord::Base.connection
7
+ @connection = ActiveRecord::Base.lease_connection
8
8
  end
9
9
 
10
- unless current_adapter?(:OracleAdapter)
11
- def test_exec_insert
12
- result = @connection.exec_insert("INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)", nil, [])
13
- assert_not_nil @connection.send(:last_inserted_id, result)
14
- end
10
+ def test_exec_insert
11
+ result = @connection.exec_insert("INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)", nil, [])
12
+ assert_not_nil @connection.send(:last_inserted_id, result)
15
13
  end
16
14
 
17
15
  def test_insert_should_return_the_inserted_id
@@ -22,15 +20,13 @@ class DatabaseStatementsTest < ActiveRecord::TestCase
22
20
  assert_not_nil return_the_inserted_id(method: :create)
23
21
  end
24
22
 
23
+ def test_extract_table_ref_from_insert_sql_with_hyphen_in_table_name
24
+ sql = "INSERT INTO \"table-with-hyphen\" (column1, column2) VALUES (value1, value2)"
25
+ assert_equal "table-with-hyphen", @connection.send(:extract_table_ref_from_insert_sql, sql)
26
+ end
27
+
25
28
  private
26
29
  def return_the_inserted_id(method:)
27
- # Oracle adapter uses prefetched primary key values from sequence and passes them to connection adapter insert method
28
- if current_adapter?(:OracleAdapter)
29
- sequence_name = "accounts_seq"
30
- id_value = @connection.next_sequence_value(sequence_name)
31
- @connection.send(method, "INSERT INTO accounts (id, firm_id,credit_limit) VALUES (accounts_seq.nextval,42,5000)", nil, :id, id_value, sequence_name)
32
- else
33
- @connection.send(method, "INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)")
34
- end
30
+ @connection.send(method, "INSERT INTO accounts (firm_id,credit_limit) VALUES (42,5000)")
35
31
  end
36
32
  end
@@ -3,15 +3,16 @@
3
3
  require "cases/helper"
4
4
  require "support/schema_dumping_helper"
5
5
 
6
- if supports_datetime_with_precision?
7
- class DateTimePrecisionTest < ActiveRecord::TestCase
6
+ class DateTimePrecisionTest < ActiveRecord::TestCase
7
+ if supports_datetime_with_precision?
8
+ include InTimeZone
8
9
  include SchemaDumpingHelper
9
10
  self.use_transactional_tests = false
10
11
 
11
12
  class Foo < ActiveRecord::Base; end
12
13
 
13
14
  setup do
14
- @connection = ActiveRecord::Base.connection
15
+ @connection = ActiveRecord::Base.lease_connection
15
16
  Foo.reset_column_information
16
17
  end
17
18
 
@@ -45,11 +46,11 @@ if supports_datetime_with_precision?
45
46
  assert_equal 123456000, foo.updated_at.nsec
46
47
  end
47
48
 
48
- unless current_adapter?(:Mysql2Adapter, :IBM_DBAdapter)
49
+ unless current_adapter?(:Mysql2Adapter, :TrilogyAdapter, :IBM_DBAdapter)
49
50
  def test_no_datetime_precision_isnt_truncated_on_assignment
50
51
  @connection.create_table(:foos, force: true)
51
- @connection.add_column :foos, :created_at, :datetime
52
- @connection.add_column :foos, :updated_at, :datetime, precision: 6
52
+ @connection.add_column :foos, :created_at, :datetime, precision: nil
53
+ @connection.add_column :foos, :updated_at, :datetime
53
54
 
54
55
  time = ::Time.now.change(nsec: 123)
55
56
  foo = Foo.new(created_at: time, updated_at: time)
@@ -84,7 +85,7 @@ if supports_datetime_with_precision?
84
85
  def test_invalid_datetime_precision_raises_error
85
86
  assert_raises ArgumentError do
86
87
  @connection.create_table(:foos, force: true) do |t|
87
- t.timestamps precision: 13
88
+ t.timestamps precision: 7
88
89
  end
89
90
  end
90
91
  end
@@ -100,22 +101,151 @@ if supports_datetime_with_precision?
100
101
 
101
102
  assert foo = Foo.find_by(created_at: date)
102
103
  assert_equal 1, Foo.where(updated_at: date).count
104
+ assert_equal date.to_i, foo.created_at.to_i
103
105
  assert_equal date.to_s, foo.created_at.to_s
104
106
  assert_equal date.to_s, foo.updated_at.to_s
105
107
  assert_equal 000000, foo.created_at.usec
106
108
  assert_equal 999900, foo.updated_at.usec
107
109
  end
108
110
 
109
- def test_schema_dump_includes_datetime_precision
111
+ def test_formatting_datetime_according_to_precision_when_time_zone_aware
112
+ with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
113
+ @connection.create_table(:foos, force: true) do |t|
114
+ t.datetime :created_at, precision: 0
115
+ t.datetime :updated_at, precision: 4
116
+ end
117
+
118
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
119
+ Foo.create!(created_at: date, updated_at: date)
120
+
121
+ assert foo = Foo.find_by(created_at: date)
122
+ assert_equal 1, Foo.where(updated_at: date).count
123
+ assert_equal date.to_i, foo.created_at.to_i
124
+ assert_equal date.in_time_zone.to_s, foo.created_at.to_s
125
+ assert_equal date.in_time_zone.to_s, foo.updated_at.to_s
126
+ assert_equal 000000, foo.created_at.usec
127
+ assert_equal 999900, foo.updated_at.usec
128
+ end
129
+ end
130
+
131
+ if current_adapter?(:PostgreSQLAdapter)
132
+ def test_formatting_datetime_according_to_precision_using_timestamptz
133
+ with_postgresql_datetime_type(:timestamptz) do
134
+ @connection.create_table(:foos, force: true) do |t|
135
+ t.datetime :created_at, precision: 0
136
+ t.datetime :updated_at, precision: 4
137
+ end
138
+
139
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
140
+ Foo.create!(created_at: date, updated_at: date)
141
+
142
+ assert foo = Foo.find_by(created_at: date)
143
+ assert_equal 1, Foo.where(updated_at: date).count
144
+ assert_equal date.to_i, foo.created_at.to_i
145
+ assert_equal date.to_s, foo.created_at.to_s
146
+ assert_equal date.to_s, foo.updated_at.to_s
147
+ assert_equal 000000, foo.created_at.usec
148
+ assert_equal 999900, foo.updated_at.usec
149
+ end
150
+ end
151
+
152
+ def test_formatting_datetime_according_to_precision_when_time_zone_aware_using_timestamptz
153
+ with_postgresql_datetime_type(:timestamptz) do
154
+ with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
155
+ @connection.create_table(:foos, force: true) do |t|
156
+ t.datetime :created_at, precision: 0
157
+ t.datetime :updated_at, precision: 4
158
+ end
159
+
160
+ date = ::Time.utc(2014, 8, 17, 12, 30, 0, 999999)
161
+ Foo.create!(created_at: date, updated_at: date)
162
+
163
+ assert foo = Foo.find_by(created_at: date)
164
+ assert_equal 1, Foo.where(updated_at: date).count
165
+ assert_equal date.to_i, foo.created_at.to_i
166
+ assert_equal date.in_time_zone.to_s, foo.created_at.to_s
167
+ assert_equal date.in_time_zone.to_s, foo.updated_at.to_s
168
+ assert_equal 000000, foo.created_at.usec
169
+ assert_equal 999900, foo.updated_at.usec
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ def test_writing_a_blank_attribute
176
+ @connection.create_table(:foos, force: true) do |t|
177
+ t.datetime :happened_at
178
+ end
179
+
180
+ assert_nil Foo.create!(happened_at: nil).happened_at
181
+ assert_nil Foo.create!(happened_at: "").happened_at
182
+ end
183
+
184
+ def test_writing_a_date_attribute
185
+ @connection.create_table(:foos, force: true) do |t|
186
+ t.datetime :happened_at
187
+ end
188
+
189
+ date = ::Date.new(2001, 2, 3)
190
+ assert_equal date, Foo.create!(happened_at: date).happened_at
191
+ end
192
+
193
+ if current_adapter?(:PostgreSQLAdapter)
194
+ def test_writing_a_blank_attribute_timestamptz
195
+ with_postgresql_datetime_type(:timestamptz) do
196
+ @connection.create_table(:foos, force: true) do |t|
197
+ t.datetime :happened_at
198
+ end
199
+
200
+ assert_nil Foo.create!(happened_at: nil).happened_at
201
+ assert_nil Foo.create!(happened_at: "").happened_at
202
+ end
203
+ end
204
+
205
+ def test_writing_a_date_attribute_timestamptz
206
+ with_postgresql_datetime_type(:timestamptz) do
207
+ @connection.create_table(:foos, force: true) do |t|
208
+ t.datetime :happened_at
209
+ end
210
+
211
+ date = ::Date.new(2001, 2, 3)
212
+ assert_equal date, Foo.create!(happened_at: date).happened_at
213
+ end
214
+ end
215
+
216
+ def test_writing_a_time_with_zone_attribute_timestamptz
217
+ with_postgresql_datetime_type(:timestamptz) do
218
+ @connection.create_table(:foos, force: true) do |t|
219
+ t.datetime :happened_at
220
+ end
221
+
222
+ in_time_zone("Pacific Time (US & Canada)") do
223
+ time = Time.zone.now
224
+ assert_equal time.zone, Foo.new(happened_at: time).happened_at.zone
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ def test_schema_dump_with_default_precision_is_not_dumped
110
231
  @connection.create_table(:foos, force: true) do |t|
111
232
  t.timestamps precision: 6
112
233
  end
113
234
  output = dump_table_schema("foos")
114
- assert_match %r{t\.datetime\s+"created_at",\s+precision: 6,\s+null: false$}, output
115
- assert_match %r{t\.datetime\s+"updated_at",\s+precision: 6,\s+null: false$}, output
235
+ assert_match %r{t\.datetime\s+"created_at",\s+null: false$}, output
236
+ assert_match %r{t\.datetime\s+"updated_at",\s+null: false$}, output
237
+ end
238
+
239
+ def test_schema_dump_with_without_precision_has_precision_as_nil
240
+ @connection.create_table(:foos, force: true) do |t|
241
+ t.timestamps precision: nil
242
+ end
243
+ output = dump_table_schema("foos")
244
+ assert_match %r{t\.datetime\s+"created_at",\s+precision: nil,\s+null: false$}, output
245
+ assert_match %r{t\.datetime\s+"updated_at",\s+precision: nil,\s+null: false$}, output
116
246
  end
117
247
 
118
- if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter)
248
+ if current_adapter?(:PostgreSQLAdapter)
119
249
  def test_datetime_precision_with_zero_should_be_dumped
120
250
  @connection.create_table(:foos, force: true) do |t|
121
251
  t.timestamps precision: 0
@@ -7,6 +7,25 @@ require "models/task"
7
7
  class DateTimeTest < ActiveRecord::TestCase
8
8
  include InTimeZone
9
9
 
10
+ def test_default_timezone_validation
11
+ assert_raises ArgumentError do
12
+ ActiveRecord.default_timezone = "UTC"
13
+ end
14
+
15
+ # These values should not raise errors
16
+ ActiveRecord.default_timezone = :local
17
+ ActiveRecord.default_timezone = :utc
18
+ end
19
+
20
+ def test_high_precision_current_timestamp
21
+ current_timestamp = Task.with_connection { |conn| conn.high_precision_current_timestamp }
22
+
23
+ task = Task.create!
24
+ task = Task.select(current_timestamp => :starting).find(task.id)
25
+
26
+ assert_in_delta Time.now, task.starting, 1
27
+ end
28
+
10
29
  def test_saves_both_date_and_time
11
30
  with_env_tz "America/New_York" do
12
31
  with_timezone_config default: :utc do
@@ -62,7 +81,6 @@ class DateTimeTest < ActiveRecord::TestCase
62
81
  end
63
82
 
64
83
  def test_date_time_with_string_value_with_subsecond_precision
65
- skip unless supports_datetime_with_precision?
66
84
  string_value = "2017-07-04 14:19:00.5"
67
85
  topic = Topic.create(written_on: string_value)
68
86
  assert_equal topic, Topic.find_by(written_on: string_value)