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
@@ -2,20 +2,27 @@
2
2
 
3
3
  require "cases/helper"
4
4
  require "support/connection_helper"
5
+ require "support/schema_dumping_helper"
5
6
 
6
7
  class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
7
8
  include ConnectionHelper
9
+ include SchemaDumpingHelper
8
10
 
9
11
  class PostgresqlEnum < ActiveRecord::Base
10
12
  self.table_name = "postgresql_enums"
13
+
14
+ enum :current_mood, {
15
+ sad: "sad",
16
+ okay: "ok", # different spelling
17
+ happy: "happy",
18
+ aliased_field: "happy"
19
+ }, prefix: true
11
20
  end
12
21
 
13
22
  def setup
14
- @connection = ActiveRecord::Base.connection
23
+ @connection = ActiveRecord::Base.lease_connection
15
24
  @connection.transaction do
16
- @connection.execute <<~SQL
17
- CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
18
- SQL
25
+ @connection.create_enum("mood", ["sad", "ok", "happy"])
19
26
  @connection.create_table("postgresql_enums") do |t|
20
27
  t.column :current_mood, :mood
21
28
  end
@@ -23,8 +30,9 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
23
30
  end
24
31
 
25
32
  teardown do
33
+ reset_connection
26
34
  @connection.drop_table "postgresql_enums", if_exists: true
27
- @connection.execute "DROP TYPE IF EXISTS mood"
35
+ @connection.drop_enum "mood", if_exists: true
28
36
  reset_connection
29
37
  end
30
38
 
@@ -62,10 +70,9 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
62
70
  def test_invalid_enum_update
63
71
  @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
64
72
  enum = PostgresqlEnum.first
65
- enum.current_mood = "angry"
66
73
 
67
- assert_raise ActiveRecord::StatementInvalid do
68
- enum.save
74
+ assert_raise ArgumentError do
75
+ enum.current_mood = "angry"
69
76
  end
70
77
  end
71
78
 
@@ -90,4 +97,197 @@ class PostgresqlEnumTest < ActiveRecord::PostgreSQLTestCase
90
97
  assert model.save
91
98
  assert_nil model.reload.current_mood
92
99
  end
