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
@@ -5,69 +5,70 @@ require "models/project"
5
5
  require "timeout"
6
6
 
7
7
  class PooledConnectionsTest < ActiveRecord::TestCase
8
- self.use_transactional_tests = false
8
+ unless in_memory_db?
9
+ self.use_transactional_tests = false
9
10
 
10
- def setup
11
- @per_test_teardown = []
12
- @connection = ActiveRecord::Base.remove_connection.configuration_hash
13
- end
11
+ def setup
12
+ @connection = ActiveRecord::Base.remove_connection.configuration_hash
13
+ end
14
14
 
15
- teardown do
16
- ActiveRecord::Base.clear_all_connections!
17
- ActiveRecord::Base.establish_connection(@connection)
18
- @per_test_teardown.each(&:call)
19
- end
15
+ def teardown
16
+ ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
17
+ ActiveRecord::Base.establish_connection(@connection)
18
+ end
20
19
 
21
- # Will deadlock due to lack of Monitor timeouts in 1.9
22
- def checkout_checkin_connections(pool_size, threads)
23
- ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5))
24
- @connection_count = 0
25
- @timed_out = 0
26
- threads.times do
27
- Thread.new do
28
- conn = ActiveRecord::Base.connection_pool.checkout
29
- sleep 0.1
30
- ActiveRecord::Base.connection_pool.checkin conn
31
- @connection_count += 1
32
- rescue ActiveRecord::ConnectionTimeoutError
33
- @timed_out += 1
34
- end.join
20
+ def test_pooled_connection_checkin_one
21
+ checkout_checkin_connections 1, 2
22
+ assert_equal 2, @connection_count
23
+ assert_equal 0, @timed_out
24
+ assert_equal 1, ActiveRecord::Base.connection_pool.connections.size
35
25
  end
36
- end
37
26
 
38
- def checkout_checkin_connections_loop(pool_size, loops)
39
- ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5))
40
- @connection_count = 0
41
- @timed_out = 0
42
- loops.times do
43
- conn = ActiveRecord::Base.connection_pool.checkout
44
- ActiveRecord::Base.connection_pool.checkin conn
45
- @connection_count += 1
46
- ActiveRecord::Base.connection.data_sources
47
- rescue ActiveRecord::ConnectionTimeoutError
48
- @timed_out += 1
27
+ def test_pooled_connection_checkin_two
28
+ checkout_checkin_connections_loop 2, 3
29
+ assert_equal 3, @connection_count
30
+ assert_equal 0, @timed_out
31
+ assert_equal 2, ActiveRecord::Base.connection_pool.connections.size
49
32
  end
50
- end
51
33
 
52
- def test_pooled_connection_checkin_one
53
- checkout_checkin_connections 1, 2
54
- assert_equal 2, @connection_count
55
- assert_equal 0, @timed_out
56
- assert_equal 1, ActiveRecord::Base.connection_pool.connections.size
57
- end
34
+ def test_pooled_connection_remove
35
+ ActiveRecord::Base.establish_connection(@connection.merge(pool: 2, checkout_timeout: 0.5))
36
+ old_connection = ActiveRecord::Base.lease_connection
37
+ extra_connection = ActiveRecord::Base.connection_pool.checkout
38
+ ActiveRecord::Base.connection_pool.remove(extra_connection)
39
+ assert_equal ActiveRecord::Base.lease_connection.object_id, old_connection.object_id
40
+ end
58
41
 
59
- def test_pooled_connection_checkin_two
60
- checkout_checkin_connections_loop 2, 3
61
- assert_equal 3, @connection_count
62
- assert_equal 0, @timed_out
63
- assert_equal 2, ActiveRecord::Base.connection_pool.connections.size
64
- end
42
+ private
43
+ # Will deadlock due to lack of Monitor timeouts in 1.9
44
+ def checkout_checkin_connections(pool_size, threads)
45
+ ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5))
46
+ @connection_count = 0
47
+ @timed_out = 0
48
+ threads.times do
49
+ Thread.new do
50
+ conn = ActiveRecord::Base.connection_pool.checkout
51
+ sleep 0.1
52
+ ActiveRecord::Base.connection_pool.checkin conn
53
+ @connection_count += 1
54
+ rescue ActiveRecord::ConnectionTimeoutError
55
+ @timed_out += 1
56
+ end.join
57
+ end
58
+ end
65
59
 
