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
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cases/helper"
4
- require "models/comment"
5
4
  require "models/post"
6
5
  require "models/subscriber"
6
+ require "models/developer"
7
+ require "models/cpk"
7
8
 
8
9
  class EachTest < ActiveRecord::TestCase
9
- fixtures :posts, :subscribers
10
+ fixtures :posts, :subscribers, :developers, :cpk_orders
10
11
 
11
12
  def setup
12
13
  @posts = Post.order("id asc")
@@ -14,8 +15,13 @@ class EachTest < ActiveRecord::TestCase
14
15
  Post.count("id") # preheat arel's table cache
15
16
  end
16
17
 
18
+ def posts_id_query_pattern
19
+ quoted_posts_id = Regexp.escape(quote_table_name("posts.id"))
20
+ current_adapter?(:IBM_DBAdapter) ? "(?:#{quoted_posts_id}|posts\\.id)" : quoted_posts_id
21
+ end
22
+
17
23
  def test_each_should_execute_one_query_per_batch
18
- assert_queries(@total + 1) do
24
+ assert_queries_count(@total + 1) do
19
25
  Post.find_each(batch_size: 1) do |post|
20
26
  assert_kind_of Post, post
21
27
  end
@@ -23,14 +29,14 @@ class EachTest < ActiveRecord::TestCase
23
29
  end
24
30
 
25
31
  def test_each_should_not_return_query_chain_and_execute_only_one_query
26
- assert_queries(1) do
32
+ assert_queries_count(1) do
27
33
  result = Post.find_each(batch_size: 100000) { }
28
34
  assert_nil result
29
35
  end
30
36
  end
31
37
 
32
38
  def test_each_should_return_an_enumerator_if_no_block_is_present
33
- assert_queries(1) do
39
+ assert_queries_count(1) do
34
40
  Post.find_each(batch_size: 100000).with_index do |post, index|
35
41
  assert_kind_of Post, post
36
42
  assert_kind_of Integer, index
@@ -45,7 +51,7 @@ class EachTest < ActiveRecord::TestCase
45
51
  end
46
52
 
47
53
  def test_each_enumerator_should_execute_one_query_per_batch
48
- assert_queries(@total + 1) do
54
+ assert_queries_count(@total + 1) do
49
55
  Post.find_each(batch_size: 1).with_index do |post, index|
50
56
  assert_kind_of Post, post
51
57
  assert_kind_of Integer, index
@@ -62,7 +68,7 @@ class EachTest < ActiveRecord::TestCase
62
68
  end
63
69
 
64
70
  def test_each_should_execute_if_id_is_in_select
65
- assert_queries(6) do
71
+ assert_queries_count(6) do
66
72
  Post.select("id, title, type").find_each(batch_size: 2) do |post|
67
73
  assert_kind_of Post, post
68
74
  end
@@ -92,9 +98,14 @@ class EachTest < ActiveRecord::TestCase
92
98
  end
93
99
 
94
100
  def test_warn_if_order_scope_is_set
101
+ previous_logger = ActiveRecord::Base.logger
102
+ ActiveRecord::Base.logger = ActiveSupport::Logger.new(nil)
103
+
95
104
  assert_called(ActiveRecord::Base.logger, :warn) do
96
105
  Post.order("title").find_each { |post| post }
97
106
  end
107
+ ensure
108
+ ActiveRecord::Base.logger = previous_logger
98
109
  end
99
110
 
100
111
  def test_logger_not_required
@@ -108,7 +119,7 @@ class EachTest < ActiveRecord::TestCase
108
119
  end
109
120
 
110
121
  def test_find_in_batches_should_return_batches
111
- assert_queries(@total + 1) do
122
+ assert_queries_count(@total + 1) do
112
123
  Post.find_in_batches(batch_size: 1) do |batch|
113
124
  assert_kind_of Array, batch
114
125
  assert_kind_of Post, batch.first
@@ -117,7 +128,7 @@ class EachTest < ActiveRecord::TestCase
117
128
  end
118
129
 
119
130
  def test_find_in_batches_should_start_from_the_start_option
120
- assert_queries(@total) do
131
+ assert_queries_count(@total) do
121
132
  Post.find_in_batches(batch_size: 1, start: 2) do |batch|
122
133
  assert_kind_of Array, batch
123
134
  assert_kind_of Post, batch.first
@@ -126,7 +137,7 @@ class EachTest < ActiveRecord::TestCase
126
137
  end
127
138
 
128
139
  def test_find_in_batches_should_end_at_the_finish_option
129
- assert_queries(6) do
140
+ assert_queries_count(6) do
130
141
  Post.find_in_batches(batch_size: 1, finish: 5) do |batch|
131
142
  assert_kind_of Array, batch
