ibm_db 5.7.0-x64-mingw-ucrt

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 (995) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +299 -0
  3. data/LICENSE +55 -0
  4. data/MANIFEST +14 -0
  5. data/ParameterizedQueries README +39 -0
  6. data/README +210 -0
  7. data/ext/Makefile +277 -0
  8. data/ext/Makefile.nt32 +181 -0
  9. data/ext/Makefile.nt32.191 +212 -0
  10. data/ext/extconf.rb +386 -0
  11. data/ext/gil_release_version.h +3 -0
  12. data/ext/ibm_db-x64-mingw-ucrt.def +2 -0
  13. data/ext/ibm_db.c +11925 -0
  14. data/ext/ibm_db.o +0 -0
  15. data/ext/ibm_db.so +0 -0
  16. data/ext/mkmf.log +110 -0
  17. data/ext/ruby_ibm_db.h +241 -0
  18. data/ext/ruby_ibm_db_cli.c +871 -0
  19. data/ext/ruby_ibm_db_cli.h +512 -0
  20. data/ext/ruby_ibm_db_cli.o +0 -0
  21. data/ext/unicode_support_version.h +3 -0
  22. data/init.rb +42 -0
  23. data/lib/IBM_DB.rb +27 -0
  24. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +5384 -0
  25. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1965 -0
  26. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -0
  27. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -0
  28. data/lib/ibm_db.so +1 -0
  29. data/lib/mswin/ibm_db.rb +105 -0
  30. data/lib/mswin/rb2x/i386/ruby25/ibm_db.so +0 -0
  31. data/lib/mswin/rb2x/i386/ruby26/ibm_db.so +0 -0
  32. data/lib/mswin/rb2x/i386/ruby27/ibm_db.so +0 -0
  33. data/lib/mswin/rb3x/i386/ruby30/ibm_db.so +0 -0
  34. data/lib/mswin/rb4x/x64/ruby40/ibm_db.so +0 -0
  35. data/test/active_record/connection_adapters/fake_adapter.rb +52 -0
  36. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  37. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  38. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  39. data/test/activejob/destroy_association_async_test.rb +441 -0
  40. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  41. data/test/activejob/helper.rb +15 -0
  42. data/test/activejob/job_runtime_test.rb +41 -0
  43. data/test/activejob/unloadable_base_job.rb +3 -0
  44. data/test/assets/example.log +1 -0
  45. data/test/assets/flowers.jpg +0 -0
  46. data/test/assets/schema_dump_5_1.yml +345 -0
  47. data/test/assets/test.txt +1 -0
  48. data/test/cases/active_record_schema_test.rb +196 -0
  49. data/test/cases/active_record_test.rb +21 -0
  50. data/test/cases/adapter_prevent_writes_test.rb +158 -0
  51. data/test/cases/adapter_test.rb +1075 -0
  52. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  53. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  54. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  55. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  56. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  57. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  58. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  59. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  60. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  61. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  62. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  63. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  64. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  65. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  66. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  67. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  68. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  69. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  70. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  71. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  72. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  73. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  74. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  75. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  76. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  77. data/test/cases/adapters/mysql2/active_schema_test.rb +203 -0
  78. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  79. data/test/cases/adapters/mysql2/bind_parameter_test.rb +52 -0
  80. data/test/cases/adapters/mysql2/boolean_test.rb +102 -0
  81. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +65 -0
  82. data/test/cases/adapters/mysql2/charset_collation_test.rb +57 -0
  83. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  84. data/test/cases/adapters/mysql2/connection_test.rb +208 -0
  85. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  86. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +49 -0
  87. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  88. data/test/cases/adapters/mysql2/enum_test.rb +47 -0
  89. data/test/cases/adapters/mysql2/explain_test.rb +23 -0
  90. data/test/cases/adapters/mysql2/json_test.rb +24 -0
  91. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  92. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +364 -0
  93. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  94. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  95. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  96. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  97. data/test/cases/adapters/mysql2/schema_migrations_test.rb +64 -0
  98. data/test/cases/adapters/mysql2/schema_test.rb +128 -0
  99. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  100. data/test/cases/adapters/mysql2/sp_test.rb +38 -0
  101. data/test/cases/adapters/mysql2/sql_types_test.rb +16 -0
  102. data/test/cases/adapters/mysql2/table_options_test.rb +125 -0
  103. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  104. data/test/cases/adapters/mysql2/unsigned_type_test.rb +68 -0
  105. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  106. data/test/cases/adapters/postgresql/active_schema_test.rb +117 -0
  107. data/test/cases/adapters/postgresql/array_test.rb +394 -0
  108. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  109. data/test/cases/adapters/postgresql/bit_string_test.rb +84 -0
  110. data/test/cases/adapters/postgresql/bytea_test.rb +135 -0
  111. data/test/cases/adapters/postgresql/case_insensitive_test.rb +27 -0
  112. data/test/cases/adapters/postgresql/change_schema_test.rb +71 -0
  113. data/test/cases/adapters/postgresql/cidr_test.rb +44 -0
  114. data/test/cases/adapters/postgresql/citext_test.rb +84 -0
  115. data/test/cases/adapters/postgresql/collation_test.rb +55 -0
  116. data/test/cases/adapters/postgresql/composite_test.rb +134 -0
  117. data/test/cases/adapters/postgresql/connection_test.rb +252 -0
  118. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +75 -0
  119. data/test/cases/adapters/postgresql/datatype_test.rb +94 -0
  120. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  121. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  122. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  123. data/test/cases/adapters/postgresql/domain_test.rb +49 -0
  124. data/test/cases/adapters/postgresql/enum_test.rb +293 -0
  125. data/test/cases/adapters/postgresql/explain_test.rb +41 -0
  126. data/test/cases/adapters/postgresql/extension_migration_test.rb +106 -0
  127. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  128. data/test/cases/adapters/postgresql/full_text_test.rb +46 -0
  129. data/test/cases/adapters/postgresql/geometric_test.rb +379 -0
  130. data/test/cases/adapters/postgresql/hstore_test.rb +380 -0
  131. data/test/cases/adapters/postgresql/infinity_test.rb +119 -0
  132. data/test/cases/adapters/postgresql/integer_test.rb +27 -0
  133. data/test/cases/adapters/postgresql/interval_test.rb +91 -0
  134. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  135. data/test/cases/adapters/postgresql/json_test.rb +57 -0
  136. data/test/cases/adapters/postgresql/ltree_test.rb +51 -0
  137. data/test/cases/adapters/postgresql/money_test.rb +135 -0
  138. data/test/cases/adapters/postgresql/network_test.rb +114 -0
  139. data/test/cases/adapters/postgresql/numbers_test.rb +67 -0
  140. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  141. data/test/cases/adapters/postgresql/partitions_test.rb +25 -0
  142. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +102 -0
  143. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +830 -0
  144. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  145. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  146. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  147. data/test/cases/adapters/postgresql/quoting_test.rb +109 -0
  148. data/test/cases/adapters/postgresql/range_test.rb +621 -0
  149. data/test/cases/adapters/postgresql/referential_integrity_test.rb +136 -0
  150. data/test/cases/adapters/postgresql/rename_table_test.rb +62 -0
  151. data/test/cases/adapters/postgresql/schema_authorization_test.rb +110 -0
  152. data/test/cases/adapters/postgresql/schema_test.rb +963 -0
  153. data/test/cases/adapters/postgresql/serial_test.rb +156 -0
  154. data/test/cases/adapters/postgresql/statement_pool_test.rb +65 -0
  155. data/test/cases/adapters/postgresql/timestamp_test.rb +209 -0
  156. data/test/cases/adapters/postgresql/transaction_nested_test.rb +238 -0
  157. data/test/cases/adapters/postgresql/transaction_test.rb +215 -0
  158. data/test/cases/adapters/postgresql/type_lookup_test.rb +35 -0
  159. data/test/cases/adapters/postgresql/utils_test.rb +64 -0
  160. data/test/cases/adapters/postgresql/uuid_test.rb +479 -0
  161. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  162. data/test/cases/adapters/postgresql/xml_test.rb +50 -0
  163. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  164. data/test/cases/adapters/sqlite3/collation_test.rb +64 -0
  165. data/test/cases/adapters/sqlite3/copy_table_test.rb +122 -0
  166. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  167. data/test/cases/adapters/sqlite3/explain_test.rb +23 -0
  168. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  169. data/test/cases/adapters/sqlite3/quoting_test.rb +110 -0
  170. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +93 -0
  171. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +1283 -0
  172. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +27 -0
  173. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  174. data/test/cases/adapters/sqlite3/statement_pool_test.rb +21 -0
  175. data/test/cases/adapters/sqlite3/transaction_test.rb +126 -0
  176. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  177. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  178. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  179. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  180. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  181. data/test/cases/aggregations_test.rb +186 -0
  182. data/test/cases/annotate_test.rb +48 -0
  183. data/test/cases/ar_schema_test.rb +213 -0
  184. data/test/cases/arel/attributes/attribute_test.rb +1184 -0
  185. data/test/cases/arel/attributes/math_test.rb +83 -0
  186. data/test/cases/arel/attributes_test.rb +27 -0
  187. data/test/cases/arel/collectors/bind_test.rb +40 -0
  188. data/test/cases/arel/collectors/composite_test.rb +57 -0
  189. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  190. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  191. data/test/cases/arel/crud_test.rb +65 -0
  192. data/test/cases/arel/delete_manager_test.rb +47 -0
  193. data/test/cases/arel/factory_methods_test.rb +91 -0
  194. data/test/cases/arel/helper.rb +45 -0
  195. data/test/cases/arel/insert_manager_test.rb +235 -0
  196. data/test/cases/arel/nodes/and_test.rb +30 -0
  197. data/test/cases/arel/nodes/as_test.rb +48 -0
  198. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  199. data/test/cases/arel/nodes/bin_test.rb +35 -0
  200. data/test/cases/arel/nodes/binary_test.rb +29 -0
  201. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  202. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  203. data/test/cases/arel/nodes/case_test.rb +96 -0
  204. data/test/cases/arel/nodes/casted_test.rb +18 -0
  205. data/test/cases/arel/nodes/comment_test.rb +22 -0
  206. data/test/cases/arel/nodes/count_test.rb +35 -0
  207. data/test/cases/arel/nodes/cte_test.rb +46 -0
  208. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  209. data/test/cases/arel/nodes/descending_test.rb +46 -0
  210. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  211. data/test/cases/arel/nodes/equality_test.rb +62 -0
  212. data/test/cases/arel/nodes/extract_test.rb +43 -0
  213. data/test/cases/arel/nodes/false_test.rb +21 -0
  214. data/test/cases/arel/nodes/filter_test.rb +37 -0
  215. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  216. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  217. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  218. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  219. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  220. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  221. data/test/cases/arel/nodes/node_test.rb +22 -0
  222. data/test/cases/arel/nodes/not_test.rb +31 -0
  223. data/test/cases/arel/nodes/or_test.rb +36 -0
  224. data/test/cases/arel/nodes/over_test.rb +69 -0
  225. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  226. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  227. data/test/cases/arel/nodes/sql_literal_test.rb +92 -0
  228. data/test/cases/arel/nodes/sum_test.rb +35 -0
  229. data/test/cases/arel/nodes/table_alias_test.rb +41 -0
  230. data/test/cases/arel/nodes/true_test.rb +21 -0
  231. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  232. data/test/cases/arel/nodes/update_statement_test.rb +64 -0
  233. data/test/cases/arel/nodes/window_test.rb +81 -0
  234. data/test/cases/arel/nodes_test.rb +35 -0
  235. data/test/cases/arel/select_manager_test.rb +1238 -0
  236. data/test/cases/arel/support/fake_record.rb +140 -0
  237. data/test/cases/arel/table_test.rb +206 -0
  238. data/test/cases/arel/update_manager_test.rb +171 -0
  239. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  240. data/test/cases/arel/visitors/dot_test.rb +265 -0
  241. data/test/cases/arel/visitors/mysql_test.rb +205 -0
  242. data/test/cases/arel/visitors/postgres_test.rb +336 -0
  243. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  244. data/test/cases/arel/visitors/to_sql_test.rb +1060 -0
  245. data/test/cases/assertions/query_assertions_test.rb +136 -0
  246. data/test/cases/associations/association_scope_test.rb +16 -0
  247. data/test/cases/associations/belongs_to_associations_test.rb +1954 -0
  248. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +43 -0
  249. data/test/cases/associations/callbacks_test.rb +208 -0
  250. data/test/cases/associations/cascaded_eager_loading_test.rb +256 -0
  251. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +156 -0
  252. data/test/cases/associations/eager_load_nested_include_test.rb +127 -0
  253. data/test/cases/associations/eager_singularization_test.rb +148 -0
  254. data/test/cases/associations/eager_test.rb +1820 -0
  255. data/test/cases/associations/extension_test.rb +93 -0
  256. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +997 -0
  257. data/test/cases/associations/has_many_associations_test.rb +3284 -0
  258. data/test/cases/associations/has_many_through_associations_test.rb +1707 -0
  259. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  260. data/test/cases/associations/has_one_associations_test.rb +1003 -0
  261. data/test/cases/associations/has_one_through_associations_test.rb +478 -0
  262. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  263. data/test/cases/associations/inner_join_association_test.rb +245 -0
  264. data/test/cases/associations/inverse_associations_test.rb +1078 -0
  265. data/test/cases/associations/join_model_test.rb +792 -0
  266. data/test/cases/associations/left_outer_join_association_test.rb +134 -0
  267. data/test/cases/associations/nested_error_test.rb +116 -0
  268. data/test/cases/associations/nested_through_associations_test.rb +671 -0
  269. data/test/cases/associations/required_test.rb +127 -0
  270. data/test/cases/associations_test.rb +1773 -0
  271. data/test/cases/asynchronous_queries_test.rb +310 -0
  272. data/test/cases/attribute_decorators_test.rb +126 -0
  273. data/test/cases/attribute_methods/read_test.rb +66 -0
  274. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  275. data/test/cases/attribute_methods_test.rb +1643 -0
  276. data/test/cases/attribute_set_test.rb +270 -0
  277. data/test/cases/attribute_test.rb +246 -0
  278. data/test/cases/attributes_test.rb +412 -0
  279. data/test/cases/autosave_association_test.rb +2506 -0
  280. data/test/cases/base_prevent_writes_test.rb +98 -0
  281. data/test/cases/base_test.rb +1995 -0
  282. data/test/cases/batches_test.rb +1079 -0
  283. data/test/cases/binary_test.rb +70 -0
  284. data/test/cases/bind_parameter_test.rb +374 -0
  285. data/test/cases/boolean_test.rb +52 -0
  286. data/test/cases/cache_key_test.rb +131 -0
  287. data/test/cases/calculations_test.rb +1792 -0
  288. data/test/cases/callbacks_test.rb +502 -0
  289. data/test/cases/clone_test.rb +46 -0
  290. data/test/cases/coders/json_test.rb +17 -0
  291. data/test/cases/coders/yaml_column_test.rb +161 -0
  292. data/test/cases/collection_cache_key_test.rb +280 -0
  293. data/test/cases/column_alias_test.rb +13 -0
  294. data/test/cases/column_definition_test.rb +43 -0
  295. data/test/cases/comment_test.rb +201 -0
  296. data/test/cases/connection_adapters/adapter_leasing_test.rb +60 -0
  297. data/test/cases/connection_adapters/connection_handler_test.rb +513 -0
  298. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +424 -0
  299. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +100 -0
  300. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +590 -0
  301. data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
  302. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +570 -0
  303. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  304. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  305. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +505 -0
  306. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +81 -0
  307. data/test/cases/connection_adapters/quoting_test.rb +13 -0
  308. data/test/cases/connection_adapters/registration_test.rb +98 -0
  309. data/test/cases/connection_adapters/schema_cache_test.rb +447 -0
  310. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  311. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  312. data/test/cases/connection_adapters/type_lookup_test.rb +107 -0
  313. data/test/cases/connection_handling_test.rb +210 -0
  314. data/test/cases/connection_management_test.rb +151 -0
  315. data/test/cases/connection_pool_test.rb +1121 -0
  316. data/test/cases/connection_specification/resolver_test.rb +131 -0
  317. data/test/cases/core_test.rb +294 -0
  318. data/test/cases/counter_cache_test.rb +495 -0
  319. data/test/cases/custom_locking_test.rb +19 -0
  320. data/test/cases/database_configurations/hash_config_test.rb +210 -0
  321. data/test/cases/database_configurations/resolver_test.rb +154 -0
  322. data/test/cases/database_configurations/url_config_test.rb +53 -0
  323. data/test/cases/database_configurations_test.rb +188 -0
  324. data/test/cases/database_selector_test.rb +318 -0
  325. data/test/cases/database_statements_test.rb +32 -0
  326. data/test/cases/date_test.rb +36 -0
  327. data/test/cases/date_time_precision_test.rb +259 -0
  328. data/test/cases/date_time_test.rb +94 -0
  329. data/test/cases/defaults_test.rb +320 -0
  330. data/test/cases/delegated_type_test.rb +117 -0
  331. data/test/cases/dirty_test.rb +1016 -0
  332. data/test/cases/disconnected_test.rb +31 -0
  333. data/test/cases/dup_test.rb +204 -0
  334. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  335. data/test/cases/encryption/cipher_test.rb +65 -0
  336. data/test/cases/encryption/concurrency_test.rb +27 -0
  337. data/test/cases/encryption/config_test.rb +21 -0
  338. data/test/cases/encryption/configurable_test.rb +93 -0
  339. data/test/cases/encryption/contexts_test.rb +105 -0
  340. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  341. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  342. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  343. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  344. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  345. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  346. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  347. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  348. data/test/cases/encryption/encryptor_test.rb +113 -0
  349. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  350. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  351. data/test/cases/encryption/helper.rb +152 -0
  352. data/test/cases/encryption/key_generator_test.rb +55 -0
  353. data/test/cases/encryption/key_provider_test.rb +57 -0
  354. data/test/cases/encryption/key_test.rb +17 -0
  355. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  356. data/test/cases/encryption/message_serializer_test.rb +82 -0
  357. data/test/cases/encryption/message_test.rb +43 -0
  358. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  359. data/test/cases/encryption/properties_test.rb +69 -0
  360. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  361. data/test/cases/encryption/scheme_test.rb +58 -0
  362. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  363. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  364. data/test/cases/enum_test.rb +1125 -0
  365. data/test/cases/errors_test.rb +19 -0
  366. data/test/cases/excluding_test.rb +116 -0
  367. data/test/cases/explain_subscriber_test.rb +71 -0
  368. data/test/cases/explain_test.rb +188 -0
  369. data/test/cases/filter_attributes_test.rb +146 -0
  370. data/test/cases/finder_respond_to_test.rb +60 -0
  371. data/test/cases/finder_test.rb +1961 -0
  372. data/test/cases/fixture_set/file_test.rb +161 -0
  373. data/test/cases/fixtures_test.rb +1881 -0
  374. data/test/cases/forbidden_attributes_protection_test.rb +130 -0
  375. data/test/cases/habtm_destroy_order_test.rb +61 -0
  376. data/test/cases/helper.rb +107 -0
  377. data/test/cases/hot_compatibility_test.rb +143 -0
  378. data/test/cases/i18n_test.rb +46 -0
  379. data/test/cases/inheritance_test.rb +661 -0
  380. data/test/cases/inherited_test.rb +40 -0
  381. data/test/cases/insert_all_test.rb +899 -0
  382. data/test/cases/instrumentation_test.rb +273 -0
  383. data/test/cases/integration_test.rb +261 -0
  384. data/test/cases/invalid_connection_test.rb +26 -0
  385. data/test/cases/invertible_migration_test.rb +611 -0
  386. data/test/cases/json_attribute_test.rb +36 -0
  387. data/test/cases/json_serialization_test.rb +310 -0
  388. data/test/cases/json_shared_test_cases.rb +286 -0
  389. data/test/cases/locking_test.rb +823 -0
  390. data/test/cases/log_subscriber_test.rb +269 -0
  391. data/test/cases/marshal_serialization_test.rb +112 -0
  392. data/test/cases/message_pack_test.rb +91 -0
  393. data/test/cases/migration/change_schema_test.rb +535 -0
  394. data/test/cases/migration/change_table_test.rb +379 -0
  395. data/test/cases/migration/check_constraint_test.rb +344 -0
  396. data/test/cases/migration/column_attributes_test.rb +181 -0
  397. data/test/cases/migration/column_positioning_test.rb +68 -0
  398. data/test/cases/migration/columns_test.rb +440 -0
  399. data/test/cases/migration/command_recorder_test.rb +604 -0
  400. data/test/cases/migration/compatibility_test.rb +1360 -0
  401. data/test/cases/migration/create_join_table_test.rb +174 -0
  402. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  403. data/test/cases/migration/foreign_key_test.rb +923 -0
  404. data/test/cases/migration/helper.rb +43 -0
  405. data/test/cases/migration/index_test.rb +332 -0
  406. data/test/cases/migration/invalid_options_test.rb +129 -0
  407. data/test/cases/migration/logger_test.rb +42 -0
  408. data/test/cases/migration/pending_migrations_test.rb +149 -0
  409. data/test/cases/migration/references_foreign_key_test.rb +304 -0
  410. data/test/cases/migration/references_index_test.rb +118 -0
  411. data/test/cases/migration/references_statements_test.rb +161 -0
  412. data/test/cases/migration/rename_table_test.rb +101 -0
  413. data/test/cases/migration/schema_definitions_test.rb +109 -0
  414. data/test/cases/migration/unique_constraint_test.rb +248 -0
  415. data/test/cases/migration_test.rb +1982 -0
  416. data/test/cases/migrator_test.rb +554 -0
  417. data/test/cases/mixin_test.rb +64 -0
  418. data/test/cases/modules_test.rb +174 -0
  419. data/test/cases/multi_db_migrator_test.rb +244 -0
  420. data/test/cases/multiparameter_attributes_test.rb +396 -0
  421. data/test/cases/multiple_db_test.rb +139 -0
  422. data/test/cases/nested_attributes_test.rb +1237 -0
  423. data/test/cases/nested_attributes_with_callbacks_test.rb +146 -0
  424. data/test/cases/normalized_attribute_test.rb +117 -0
  425. data/test/cases/null_relation_test.rb +117 -0
  426. data/test/cases/numeric_data_test.rb +93 -0
  427. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  428. data/test/cases/persistence_test.rb +1700 -0
  429. data/test/cases/pooled_connections_test.rb +74 -0
  430. data/test/cases/prepared_statement_status_test.rb +53 -0
  431. data/test/cases/primary_class_test.rb +134 -0
  432. data/test/cases/primary_keys_test.rb +598 -0
  433. data/test/cases/query_cache_test.rb +1210 -0
  434. data/test/cases/query_logs_test.rb +293 -0
  435. data/test/cases/quoting_test.rb +270 -0
  436. data/test/cases/readonly_test.rb +158 -0
  437. data/test/cases/reaper_test.rb +215 -0
  438. data/test/cases/reflection_test.rb +718 -0
  439. data/test/cases/relation/and_test.rb +43 -0
  440. data/test/cases/relation/delegation_test.rb +103 -0
  441. data/test/cases/relation/delete_all_test.rb +138 -0
  442. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  443. data/test/cases/relation/load_async_test.rb +650 -0
  444. data/test/cases/relation/merging_test.rb +405 -0
  445. data/test/cases/relation/mutation_test.rb +150 -0
  446. data/test/cases/relation/or_test.rb +195 -0
  447. data/test/cases/relation/order_test.rb +90 -0
  448. data/test/cases/relation/predicate_builder_test.rb +46 -0
  449. data/test/cases/relation/record_fetch_warning_test.rb +42 -0
  450. data/test/cases/relation/select_test.rb +226 -0
  451. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  452. data/test/cases/relation/update_all_test.rb +371 -0
  453. data/test/cases/relation/where_chain_test.rb +328 -0
  454. data/test/cases/relation/where_clause_test.rb +299 -0
  455. data/test/cases/relation/where_test.rb +517 -0
  456. data/test/cases/relation/with_test.rb +165 -0
  457. data/test/cases/relation_test.rb +487 -0
  458. data/test/cases/relations_test.rb +2549 -0
  459. data/test/cases/reload_models_test.rb +30 -0
  460. data/test/cases/reserved_word_test.rb +142 -0
  461. data/test/cases/result_test.rb +133 -0
  462. data/test/cases/sanitize_test.rb +254 -0
  463. data/test/cases/schema_dumper_test.rb +1023 -0
  464. data/test/cases/schema_loading_test.rb +53 -0
  465. data/test/cases/scoping/default_scoping_test.rb +753 -0
  466. data/test/cases/scoping/named_scoping_test.rb +628 -0
  467. data/test/cases/scoping/relation_scoping_test.rb +630 -0
  468. data/test/cases/secure_password_test.rb +108 -0
  469. data/test/cases/secure_token_test.rb +119 -0
  470. data/test/cases/serialization_test.rb +106 -0
  471. data/test/cases/serialized_attribute_test.rb +700 -0
  472. data/test/cases/shard_keys_test.rb +125 -0
  473. data/test/cases/shard_selector_test.rb +45 -0
  474. data/test/cases/signed_id_test.rb +220 -0
  475. data/test/cases/statement_cache_test.rb +154 -0
  476. data/test/cases/statement_invalid_test.rb +46 -0
  477. data/test/cases/store_test.rb +384 -0
  478. data/test/cases/strict_loading_test.rb +787 -0
  479. data/test/cases/suppressor_test.rb +77 -0
  480. data/test/cases/table_metadata_test.rb +16 -0
  481. data/test/cases/tasks/database_tasks_test.rb +1799 -0
  482. data/test/cases/tasks/mysql_rake_test.rb +417 -0
  483. data/test/cases/tasks/postgresql_rake_test.rb +534 -0
  484. data/test/cases/tasks/sqlite_rake_test.rb +267 -0
  485. data/test/cases/test_case.rb +336 -0
  486. data/test/cases/test_case_test.rb +69 -0
  487. data/test/cases/test_databases_test.rb +83 -0
  488. data/test/cases/test_fixtures_test.rb +75 -0
  489. data/test/cases/time_precision_test.rb +137 -0
  490. data/test/cases/timestamp_test.rb +612 -0
  491. data/test/cases/token_for_test.rb +165 -0
  492. data/test/cases/touch_later_test.rb +165 -0
  493. data/test/cases/transaction_callbacks_test.rb +1089 -0
  494. data/test/cases/transaction_instrumentation_test.rb +453 -0
  495. data/test/cases/transaction_isolation_test.rb +110 -0
  496. data/test/cases/transactions_test.rb +1802 -0
  497. data/test/cases/type/adapter_specific_registry_test.rb +145 -0
  498. data/test/cases/type/date_time_test.rb +22 -0
  499. data/test/cases/type/integer_test.rb +29 -0
  500. data/test/cases/type/string_test.rb +24 -0
  501. data/test/cases/type/time_test.rb +37 -0
  502. data/test/cases/type/type_map_test.rb +213 -0
  503. data/test/cases/type/unsigned_integer_test.rb +31 -0
  504. data/test/cases/type_caster/connection_test.rb +19 -0
  505. data/test/cases/type_test.rb +41 -0
  506. data/test/cases/types_test.rb +26 -0
  507. data/test/cases/unconnected_test.rb +46 -0
  508. data/test/cases/unsafe_raw_sql_test.rb +305 -0
  509. data/test/cases/validations/absence_validation_test.rb +75 -0
  510. data/test/cases/validations/association_validation_test.rb +121 -0
  511. data/test/cases/validations/i18n_generate_message_validation_test.rb +102 -0
  512. data/test/cases/validations/i18n_validation_test.rb +87 -0
  513. data/test/cases/validations/length_validation_test.rb +80 -0
  514. data/test/cases/validations/numericality_validation_test.rb +175 -0
  515. data/test/cases/validations/presence_validation_test.rb +105 -0
  516. data/test/cases/validations/uniqueness_validation_test.rb +858 -0
  517. data/test/cases/validations_repair_helper.rb +21 -0
  518. data/test/cases/validations_test.rb +229 -0
  519. data/test/cases/view_test.rb +233 -0
  520. data/test/cases/yaml_serialization_test.rb +172 -0
  521. data/test/config.example.yml +99 -0
  522. data/test/config.rb +8 -0
  523. data/test/config.yml +220 -0
  524. data/test/connections/native_ibm_db/connection.rb +44 -0
  525. data/test/fixtures/1_need_quoting.yml +2 -0
  526. data/test/fixtures/accounts.yml +34 -0
  527. data/test/fixtures/admin/accounts.yml +2 -0
  528. data/test/fixtures/admin/randomly_named_a9.yml +7 -0
  529. data/test/fixtures/admin/randomly_named_b0.yml +7 -0
  530. data/test/fixtures/admin/users.yml +10 -0
  531. data/test/fixtures/aircrafts.yml +7 -0
  532. data/test/fixtures/all/admin +1 -0
  533. data/test/fixtures/all/developers.yml +0 -0
  534. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  535. data/test/fixtures/all/people.yml +0 -0
  536. data/test/fixtures/all/tasks.yml +0 -0
  537. data/test/fixtures/author_addresses.yml +11 -0
  538. data/test/fixtures/author_favorites.yml +4 -0
  539. data/test/fixtures/authors.yml +17 -0
  540. data/test/fixtures/bad_posts.yml +9 -0
  541. data/test/fixtures/binaries.yml +137 -0
  542. data/test/fixtures/book_identifiers.yml +11 -0
  543. data/test/fixtures/books.yml +39 -0
  544. data/test/fixtures/bulbs.yml +5 -0
  545. data/test/fixtures/cake_designers.yml +5 -0
  546. data/test/fixtures/cars.yml +15 -0
  547. data/test/fixtures/categories/special_categories.yml +9 -0
  548. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  549. data/test/fixtures/categories.yml +19 -0
  550. data/test/fixtures/categories_ordered.yml +7 -0
  551. data/test/fixtures/categories_posts.yml +34 -0
  552. data/test/fixtures/categorizations.yml +23 -0
  553. data/test/fixtures/chefs.yml +5 -0
  554. data/test/fixtures/citations.yml +5 -0
  555. data/test/fixtures/clothing_items.yml +23 -0
  556. data/test/fixtures/clubs.yml +8 -0
  557. data/test/fixtures/collections.yml +3 -0
  558. data/test/fixtures/colleges.yml +3 -0
  559. data/test/fixtures/comments.yml +73 -0
  560. data/test/fixtures/companies.yml +72 -0
  561. data/test/fixtures/computers.yml +12 -0
  562. data/test/fixtures/content.yml +3 -0
  563. data/test/fixtures/content_positions.yml +3 -0
  564. data/test/fixtures/courses.yml +8 -0
  565. data/test/fixtures/cpk_authors.yml +8 -0
  566. data/test/fixtures/cpk_books.yml +21 -0
  567. data/test/fixtures/cpk_order_agreements.yml +13 -0
  568. data/test/fixtures/cpk_order_tags.yml +15 -0
  569. data/test/fixtures/cpk_orders.yml +11 -0
  570. data/test/fixtures/cpk_posts.yml +12 -0
  571. data/test/fixtures/cpk_reviews.yml +13 -0
  572. data/test/fixtures/cpk_tags.yml +11 -0
  573. data/test/fixtures/customers.yml +35 -0
  574. data/test/fixtures/dashboards.yml +6 -0
  575. data/test/fixtures/dead_parrots.yml +5 -0
  576. data/test/fixtures/developers.yml +22 -0
  577. data/test/fixtures/developers_projects.yml +17 -0
  578. data/test/fixtures/dog_lovers.yml +7 -0
  579. data/test/fixtures/dogs.yml +4 -0
  580. data/test/fixtures/doubloons.yml +3 -0
  581. data/test/fixtures/drink_designers.yml +5 -0
  582. data/test/fixtures/edges.yml +5 -0
  583. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  584. data/test/fixtures/encrypted_books.yml +4 -0
  585. data/test/fixtures/entrants.yml +14 -0
  586. data/test/fixtures/essays.yml +16 -0
  587. data/test/fixtures/faces.yml +11 -0
  588. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  589. data/test/fixtures/fk_test_has_fk.yml +3 -0
  590. data/test/fixtures/fk_test_has_pk.yml +2 -0
  591. data/test/fixtures/friendships.yml +4 -0
  592. data/test/fixtures/funny_jokes.yml +10 -0
  593. data/test/fixtures/humans.yml +5 -0
  594. data/test/fixtures/interests.yml +33 -0
  595. data/test/fixtures/items.yml +3 -0
  596. data/test/fixtures/jobs.yml +7 -0
  597. data/test/fixtures/legacy_things.yml +3 -0
  598. data/test/fixtures/live_parrots.yml +4 -0
  599. data/test/fixtures/mateys.yml +4 -0
  600. data/test/fixtures/member_details.yml +8 -0
  601. data/test/fixtures/member_types.yml +6 -0
  602. data/test/fixtures/members.yml +11 -0
  603. data/test/fixtures/memberships.yml +41 -0
  604. data/test/fixtures/men.yml +5 -0
  605. data/test/fixtures/minimalistics.yml +5 -0
  606. data/test/fixtures/minivans.yml +5 -0
  607. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  608. data/test/fixtures/mixins.yml +29 -0
  609. data/test/fixtures/movies.yml +7 -0
  610. data/test/fixtures/naked/yml/accounts.yml +1 -0
  611. data/test/fixtures/naked/yml/companies.yml +1 -0
  612. data/test/fixtures/naked/yml/courses.yml +1 -0
  613. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  614. data/test/fixtures/naked/yml/parrots.yml +3 -0
  615. data/test/fixtures/naked/yml/trees.yml +3 -0
  616. data/test/fixtures/nodes.yml +29 -0
  617. data/test/fixtures/organizations.yml +5 -0
  618. data/test/fixtures/other_books.yml +26 -0
  619. data/test/fixtures/other_comments.yml +6 -0
  620. data/test/fixtures/other_dogs.yml +2 -0
  621. data/test/fixtures/other_posts.yml +8 -0
  622. data/test/fixtures/other_topics.yml +42 -0
  623. data/test/fixtures/owners.yml +9 -0
  624. data/test/fixtures/paragraphs.yml +5 -0
  625. data/test/fixtures/parrots.yml +37 -0
  626. data/test/fixtures/parrots_pirates.yml +7 -0
  627. data/test/fixtures/people.yml +26 -0
  628. data/test/fixtures/peoples_treasures.yml +3 -0
  629. data/test/fixtures/pets.yml +19 -0
  630. data/test/fixtures/pirates.yml +15 -0
  631. data/test/fixtures/posts.yml +88 -0
  632. data/test/fixtures/price_estimates.yml +16 -0
  633. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  634. data/test/fixtures/products.yml +4 -0
  635. data/test/fixtures/projects.yml +7 -0
  636. data/test/fixtures/randomly_named_a9.yml +7 -0
  637. data/test/fixtures/ratings.yml +14 -0
  638. data/test/fixtures/readers.yml +17 -0
  639. data/test/fixtures/references.yml +17 -0
  640. data/test/fixtures/reserved_words/distinct.yml +5 -0
  641. data/test/fixtures/reserved_words/distinct_select.yml +11 -0
  642. data/test/fixtures/reserved_words/group.yml +14 -0
  643. data/test/fixtures/reserved_words/select.yml +8 -0
  644. data/test/fixtures/reserved_words/values.yml +7 -0
  645. data/test/fixtures/sharded_blog_posts.yml +14 -0
  646. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  647. data/test/fixtures/sharded_blogs.yml +8 -0
  648. data/test/fixtures/sharded_comments.yml +22 -0
  649. data/test/fixtures/sharded_tags.yml +34 -0
  650. data/test/fixtures/ships.yml +6 -0
  651. data/test/fixtures/speedometers.yml +8 -0
  652. data/test/fixtures/sponsors.yml +15 -0
  653. data/test/fixtures/strict_zines.yml +2 -0
  654. data/test/fixtures/string_key_objects.yml +7 -0
  655. data/test/fixtures/subscribers.yml +11 -0
  656. data/test/fixtures/subscriptions.yml +12 -0
  657. data/test/fixtures/taggings.yml +78 -0
  658. data/test/fixtures/tags.yml +11 -0
  659. data/test/fixtures/tasks.yml +7 -0
  660. data/test/fixtures/teapots.yml +3 -0
  661. data/test/fixtures/to_be_linked/accounts.yml +2 -0
  662. data/test/fixtures/to_be_linked/users.yml +10 -0
  663. data/test/fixtures/topics.yml +50 -0
  664. data/test/fixtures/toys.yml +14 -0
  665. data/test/fixtures/traffic_lights.yml +10 -0
  666. data/test/fixtures/treasures.yml +14 -0
  667. data/test/fixtures/trees.yml +3 -0
  668. data/test/fixtures/uuid_children.yml +3 -0
  669. data/test/fixtures/uuid_parents.yml +2 -0
  670. data/test/fixtures/variants.yml +4 -0
  671. data/test/fixtures/vegetables.yml +20 -0
  672. data/test/fixtures/vertices.yml +4 -0
  673. data/test/fixtures/virtual_columns.yml +5 -0
  674. data/test/fixtures/warehouse-things.yml +3 -0
  675. data/test/fixtures/warehouse_things.yml +3 -0
  676. data/test/fixtures/zines.yml +5 -0
  677. data/test/ibm_db_test.rb +25 -0
  678. data/test/migrations/10_urban/9_add_expressions.rb +13 -0
  679. data/test/migrations/decimal/1_give_me_big_numbers.rb +17 -0
  680. data/test/migrations/magic/1_currencies_have_symbols.rb +13 -0
  681. data/test/migrations/missing/1000_people_have_middle_names.rb +11 -0
  682. data/test/migrations/missing/1_people_have_last_names.rb +11 -0
  683. data/test/migrations/missing/3_we_need_reminders.rb +14 -0
  684. data/test/migrations/missing/4_innocent_jointable.rb +14 -0
  685. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  686. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  687. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  688. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  689. data/test/migrations/rename/1_we_need_things.rb +13 -0
  690. data/test/migrations/rename/2_rename_things.rb +11 -0
  691. data/test/migrations/scope/1_unscoped.rb +7 -0
  692. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  693. data/test/migrations/to_copy/1_people_have_hobbies.rb +11 -0
  694. data/test/migrations/to_copy/2_people_have_descriptions.rb +11 -0
  695. data/test/migrations/to_copy2/1_create_articles.rb +9 -0
  696. data/test/migrations/to_copy2/2_create_comments.rb +9 -0
  697. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +11 -0
  698. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +11 -0
  699. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +11 -0
  700. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +9 -0
  701. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +9 -0
  702. data/test/migrations/valid/1_valid_people_have_last_names.rb +11 -0
  703. data/test/migrations/valid/2_we_need_reminders.rb +14 -0
  704. data/test/migrations/valid/3_innocent_jointable.rb +14 -0
  705. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +11 -0
  706. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +14 -0
  707. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +14 -0
  708. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +11 -0
  709. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +14 -0
  710. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +14 -0
  711. data/test/migrations/version_check/20131219224947_migration_version_check.rb +10 -0
  712. data/test/models/account.rb +46 -0
  713. data/test/models/admin/account.rb +5 -0
  714. data/test/models/admin/randomly_named_c1.rb +9 -0
  715. data/test/models/admin/user.rb +50 -0
  716. data/test/models/admin/user_json.rb +48 -0
  717. data/test/models/admin.rb +7 -0
  718. data/test/models/aircraft.rb +7 -0
  719. data/test/models/arunit2_model.rb +5 -0
  720. data/test/models/attachment.rb +7 -0
  721. data/test/models/author.rb +327 -0
  722. data/test/models/author_encrypted.rb +16 -0
  723. data/test/models/auto_id.rb +6 -0
  724. data/test/models/autoloadable/extra_firm.rb +4 -0
  725. data/test/models/binary.rb +4 -0
  726. data/test/models/binary_field.rb +6 -0
  727. data/test/models/bird.rb +24 -0
  728. data/test/models/book.rb +40 -0
  729. data/test/models/book_destroy_async.rb +24 -0
  730. data/test/models/book_encrypted.rb +106 -0
  731. data/test/models/book_identifier.rb +5 -0
  732. data/test/models/boolean.rb +7 -0
  733. data/test/models/branch.rb +11 -0
  734. data/test/models/bulb.rb +61 -0
  735. data/test/models/cake_designer.rb +5 -0
  736. data/test/models/car.rb +43 -0
  737. data/test/models/carrier.rb +4 -0
  738. data/test/models/cart.rb +5 -0
  739. data/test/models/cat.rb +12 -0
  740. data/test/models/categorization.rb +21 -0
  741. data/test/models/category.rb +49 -0
  742. data/test/models/chat_message.rb +8 -0
  743. data/test/models/chef.rb +62 -0
  744. data/test/models/citation.rb +7 -0
  745. data/test/models/clothing_item.rb +12 -0
  746. data/test/models/club.rb +31 -0
  747. data/test/models/college.rb +12 -0
  748. data/test/models/column.rb +5 -0
  749. data/test/models/column_name.rb +5 -0
  750. data/test/models/comment.rb +101 -0
  751. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  752. data/test/models/company.rb +240 -0
  753. data/test/models/company_in_module.rb +99 -0
  754. data/test/models/computer.rb +6 -0
  755. data/test/models/contact.rb +43 -0
  756. data/test/models/content.rb +42 -0
  757. data/test/models/contract.rb +42 -0
  758. data/test/models/country.rb +5 -0
  759. data/test/models/course.rb +8 -0
  760. data/test/models/cpk/author.rb +9 -0
  761. data/test/models/cpk/book.rb +55 -0
  762. data/test/models/cpk/book_destroy_async.rb +9 -0
  763. data/test/models/cpk/car.rb +9 -0
  764. data/test/models/cpk/car_review.rb +9 -0
  765. data/test/models/cpk/chapter.rb +16 -0
  766. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  767. data/test/models/cpk/comment.rb +9 -0
  768. data/test/models/cpk/order.rb +55 -0
  769. data/test/models/cpk/order_agreement.rb +10 -0
  770. data/test/models/cpk/order_tag.rb +10 -0
  771. data/test/models/cpk/post.rb +10 -0
  772. data/test/models/cpk/posts_tag.rb +10 -0
  773. data/test/models/cpk/review.rb +9 -0
  774. data/test/models/cpk/tag.rb +10 -0
  775. data/test/models/cpk.rb +15 -0
  776. data/test/models/customer.rb +87 -0
  777. data/test/models/customer_carrier.rb +16 -0
  778. data/test/models/dashboard.rb +5 -0
  779. data/test/models/default.rb +4 -0
  780. data/test/models/department.rb +6 -0
  781. data/test/models/destroy_async_parent.rb +15 -0
  782. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  783. data/test/models/developer.rb +382 -0
  784. data/test/models/discount.rb +4 -0
  785. data/test/models/dl_keyed_belongs_to.rb +13 -0
  786. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  787. data/test/models/dl_keyed_has_many.rb +5 -0
  788. data/test/models/dl_keyed_has_many_through.rb +5 -0
  789. data/test/models/dl_keyed_has_one.rb +5 -0
  790. data/test/models/dl_keyed_join.rb +10 -0
  791. data/test/models/dog.rb +7 -0
  792. data/test/models/dog_lover.rb +7 -0
  793. data/test/models/doubloon.rb +14 -0
  794. data/test/models/drink_designer.rb +21 -0
  795. data/test/models/edge.rb +7 -0
  796. data/test/models/editor.rb +8 -0
  797. data/test/models/editorship.rb +6 -0
  798. data/test/models/electron.rb +7 -0
  799. data/test/models/engine.rb +5 -0
  800. data/test/models/entrant.rb +5 -0
  801. data/test/models/entry.rb +10 -0
  802. data/test/models/essay.rb +13 -0
  803. data/test/models/essay_destroy_async.rb +13 -0
  804. data/test/models/event.rb +5 -0
  805. data/test/models/eye.rb +105 -0
  806. data/test/models/face.rb +17 -0
  807. data/test/models/family.rb +6 -0
  808. data/test/models/family_tree.rb +6 -0
  809. data/test/models/friendship.rb +11 -0
  810. data/test/models/frog.rb +8 -0
  811. data/test/models/guid.rb +4 -0
  812. data/test/models/guitar.rb +6 -0
  813. data/test/models/hardback.rb +7 -0
  814. data/test/models/hotel.rb +15 -0
  815. data/test/models/human.rb +39 -0
  816. data/test/models/image.rb +5 -0
  817. data/test/models/interest.rb +16 -0
  818. data/test/models/invoice.rb +7 -0
  819. data/test/models/invokes_an_undefined_method.rb +5 -0
  820. data/test/models/item.rb +9 -0
  821. data/test/models/job.rb +9 -0
  822. data/test/models/joke.rb +9 -0
  823. data/test/models/keyboard.rb +5 -0
  824. data/test/models/legacy_thing.rb +5 -0
  825. data/test/models/lesson.rb +13 -0
  826. data/test/models/line_item.rb +11 -0
  827. data/test/models/liquid.rb +6 -0
  828. data/test/models/man.rb +11 -0
  829. data/test/models/matey.rb +6 -0
  830. data/test/models/measurement.rb +4 -0
  831. data/test/models/member.rb +50 -0
  832. data/test/models/member_detail.rb +11 -0
  833. data/test/models/member_type.rb +5 -0
  834. data/test/models/membership.rb +38 -0
  835. data/test/models/mentor.rb +5 -0
  836. data/test/models/message.rb +6 -0
  837. data/test/models/minimalistic.rb +4 -0
  838. data/test/models/minivan.rb +10 -0
  839. data/test/models/mixed_case_monkey.rb +5 -0
  840. data/test/models/mocktail_designer.rb +2 -0
  841. data/test/models/molecule.rb +8 -0
  842. data/test/models/mouse.rb +6 -0
  843. data/test/models/movie.rb +7 -0
  844. data/test/models/need_quoting.rb +5 -0
  845. data/test/models/node.rb +7 -0
  846. data/test/models/non_primary_key.rb +4 -0
  847. data/test/models/notification.rb +5 -0
  848. data/test/models/numeric_data.rb +12 -0
  849. data/test/models/order.rb +6 -0
  850. data/test/models/organization.rb +16 -0
  851. data/test/models/other_dog.rb +7 -0
  852. data/test/models/owner.rb +39 -0
  853. data/test/models/paragraph.rb +5 -0
  854. data/test/models/parrot.rb +39 -0
  855. data/test/models/person.rb +150 -0
  856. data/test/models/personal_legacy_thing.rb +6 -0
  857. data/test/models/pet.rb +20 -0
  858. data/test/models/pet_treasure.rb +8 -0
  859. data/test/models/pirate.rb +119 -0
  860. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  861. data/test/models/possession.rb +5 -0
  862. data/test/models/post.rb +434 -0
  863. data/test/models/post_encrypted.rb +15 -0
  864. data/test/models/post_with_prefetched_pk.rb +15 -0
  865. data/test/models/price_estimate.rb +14 -0
  866. data/test/models/professor.rb +7 -0
  867. data/test/models/project.rb +43 -0
  868. data/test/models/publication.rb +16 -0
  869. data/test/models/publisher/article.rb +6 -0
  870. data/test/models/publisher/magazine.rb +5 -0
  871. data/test/models/publisher.rb +4 -0
  872. data/test/models/raises_argument_error.rb +5 -0
  873. data/test/models/raises_no_method_error.rb +5 -0
  874. data/test/models/randomly_named_c1.rb +5 -0
  875. data/test/models/rating.rb +8 -0
  876. data/test/models/reader.rb +25 -0
  877. data/test/models/recipe.rb +5 -0
  878. data/test/models/recipient.rb +5 -0
  879. data/test/models/record.rb +4 -0
  880. data/test/models/reference.rb +25 -0
  881. data/test/models/reply.rb +79 -0
  882. data/test/models/room.rb +9 -0
  883. data/test/models/section.rb +6 -0
  884. data/test/models/seminar.rb +6 -0
  885. data/test/models/session.rb +6 -0
  886. data/test/models/sharded/blog.rb +12 -0
  887. data/test/models/sharded/blog_post.rb +17 -0
  888. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  889. data/test/models/sharded/blog_post_tag.rb +11 -0
  890. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  891. data/test/models/sharded/comment.rb +12 -0
  892. data/test/models/sharded/comment_destroy_async.rb +12 -0
  893. data/test/models/sharded/tag.rb +11 -0
  894. data/test/models/sharded.rb +8 -0
  895. data/test/models/ship.rb +42 -0
  896. data/test/models/ship_part.rb +10 -0
  897. data/test/models/shipping_line.rb +11 -0
  898. data/test/models/shop.rb +19 -0
  899. data/test/models/shop_account.rb +8 -0
  900. data/test/models/speedometer.rb +8 -0
  901. data/test/models/sponsor.rb +10 -0
  902. data/test/models/squeak.rb +6 -0
  903. data/test/models/strict_zine.rb +7 -0
  904. data/test/models/string_key_object.rb +5 -0
  905. data/test/models/student.rb +6 -0
  906. data/test/models/subject.rb +16 -0
  907. data/test/models/subscriber.rb +11 -0
  908. data/test/models/subscription.rb +10 -0
  909. data/test/models/tag.rb +16 -0
  910. data/test/models/tagging.rb +20 -0
  911. data/test/models/task.rb +7 -0
  912. data/test/models/too_long_table_name.rb +5 -0
  913. data/test/models/topic.rb +155 -0
  914. data/test/models/toy.rb +10 -0
  915. data/test/models/traffic_light.rb +6 -0
  916. data/test/models/traffic_light_encrypted.rb +21 -0
  917. data/test/models/translation.rb +9 -0
  918. data/test/models/treasure.rb +16 -0
  919. data/test/models/treaty.rb +5 -0
  920. data/test/models/tree.rb +5 -0
  921. data/test/models/tuning_peg.rb +6 -0
  922. data/test/models/tyre.rb +13 -0
  923. data/test/models/user.rb +38 -0
  924. data/test/models/user_with_invalid_relation.rb +28 -0
  925. data/test/models/uuid_child.rb +5 -0
  926. data/test/models/uuid_comment.rb +5 -0
  927. data/test/models/uuid_entry.rb +5 -0
  928. data/test/models/uuid_item.rb +8 -0
  929. data/test/models/uuid_message.rb +5 -0
  930. data/test/models/uuid_parent.rb +5 -0
  931. data/test/models/vegetables.rb +33 -0
  932. data/test/models/vehicle.rb +7 -0
  933. data/test/models/vertex.rb +11 -0
  934. data/test/models/warehouse_thing.rb +7 -0
  935. data/test/models/wheel.rb +5 -0
  936. data/test/models/without_table.rb +5 -0
  937. data/test/models/zine.rb +6 -0
  938. data/test/schema/i5/ibm_db_specific_schema.rb +137 -0
  939. data/test/schema/ids/ibm_db_specific_schema.rb +140 -0
  940. data/test/schema/luw/ibm_db_specific_schema.rb +137 -0
  941. data/test/schema/mysql2_specific_schema.rb +96 -0
  942. data/test/schema/oracle_specific_schema.rb +38 -0
  943. data/test/schema/postgresql_specific_schema.rb +233 -0
  944. data/test/schema/schema.rb +1495 -0
  945. data/test/schema/schema.rb.original +1057 -0
  946. data/test/schema/sqlite_specific_schema.rb +22 -0
  947. data/test/schema/trilogy_specific_schema.rb +96 -0
  948. data/test/schema/zOS/ibm_db_specific_schema.rb +208 -0
  949. data/test/support/adapter_helper.rb +104 -0
  950. data/test/support/async_helper.rb +15 -0
  951. data/test/support/config.rb +43 -0
  952. data/test/support/connection.rb +41 -0
  953. data/test/support/connection_helper.rb +16 -0
  954. data/test/support/ddl_helper.rb +10 -0
  955. data/test/support/fake_adapter.rb +42 -0
  956. data/test/support/load_schema_helper.rb +22 -0
  957. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  958. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  959. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  960. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  961. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  962. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  963. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  964. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  965. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  966. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  967. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  968. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  969. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  970. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  971. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  972. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  973. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  974. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  975. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  976. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  977. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  978. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  979. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  980. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  981. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  982. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  983. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  984. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  985. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  986. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  987. data/test/support/schema_dumping_helper.rb +28 -0
  988. data/test/support/stubs/strong_parameters.rb +40 -0
  989. data/test/support/tools.rb +37 -0
  990. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  991. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  992. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  993. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  994. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  995. metadata +1129 -0