66
- def test_pooled_connection_remove
67
- ActiveRecord::Base.establish_connection(@connection.merge(pool: 2, checkout_timeout: 0.5))
68
- old_connection = ActiveRecord::Base.connection
69
- extra_connection = ActiveRecord::Base.connection_pool.checkout
70
- ActiveRecord::Base.connection_pool.remove(extra_connection)
71
- assert_equal ActiveRecord::Base.connection, old_connection
60
+ def checkout_checkin_connections_loop(pool_size, loops)
61
+ ActiveRecord::Base.establish_connection(@connection.merge(pool: pool_size, checkout_timeout: 0.5))
62
+ @connection_count = 0
63
+ @timed_out = 0
64
+ loops.times do
65
+ conn = ActiveRecord::Base.connection_pool.checkout
66
+ ActiveRecord::Base.connection_pool.checkin conn
67
+ @connection_count += 1
68
+ ActiveRecord::Base.lease_connection.data_sources
69
+ rescue ActiveRecord::ConnectionTimeoutError
70
+ @timed_out += 1
71
+ end
72
+ end
72
73
  end
73
- end unless in_memory_db?
74
+ end
@@ -7,8 +7,13 @@ require "models/entrant"
7
7
  module ActiveRecord
8
8
  class PreparedStatementStatusTest < ActiveRecord::TestCase
9
9
  def test_prepared_statement_status_is_thread_and_instance_specific
10
- course_conn = Course.connection
11
- entrant_conn = Entrant.connection
10
+ course_conn = Course.lease_connection
11
+ entrant_conn = Entrant.lease_connection
12
+ base_conn = ActiveRecord::Base.lease_connection
13
+
14
+ if base_conn.prepared_statements && (!course_conn.prepared_statements || !entrant_conn.prepared_statements)
15
+ skip "prepared statements are not uniformly enabled across leased connections"
16
+ end
12
17
 
13
18
  inside = Concurrent::Event.new
14
19
  preventing = Concurrent::Event.new
@@ -16,7 +21,7 @@ module ActiveRecord
16
21
 
17
22
  assert_not_same course_conn, entrant_conn
18
23
 
19
- if ActiveRecord::Base.connection.prepared_statements
24
+ if ActiveRecord::Base.lease_connection.prepared_statements
20
25
  t1 = Thread.new do
21
26
  course_conn.unprepared_statement do