132
143
  assert_kind_of Post, batch.first
@@ -135,18 +146,17 @@ class EachTest < ActiveRecord::TestCase
135
146
  end
136
147
 
137
148
  def test_find_in_batches_shouldnt_execute_query_unless_needed
138
- assert_queries(2) do
149
+ assert_queries_count(2) do
139
150
  Post.find_in_batches(batch_size: @total) { |batch| assert_kind_of Array, batch }
140
151
  end
141
152
 
142
- assert_queries(1) do
153
+ assert_queries_count(1) do
143
154
  Post.find_in_batches(batch_size: @total + 1) { |batch| assert_kind_of Array, batch }
144
155
  end
145
156
  end
146
157
 
147
158
  def test_find_in_batches_should_quote_batch_order
148
- c = Post.connection
149
- assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("posts.id"))}/i) do
159
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern}/i) do
150
160
  Post.find_in_batches(batch_size: 1) do |batch|
151
161
  assert_kind_of Array, batch
152
162
  assert_kind_of Post, batch.first
@@ -155,8 +165,7 @@ class EachTest < ActiveRecord::TestCase
155
165
  end
156
166
 
157
167
  def test_find_in_batches_should_quote_batch_order_with_desc_order
158
- c = Post.connection
159
- assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("posts.id"))} DESC/) do
168
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern} DESC/) do
160
169
  Post.find_in_batches(batch_size: 1, order: :desc) do |batch|
161
170
  assert_kind_of Array, batch
162
171
  assert_kind_of Post, batch.first
@@ -172,6 +181,12 @@ class EachTest < ActiveRecord::TestCase
172
181
  end
173
182
  end
174
183
 
184
+ def test_in_batches_without_block_should_raise_if_order_is_invalid
185
+ assert_raise(ArgumentError) do
186
+ Post.select(:title).in_batches(order: :invalid)
187
+ end
188
+ end
189
+
175
190
  def test_find_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified
176
191
  not_a_post = +"not a post"
177
192
  def not_a_post.id; end
@@ -207,26 +222,26 @@ class EachTest < ActiveRecord::TestCase
207
222
 
208
223
  def test_find_in_batches_should_not_error_if_config_overridden
209
224
  # Set the config option which will be overridden
210
- prev = ActiveRecord::Base.error_on_ignored_order
211
- ActiveRecord::Base.error_on_ignored_order = true
225
+ prev = ActiveRecord.error_on_ignored_order
226
+ ActiveRecord.error_on_ignored_order = true
212
227
  assert_nothing_raised do
213
228
  PostWithDefaultScope.find_in_batches(error_on_ignore: false) { }
214
229
  end
215
230
  ensure
216
231
  # Set back to default
217
- ActiveRecord::Base.error_on_ignored_order = prev
232
+ ActiveRecord.error_on_ignored_order = prev
218
233
  end
219
234
 
220
235
  def test_find_in_batches_should_error_on_config_specified_to_error
221
236
  # Set the config option
222
- prev = ActiveRecord::Base.error_on_ignored_order
223
- ActiveRecord::Base.error_on_ignored_order = true
237
+ prev = ActiveRecord.error_on_ignored_order
238
+ ActiveRecord.error_on_ignored_order = true
224
239
  assert_raise(ArgumentError) do
225
240
  PostWithDefaultScope.find_in_batches() { }
226
241
  end
227
242
  ensure
228
243
  # Set back to default
229
- ActiveRecord::Base.error_on_ignored_order = prev
244
+ ActiveRecord.error_on_ignored_order = prev
230
245
  end
231
246
 
232
247
  def test_find_in_batches_should_not_error_by_default
@@ -257,7 +272,7 @@ class EachTest < ActiveRecord::TestCase
257
272
  end
258
273
 
259
274
  def test_find_in_batches_should_use_any_column_as_primary_key_when_start_is_not_specified
260
- assert_queries(Subscriber.count + 1) do
275
+ assert_queries_count(Subscriber.count + 1) do
261
276
  Subscriber.find_in_batches(batch_size: 1) do |batch|
262
277
  assert_kind_of Array, batch
263
278
  assert_kind_of Subscriber, batch.first
@@ -270,7 +285,7 @@ class EachTest < ActiveRecord::TestCase
270
285
  assert_no_queries do
271
286
  enum = Post.find_in_batches(batch_size: 1)
272
287
  end
273
- assert_queries(4) do
288
+ assert_queries_count(4) do
274
289
  enum.first(4) do |batch|
275
290
  assert_kind_of Array, batch
276
291
  assert_kind_of Post, batch.first
@@ -306,8 +321,26 @@ class EachTest < ActiveRecord::TestCase
306
321
  end
307
322
  end
308
323
 