100
+
101
+ def test_schema_dump
102
+ @connection.add_column "postgresql_enums", "good_mood", :mood, default: "happy", null: false
103
+
104
+ output = dump_table_schema("postgresql_enums")
105
+
106
+ assert_includes output, "# Note that some types may not work with other database engines. Be careful if changing database."
107
+
108
+ assert_includes output, 'create_enum "mood", ["sad", "ok", "happy"]'
109
+
110
+ assert_includes output, 't.enum "current_mood", enum_type: "mood"'
111
+ assert_includes output, 't.enum "good_mood", default: "happy", null: false, enum_type: "mood"'
112
+ end
113
+
114
+ def test_schema_dump_renamed_enum
115
+ @connection.rename_enum :mood, :feeling
116
+
117
+ output = dump_table_schema("postgresql_enums")
118
+
119
+ assert_includes output, 'create_enum "feeling", ["sad", "ok", "happy"]'
120
+
121
+ assert_includes output, 't.enum "current_mood", enum_type: "feeling"'
122
+ end
123
+
124
+ def test_schema_dump_renamed_enum_with_to_option
125
+ @connection.rename_enum :mood, to: :feeling
126
+
127
+ output = dump_table_schema("postgresql_enums")
128
+
129
+ assert_includes output, 'create_enum "feeling", ["sad", "ok", "happy"]'
130
+
131
+ assert_includes output, 't.enum "current_mood", enum_type: "feeling"'
132
+ end
133
+
134
+ def test_schema_dump_added_enum_value
135
+ skip("Adding enum values can not be run in a transaction") if @connection.database_version < 10_00_00
136
+
137
+ @connection.add_enum_value :mood, :angry, before: :ok
138
+ @connection.add_enum_value :mood, :nervous, after: :ok
139
+ @connection.add_enum_value :mood, :glad
140
+
141
+ assert_nothing_raised do
142
+ @connection.add_enum_value :mood, :glad, if_not_exists: true
143
+ @connection.add_enum_value :mood, :curious, if_not_exists: true
144
+ end
145
+
146
+ output = dump_table_schema("postgresql_enums")
147
+
148
+ assert_includes output, 'create_enum "mood", ["sad", "angry", "ok", "nervous", "happy", "glad", "curious"]'
149
+ end
150
+
151
+ def test_schema_dump_renamed_enum_value
152
+ skip("Renaming enum values is only supported in PostgreSQL 10 or later") if @connection.database_version < 10_00_00
153
+
154
+ @connection.rename_enum_value :mood, from: :ok, to: :okay
155
+
156
+ output = dump_table_schema("postgresql_enums")
157
+
158
+ assert_includes output, 'create_enum "mood", ["sad", "okay", "happy"]'
159
+ end
160
+
161
+ def test_schema_load
162
+ original, $stdout = $stdout, StringIO.new
163
+
164
+ ActiveRecord::Schema.define do
165
+ create_enum :color, ["blue", "green"]
166
+
167
+ change_table :postgresql_enums do |t|
168
+ t.enum :best_color, enum_type: "color", default: "blue", null: false
169
+ end
170
+ end
171
+
172
+ assert @connection.column_exists?(:postgresql_enums, :best_color, sql_type: "color", default: "blue", null: false)
173
+ ensure
174
+ $stdout = original
175
+ end
176
+
177
+ def test_drop_enum
178
+ @connection.create_enum :unused, []
179
+
180
+ assert_nothing_raised do
181
+ @connection.drop_enum "unused"
182
+ end
183
+
184
+ assert_nothing_raised do
185
+ @connection.drop_enum "unused", if_exists: true
186
+ end
187
+
188
+ assert_raises ActiveRecord::StatementInvalid do
189
+ @connection.drop_enum "unused"
190
+ end
191
+ end
192
+
193
+ def test_works_with_activerecord_enum
194
+ model = PostgresqlEnum.create!
195
+ model.current_mood_okay!
196
+
197
+ model = PostgresqlEnum.find(model.id)
198
+ assert_equal "okay", model.current_mood
199
+
200
+ model.current_mood = "happy"
201
+ model.save!
202
+
203
+ model = PostgresqlEnum.find(model.id)
204
+ assert_predicate model, :current_mood_happy?
205
+ end
206
+
207
+ def test_enum_type_scoped_to_schemas
208
+ with_test_schema("test_schema") do
209
+ @connection.create_enum("mood_in_other_schema", ["sad", "ok", "happy"])
210
+
211
+ assert_nothing_raised do
212
+ @connection.create_table("postgresql_enums_in_other_schema") do |t|
213
+ t.column :current_mood, :mood_in_other_schema, default: "happy", null: false
214
+ end
215
+ end
216
+
217
+ assert @connection.table_exists?("postgresql_enums_in_other_schema")
218
+ end
219
+ end
220
+
221
+ def test_enum_type_explicit_schema
222
+ @connection.create_schema("test_schema")
223
+ @connection.create_enum("test_schema.mood_in_other_schema", ["sad", "ok", "happy"])
224
+
225
+ @connection.create_table("test_schema.postgresql_enums_in_other_schema") do |t|
226
+ t.column :current_mood, "test_schema.mood_in_other_schema"
227
+ end
228
+
229
+ assert @connection.table_exists?("test_schema.postgresql_enums_in_other_schema")
230
+
231
+ assert_nothing_raised do
232
+ @connection.drop_table("test_schema.postgresql_enums_in_other_schema")
233
+ @connection.drop_enum("test_schema.mood_in_other_schema")
234
+ end
235
+ ensure
236
+ @connection.drop_schema("test_schema", if_exists: true)
237
+ end
238
+
239
+ def test_schema_dump_scoped_to_schemas
240
+ @connection.create_schema("other_schema")
241
+ @connection.create_enum("other_schema.mood_in_other_schema", ["sad", "ok", "happy"])
242
+
243
+ with_test_schema("test_schema") do
244
+ @connection.create_enum("mood_in_test_schema", ["sad", "ok", "happy"])
245
+ @connection.create_table("postgresql_enums_in_test_schema") do |t|
246
+ t.column :current_mood, :mood_in_test_schema
247
+ end
248
+
249
+ output = dump_all_table_schema
250
+
251
+ assert_includes output, 'create_enum "public.mood", ["sad", "ok", "happy"]'
252
+ assert_includes output, 'create_enum "mood_in_test_schema", ["sad", "ok", "happy"]'
253
+ assert_includes output, 't.enum "current_mood", enum_type: "mood_in_test_schema"'
254
+ assert_not_includes output, 'create_enum "other_schema.mood_in_other_schema"'
255
+ end
256
+ ensure
257
+ @connection.drop_schema("other_schema")
258
+ end
259
+
260
+ def test_schema_load_scoped_to_schemas
261
+ silence_stream($stdout) do
262
+ with_test_schema("test_schema", drop: false) do
263
+ ActiveRecord::Schema.define do
264
+ create_enum "mood_in_test_schema", ["sad", "ok", "happy"]
265
+ create_enum "public.mood", ["sad", "ok", "happy"]
266
+
267
+ create_table "postgresql_enums_in_test_schema", force: :cascade do |t|
268
+ t.enum "current_mood", enum_type: "mood_in_test_schema"
269
+ end
270
+ end
271
+
272
+ assert @connection.column_exists?(:postgresql_enums_in_test_schema, :current_mood, sql_type: "mood_in_test_schema")
273
+ end
274
+
275
+ # This is outside `with_test_schema`, so we need to explicitly specify which schema we query
276
+ assert @connection.column_exists?("test_schema.postgresql_enums_in_test_schema", :current_mood, sql_type: "test_schema.mood_in_test_schema")
277
+ end
278
+ ensure
279
+ @connection.drop_schema("test_schema")
280
+ end
281
+
282
+ private
283
+ def with_test_schema(name, drop: true)
284
+ old_search_path = @connection.schema_search_path
285
+ @connection.create_schema(name)
286
+ @connection.schema_search_path = "#{name}, public"
287
+ yield
288
+ ensure
289
+ @connection.drop_schema(name) if drop
290
+ @connection.schema_search_path = old_search_path
291
+ @connection.schema_cache.clear!
292
+ end
93
293
  end