22
27
  inside.set
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ class PrimaryClassTest < ActiveRecord::TestCase
6
+ self.use_transactional_tests = false
7
+
8
+ def teardown
9
+ clean_up_connection_handler
10
+ end
11
+
12
+ class PrimaryAppRecord < ActiveRecord::Base
13
+ end
14
+
15
+ class AnotherAppRecord < PrimaryAppRecord
16
+ self.abstract_class = true
17
+ end
18
+
19
+ class ApplicationRecord < ActiveRecord::Base
20
+ self.abstract_class = true
21
+ end
22
+
23
+ def test_application_record_is_used_if_no_primary_class_is_set
24
+ Object.const_set(:ApplicationRecord, ApplicationRecord)
25
+
26
+ assert_predicate ApplicationRecord, :primary_class?
27
+ assert_predicate ApplicationRecord, :application_record_class?
28
+ assert_predicate ApplicationRecord, :abstract_class?
29
+ ensure
30
+ ActiveRecord.application_record_class = nil
31
+ Object.send(:remove_const, :ApplicationRecord)
32
+ end
33
+
34
+ def test_primary_class_and_primary_abstract_class_behavior
35
+ PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
36
+
37
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :primary_class?
38
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :application_record_class?
39
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :abstract_class?
40
+
41
+ assert_not_predicate AnotherAppRecord, :primary_class?
42
+ assert_not_predicate AnotherAppRecord, :application_record_class?
43
+ assert_predicate AnotherAppRecord, :abstract_class?
44
+
45
+ assert_predicate ActiveRecord::Base, :primary_class?
46
+ assert_not_predicate ActiveRecord::Base, :application_record_class?
47
+ assert_not_predicate ActiveRecord::Base, :abstract_class?
48
+ ensure
49
+ ActiveRecord.application_record_class = nil
50
+ end
51
+
52
+ def test_primary_abstract_class_cannot_be_reset
53
+ PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
54
+
55
+ assert_raises do
56
+ PrimaryClassTest::AnotherAppRecord.primary_abstract_class
57
+ end
58
+ ensure
59
+ ActiveRecord.application_record_class = nil
60
+ end
61
+
62
+ def test_primary_abstract_class_is_used_over_application_record_if_set
63
+ PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
64
+ Object.const_set(:ApplicationRecord, ApplicationRecord)
65
+
66
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :primary_class?
67
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :application_record_class?
68
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :abstract_class?
69
+
70
+ assert_not_predicate ApplicationRecord, :primary_class?
71
+ assert_not_predicate ApplicationRecord, :application_record_class?
72
+ assert_predicate ApplicationRecord, :abstract_class?
73
+
74
+ assert_predicate ActiveRecord::Base, :primary_class?
75
+ assert_not_predicate ActiveRecord::Base, :application_record_class?
76
+ assert_not_predicate ActiveRecord::Base, :abstract_class?
77
+ ensure
78
+ ActiveRecord.application_record_class = nil
79
+ Object.send(:remove_const, :ApplicationRecord)
80
+ end
81
+
82
+ def test_setting_primary_abstract_class_explicitly_wins_over_application_record_set_implicitly
83
+ Object.const_set(:ApplicationRecord, ApplicationRecord)
84
+
85
+ assert_predicate ApplicationRecord, :primary_class?
86
+ assert_predicate ApplicationRecord, :application_record_class?
87
+ assert_predicate ApplicationRecord, :abstract_class?
88
+
89
+ PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
90
+
91
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :primary_class?
92
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :application_record_class?
93
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :abstract_class?
94
+
95
+ assert_not_predicate ApplicationRecord, :primary_class?
96
+ assert_not_predicate ApplicationRecord, :application_record_class?
97
+ assert_predicate ApplicationRecord, :abstract_class?
98
+ ensure
99
+ ActiveRecord.application_record_class = nil
100
+ Object.send(:remove_const, :ApplicationRecord)
101
+ end
102
+
103
+ unless in_memory_db?
104
+ def test_application_record_shares_a_connection_with_active_record_by_default
105
+ Object.const_set(:ApplicationRecord, ApplicationRecord)
106
+
107
+ ApplicationRecord.connects_to(database: { writing: :arunit, reading: :arunit })
108
+
109
+ assert_predicate ApplicationRecord, :primary_class?
110
+ assert_predicate ApplicationRecord, :application_record_class?
111
+ assert_equal ActiveRecord::Base.lease_connection, ApplicationRecord.lease_connection
112
+ ensure
113
+ ApplicationRecord.remove_connection
114
+ ActiveRecord.application_record_class = nil
115
+ Object.send(:remove_const, :ApplicationRecord)
116
+ ActiveRecord::Base.establish_connection :arunit
117
+ end
118
+
119
+ def test_application_record_shares_a_connection_with_the_primary_abstract_class_if_set
120
+ PrimaryClassTest::PrimaryAppRecord.primary_abstract_class
121
+
122
+ PrimaryClassTest::PrimaryAppRecord.connects_to(database: { writing: :arunit, reading: :arunit })
123
+
124
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :primary_class?
125
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :application_record_class?
126
+ assert_predicate PrimaryClassTest::PrimaryAppRecord, :abstract_class?
127
+ assert_equal ActiveRecord::Base.lease_connection, PrimaryClassTest::PrimaryAppRecord.lease_connection
128
+ ensure
129
+ PrimaryClassTest::PrimaryAppRecord.remove_connection
130
+ ActiveRecord.application_record_class = nil
131
+ ActiveRecord::Base.establish_connection :arunit
132
+ end
133
+ end
134
+ end
@@ -10,6 +10,7 @@ require "models/keyboard"
10
10
  require "models/mixed_case_monkey"