324
+ def test_in_batches_should_error_on_ignore_the_order
325
+ assert_raise(ArgumentError, match: "Scoped order is ignored") do
326
+ PostWithDefaultScope.in_batches(error_on_ignore: true) { }
327
+ end
328
+
329
+ assert_raise(ArgumentError, match: "Scoped order is ignored") do
330
+ PostWithDefaultScope.in_batches(error_on_ignore: true).delete_all
331
+ end
332
+ end
333
+
334
+ def test_in_batches_has_attribute_readers
335
+ enumerator = Post.no_comments.in_batches(of: 2, start: 42, finish: 84)
336
+ assert_equal Post.no_comments, enumerator.relation
337
+ assert_equal 2, enumerator.batch_size
338
+ assert_equal 42, enumerator.start
339
+ assert_equal 84, enumerator.finish
340
+ end
341
+
309
342
  def test_in_batches_should_yield_relation_if_block_given
310
- assert_queries(6) do
343
+ assert_queries_count(6) do
311
344
  Post.in_batches(of: 2) do |relation|
312
345
  assert_kind_of ActiveRecord::Relation, relation
313
346
  end
@@ -315,7 +348,7 @@ class EachTest < ActiveRecord::TestCase
315
348
  end
316
349
 
317
350
  def test_in_batches_should_be_enumerable_if_no_block_given
318
- assert_queries(6) do
351
+ assert_queries_count(6) do
319
352
  Post.in_batches(of: 2).each do |relation|
320
353
  assert_kind_of ActiveRecord::Relation, relation
321
354
  end
@@ -323,7 +356,7 @@ class EachTest < ActiveRecord::TestCase
323
356
  end
324
357
 
325
358
  def test_in_batches_each_record_should_yield_record_if_block_is_given
326
- assert_queries(6) do
359
+ assert_queries_count(6) do
327
360
  Post.in_batches(of: 2).each_record do |post|
328
361
  assert_predicate post.title, :present?
329
362
  assert_kind_of Post, post
@@ -332,7 +365,7 @@ class EachTest < ActiveRecord::TestCase
332
365
  end
333
366
 
334
367
  def test_in_batches_each_record_should_return_enumerator_if_no_block_given
335
- assert_queries(6) do
368
+ assert_queries_count(6) do
336
369
  Post.in_batches(of: 2).each_record.with_index do |post, i|
337
370
  assert_predicate post.title, :present?
338
371
  assert_kind_of Post, post
@@ -342,7 +375,7 @@ class EachTest < ActiveRecord::TestCase
342
375
 
343
376
  def test_in_batches_each_record_should_be_ordered_by_id
344
377
  ids = Post.order("id ASC").pluck(:id)
345
- assert_queries(6) do
378
+ assert_queries_count(6) do
346
379
  Post.in_batches(of: 2).each_record.with_index do |post, i|
347
380
  assert_equal ids[i], post.id
348
381
  end
@@ -350,7 +383,7 @@ class EachTest < ActiveRecord::TestCase
350
383
  end
351
384
 
352
385
  def test_in_batches_update_all_affect_all_records
353
- assert_queries(6 + 6) do # 6 selects, 6 updates
386
+ assert_queries_count(6 + 6) do # 6 selects, 6 updates
354
387
  Post.in_batches(of: 2).update_all(title: "updated-title")
355
388
  end
356
389
  assert_equal Post.all.pluck(:title), ["updated-title"] * Post.count
@@ -364,6 +397,22 @@ class EachTest < ActiveRecord::TestCase
364
397
  assert_equal 0, Post.where("1=0").in_batches(of: 2).update_all(title: "updated-title")
365
398
  end
366
399
 
400
+ def test_in_batches_touch_all_affect_all_records
401
+ time = Time.new(2000, 1, 1, 0, 0, 0)
402
+ assert_queries_count(6 + 6) do # 6 selects, 6 updates
403
+ Developer.in_batches(of: 2).touch_all(time: time)
404
+ end
405
+ assert_equal [time] * Developer.count, Developer.all.pluck(:updated_at)
406
+ end
407
+
408
+ def test_in_batches_touch_all_returns_rows_affected
409
+ assert_equal 11, Developer.in_batches(of: 2).touch_all
410
+ end
411
+
412
+ def test_in_batches_touch_all_returns_zero_when_no_batches
413
+ assert_equal 0, Developer.where("1=0").in_batches(of: 2).touch_all
414
+ end
415
+
367
416
  def test_in_batches_delete_all_should_not_delete_records_in_other_batches
368
417
  not_deleted_count = Post.where("id <= 2").count
369
418
  Post.where("id > 2").in_batches(of: 2).delete_all
@@ -379,6 +428,22 @@ class EachTest < ActiveRecord::TestCase
379
428
  assert_equal 0, Post.where("1=0").in_batches(of: 2).delete_all