@@ -0,0 +1,899 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/author"
5
+ require "models/book"
6
+ require "models/category"
7
+ require "models/cart"
8
+ require "models/developer"
9
+ require "models/ship"
10
+ require "models/speedometer"
11
+ require "models/subscription"
12
+ require "models/subscriber"
13
+
14
+ class ReadonlyNameBook < Book
15
+ attr_readonly :name
16
+ end
17
+
18
+ class InsertAllTest < ActiveRecord::TestCase
19
+ fixtures :books
20
+
21
+ def setup
22
+ Arel::Table.engine = nil # should not rely on the global Arel::Table.engine
23
+ @original_db_warnings_action = :ignore
24
+ end
25
+
26
+ def teardown
27
+ Arel::Table.engine = ActiveRecord::Base
28
+ end
29
+
30
+ def test_insert
31
+ skip unless supports_insert_on_duplicate_skip?
32
+
33
+ id = 1_000_000
34
+
35
+ assert_difference "Book.count", +1 do
36
+ Book.insert({ id: id, name: "Rework", author_id: 1 })
37
+ end
38
+
39
+ Book.upsert({ id: id, name: "Remote", author_id: 1 })
40
+
41
+ assert_equal "Remote", Book.find(id).name
42
+ end
43
+
44
+ def test_insert!
45
+ assert_difference "Book.count", +1 do
46
+ Book.insert!({ name: "Rework", author_id: 1 })
47
+ end
48
+ end
49
+
50
+ def test_insert_with_type_casting_and_serialize_is_consistent
51
+ skip unless supports_insert_returning?
52
+
53
+ book_name = ["Array"]
54
+ created_book_id = Book.create!(name: book_name).id
55
+ inserted_book_id = Book.insert!({ name: book_name }, returning: :id).first["id"]
56
+ created_book = Book.find_by!(id: created_book_id)
57
+ inserted_book = Book.find_by!(id: inserted_book_id)
58
+ assert_equal created_book.name, inserted_book.name
59
+ end
60
+
61
+ def test_insert_all
62
+ assert_difference "Book.count", +10 do
63
+ Book.insert_all! [
64
+ { name: "Rework", author_id: 1 },
65
+ { name: "Patterns of Enterprise Application Architecture", author_id: 1 },
66
+ { name: "Design of Everyday Things", author_id: 1 },
67
+ { name: "Practical Object-Oriented Design in Ruby", author_id: 1 },
68
+ { name: "Clean Code", author_id: 1 },
69
+ { name: "Ruby Under a Microscope", author_id: 1 },
70
+ { name: "The Principles of Product Development Flow", author_id: 1 },
71
+ { name: "Peopleware", author_id: 1 },
72
+ { name: "About Face", author_id: 1 },
73
+ { name: "Eloquent Ruby", author_id: 1 },
74
+ ]
75
+ end
76
+ end
77
+
78
+ def test_insert_all_should_handle_empty_arrays
79
+ skip unless supports_insert_on_duplicate_update?
80
+
81
+ assert_empty Book.insert_all([])
82
+ assert_empty Book.insert_all!([])
83
+ assert_empty Book.upsert_all([])
84
+ end
85
+
86
+ def test_insert_all_raises_on_duplicate_records
87
+ assert_raise ActiveRecord::RecordNotUnique do
88
+ Book.insert_all! [
89
+ { name: "Rework", author_id: 1 },
90
+ { name: "Patterns of Enterprise Application Architecture", author_id: 1 },
91
+ { name: "Agile Web Development with Rails", author_id: 1 },
92
+ ]
93
+ end
94
+ end
95
+
96
+ def test_insert_all_returns_ActiveRecord_Result
97
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }]
98
+ assert_kind_of ActiveRecord::Result, result
99
+ end
100
+
101
+ def test_insert_all_returns_primary_key_if_returning_is_supported
102
+ skip unless supports_insert_returning?
103
+
104
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }]
105
+ assert_equal %w[ id ], result.columns
106
+ end
107
+
108
+ def test_insert_all_returns_nothing_if_returning_is_empty
109
+ skip unless supports_insert_returning?
110
+
111
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: []
112
+ assert_equal [], result.columns
113
+ end
114
+
115
+ def test_insert_all_returns_nothing_if_returning_is_false
116
+ skip unless supports_insert_returning?
117
+
118
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: false
119
+ assert_equal [], result.columns
120
+ end
121
+
122
+ def test_insert_all_returns_requested_fields
123
+ skip unless supports_insert_returning?
124
+
125
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: [:id, :name]
126
+ assert_equal %w[ Rework ], result.pluck("name")
127
+ end
128
+
129
+ def test_insert_all_returns_requested_sql_fields
130
+ skip unless supports_insert_returning?
131
+
132
+ result = Book.insert_all! [{ name: "Rework", author_id: 1 }], returning: Arel.sql("UPPER(name) as name")
133
+ assert_equal %w[ REWORK ], result.pluck("name")
134
+ end
135
+
136
+ def test_insert_all_can_skip_duplicate_records
137
+ skip unless supports_insert_on_duplicate_skip?
138
+
139
+ assert_no_difference "Book.count" do
140
+ Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }]
141
+ end
142
+ end
143
+
144
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
145
+ def test_insert_all_generates_correct_sql
146
+ skip unless supports_insert_on_duplicate_skip?
147
+
148
+ assert_queries_match(/ON DUPLICATE KEY UPDATE/) do
149
+ Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }]
150
+ end
151
+ end
152
+
153
+ def test_insert_all_succeeds_when_passed_no_attributes
154
+ skip unless supports_insert_on_duplicate_skip?
155
+
156
+ assert_nothing_raised do
157
+ Book.insert_all [{}]
158
+ end
159
+ end
160
+ end
161
+
162
+ def test_insert_all_with_skip_duplicates_and_autonumber_id_not_given
163
+ skip unless supports_insert_on_duplicate_skip?
164
+
165
+ assert_difference "Book.count", 1 do
166
+ # These two books are duplicates according to an index on %i[author_id name]
167
+ # but their IDs are not specified so they will be assigned different IDs
168
+ # by autonumber. We will get an exception from MySQL if we attempt to skip
169
+ # one of these records by assigning its ID.
170
+ Book.insert_all [
171
+ { author_id: 8, name: "Refactoring" },
172
+ { author_id: 8, name: "Refactoring" }
173
+ ]
174
+ end
175
+ end
176
+
177
+ def test_insert_all_with_skip_duplicates_and_autonumber_id_given
178
+ skip unless supports_insert_on_duplicate_skip?
179
+
180
+ assert_difference "Book.count", 1 do
181
+ Book.insert_all [
182
+ { id: 200, author_id: 8, name: "Refactoring" },
183
+ { id: 201, author_id: 8, name: "Refactoring" }
184
+ ]
185
+ end
186
+ end
187
+
188
+ def test_skip_duplicates_strategy_does_not_secretly_upsert
189
+ skip unless supports_insert_on_duplicate_skip?
190
+
191
+ book = Book.create!(format: "EXPECTED", author_id: 8, name: "Refactoring")
192
+
193
+ assert_no_difference "Book.count" do
194
+ Book.insert_all([{ format: "UNEXPECTED", author_id: 8, name: "Refactoring" }])
195
+ end
196
+
197
+ assert_equal "EXPECTED", book.reload.format
198
+ end
199
+
200
+ def test_insert_all_will_raise_if_duplicates_are_skipped_only_for_a_certain_conflict_target
201
+ skip unless supports_insert_on_duplicate_skip? && supports_insert_conflict_target?
202
+
203
+ assert_raise ActiveRecord::RecordNotUnique do
204
+ Book.insert_all [{ id: 1, name: "Agile Web Development with Rails" }],
205
+ unique_by: :index_books_on_author_id_and_name
206
+ end
207
+ end
208
+
209
+ def test_insert_all_and_upsert_all_with_index_finding_options
210
+ skip unless supports_insert_conflict_target?
211
+
212
+ assert_difference "Book.count", +4 do
213
+ Book.insert_all [{ name: "Rework", author_id: 1 }], unique_by: :isbn
214
+ Book.insert_all [{ name: "Remote", author_id: 1 }], unique_by: %i( author_id name )
215
+ Book.insert_all [{ name: "Renote", author_id: 1 }], unique_by: :index_books_on_isbn
216
+ Book.insert_all [{ name: "Recoat", author_id: 1 }], unique_by: :id
217
+ end
218
+
219
+ assert_raise ActiveRecord::RecordNotUnique do
220
+ Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: :isbn
221
+ end
222
+ end
223
+
224
+ def test_insert_all_and_upsert_all_with_expression_index
225
+ skip unless supports_expression_index? && supports_insert_conflict_target?
226
+
227
+ book = Book.create!(external_id: "abc")
228
+
229
+ assert_no_difference "Book.count" do
230
+ Book.insert_all [{ external_id: "ABC" }], unique_by: :index_books_on_lower_external_id
231
+ end
232
+
233
+ Book.upsert_all [{ external_id: "Abc" }], unique_by: :index_books_on_lower_external_id
234
+
235
+ assert_equal "Abc", book.reload.external_id
236
+ end
237
+
238
+ def test_insert_all_and_upsert_all_raises_when_index_is_missing
239
+ skip unless supports_insert_conflict_target?
240
+
241
+ [ :cats, %i( author_id isbn ), :author_id ].each do |missing_or_non_unique_by|
242
+ error = assert_raises ArgumentError do
243
+ Book.insert_all [{ name: "Rework", author_id: 1 }], unique_by: missing_or_non_unique_by
244
+ end
245
+ assert_match "No unique index", error.message
246
+
247
+ error = assert_raises ArgumentError do
248
+ Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: missing_or_non_unique_by
249
+ end
250
+ assert_match "No unique index", error.message
251
+ end
252
+ end
253
+
254
+ def test_insert_all_and_upsert_all_finds_index_with_inverted_unique_by_columns
255
+ skip unless supports_insert_conflict_target?
256
+
257
+ columns = [:author_id, :name]
258
+ assert ActiveRecord::Base.lease_connection.index_exists?(:books, columns)
259
+
260
+ assert_difference "Book.count", +2 do
261
+ Book.insert_all [{ name: "Remote", author_id: 1 }], unique_by: columns.reverse
262
+ Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: columns.reverse
263
+ end
264
+ end
265
+
266
+ def test_insert_all_and_upsert_all_works_with_composite_primary_keys_when_unique_by_is_provided
267
+ skip unless supports_insert_conflict_target?
268
+
269
+ assert_difference "Cart.count", 2 do
270
+ Cart.insert_all [{ id: 1, shop_id: 1, title: "My cart" }], unique_by: [:shop_id, :id]
271
+
272
+ Cart.upsert_all [{ id: 3, shop_id: 2, title: "My other cart" }], unique_by: [:shop_id, :id]
273
+ end
274
+ end
275
+
276
+ def test_insert_all_bang_does_not_require_unique_index
277
+ skip unless supports_insert_conflict_target?
278
+
279
+ assert_difference "Cart.count", +1 do
280
+ Cart.insert_all! [{ id: 2, shop_id: 1, title: "My cart" }]
281
+ end
282
+ end
283
+
284
+ def test_insert_all_and_upsert_all_raises_when_no_unique_index_found_for_composite_primary_key
285
+ skip unless supports_insert_conflict_target?
286
+
287
+ error = assert_raises ArgumentError do
288
+ Cart.insert_all [{ id: 2, shop_id: 1, title: "My cart" }]
289
+ end
290
+ assert_match "No unique index found for id", error.message
291
+
292
+ error = assert_raises ArgumentError do
293
+ Cart.upsert_all [{ id: 2, shop_id: 1, title: "My cart" }]
294
+ end
295
+ assert_match "No unique index found for id", error.message
296
+ end
297
+
298
+ def test_insert_all_and_upsert_all_works_with_composite_primary_keys_when_unique_by_is_not_provided
299
+ skip unless supports_insert_on_duplicate_skip? && !supports_insert_conflict_target?
300
+
301
+ assert_difference "Cart.count", 3 do
302
+ Cart.insert_all [{ id: 1, shop_id: 1, title: "My cart" }]
303
+
304
+ Cart.insert_all! [{ id: 2, shop_id: 1, title: "My cart 2" }]
305
+
306
+ Cart.upsert_all [{ id: 3, shop_id: 2, title: "My other cart" }]
307
+ end
308
+ end
309
+
310
+ def test_insert_logs_message_including_model_name
311
+ skip unless supports_insert_conflict_target?
312
+
313
+ capture_log_output do |output|
314
+ Book.insert({ name: "Rework", author_id: 1 })
315
+ assert_match "Book Insert", output.string
316
+ end
317
+ end
318
+
319
+ def test_insert_logs_message_including_model_name_from_anonymous_class
320
+ skip unless supports_insert_conflict_target?
321
+
322
+ anonymous_book_klass = Class.new(Book) do
323
+ def self.name
324
+ "AnonymousBook"
325
+ end
326
+ end
327
+
328
+ capture_log_output do |output|
329
+ anonymous_book_klass.insert({ name: "Rework", author_id: 1 })
330
+ assert_match "AnonymousBook Insert", output.string
331
+ end
332
+ end
333
+
334
+ def test_insert_all_logs_message_including_model_name
335
+ skip unless supports_insert_conflict_target?
336
+
337
+ capture_log_output do |output|
338
+ Book.insert_all [{ name: "Remote", author_id: 1 }, { name: "Renote", author_id: 1 }]
339
+ assert_match "Book Bulk Insert", output.string
340
+ end
341
+ end
342
+
343
+ def test_insert_all_and_upsert_all_with_aliased_attributes
344
+ skip unless supports_insert_on_duplicate_update?
345
+
346
+ if supports_insert_returning?
347
+ assert_difference "Book.count" do
348
+ result = Book.insert_all [{ title: "Remote", author_id: 1 }], returning: :title
349
+ assert_includes result.columns, "title"
350
+ end
351
+ end
352
+
353
+ Book.upsert_all [{ id: 101, title: "Perelandra", author_id: 7, isbn: "1974522598" }]
354
+ Book.upsert_all [{ id: 101, title: "Perelandra 2", author_id: 6, isbn: "111111" }], update_only: %i[ title isbn ]
355
+
356
+ book = Book.find(101)
357
+ assert_equal "Perelandra 2", book.title, "Should have updated the title"
358
+ assert_equal "111111", book.isbn, "Should have updated the isbn"
359
+ assert_equal 7, book.author_id, "Should not have updated the author_id"
360
+ end
361
+
362
+ def test_insert_all_and_upsert_all_with_sti
363
+ skip unless supports_insert_on_duplicate_update?
364
+
365
+ assert_difference -> { Category.count }, 2 do
366
+ SpecialCategory.insert_all [{ name: "First" }, { name: "Second", type: nil }]
367
+ end
368
+
369
+ first, second = Category.last(2)
370
+ assert_equal "SpecialCategory", first.type
371
+ assert_nil second.type
372
+
373
+ SpecialCategory.upsert_all [{ id: 103, name: "First" }, { id: 104, name: "Second", type: nil }]
374
+
375
+ category3 = Category.find(103)
376
+ assert_equal "SpecialCategory", category3.type
377
+
378
+ category4 = Category.find(104)
379
+ assert_nil category4.type
380
+ end
381
+
382
+ def test_upsert_logs_message_including_model_name
383
+ skip unless supports_insert_on_duplicate_update?
384
+
385
+ capture_log_output do |output|
386
+ Book.upsert({ name: "Remote", author_id: 1 })
387
+ assert_match "Book Upsert", output.string
388
+ end
389
+ end
390
+
391
+ unless in_memory_db?
392
+ def test_upsert_and_db_warnings
393
+ skip unless supports_insert_on_duplicate_update?
394
+
395
+ begin
396
+ with_db_warnings_action(:raise) do
397
+ assert_nothing_raised do
398
+ Book.upsert({ id: 1001, name: "Remote", author_id: 1 })
399
+ end
400
+ end
401
+ ensure
402
+ # We need to explicitly remove the record, because `with_db_warnings_action`
403
+ # prevents the wrapping transaction to be rolled back.
404
+ Book.delete(1001)
405
+ end
406
+ end
407
+ end
408
+
409
+ def test_upsert_all_logs_message_including_model_name
410
+ skip unless supports_insert_on_duplicate_update?
411
+
412
+ capture_log_output do |output|
413
+ Book.upsert_all [{ name: "Remote", author_id: 1 }, { name: "Renote", author_id: 1 }]
414
+ assert_match "Book Bulk Upsert", output.string
415
+ end
416
+ end
417
+
418
+ def test_upsert_all_updates_existing_records
419
+ skip unless supports_insert_on_duplicate_update?
420
+
421
+ new_name = "Agile Web Development with Rails, 4th Edition"
422
+ Book.upsert_all [{ id: 1, name: new_name }]
423
+ assert_equal new_name, Book.find(1).name
424
+ end
425
+
426
+ def test_upsert_all_updates_existing_record_by_primary_key
427
+ skip unless supports_insert_conflict_target?
428
+
429
+ Book.upsert_all [{ id: 1, name: "New edition" }], unique_by: :id
430
+
431
+ assert_equal "New edition", Book.find(1).name
432
+ end
433
+
434
+ def test_upsert_all_does_notupdates_existing_record_by_when_there_is_no_key
435
+ skip unless supports_insert_on_duplicate_update? && !supports_insert_conflict_target?
436
+
437
+ Speedometer.create!(speedometer_id: "s3", name: "Very fast")
438
+
439
+ Speedometer.upsert_all [{ speedometer_id: "s3", name: "New Speedometer" }]
440
+
441
+ assert_equal "Very fast", Speedometer.find("s3").name
442
+ end
443
+
444
+ def test_upsert_all_updates_existing_record_by_configured_primary_key_fails_when_database_supports_insert_conflict_target
445
+ skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target?
446
+
447
+ error = assert_raises ArgumentError do
448
+ Speedometer.upsert_all [{ speedometer_id: "s1", name: "New Speedometer" }]
449
+ end
450
+ assert_match "No unique index found for speedometer_id", error.message
451
+ end
452
+
453
+ def test_upsert_all_does_not_update_readonly_attributes
454
+ skip unless supports_insert_on_duplicate_update?
455
+
456
+ new_name = "Agile Web Development with Rails, 4th Edition"
457
+ ReadonlyNameBook.upsert_all [{ id: 1, name: new_name }]
458
+ assert_not_equal new_name, Book.find(1).name
459
+ end
460
+
461
+ def test_upsert_all_does_not_update_primary_keys
462
+ skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target?
463
+
464
+ Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7 }]
465
+ Book.upsert_all [{ id: 103, name: "Perelandra", author_id: 7, isbn: "1974522598" }],
466
+ unique_by: :index_books_on_author_id_and_name
467
+
468
+ book = Book.find_by(name: "Perelandra")
469
+ assert_equal 101, book.id, "Should not have updated the ID"
470
+ assert_equal "1974522598", book.isbn, "Should have updated the isbn"
471
+ end
472
+
473
+ def test_upsert_all_passing_both_on_duplicate_and_update_only_will_raise_an_error
474
+ assert_raises ArgumentError do
475
+ Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7, isbn: "1974522598" }], on_duplicate: "NAME=values(name)", update_only: :name
476
+ end
477
+ end
478
+
479
+ def test_upsert_all_only_updates_the_column_provided_via_update_only
480
+ skip unless supports_insert_on_duplicate_update?
481
+
482
+ Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7, isbn: "1974522598" }]
483
+ Book.upsert_all [{ id: 101, name: "Perelandra 2", author_id: 7, isbn: "111111" }], update_only: :name
484
+
485
+ book = Book.find(101)
486
+ assert_equal "Perelandra 2", book.name, "Should have updated the name"
487
+ assert_equal "1974522598", book.isbn, "Should not have updated the isbn"
488
+ end
489
+
490
+ def test_upsert_all_only_updates_the_list_of_columns_provided_via_update_only
491
+ skip unless supports_insert_on_duplicate_update?
492
+
493
+ Book.upsert_all [{ id: 101, name: "Perelandra", author_id: 7, isbn: "1974522598" }]
494
+ Book.upsert_all [{ id: 101, name: "Perelandra 2", author_id: 6, isbn: "111111" }], update_only: %i[ name isbn ]
495
+
496
+ book = Book.find(101)
497
+ assert_equal "Perelandra 2", book.name, "Should have updated the name"
498
+ assert_equal "111111", book.isbn, "Should have updated the isbn"
499
+ assert_equal 7, book.author_id, "Should not have updated the author_id"
500
+ end
501
+
502
+ def test_upsert_all_does_not_perform_an_upsert_if_a_partial_index_doesnt_apply
503
+ skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target? && supports_partial_index?
504
+
505
+ Book.upsert_all [{ name: "Out of the Silent Planet", author_id: 7, isbn: "1974522598", published_on: Date.new(1938, 4, 1) }]
506
+ Book.upsert_all [{ name: "Perelandra", author_id: 7, isbn: "1974522598" }],
507
+ unique_by: :index_books_on_isbn
508
+
509
+ assert_equal ["Out of the Silent Planet", "Perelandra"], Book.where(isbn: "1974522598").order(:name).pluck(:name)
510
+ end
511
+
512
+ def test_upsert_all_does_not_touch_updated_at_when_values_do_not_change
513
+ skip unless supports_insert_on_duplicate_update?
514
+
515
+ updated_at = Time.now.utc - 5.years
516
+ Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_at: updated_at }]
517
+ Book.upsert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1) }]
518
+
519
+ assert_in_delta updated_at, Book.find(101).updated_at, 1
520
+ end
521
+
522
+ def test_upsert_all_touches_updated_at_and_updated_on_when_values_change
523
+ skip unless supports_insert_on_duplicate_update?
524
+
525
+ Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_at: 5.years.ago, updated_on: 5.years.ago }]
526
+ Book.upsert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 8) }]
527
+
528
+ assert_equal Time.now.utc.year, Book.find(101).updated_at.year
529
+ assert_equal Time.now.utc.year, Book.find(101).updated_on.year
530
+ end
531
+
532
+ def test_upsert_all_respects_updated_at_precision_when_touched_implicitly
533
+ skip unless supports_insert_on_duplicate_update?
534
+
535
+ Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_at: 5.years.ago, updated_on: 5.years.ago }]
536
+
537
+ # A single upsert can occur exactly at the seconds boundary (when usec is naturally zero), so try multiple times.
538
+ has_subsecond_precision = (1..100).any? do |i|
539
+ Book.upsert_all [{ id: 101, name: "Out of the Silent Planet (Edition #{i})" }]
540
+ Book.find(101).updated_at.usec > 0
541
+ end
542
+
543
+ assert has_subsecond_precision, "updated_at should have sub-second precision"
544
+ end
545
+
546
+ def test_upsert_all_uses_given_updated_at_over_implicit_updated_at
547
+ skip unless supports_insert_on_duplicate_update?
548
+
549
+ updated_at = Time.now.utc - 1.year
550
+ Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_at: 5.years.ago }]
551
+ Book.upsert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 8), updated_at: updated_at }]
552
+
553
+ assert_in_delta updated_at, Book.find(101).updated_at, 1
554
+ end
555
+
556
+ def test_upsert_all_uses_given_updated_on_over_implicit_updated_on
557
+ skip unless supports_insert_on_duplicate_update?
558
+
559
+ updated_on = Time.now.utc.to_date - 30
560
+ Book.insert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1), updated_on: 5.years.ago }]
561
+ Book.upsert_all [{ id: 101, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 8), updated_on: updated_on }]
562
+
563
+ assert_equal updated_on, Book.find(101).updated_on
564
+ end
565
+
566
+ def test_upsert_all_implicitly_sets_timestamps_on_create_when_model_record_timestamps_is_true
567
+ skip unless supports_insert_on_duplicate_update?
568
+
569
+ with_record_timestamps(Ship, true) do
570
+ Ship.upsert_all [{ id: 101, name: "RSS Boaty McBoatface" }]
571
+
572
+ ship = Ship.find(101)
573
+ assert_equal Time.new.utc.year, ship.created_at.year
574
+ assert_equal Time.new.utc.year, ship.created_on.year
575
+ assert_equal Time.new.utc.year, ship.updated_at.year
576
+ assert_equal Time.new.utc.year, ship.updated_on.year
577
+ end
578
+ end
579
+
580
+ def test_upsert_all_does_not_implicitly_set_timestamps_on_create_when_model_record_timestamps_is_true_but_overridden
581
+ skip unless supports_insert_on_duplicate_update?
582
+
583
+ with_record_timestamps(Ship, true) do
584
+ Ship.upsert_all [{ id: 101, name: "RSS Boaty McBoatface" }], record_timestamps: false
585
+
586
+ ship = Ship.find(101)
587
+ assert_nil ship.created_at
588
+ assert_nil ship.created_on
589
+ assert_nil ship.updated_at
590
+ assert_nil ship.updated_on
591
+ end
592
+ end
593
+
594
+ def test_upsert_all_does_not_implicitly_set_timestamps_on_create_when_model_record_timestamps_is_false
595
+ skip unless supports_insert_on_duplicate_update?
596
+
597
+ with_record_timestamps(Ship, false) do
598
+ Ship.upsert_all [{ id: 101, name: "RSS Boaty McBoatface" }]
599
+
600
+ ship = Ship.find(101)
601
+ assert_nil ship.created_at
602
+ assert_nil ship.created_on
603
+ assert_nil ship.updated_at
604
+ assert_nil ship.updated_on
605
+ end
606
+ end
607
+
608
+ def test_upsert_all_implicitly_sets_timestamps_on_create_when_model_record_timestamps_is_false_but_overridden
609
+ skip unless supports_insert_on_duplicate_update?
610
+
611
+ with_record_timestamps(Ship, false) do
612
+ Ship.upsert_all [{ id: 101, name: "RSS Boaty McBoatface" }], record_timestamps: true
613
+
614
+ ship = Ship.find(101)
615
+ assert_equal Time.now.utc.year, ship.created_at.year
616
+ assert_equal Time.now.utc.year, ship.created_on.year
617
+ assert_equal Time.now.utc.year, ship.updated_at.year
618
+ assert_equal Time.now.utc.year, ship.updated_on.year
619
+ end
620
+ end
621
+
622
+ def test_upsert_all_respects_created_at_precision_when_touched_implicitly
623
+ skip unless supports_insert_on_duplicate_update?
624
+
625
+ # A single upsert can occur exactly at the seconds boundary (when usec is naturally zero), so try multiple times.
626
+ has_subsecond_precision = (1..100).any? do |i|
627
+ Book.upsert_all [{ id: 101 + i, name: "Out of the Silent Planet", published_on: Date.new(1938, 4, 1) }]
628
+ Book.find(101 + i).created_at.usec > 0
629
+ end
630
+
631
+ assert has_subsecond_precision, "created_at should have sub-second precision"
632
+ end
633
+
634
+ def test_upsert_all_implicitly_sets_timestamps_on_update_when_model_record_timestamps_is_true
635
+ skip unless supports_insert_on_duplicate_update?
636
+
637
+ with_record_timestamps(Ship, true) do
638
+ travel_to(Date.new(2016, 4, 17)) { Ship.create! id: 101, name: "RSS Boaty McBoatface" }
639
+
640
+ Ship.upsert_all [{ id: 101, name: "RSS Sir David Attenborough" }]
641
+
642
+ ship = Ship.find(101)
643
+ assert_equal 2016, ship.created_at.year
644
+ assert_equal 2016, ship.created_on.year
645
+ assert_equal Time.now.utc.year, ship.updated_at.year
646
+ assert_equal Time.now.utc.year, ship.updated_on.year
647
+ end
648
+ end
649
+
650
+ def test_upsert_all_does_not_implicitly_set_timestamps_on_update_when_model_record_timestamps_is_true_but_overridden
651
+ skip unless supports_insert_on_duplicate_update?
652
+
653
+ with_record_timestamps(Ship, true) do
654
+ travel_to(Date.new(2016, 4, 17)) { Ship.create! id: 101, name: "RSS Boaty McBoatface" }
655
+
656
+ Ship.upsert_all [{ id: 101, name: "RSS Sir David Attenborough" }], record_timestamps: false
657
+
658
+ ship = Ship.find(101)
659
+ assert_equal 2016, ship.created_at.year
660
+ assert_equal 2016, ship.created_on.year
661
+ assert_equal 2016, ship.updated_at.year
662
+ assert_equal 2016, ship.updated_on.year
663
+ end
664
+ end
665
+
666
+ def test_upsert_all_does_not_implicitly_set_timestamps_on_update_when_model_record_timestamps_is_false
667
+ skip unless supports_insert_on_duplicate_update?
668
+
669
+ with_record_timestamps(Ship, false) do
670
+ Ship.create! id: 101, name: "RSS Boaty McBoatface"
671
+
672
+ Ship.upsert_all [{ id: 101, name: "RSS Sir David Attenborough" }]
673
+
674
+ ship = Ship.find(101)
675
+ assert_nil ship.created_at
676
+ assert_nil ship.created_on
677
+ assert_nil ship.updated_at
678
+ assert_nil ship.updated_on
679
+ end
680
+ end
681
+
682
+ def test_upsert_all_implicitly_sets_timestamps_on_update_when_model_record_timestamps_is_false_but_overridden
683
+ skip unless supports_insert_on_duplicate_update?
684
+
685
+ with_record_timestamps(Ship, false) do
686
+ Ship.create! id: 101, name: "RSS Boaty McBoatface"
687
+
688
+ Ship.upsert_all [{ id: 101, name: "RSS Sir David Attenborough" }], record_timestamps: true
689
+
690
+ ship = Ship.find(101)
691
+ assert_nil ship.created_at
692
+ assert_nil ship.created_on
693
+ assert_equal Time.now.utc.year, ship.updated_at.year
694
+ assert_equal Time.now.utc.year, ship.updated_on.year
695
+ end
696
+ end
697
+
698
+ def test_upsert_all_implicitly_sets_timestamps_even_when_columns_are_aliased
699
+ skip unless supports_insert_on_duplicate_update?
700
+
701
+ Developer.upsert_all [{ id: 101, name: "Alice" }]
702
+ alice = Developer.find(101)
703
+
704
+ assert_not_nil alice.created_at
705
+ assert_not_nil alice.created_on
706
+ assert_not_nil alice.updated_at
707
+ assert_not_nil alice.updated_on
708
+
709
+ alice.update!(created_at: nil, created_on: nil, updated_at: nil, updated_on: nil)
710
+
711
+ Developer.upsert_all [{ id: alice.id, name: alice.name, salary: alice.salary * 2 }]
712
+ alice.reload
713
+
714
+ assert_nil alice.created_at
715
+ assert_nil alice.created_on
716
+ assert_not_nil alice.updated_at
717
+ assert_not_nil alice.updated_on
718
+ end
719
+
720
+ def test_insert_all_raises_on_unknown_attribute
721
+ assert_raise ActiveRecord::UnknownAttributeError do
722
+ Book.insert_all! [{ unknown_attribute: "Test" }]
723
+ end
724
+ end
725
+
726
+ def test_upsert_all_works_with_partitioned_indexes
727
+ skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target? && supports_partitioned_indexes?
728
+
729
+ require "models/measurement"
730
+
731
+ Measurement.upsert_all([{ city_id: "1", logdate: 1.days.ago, peaktemp: 1, unitsales: 1 },
732
+ { city_id: "2", logdate: 2.days.ago, peaktemp: 2, unitsales: 2 },
733
+ { city_id: "2", logdate: 3.days.ago, peaktemp: 0, unitsales: 0 }],
734
+ unique_by: %i[logdate city_id])
735
+ assert_equal [[1.day.ago.to_date, 1, 1]],
736
+ Measurement.where(city_id: 1).pluck(:logdate, :peaktemp, :unitsales)
737
+ assert_equal [[2.days.ago.to_date, 2, 2], [3.days.ago.to_date, 0, 0]],
738
+ Measurement.where(city_id: 2).pluck(:logdate, :peaktemp, :unitsales)
739
+ end
740
+
741
+ def test_insert_all_with_enum_values
742
+ Book.insert_all! [{ status: :published, isbn: "1234566", name: "Rework", author_id: 1 },
743
+ { status: :proposed, isbn: "1234567", name: "Remote", author_id: 2 }]
744
+ assert_equal ["published", "proposed"], Book.where(isbn: ["1234566", "1234567"]).order(:id).pluck(:status)
745
+ end
746
+
747
+ def test_insert_all_on_relation
748
+ author = Author.create!(name: "Jimmy")
749
+
750
+ assert_difference "author.books.count", +1 do
751
+ author.books.insert_all!([{ name: "My little book", isbn: "1974522598" }])
752
+ end
753
+ end
754
+
755
+ def test_insert_all_on_relation_precedence
756
+ author = Author.create!(name: "Jimmy")
757
+ second_author = Author.create!(name: "Bob")
758
+
759
+ assert_difference "author.books.count", +1 do
760
+ author.books.insert_all!([{ name: "My little book", isbn: "1974522598", author_id: second_author.id }])
761
+ end
762
+ end
763
+
764
+ def test_insert_all_create_with
765
+ assert_difference "Book.where(format: 'X').count", +2 do
766
+ Book.create_with(format: "X").insert_all!([ { name: "A" }, { name: "B" } ])
767
+ end
768
+ end
769
+
770
+ def test_insert_all_has_many_through
771
+ book = Book.first
772
+ assert_raise(ArgumentError) { book.subscribers.insert_all!([ { nick: "Jimmy" } ]) }
773
+ end
774
+
775
+ def test_upsert_all_on_relation
776
+ skip unless supports_insert_on_duplicate_update?
777
+
778
+ author = Author.create!(name: "Jimmy")
779
+
780
+ assert_difference "author.books.count", +1 do
781
+ author.books.upsert_all([{ name: "My little book", isbn: "1974522598" }])
782
+ end
783
+ end
784
+
785
+ def test_upsert_all_on_relation_precedence
786
+ skip unless supports_insert_on_duplicate_update?
787
+
788
+ author = Author.create!(name: "Jimmy")
789
+ second_author = Author.create!(name: "Bob")
790
+
791
+ assert_difference "author.books.count", +1 do
792
+ author.books.upsert_all([{ name: "My little book", isbn: "1974522598", author_id: second_author.id }])
793
+ end
794
+ end
795
+
796
+ def test_upsert_all_create_with
797
+ skip unless supports_insert_on_duplicate_update?
798
+
799
+ assert_difference "Book.where(format: 'X').count", +2 do
800
+ Book.create_with(format: "X").upsert_all([ { name: "A" }, { name: "B" } ])
801
+ end
802
+ end
803
+
804
+ def test_upsert_all_has_many_through
805
+ skip unless supports_insert_on_duplicate_update?
806
+
807
+ book = Book.first
808
+ assert_raise(ArgumentError) { book.subscribers.upsert_all([ { nick: "Jimmy" } ]) }
809
+ end
810
+
811
+ def test_upsert_all_updates_using_provided_sql
812
+ skip unless supports_insert_on_duplicate_update?
813
+
814
+ operator = current_adapter?(:SQLite3Adapter) ? "MAX" : "GREATEST"
815
+
816
+ Book.upsert_all(
817
+ [{ id: 1, status: 1 }, { id: 2, status: 1 }],
818
+ on_duplicate: Arel.sql("status = #{operator}(books.status, 1)")
819
+ )
820
+ assert_equal "published", Book.find(1).status
821
+ assert_equal "written", Book.find(2).status
822
+ end
823
+
824
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
825
+ def test_upsert_all_updates_using_values_function_on_duplicate_raw_sql
826
+ skip unless supports_insert_on_duplicate_update?
827
+
828
+ b1 = Book.create!(name: "Name")
829
+ b2 = Book.create!(name: nil)
830
+
831
+ Book.upsert_all(
832
+ [{ id: b1.id, name: "No Name" }, { id: b2.id, name: "No Name" }],
833
+ on_duplicate: Arel.sql("name = IFNULL(name, values(name))")
834
+ )
835
+
836
+ b1.reload
837
+ b2.reload
838
+
839
+ assert_equal "Name", b1.name
840
+ assert_equal "No Name", b2.name
841
+ end
842
+ end
843
+
844
+ def test_upsert_all_updates_using_provided_sql_and_unique_by
845
+ skip unless supports_insert_on_duplicate_update? && supports_insert_conflict_target?
846
+
847
+ book = books(:rfr)
848
+ assert_equal "proposed", book.status
849
+
850
+ Book.upsert_all(
851
+ [{ name: book.name, author_id: book.author_id }],
852
+ unique_by: [:name, :author_id],
853
+ on_duplicate: Arel.sql("status = 2")
854
+ )
855
+ assert_equal "published", book.reload.status
856
+ end
857
+
858
+ def test_upsert_all_with_unique_by_fails_cleanly_for_adapters_not_supporting_insert_conflict_target
859
+ skip if supports_insert_conflict_target?
860
+
861
+ error = assert_raises ArgumentError do
862
+ Book.upsert_all [{ name: "Rework", author_id: 1 }], unique_by: :isbn
863
+ end
864
+ assert_match "#{ActiveRecord::Base.lease_connection.class} does not support :unique_by", error.message
865
+ end
866
+
867
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter)
868
+ def test_insert_all_when_table_name_contains_database
869
+ database_name = Book.connection_db_config.database
870
+ Book.table_name = "#{database_name}.books"
871
+
872
+ assert_nothing_raised do
873
+ Book.insert_all! [{ name: "Rework", author_id: 1 }]
874
+ end
875
+ ensure
876
+ Book.table_name = "books"
877
+ end
878
+ end
879
+
880
+ private
881
+ def capture_log_output
882
+ output = StringIO.new
883
+ old_logger, ActiveRecord::Base.logger = ActiveRecord::Base.logger, ActiveSupport::Logger.new(output)
884
+
885
+ begin
886
+ yield output
887
+ ensure
888
+ ActiveRecord::Base.logger = old_logger
889
+ end
890
+ end
891
+
892
+ def with_record_timestamps(model, value)
893
+ original = model.record_timestamps
894
+ model.record_timestamps = value
895
+ yield
896
+ ensure
897
+ model.record_timestamps = original
898
+ end
899
+ end