11
11
  require "models/dashboard"
12
12
  require "models/non_primary_key"
13
+ require "models/cpk"
13
14
 
14
15
  class PrimaryKeysTest < ActiveRecord::TestCase
15
16
  fixtures :topics, :subscribers, :movies, :mixed_case_monkeys
@@ -28,9 +29,36 @@ class PrimaryKeysTest < ActiveRecord::TestCase
28
29
  assert_equal keyboard.to_key, [keyboard.id]
29
30
  end
30
31
 
31
- def test_read_attribute_with_custom_primary_key
32
+ def test_to_key_with_composite_primary_key
33
+ order = Cpk::Order.new
34
+ assert_equal [nil, nil], order.to_key
35
+ order.id = [1, 2]
36
+ assert_equal [1, 2], order.to_key
37
+ end
38
+
39
+ def test_read_attribute_id
40
+ topic = Topic.find(1)
41
+ id = assert_not_deprecated(ActiveRecord.deprecator) do
42
+ topic.read_attribute(:id)
43
+ end
44
+
45
+ assert_equal 1, id
46
+ end
47
+
48
+ def test_read_attribute_with_custom_primary_key_does_not_return_it_when_reading_the_id_attribute
32
49
  keyboard = Keyboard.create!
33
- assert_equal keyboard.key_number, keyboard.read_attribute(:id)
50
+ id = keyboard.read_attribute(:id)
51
+
52
+ assert_nil id
53
+ end
54
+
55
+ def test_read_attribute_with_composite_primary_key
56
+ book = Cpk::Book.new(id: [1, 2])
57
+ id = assert_not_deprecated(ActiveRecord.deprecator) do
58
+ book.read_attribute(:id)
59
+ end
60
+
61
+ assert_equal 2, id
34
62
  end
35
63
 
36
64
  def test_to_key_with_primary_key_after_destroy
@@ -39,6 +67,24 @@ class PrimaryKeysTest < ActiveRecord::TestCase
39
67
  assert_equal [1], topic.to_key
40
68
  end
41
69
 
70
+ def test_id_was
71
+ topic = Topic.find(1)
72
+ assert_equal 1, topic.id
73
+
74
+ topic.id = 3
75
+
76
+ assert_equal 1, topic.id_was
77
+ assert_equal 3, topic.id
78
+ end
79
+
80
+ def test_id?
81
+ topic = Topic.find(1)
82
+
83
+ assert_changes("topic.id?", from: true, to: false) do
84
+ topic.id = nil
85
+ end
86
+ end
87
+
42
88
  def test_integer_key
43
89
  topic = Topic.find(1)
44
90
  assert_equal(topics(:first).author_name, topic.author_name)
@@ -174,9 +220,10 @@ class PrimaryKeysTest < ActiveRecord::TestCase
174
220
 
175
221
  def test_quoted_primary_key_after_set_primary_key
176
222
  k = Class.new(ActiveRecord::Base)
177
- assert_equal k.connection.quote_column_name("id"), k.quoted_primary_key
223
+ k.table_name = "bar"
224
+ assert_equal k.lease_connection.quote_column_name("id"), k.quoted_primary_key
178
225
  k.primary_key = "foo"
179
- assert_equal k.connection.quote_column_name("foo"), k.quoted_primary_key
226
+ assert_equal k.lease_connection.quote_column_name("foo"), k.quoted_primary_key
180
227
  end
181
228
 
182
229
  def test_auto_detect_primary_key_from_schema
@@ -194,13 +241,11 @@ class PrimaryKeysTest < ActiveRecord::TestCase
194
241
  end
195
242
 
196
243
  def test_create_without_primary_key_no_extra_query