380
429
  end
381
430
 
431
+ def test_in_batches_destroy_all_should_not_destroy_records_in_other_batches
432
+ not_destroyed_count = Post.where("id <= 2").count
433
+ Post.where("id > 2").in_batches(of: 2).destroy_all
434
+ assert_equal 0, Post.where("id > 2").count
435
+ assert_equal not_destroyed_count, Post.count
436
+ end
437
+
438
+ def test_in_batches_destroy_all_returns_rows_affected
439
+ # 1 records is not destroyed because of the callback.
440
+ assert_equal 10, PostWithDestroyCallback.in_batches(of: 2).destroy_all
441
+ end
442
+
443
+ def test_in_batches_destroy_all_returns_zero_when_no_batches
444
+ assert_equal 0, Post.where("1=0").in_batches(of: 2).destroy_all
445
+ end
446
+
382
447
  def test_in_batches_should_not_be_loaded
383
448
  Post.in_batches(of: 1) do |relation|
384
449
  assert_not_predicate relation, :loaded?
@@ -396,15 +461,138 @@ class EachTest < ActiveRecord::TestCase
396
461
  end
397
462
 
398
463
  def test_in_batches_if_not_loaded_executes_more_queries
399
- assert_queries(@total + 1) do
464
+ assert_queries_count(@total + 1) do
400
465
  Post.in_batches(of: 1, load: false) do |relation|
401
466
  assert_not_predicate relation, :loaded?
402
467
  end
403
468
  end
404
469
  end
405
470
 
471
+ def test_in_batches_when_loaded_runs_no_queries
472
+ posts = Post.all
473
+ posts.load
474
+ batch_count = 0
475
+ last_id = posts.map(&:id).min
476
+ assert_queries_count(0) do
477
+ posts.in_batches(of: 1) do |relation|
478
+ batch_count += 1
479
+ assert_kind_of ActiveRecord::Relation, relation
480
+ assert_operator last_id, :<=, relation.map(&:id).min
481
+ last_id = relation.map(&:id).min
482
+ end
483
+ end
484
+
485
+ assert_equal posts.size, batch_count
486
+ end
487
+
488
+ def test_in_batches_when_loaded_runs_no_queries_with_order_argument
489
+ posts = Post.all.order(id: :asc)
490
+ posts.load
491
+ batch_count = 0
492
+ last_id = posts.map(&:id).max
493
+ assert_queries_count(0) do
494
+ posts.in_batches(of: 1, order: :desc) do |relation|
495
+ batch_count += 1
496
+ assert_kind_of ActiveRecord::Relation, relation
497
+ assert_operator last_id, :>=, relation.map(&:id).max
498
+ last_id = relation.map(&:id).max
499
+ end
500
+ end
501
+
502
+ assert_equal posts.size, batch_count
503
+ end
504
+
505
+ def test_in_batches_when_loaded_runs_no_queries_with_start_and_end_arguments
506
+ posts = Post.all.order(id: :asc)
507
+ posts.load
508
+ batch_count = 0
509
+
510
+ start_id = posts.map(&:id)[1]
511
+ finish_id = posts.map(&:id)[-2]
512
+ assert_queries_count(0) do
513
+ posts.in_batches(of: 1, start: start_id, finish: finish_id) do |relation|
514
+ batch_count += 1
515
+ assert_kind_of ActiveRecord::Relation, relation
516
+ end
517
+ end
518
+
519
+ assert_equal posts.size - 2, batch_count
520
+ end
521
+
522
+ def test_in_batches_when_loaded_runs_no_queries_with_start_and_end_arguments_and_reverse_order
523
+ posts = Post.all.order(id: :asc)
524
+ posts.load
525
+ batch_count = 0
526
+
527
+ start_id = posts.map(&:id)[-2]
528
+ finish_id = posts.map(&:id)[1]
529
+ assert_queries_count(0) do
530
+ posts.in_batches(of: 1, start: start_id, finish: finish_id, order: :desc) do |relation|
531
+ batch_count += 1
532
+ assert_kind_of ActiveRecord::Relation, relation
533
+ end
534
+ end
535
+
536
+ assert_equal posts.size - 2, batch_count
537
+ end
538
+
539
+ def test_in_batches_when_loaded_can_return_an_enum
540
+ posts = Post.all
541
+ posts.load
542
+ batch_count = 0
543
+
544
+ assert_queries_count(0) do
545
+ posts.in_batches(of: 1).each do |relation|
546
+ batch_count += 1
547
+ assert_kind_of ActiveRecord::Relation, relation
548
+ end
549
+ end
550
+
551
+ assert_equal posts.size, batch_count
552
+ end
553
+
554
+ def test_in_batches_when_loaded_runs_no_queries_when_batching_over_cpk_model
555
+ incorrectly_sorted_orders = Cpk::Order.order(shop_id: :asc, id: :desc)
556
+ incorrectly_sorted_orders.load
557
+
558
+ correctly_sorted_orders = Cpk::Order.order(shop_id: :desc, id: :asc).to_a
559
+ expected_orders = correctly_sorted_orders[1..-2]
560
+ start_id = expected_orders.first.id
561
+ finish_id = expected_orders.last.id
562
+ orders = []
563
+
564
+ assert_no_queries do
565
+ incorrectly_sorted_orders.find_each(batch_size: 1, start: start_id, finish: finish_id, order: [:desc, :asc]) do |order|
566
+ orders << order
567
+ end
568
+ end
569
+
570
+ assert_equal expected_orders, orders
571
+ end
572
+
573
+ def test_in_batches_when_loaded_iterates_using_custom_column
574
+ c = Post.lease_connection
575
+ c.add_index(:posts, :title, unique: true)
576
+ ActiveRecord::Base.schema_cache.clear!
577
+
578
+ ordered_posts = Post.order(id: :desc)
579
+ ordered_posts.load
580
+
581
+ posts = []
582
+
583
+ assert_no_queries do
584
+ ordered_posts.in_batches(of: 1, cursor: :id, order: :desc).each_record do |post|
585
+ posts << post
586
+ end
587
+ end
588
+
589
+ assert_equal ordered_posts.to_a, posts
590
+ ensure
591
+ c.remove_index(:posts, :title)
592
+ end
593
+
406
594
  def test_in_batches_should_return_relations