@@ -5,18 +5,37 @@ require "models/author"
5
5
  require "models/post"
6
6
 
7
7
  class PostgreSQLExplainTest < ActiveRecord::PostgreSQLTestCase
8
- fixtures :authors
8
+ fixtures :authors, :author_addresses
9
9
 
10
10
  def test_explain_for_one_query
11
- explain = Author.where(id: 1).explain
12
- assert_match %r(EXPLAIN for: SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
11
+ explain = Author.where(id: 1).explain.inspect
12
+ assert_match %r(EXPLAIN SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
13
13
  assert_match %(QUERY PLAN), explain
14
14
  end
15
15
 
16
16
  def test_explain_with_eager_loading
17
- explain = Author.where(id: 1).includes(:posts).explain
17
+ explain = Author.where(id: 1).includes(:posts).explain.inspect
18
18
  assert_match %(QUERY PLAN), explain
19
- assert_match %r(EXPLAIN for: SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
20
- assert_match %r(EXPLAIN for: SELECT "posts"\.\* FROM "posts" WHERE "posts"\."author_id" = (?:\$1 \[\["author_id", 1\]\]|1)), explain
19
+ assert_match %r(EXPLAIN SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
20
+ assert_match %r(EXPLAIN SELECT "posts"\.\* FROM "posts" WHERE "posts"\."author_id" = (?:\$1 \[\["author_id", 1\]\]|1)), explain
21
+ end
22
+
23
+ def test_explain_with_options_as_symbols
24
+ explain = Author.where(id: 1).explain(:analyze, :buffers).inspect
25
+ assert_match %r(EXPLAIN \(ANALYZE, BUFFERS\) SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
26
+ assert_match %(QUERY PLAN), explain
27
+ end
28
+
29
+ def test_explain_with_options_as_strings
30
+ explain = Author.where(id: 1).explain("VERBOSE", "ANALYZE", "FORMAT JSON").inspect
31
+ assert_match %r(EXPLAIN \(VERBOSE, ANALYZE, FORMAT JSON\) SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
32
+ assert_match %(QUERY PLAN), explain
33
+ end
34
+
35
+ def test_explain_options_with_eager_loading
36
+ explain = Author.where(id: 1).includes(:posts).explain(:analyze).inspect
37
+ assert_match %(QUERY PLAN), explain
38
+ assert_match %r(EXPLAIN \(ANALYZE\) SELECT "authors"\.\* FROM "authors" WHERE "authors"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
39
+ assert_match %r(EXPLAIN \(ANALYZE\) SELECT "posts"\.\* FROM "posts" WHERE "posts"\."author_id" = (?:\$1 \[\["author_id", 1\]\]|1)), explain
21
40
  end
22
41
  end
@@ -17,31 +17,34 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
17
17
  end
18
18
  end
19
19
 
20
+ class EnableHstoreInSchema < ActiveRecord::Migration::Current
21
+ def change
22
+ enable_extension "other_schema.hstore"
23
+ end
24
+ end
25
+
20
26
  def setup
21
27
  super
22
28
 
23
- @connection = ActiveRecord::Base.connection
29
+ @connection = ActiveRecord::Base.lease_connection
30
+ @pool = ActiveRecord::Base.connection_pool
24
31
 
25
32
  @old_table_name_prefix = ActiveRecord::Base.table_name_prefix
26
33
  @old_table_name_suffix = ActiveRecord::Base.table_name_suffix
27
34
 
28
35
  ActiveRecord::Base.table_name_prefix = "p_"
29
36
  ActiveRecord::Base.table_name_suffix = "_s"
30
- @connection.schema_migration.reset_table_name
31
- ActiveRecord::InternalMetadata.reset_table_name
32
37
 
33
- @connection.schema_migration.delete_all rescue nil
38
+ @pool.schema_migration.delete_all_versions rescue nil
34
39
  ActiveRecord::Migration.verbose = false
35
40
  end
36
41
 
37
42
  def teardown
38
- @connection.schema_migration.delete_all rescue nil
43
+ @pool.schema_migration.delete_all_versions rescue nil
39
44
  ActiveRecord::Migration.verbose = true
40
45
 
41
46
  ActiveRecord::Base.table_name_prefix = @old_table_name_prefix
42
47
  ActiveRecord::Base.table_name_suffix = @old_table_name_suffix
43
- @connection.schema_migration.reset_table_name
44
- ActiveRecord::InternalMetadata.reset_table_name
45
48
 
46
49
  super
47
50
  end
@@ -50,15 +53,54 @@ class PostgresqlExtensionMigrationTest < ActiveRecord::PostgreSQLTestCase
50
53
  @connection.disable_extension("hstore")
51
54
 
52
55
  migrations = [EnableHstore.new(nil, 1)]
53
- ActiveRecord::Migrator.new(:up, migrations, ActiveRecord::Base.connection.schema_migration).migrate
56
+ ActiveRecord::Migrator.new(:up, migrations, @pool.schema_migration, @pool.internal_metadata).migrate
57
+ assert @connection.extension_enabled?("hstore"), "extension hstore should be enabled"
58
+ end
59
+
60
+ def test_enable_extension_migration_with_schema
61
+ @connection.disable_extension("hstore")
62
+ @connection.create_schema "other_schema"
63
+
64
+ migrations = [EnableHstoreInSchema.new(nil, 1)]
65
+ ActiveRecord::Migrator.new(:up, migrations, @pool.schema_migration, @pool.internal_metadata).migrate
66
+
54
67
  assert @connection.extension_enabled?("hstore"), "extension hstore should be enabled"
68
+ ensure
69
+ @connection.drop_schema "other_schema", if_exists: true
55
70
  end
56
71
 
72
+
57
73
  def test_disable_extension_migration_ignores_prefix_and_suffix
58
74
  @connection.enable_extension("hstore")
59
75
 
60
76
  migrations = [DisableHstore.new(nil, 1)]
61
- ActiveRecord::Migrator.new(:up, migrations, ActiveRecord::Base.connection.schema_migration).migrate
77
+ ActiveRecord::Migrator.new(:up, migrations, @pool.schema_migration, @pool.internal_metadata).migrate
78
+ assert_not @connection.extension_enabled?("hstore"), "extension hstore should not be enabled"
79
+ end
80
+
81
+ def test_disable_extension_raises_when_dependent_objects_exist
82
+ @connection.enable_extension("hstore")
83
+ @connection.create_table(:hstores) do |t|
84
+ t.hstore :settings
85
+ end
86
+
87
+ error = assert_raises(StandardError) do
88
+ @connection.disable_extension(:hstore)
89
+ end
90
+ assert_match(/cannot drop extension hstore because other objects depend on it/i, error.message)
91
+ ensure
92
+ @connection.drop_table(:hstores, if_exists: true)
93
+ end
94
+
95
+ def test_disable_extension_drops_extension_when_cascading
96
+ @connection.enable_extension("hstore")
97
+ @connection.create_table(:hstores) do |t|
98
+ t.hstore :settings
99
+ end
100
+
101
+ @connection.disable_extension(:hstore, force: :cascade)
62
102
  assert_not @connection.extension_enabled?("hstore"), "extension hstore should not be enabled"
103
+ ensure
104
+ @connection.drop_table(:hstores, if_exists: true)
63
105
  end
64
106
  end
@@ -3,7 +3,7 @@
3
3
  require "cases/helper"
4
4
  require "models/professor"
5
5
 
6
- if ActiveRecord::Base.connection.supports_foreign_tables?
6
+ if ActiveRecord::Base.lease_connection.supports_foreign_tables?
7
7
  class ForeignTableTest < ActiveRecord::TestCase
8
8
  self.use_transactional_tests = false
9
9
 
@@ -18,7 +18,7 @@ if ActiveRecord::Base.connection.supports_foreign_tables?
18
18
  def setup
19
19
  @professor = Professor.create(name: "Nicola")
20
20
 
21
- @connection = ActiveRecord::Base.connection
21
+ @connection = ActiveRecord::Base.lease_connection
22
22
  enable_extension!("postgres_fdw", @connection)
23
23
 
24
24
  foreign_db_config = ARTest.test_configuration_hashes["arunit2"]
@@ -52,7 +52,7 @@ if ActiveRecord::Base.connection.supports_foreign_tables?
52
52
 
53
53
  def test_table_exists
54
54
  table_name = ForeignProfessor.table_name
55
- assert_not ActiveRecord::Base.connection.table_exists?(table_name)
55
+ assert_not ActiveRecord::Base.lease_connection.table_exists?(table_name)
56
56
  end
57
57
 
58
58
  def test_foreign_tables_are_valid_data_sources
@@ -8,7 +8,7 @@ class PostgresqlFullTextTest < ActiveRecord::PostgreSQLTestCase
8
8
  class Tsvector < ActiveRecord::Base; end
9
9
 
10
10
  setup do
11
- @connection = ActiveRecord::Base.connection
11
+ @connection = ActiveRecord::Base.lease_connection
12
12
  @connection.create_table("tsvectors") do |t|
13
13
  t.tsvector "text_vector"
14
14
  end
@@ -19,7 +19,7 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
19
19
  end
20
20
 
21
21
  def setup
22
- @connection = ActiveRecord::Base.connection
22
+ @connection = ActiveRecord::Base.lease_connection
23
23
  @connection.create_table("postgresql_points") do |t|
24
24
  t.point :x
25
25
  t.point :y, default: [12.2, 13.3]
@@ -88,6 +88,13 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
88
88
  assert_equal ActiveRecord::Point.new(1, 2), p.x
89
89
  end
90
90
 
91
+ def test_hash_assignment
92
+ p = PostgresqlPoint.new(x: { x: 1, y: 2 }, y: { "x" => 3, "y" => 4 })
93
+
94
+ assert_equal ActiveRecord::Point.new(1, 2), p.x
95
+ assert_equal ActiveRecord::Point.new(3, 4), p.y
96
+ end
97
+
91
98
  def test_string_assignment
92
99
  p = PostgresqlPoint.new(x: "(1, 2)")
93
100
 
@@ -167,7 +174,7 @@ class PostgresqlGeometricTest < ActiveRecord::PostgreSQLTestCase
167
174
  class PostgresqlGeometric < ActiveRecord::Base; end
168
175
 
169
176
  setup do
170
- @connection = ActiveRecord::Base.connection
177
+ @connection = ActiveRecord::Base.lease_connection
171
178
  @connection.create_table("postgresql_geometrics") do |t|
172
179
  t.lseg :a_line_segment
173
180
  t.box :a_box
@@ -247,17 +254,17 @@ class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase
247
254
  class PostgresqlLine < ActiveRecord::Base; end
248
255
 
249
256
  setup do
250
- unless ActiveRecord::Base.connection.database_version >= 90400
257
+ unless ActiveRecord::Base.lease_connection.database_version >= 90400
251
258
  skip("line type is not fully implemented")
252
259
  end
253
- @connection = ActiveRecord::Base.connection
260
+ @connection = ActiveRecord::Base.lease_connection
254
261
  @connection.create_table("postgresql_lines") do |t|
255
262
  t.line :a_line
256
263
  end
257
264
  end
258
265
 
259
266
  teardown do
260
- if defined?(@connection)
267
+ if @connection
261
268
  @connection.drop_table "postgresql_lines", if_exists: true
262
269
  end
263
270
  end
@@ -293,7 +300,7 @@ class PostgreSQLGeometricTypesTest < ActiveRecord::PostgreSQLTestCase
293
300
 
294
301
  def setup
295
302
  super
296
- @connection = ActiveRecord::Base.connection
303
+ @connection = ActiveRecord::Base.lease_connection
297
304
  @table_name = :testings
298
305
  end
299
306
 
@@ -13,7 +13,7 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
13
13
  end
14
14
 
15
15
  def setup
16
- @connection = ActiveRecord::Base.connection
16
+ @connection = ActiveRecord::Base.lease_connection
17
17
 
18
18
  enable_extension!("hstore", @connection)
19
19
 
@@ -41,7 +41,7 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
41
41
 
42
42
  def test_disable_enable_hstore
43
43
  assert @connection.extension_enabled?("hstore")
44
- @connection.disable_extension "hstore"
44
+ @connection.disable_extension "hstore", force: :cascade
45
45
  assert_not @connection.extension_enabled?("hstore")
46
46
  @connection.enable_extension "hstore"
47
47
  assert @connection.extension_enabled?("hstore")
@@ -111,8 +111,8 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
111
111
  def test_type_cast_hstore
112
112
  assert_equal({ "1" => "2" }, @type.deserialize("\"1\"=>\"2\""))
113
113
  assert_equal({}, @type.deserialize(""))
114
- assert_equal({ "key" => nil }, @type.deserialize("key => NULL"))
115
- assert_equal({ "c" => "}", '"a"' => 'b "a b' }, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
114
+ assert_cycle("key" => nil)
115
+ assert_cycle("c" => "}", '"a"' => 'b "a b')
116
116
  end
117
117
 
118
118
  def test_with_store_accessors
@@ -156,7 +156,7 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
156
156
 
157
157
  def test_changes_with_store_accessors
158
158
  x = Hstore.new(language: "de")
159
- assert x.language_changed?
159
+ assert_predicate x, :language_changed?
160
160
  assert_nil x.language_was
161
161
  assert_equal [nil, "de"], x.language_change
162
162
  x.save!
@@ -165,7 +165,7 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
165
165
  x.reload
166
166
 
167
167
  x.settings = nil
168
- assert x.language_changed?
168
+ assert_predicate x, :language_changed?
169
169
  assert_equal "de", x.language_was
170
170
  assert_equal ["de", nil], x.language_change
171
171
  end
@@ -199,48 +199,36 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
199
199
  assert_not_predicate hstore, :changed?
200
200
  end
201
201
 
202
- def test_gen1
203
- assert_equal('" "=>""', @type.serialize(" " => ""))
202
+ def test_spaces
203
+ assert_cycle(" " => " ")
204
204
  end
205
205
 
206
- def test_gen2
207
- assert_equal('","=>""', @type.serialize("," => ""))
206
+ def test_commas
207
+ assert_cycle("," => "")
208
208
  end
209
209
 
210
- def test_gen3
211
- assert_equal('"="=>""', @type.serialize("=" => ""))
210
+ def test_signs
211
+ assert_cycle("=" => ">")
212
212
  end
213
213
 
214
- def test_gen4
215
- assert_equal('">"=>""', @type.serialize(">" => ""))
214
+ def test_various_null
215
+ assert_cycle({ "a" => nil, "b" => nil, "c" => "NuLl", "null" => "c" })
216
216
  end
217
217
 
218
- def test_parse1
219
- assert_equal({ "a" => nil, "b" => nil, "c" => "NuLl", "null" => "c" }, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
220
- end
221
-
222
- def test_parse2
223
- assert_equal({ " " => " " }, @type.deserialize("\\ =>\\ "))
224
- end
225
-
226
- def test_parse3
227
- assert_equal({ "=" => ">" }, @type.deserialize("==>>"))
228
- end
229
-
230
- def test_parse4
231
- assert_equal({ "=a" => "q=w" }, @type.deserialize('\=a=>q=w'))
218
+ def test_equal_signs
219
+ assert_cycle("=a" => "q=w")
232
220
  end
233
221
 
234
222
  def test_parse5
235
- assert_equal({ "=a" => "q=w" }, @type.deserialize('"=a"=>q\=w'))
223
+ assert_cycle("=a" => "q=w")
236
224
  end
237
225
 
238
226
  def test_parse6
239
- assert_equal({ "\"a" => "q>w" }, @type.deserialize('"\"a"=>q>w'))
227
+ assert_cycle("\"a" => "q>w")
240
228
  end
241
229
 
242
230
  def test_parse7
243
- assert_equal({ "\"a" => "q\"w" }, @type.deserialize('\"a=>q"w'))
231
+ assert_cycle("\"a" => "q\"w")
244
232
  end
245
233
 
246
234
  def test_rewrite
@@ -304,6 +292,8 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
304
292
 
305
293
  def test_backslash
306
294
  assert_cycle('a\\b' => 'b\\ar', '1"foo' => "2")
295
+ assert_cycle('a\\"' => 'b\\ar', '1"foo' => "2")
296
+ assert_cycle("a\\" => "bar\\", '1"foo' => "2")
307
297
  end
308
298
 
309
299
  def test_comma
@@ -330,7 +320,7 @@ class PostgresqlHstoreTest < ActiveRecord::PostgreSQLTestCase
330
320
  end
331
321
 
332
322
  class HstoreWithSerialize < Hstore
333
- serialize :tags, TagCollection
323
+ serialize :tags, coder: TagCollection
334
324
  end
335
325
 
336
326
  def test_hstore_with_serialized_attributes
@@ -9,7 +9,7 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
9
9
  end
10
10
 
11
11
  setup do
12
- @connection = ActiveRecord::Base.connection
12
+ @connection = ActiveRecord::Base.lease_connection
13
13
  @connection.create_table(:postgresql_infinities) do |t|
14
14
  t.float :float
15
15
  t.datetime :datetime
@@ -33,7 +33,7 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
33
33
  record = PostgresqlInfinity.new(float: "-Infinity")
34
34
  assert_equal(-Float::INFINITY, record.float)
35
35
  record = PostgresqlInfinity.new(float: "NaN")
36
- assert record.float.nan?, "Expected #{record.float} to be NaN"
36
+ assert_predicate record.float, :nan?, "Expected #{record.float} to be NaN"
37
37
  end
38
38
 
39
39
  test "update_all with infinity on a float column" do
@@ -72,9 +72,20 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
72
72
 
73
73
  test "assigning 'infinity' on a datetime column with TZ aware attributes" do
74
74
  in_time_zone "Pacific Time (US & Canada)" do
75
+ # reset_column_information should be called to recreate types with TimeZoneConverter
76
+ PostgresqlInfinity.reset_column_information
77
+
75
78
  record = PostgresqlInfinity.create!(datetime: "infinity")
76
79
  assert_equal Float::INFINITY, record.datetime
77
80
  assert_equal record.datetime, record.reload.datetime
81
+
82
+ record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
83
+ assert_equal Float::INFINITY, record.datetime
84
+ assert_equal record.datetime, record.reload.datetime
85
+
86
+ record = PostgresqlInfinity.create!(datetime: BigDecimal::INFINITY)
87
+ assert_equal Float::INFINITY, record.datetime
88
+ assert_equal record.datetime, record.reload.datetime
78
89
  end
79
90
  ensure
80
91
  # setting time_zone_aware_attributes causes the types to change.
@@ -8,7 +8,7 @@ class PostgresqlIntegerTest < ActiveRecord::PostgreSQLTestCase
8
8
  end
9
9
 
10
10
  def setup
11
- @connection = ActiveRecord::Base.connection
11
+ @connection = ActiveRecord::Base.lease_connection
12
12
 
13
13
  @connection.transaction do
14
14
  @connection.create_table "pg_integers", force: true do |t|