197
- skip if current_adapter?(:OracleAdapter, :IBM_DBAdapter)
198
-
199
244
  klass = Class.new(ActiveRecord::Base) do
200
245
  self.table_name = "dashboards"
201
246
  end
202
247
  klass.create! # warmup schema cache
203
- assert_queries(3, ignore_none: true) { klass.create! }
248
+ assert_queries_count(3, include_schema: true) { klass.create! }
204
249
  end
205
250
 
206
251
  def test_assign_id_raises_error_if_primary_key_doesnt_exist
@@ -211,6 +256,28 @@ class PrimaryKeysTest < ActiveRecord::TestCase
211
256
  assert_raises(ActiveModel::MissingAttributeError) { dashboard.id = "1" }
212
257
  end
213
258
 
259
+ def test_reconfiguring_primary_key_resets_composite_primary_key
260
+ klass = Class.new(ActiveRecord::Base) do
261
+ self.table_name = "cpk_books"
262
+ end
263
+
264
+ assert_predicate klass, :composite_primary_key?
265
+
266
+ klass.primary_key = :id
267
+ assert_not_predicate klass, :composite_primary_key?
268
+ end
269
+
270
+ def composite_primary_key_is_false_for_a_non_cpk_model
271
+ assert_not_predicate Dashboard, :composite_primary_key?
272
+ end
273
+
274
+ def test_primary_key_values_present
275
+ assert_predicate Topic.new(id: 1), :primary_key_values_present?
276
+
277
+ assert_not_predicate Topic.new, :primary_key_values_present?
278
+ assert_not_predicate Topic.new(title: "Topic A"), :primary_key_values_present?
279
+ end
280
+
214
281
  if current_adapter?(:PostgreSQLAdapter)
215
282
  def test_serial_with_quoted_sequence_name
216
283
  column = MixedCaseMonkey.columns_hash[MixedCaseMonkey.primary_key]
@@ -226,25 +293,6 @@ class PrimaryKeysTest < ActiveRecord::TestCase
226
293
  end
227
294
  end
228
295
 
229
- class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase
230
- self.use_transactional_tests = false
231
-
232
- unless in_memory_db?
233
- def test_set_primary_key_with_no_connection
234
- connection = ActiveRecord::Base.remove_connection
235
-
236
- model = Class.new(ActiveRecord::Base)
237
- model.primary_key = "foo"
238
-
239
- assert_equal "foo", model.primary_key
240
-
241
- ActiveRecord::Base.establish_connection(connection)
242
-
243
- assert_equal "foo", model.primary_key
244
- end
245
- end
246
- end
247
-
248
296
  class PrimaryKeyWithAutoIncrementTest < ActiveRecord::TestCase
249
297
  self.use_transactional_tests = false
250
298
 
@@ -252,7 +300,7 @@ class PrimaryKeyWithAutoIncrementTest < ActiveRecord::TestCase
252
300
  end
253
301
 
254
302
  def setup
255
- @connection = ActiveRecord::Base.connection
303
+ @connection = ActiveRecord::Base.lease_connection
256
304
  end
257
305
 
258
306
  def teardown
@@ -285,13 +333,11 @@ end
285
333
  class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
286
334
  include SchemaDumpingHelper
287
335
 
288
- self.use_transactional_tests = false
289
-
290
336
  class Barcode < ActiveRecord::Base
291
337
  end
292
338
 
293
339
  setup do
294
- @connection = ActiveRecord::Base.connection
340
+ @connection = ActiveRecord::Base.lease_connection
295
341
  @connection.create_table(:barcodes, primary_key: "code", id: :string, limit: 42, force: true)
296
342
  end
297
343
 
@@ -316,11 +362,11 @@ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
316
362
  assert_no_match %r{t\.index \["code"\]}, schema
317
363
  end
318
364
 
319
- if current_adapter?(:Mysql2Adapter) && supports_datetime_with_precision?
365
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
320
366
  test "schema typed primary key column" do