407
- assert_queries(@total + 1) do
595
+ assert_queries_count(@total + 1) do
408
596
  Post.in_batches(of: 1) do |relation|
409
597
  assert_kind_of ActiveRecord::Relation, relation
410
598
  end
@@ -413,7 +601,7 @@ class EachTest < ActiveRecord::TestCase
413
601
 
414
602
  def test_in_batches_should_start_from_the_start_option
415
603
  post = Post.order("id ASC").where("id >= ?", 2).first
416
- assert_queries(2) do
604
+ assert_queries_count(2) do
417
605
  relation = Post.in_batches(of: 1, start: 2).first
418
606
  assert_equal post, relation.first
419
607
  end
@@ -421,25 +609,59 @@ class EachTest < ActiveRecord::TestCase
421
609
 
422
610
  def test_in_batches_should_end_at_the_finish_option
423
611
  post = Post.order("id DESC").where("id <= ?", 5).first
424
- assert_queries(7) do
612
+ assert_queries_count(7) do
425
613
  relation = Post.in_batches(of: 1, finish: 5, load: true).reverse_each.first
426
614
  assert_equal post, relation.last
427
615
  end
428
616
  end
429
617
 
618
+ def test_in_batches_executes_range_queries_when_unconstrained
619
+ quoted_posts_id = posts_id_query_pattern
620
+ assert_queries_match(/WHERE #{quoted_posts_id} > .+ AND #{quoted_posts_id} <= .+/i) do
621
+ Post.in_batches(of: 2) { |relation| assert_kind_of Post, relation.first }
622
+ end
623
+ end
624
+
625
+ def test_in_batches_executes_in_queries_when_unconstrained_and_opted_out_of_ranges
626
+ quoted_posts_id = posts_id_query_pattern
627
+ assert_queries_match(/#{quoted_posts_id} IN \(.+\)/i) do
628
+ Post.in_batches(of: 2, use_ranges: false) { |relation| assert_kind_of Post, relation.first }
629
+ end
630
+ end
631
+
632
+ def test_in_batches_executes_in_queries_when_constrained
633
+ quoted_posts_id = posts_id_query_pattern
634
+ assert_queries_match(/#{quoted_posts_id} IN \(.+\)/i) do
635
+ Post.where("id < ?", 5).in_batches(of: 2) { |relation| assert_kind_of Post, relation.first }
636
+ end
637
+ end
638
+
639
+ def test_in_batches_executes_range_queries_when_constrained_and_opted_in_into_ranges
640
+ quoted_posts_id = posts_id_query_pattern
641
+ assert_queries_match(/#{quoted_posts_id} > .+ AND #{quoted_posts_id} <= .+/i) do
642
+ Post.where("id < ?", 5).in_batches(of: 2, use_ranges: true) { |relation| assert_kind_of Post, relation.first }
643
+ end
644
+ end
645
+
646
+ def test_in_batches_no_subqueries_for_whole_tables_batching
647
+ quoted_posts_id = posts_id_query_pattern
648
+ assert_queries_match(/DELETE FROM #{Regexp.escape(quote_table_name("posts"))} WHERE #{quoted_posts_id} > .+ AND #{quoted_posts_id} <=/i) do
649
+ Post.in_batches(of: 2).delete_all
650
+ end
651
+ end
652
+
430
653
  def test_in_batches_shouldnt_execute_query_unless_needed
431
- assert_queries(2) do
654
+ assert_queries_count(2) do
432
655
  Post.in_batches(of: @total) { |relation| assert_kind_of ActiveRecord::Relation, relation }
433
656
  end
434
657
 
435
- assert_queries(1) do
658
+ assert_queries_count(1) do
436
659
  Post.in_batches(of: @total + 1) { |relation| assert_kind_of ActiveRecord::Relation, relation }
437
660
  end
438
661
  end
439
662
 
440
663
  def test_in_batches_should_quote_batch_order
441
- c = Post.connection
442
- assert_sql(/ORDER BY #{c.quote_table_name('posts')}\.#{c.quote_column_name('id')}/) do
664
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern}/) do
443
665
  Post.in_batches(of: 1) do |relation|
444
666
  assert_kind_of ActiveRecord::Relation, relation
445
667
  assert_kind_of Post, relation.first
@@ -448,8 +670,7 @@ class EachTest < ActiveRecord::TestCase
448
670
  end
449
671
 
450
672
  def test_in_batches_should_quote_batch_order_with_desc_order
451
- c = Post.connection
452
- assert_sql(/ORDER BY #{Regexp.escape(c.quote_table_name("posts.id"))} DESC/) do
673
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern} DESC/) do
453
674
  Post.in_batches(of: 1, order: :desc) do |relation|
454
675
  assert_kind_of ActiveRecord::Relation, relation
455
676
  assert_kind_of Post, relation.first
@@ -457,6 +678,22 @@ class EachTest < ActiveRecord::TestCase
457
678
  end
458
679
  end
459
680
 
681
+ def test_in_batches_enumerator_should_quote_batch_order_with_desc_order
682
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern} DESC/) do
683
+ relation = Post.in_batches(of: 1, order: :desc).first
684
+ assert_kind_of ActiveRecord::Relation, relation
685
+ assert_kind_of Post, relation.first
686
+ end
687
+ end
688
+
689
+ def test_in_batches_enumerator_each_record_should_quote_batch_order_with_desc_order
690
+ assert_queries_match(/ORDER BY #{posts_id_query_pattern} DESC/) do
691
+ Post.in_batches(of: 1, order: :desc).each_record do |record|
692
+ assert_kind_of Post, record
693
+ end
694
+ end
695
+ end
696
+
460
697
  def test_in_batches_should_not_use_records_after_yielding_them_in_case_original_array_is_modified
461
698
  not_a_post = +"not a post"
462
699
  def not_a_post.id
@@ -495,7 +732,7 @@ class EachTest < ActiveRecord::TestCase
495
732
  end
496
733
 
497
734
  def test_in_batches_should_use_any_column_as_primary_key_when_start_is_not_specified
498
- assert_queries(Subscriber.count + 1) do
735
+ assert_queries_count(Subscriber.count + 1) do
499
736
  Subscriber.in_batches(of: 1, load: true) do |relation|
500
737
  assert_kind_of ActiveRecord::Relation, relation
501
738
  assert_kind_of Subscriber, relation.first
@@ -508,7 +745,7 @@ class EachTest < ActiveRecord::TestCase
508
745
  assert_no_queries do
509
746
  enum = Post.in_batches(of: 1)
510
747
  end
511
- assert_queries(4) do
748
+ assert_queries_count(4) do
512
749
  enum.first(4) do |relation|
513
750
  assert_kind_of ActiveRecord::Relation, relation
514
751
  assert_kind_of Post, relation.first
@@ -548,6 +785,79 @@ class EachTest < ActiveRecord::TestCase
548
785
  assert_equal 2, person.reload.author_id # incremented only once
549
786
  end
550
787
 
788
+ def test_in_batches_with_custom_columns_raises_when_start_missing_items
789
+ assert_raises(ArgumentError, match: ":start must contain one value per cursor column") do
790
+ Post.in_batches(start: 1, cursor: [:author_id, :id]) { }
791
+ end
792
+ end
793
+
794
+ def test_in_batches_with_custom_columns_raises_when_finish_missing_items
795
+ assert_raises(ArgumentError, match: ":finish must contain one value per cursor column") do
796
+ Post.in_batches(finish: 10, cursor: [:author_id, :id]) { }
797
+ end
798
+ end
799
+
800
+ def test_in_batches_with_custom_columns_raises_when_non_unique_columns
801
+ ActiveRecord::Base.schema_cache.clear!
802
+
803
+ # Non unique column.
804
+ assert_raises(ArgumentError, match: /must include a primary key/) do
805
+ Post.in_batches(cursor: :title) { }
806
+ end
807
+
808
+ # Primary key column.
809
+ assert_nothing_raised do
810
+ Post.in_batches(cursor: :id) { }
811
+ end
812
+
813
+ c = Post.lease_connection
814
+ c.add_index(:posts, :title)
815
+ ActiveRecord::Base.schema_cache.clear!
816
+
817
+ # Non unique indexed column.
818
+ assert_raises(ArgumentError, match: /must include a primary key/) do
819
+ Post.in_batches(cursor: :title) { }
820
+ end
821
+
822
+ c.remove_index(:posts, :title)
823
+
824
+ if current_adapter?(:PostgreSQLAdapter)
825
+ c.add_index(:posts, :title, unique: true, where: "id > 5")
826
+ ActiveRecord::Base.schema_cache.clear!
827
+
828
+ # Column having a unique, but partial, index.
829
+ assert_raises(ArgumentError, match: /must include a primary key/) do
830
+ Post.in_batches(cursor: :title) { }
831
+ end
832
+
833
+ c.remove_index(:posts, :title)
834
+ end
835
+
836
+ c.add_index(:posts, :title, unique: true)
837
+ ActiveRecord::Base.schema_cache.clear!
838
+ assert_nothing_raised do
839
+ Post.in_batches(cursor: :title) { }
840
+ end
841
+ ensure
842
+ c.remove_index(:posts, :title)
843
+ end
844
+
845
+ def test_in_batches_iterating_using_custom_columns
846
+ c = Post.lease_connection
847
+ c.add_index(:posts, :title, unique: true)
848
+ ActiveRecord::Base.schema_cache.clear!
849
+
850
+ expected_posts = Post.order(id: :desc).to_a
851
+ posts = []
852
+ Post.in_batches(of: 1, cursor: :id, order: :desc).each_record do |post|
853
+ posts << post
854
+ end
855
+
856
+ assert_equal expected_posts, posts
857
+ ensure
858
+ c.remove_index(:posts, :title)
859
+ end
860
+
551
861
  def test_find_in_batches_should_return_a_sized_enumerator
552
862
  assert_equal 11, Post.find_in_batches(batch_size: 1).size
553
863
  assert_equal 6, Post.find_in_batches(batch_size: 2).size
@@ -619,23 +929,17 @@ class EachTest < ActiveRecord::TestCase
619
929
  end
620
930
 
621
931
  test ".find_each respects table alias" do
622
- assert_queries(1) do
932
+ assert_queries_count(1) do
623
933
  table_alias = Post.arel_table.alias("omg_posts")
624
- table_metadata = ActiveRecord::TableMetadata.new(Post, table_alias)
625
- predicate_builder = ActiveRecord::PredicateBuilder.new(table_metadata)
626
-
627
- posts = ActiveRecord::Relation.create(
628
- Post,
629
- table: table_alias,
630
- predicate_builder: predicate_builder
631
- )
934
+
935
+ posts = ActiveRecord::Relation.create(Post, table: table_alias)
632
936
  posts.find_each { }
633
937
  end
634
938
  end
635
939
 
636
940
  test ".find_each bypasses the query cache for its own queries" do
637
941
  Post.cache do
638
- assert_queries(2) do
942
+ assert_queries_count(2) do
639
943
  Post.find_each { }
640
944
  Post.find_each { }
641
945
  end
@@ -645,7 +949,7 @@ class EachTest < ActiveRecord::TestCase
645
949
  test ".find_each does not disable the query cache inside the given block" do
646
950
  Post.cache do
647
951
  Post.find_each(start: 1, finish: 1) do |post|
648
- assert_queries(1) do
952
+ assert_queries_count(1) do
649
953
  post.comments.count
650
954
  post.comments.count
651
955
  end
@@ -655,7 +959,7 @@ class EachTest < ActiveRecord::TestCase
655
959
 
656
960
  test ".find_in_batches bypasses the query cache for its own queries" do
657
961
  Post.cache do
658
- assert_queries(2) do
962
+ assert_queries_count(2) do
659
963
  Post.find_in_batches { }
660
964
  Post.find_in_batches { }
661
965
  end
@@ -665,7 +969,7 @@ class EachTest < ActiveRecord::TestCase
665
969
  test ".find_in_batches does not disable the query cache inside the given block" do
666
970
  Post.cache do
667
971
  Post.find_in_batches(start: 1, finish: 1) do |batch|
668
- assert_queries(1) do
972
+ assert_queries_count(1) do
669
973
  batch.first.comments.count
670
974
  batch.first.comments.count
671
975
  end
@@ -675,7 +979,7 @@ class EachTest < ActiveRecord::TestCase
675
979
 
676
980
  test ".in_batches bypasses the query cache for its own queries" do
677
981
  Post.cache do
678
- assert_queries(2) do
982
+ assert_queries_count(2) do
679
983
  Post.in_batches { }
680
984
  Post.in_batches { }
681
985
  end
@@ -685,11 +989,91 @@ class EachTest < ActiveRecord::TestCase
685
989
  test ".in_batches does not disable the query cache inside the given block" do
686
990
  Post.cache do
687
991
  Post.in_batches(start: 1, finish: 1) do |relation|
688
- assert_queries(1) do
992
+ assert_queries_count(1) do
689
993
  relation.count
690
994
  relation.count
691
995
  end
692
996
  end
693
997
  end
694
998
  end
999
+
1000
+ test ".find_each iterates over composite primary key" do
1001
+ orders = Cpk::Order.order(*Cpk::Order.primary_key).to_a
1002
+
1003
+ index = 0
1004
+ Cpk::Order.find_each(batch_size: 1) do |order|
1005
+ assert_equal orders[index], order
1006
+ index += 1
1007
+ end
1008
+ assert_equal orders.size, index
1009
+ end
1010
+
1011
+ test ".in_batches should start from the start option when using composite primary key" do
1012
+ order = Cpk::Order.second
1013
+ relation = Cpk::Order.in_batches(of: 1, start: order.id).first
1014
+ assert_equal order, relation.first
1015
+ end
1016
+
1017
+ test ".in_batches should end at the finish option when using composite primary key" do
1018
+ order = Cpk::Order.second_to_last
1019
+ relation = Cpk::Order.in_batches(of: 1, finish: order.id).reverse_each.first
1020
+ assert_equal order, relation.last
1021
+ end
1022
+
1023
+ test ".in_batches with scope and using composite primary key" do
1024
+ order1, order2 = Cpk::Order.first(2)
1025
+ shop_id, id = order1.id
1026
+ relation = Cpk::Order.where("shop_id > ? OR shop_id = ? AND id > ?", shop_id, shop_id, id).in_batches(of: 1).first
1027
+ assert_equal order2, relation.first
1028
+ end
1029
+
1030
+ test ".find_each with multiple column ordering and using composite primary key" do
1031
+ Cpk::Book.insert_all!([
1032
+ { author_id: 1, id: 1 },
1033
+ { author_id: 2, id: 1 },
1034
+ { author_id: 2, id: 2 }
1035
+ ])
1036
+ books = Cpk::Book.order(author_id: :asc, id: :desc).to_a
1037
+
1038
+ index = 0
1039
+ Cpk::Book.find_each(batch_size: 1, order: [:asc, :desc]) do |book|
1040
+ assert_equal books[index], book
1041
+ index += 1
1042
+ end
1043
+ assert_equal books.size, index
1044
+ end
1045
+
1046
+ test ".in_batches should start from the start option when using composite primary key with multiple column ordering" do
1047
+ Cpk::Book.insert_all!([
1048
+ { author_id: 1, id: 1 },
1049
+ { author_id: 1, id: 2 },
1050
+ { author_id: 1, id: 3 }
1051
+ ])
1052
+ second_book = Cpk::Book.order(author_id: :asc, id: :desc).second
1053
+ relation = Cpk::Book.in_batches(of: 1, start: second_book.id, order: [:asc, :desc]).first
1054
+ assert_equal second_book, relation.first
1055
+ end
1056
+
1057
+ test ".in_batches should end at the finish option when using composite primary key with multiple column ordering" do
1058
+ Cpk::Book.insert_all!([
1059
+ { author_id: 1, id: 1 },
1060
+ { author_id: 1, id: 2 },
1061
+ { author_id: 1, id: 3 }
1062
+ ])
1063
+ second_book = Cpk::Book.order(author_id: :asc, id: :desc).second
1064
+ relation = Cpk::Book.in_batches(of: 1, finish: second_book.id, order: [:asc, :desc]).to_a.last
1065
+ assert_equal second_book, relation.first
1066
+ end
1067
+
1068
+ test ".in_batches with scope and multiple column ordering and using composite primary key" do
1069
+ Cpk::Book.insert_all!([
1070
+ { author_id: 1, id: 1 },
1071
+ { author_id: 1, id: 2 },
1072
+ { author_id: 1, id: 3 }
1073
+ ])
1074
+ book1, book2 = Cpk::Book.order(author_id: :asc, id: :desc).first(2)
1075
+ author_id, id = book1.id
1076
+ relation = Cpk::Book.where("author_id >= ? AND id < ?", author_id, id).in_batches(of: 1, order: [:asc, :desc]).first
1077
+ assert_equal book2, relation.first
1078
+ end
695
1079
  end