321
367
  @connection.create_table(:scheduled_logs, id: :timestamp, precision: 6, force: true)
322
368
  schema = dump_table_schema("scheduled_logs")
323
- assert_match %r/create_table "scheduled_logs", id: { type: :timestamp, precision: 6.* }/, schema
369
+ assert_match %r/create_table "scheduled_logs", id: :timestamp.*/, schema
324
370
  end
325
371
  end
326
372
  end
@@ -330,20 +376,22 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
330
376
 
331
377
  self.use_transactional_tests = false
332
378
 
379
+ fixtures :cpk_books, :cpk_orders
380
+
333
381
  def setup
334
- @connection = ActiveRecord::Base.connection
335
- @connection.schema_cache.clear!
382
+ ActiveRecord::Base.schema_cache.clear!
383
+ @connection = ActiveRecord::Base.lease_connection
336
384
  @connection.create_table(:uber_barcodes, primary_key: ["region", "code"], force: true) do |t|
337
- t.string :region, null: false
338
- t.integer :code, null: false
385
+ t.string :region
386
+ t.integer :code
339
387
  end
340
388
  @connection.create_table(:barcodes_reverse, primary_key: ["code", "region"], force: true) do |t|
341
- t.string :region, null: false
342
- t.integer :code, null: false
389
+ t.string :region
390
+ t.integer :code
343
391
  end
344
392
  @connection.create_table(:travels, primary_key: ["from", "to"], force: true) do |t|
345
- t.string :from, null: false
346
- t.string :to, null: false
393
+ t.string :from
394
+ t.string :to
347
395
  end
348
396
  end
349
397
 
@@ -354,7 +402,6 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
354
402
  end
355
403
 
356
404
  def test_composite_primary_key
357
- pri = @connection.primary_keys("uber_barcodes")
358
405
  assert_equal ["region", "code"], @connection.primary_keys("uber_barcodes")
359
406
  end
360
407
 
@@ -366,16 +413,66 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
366
413
  assert_equal ["code", "region"], @connection.primary_keys("barcodes_reverse")
367
414
  end
368
415
 
369
- def test_primary_key_issues_warning
416
+ def test_assigning_a_composite_primary_key
417
+ book = Cpk::Book.new
418
+ book.id = [1, 2]
419
+ book.save!
420
+
421
+ assert_equal [1, 2], book.id
422
+ ensure
423
+ Cpk::Book.delete_all
424
+ end
425
+
426
+ def test_assigning_a_non_array_value_to_model_with_composite_primary_key_raises
427
+ book = Cpk::Book.new
428
+
429
+ error = assert_raises(TypeError) do
430
+ book.id = 1
431
+ end
432
+
433
+ assert_equal("Expected value matching [\"author_id\", \"id\"], got 1.", error.message)
434
+ end
435
+
436
+ def test_id_was_composite
437
+ book = cpk_books(:cpk_great_author_first_book)
438
+ book_id = book.id
439
+
440
+ assert_not_equal [42, 42], book_id
441
+
442
+ book.id = [42, 42]
443
+
444
+ assert_equal book_id, book.id_was
445
+ assert_equal [42, 42], book.id
446
+ end
447
+
448
+ def test_id_predicate_composite
449
+ book = cpk_books(:cpk_great_author_first_book)
450
+
451
+ valid_id = [42, 42]
452
+
453
+ invalid_ids = [
454
+ [42, nil],
455
+ [nil, 42],
456
+ [nil, nil],
457
+ ]
458
+
459
+ invalid_ids.each do |invalid_id|
460
+ book.id = valid_id
461
+
462
+ assert_changes("book.id?", from: true, to: false) do
463
+ book.id = invalid_id
464
+ end
465
+ end
466
+ end
467
+
468
+ def test_derives_composite_primary_key
370
469
  model = Class.new(ActiveRecord::Base) do
371
470
  def self.table_name
372
471
  "uber_barcodes"
373
472
  end
374
473
  end
375
- warning = capture(:stderr) do
376
- assert_nil model.primary_key
377
- end
378
- assert_match(/WARNING: Active Record does not support composite primary key\./, warning)
474
+
475
+ assert_equal ["region", "code"], model.primary_key
379
476
  end
380
477
 
381
478
  def test_collectly_dump_composite_primary_key
@@ -387,15 +484,32 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
387
484
  schema = dump_table_schema "barcodes_reverse"
388
485
  assert_match %r{create_table "barcodes_reverse", primary_key: \["code", "region"\]}, schema
389
486
  end
487
+
488
+ def test_model_with_a_composite_primary_key
489
+ assert_equal(["author_id", "id"], Cpk::Book.primary_key)
490
+ assert_equal(["shop_id", "id"], Cpk::Order.primary_key)
491
+ end
492
+
493
+ def composite_primary_key_is_true_for_a_cpk_model
494
+ assert_predicate Cpk::Book, :composite_primary_key?
495
+ end
496
+
497
+ def test_primary_key_values_present_for_a_composite_pk_model
498
+ assert_predicate Cpk::Book.new(id: [1, 1]), :primary_key_values_present?
499
+
500
+ assert_not_predicate Cpk::Book.new, :primary_key_values_present?
501
+ assert_not_predicate Cpk::Book.new(author_id: 1), :primary_key_values_present?
502
+ assert_not_predicate Cpk::Book.new(id: [nil, 1]), :primary_key_values_present?
503
+ assert_not_predicate Cpk::Book.new(title: "Book A"), :primary_key_values_present?
504
+ assert_not_predicate Cpk::Book.new(author_id: 1, title: "Book A"), :primary_key_values_present?
505
+ end
390
506
  end
391
507
 
392
508
  class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
393
509
  include SchemaDumpingHelper
394
510
 
395
- self.use_transactional_tests = false
396
-
397
511
  def setup
398
- @connection = ActiveRecord::Base.connection
512
+ @connection = ActiveRecord::Base.lease_connection
399
513
  end
400
514
 
401
515
  def teardown
@@ -403,10 +517,12 @@ class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
403
517
  end
404
518
 
405
519
  def test_schema_dump_primary_key_integer_with_default_nil
406
- skip if current_adapter?(:SQLite3Adapter, :IBM_DBAdapter)
407
520
  @connection.create_table(:int_defaults, id: :integer, default: nil, force: true)
408
521
  schema = dump_table_schema "int_defaults"
409
- assert_match %r{create_table "int_defaults", id: :integer, default: nil}, schema
522
+ assert_match(
523
+ %r{create_table "int_defaults", (?:id: :integer, default: nil|force: :cascade)},
524
+ schema
525
+ )
410
526
  end
411
527
 
412
528
  def test_schema_dump_primary_key_bigint_with_default_nil
@@ -416,8 +532,8 @@ class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
416
532
  end
417
533
  end
418
534
 
419
- if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
420
- class PrimaryKeyIntegerTest < ActiveRecord::TestCase
535
+ class PrimaryKeyIntegerTest < ActiveRecord::TestCase
536
+ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter, :TrilogyAdapter)
421
537
  include SchemaDumpingHelper
422
538
 
423
539
  self.use_transactional_tests = false
@@ -426,7 +542,7 @@ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
426
542
  end
427
543
 
428
544
  setup do
429
- @connection = ActiveRecord::Base.connection
545
+ @connection = ActiveRecord::Base.lease_connection
430
546
  @pk_type = current_adapter?(:PostgreSQLAdapter) ? :serial : :integer
431
547
  end
432
548
 
@@ -453,7 +569,7 @@ if current_adapter?(:PostgreSQLAdapter, :Mysql2Adapter)
453
569
  assert_match %r{create_table "widgets", id: :#{@pk_type}, }, schema
454
570
  end
455
571
 
456
- if current_adapter?(:Mysql2Adapter)
572
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
457
573
  test "primary key column type with options" do
458
574
  @connection.create_table(:widgets, id: :primary_key, limit: 4, unsigned: true, force: true)
459
575
  column = @connection.columns(:widgets).find { |c| c.name == "id" }