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
data/test/models/post.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "models/tag"
4
+ require "models/tagging"
5
+ require "models/comment"
6
+ require "models/category"
7
+
3
8
  class Post < ActiveRecord::Base
4
9
  class CategoryPost < ActiveRecord::Base
5
10
  self.table_name = "categories_posts"
@@ -30,9 +35,15 @@ class Post < ActiveRecord::Base
30
35
  scope :containing_the_letter_a, -> { where("body LIKE '%a%'") }
31
36
  scope :titled_with_an_apostrophe, -> { where("title LIKE '%''%'") }
32
37
  scope :ranked_by_comments, -> { order(table[:comments_count].desc) }
38
+ scope :ordered_by_post_id, -> { order("posts.post_id ASC") }
33
39
 
34
40
  scope :limit_by, lambda { |l| limit(l) }
35
41
  scope :locked, -> { lock }
42
+ scope :most_commented, lambda { |comments_count|
43
+ joins(:comments)
44
+ .group("posts.id", "posts.author_id", "posts.title", "posts.body", "posts.type", "posts.legacy_comments_count", "posts.taggings_with_delete_all_count", "posts.taggings_with_destroy_count", "posts.tags_count", "posts.indestructible_tags_count", "posts.tags_with_destroy_count", "posts.tags_with_nullify_count")
45
+ .having("count(comments.id) >= ?", comments_count)
46
+ }
36
47
 
37
48
  belongs_to :author
38
49
  belongs_to :readonly_author, -> { readonly }, class_name: "Author", foreign_key: :author_id
@@ -40,6 +51,7 @@ class Post < ActiveRecord::Base
40
51
  belongs_to :author_with_posts, -> { includes(:posts) }, class_name: "Author", foreign_key: :author_id
41
52
  belongs_to :author_with_address, -> { includes(:author_address) }, class_name: "Author", foreign_key: :author_id
42
53
  belongs_to :author_with_select, -> { select(:id) }, class_name: "Author", foreign_key: :author_id
54
+ belongs_to :author_with_the_letter_a, -> { where("name LIKE '%a%'") }, class_name: "Author", foreign_key: :author_id
43
55
 
44
56
  def first_comment
45
57
  super.body
@@ -54,6 +66,7 @@ class Post < ActiveRecord::Base
54
66
 
55
67
  scope :with_comments, -> { preload(:comments) }
56
68
  scope :with_tags, -> { preload(:taggings) }
69
+ scope :with_tags_cte, -> { with(posts_with_tags: where("tags_count > 0")).from("posts_with_tags AS posts") }
57
70
 
58
71
  scope :tagged_with, ->(id) { joins(:taggings).where(taggings: { tag_id: id }) }
59
72
  scope :tagged_with_comment, ->(comment) { joins(:taggings).where(taggings: { comment: comment }) }
@@ -84,6 +97,8 @@ class Post < ActiveRecord::Base
84
97
  end
85
98
  end
86
99
 
100
+ has_many :comments_with_extending, -> { extending(NamedExtension) }, class_name: "Comment", foreign_key: "post_id"
101
+
87
102
  has_many :comments_with_extend_2, extend: [NamedExtension, NamedExtension2], class_name: "Comment", foreign_key: "post_id"
88
103
 
89
104
  has_many :author_favorites, through: :author
@@ -97,6 +112,10 @@ class Post < ActiveRecord::Base
97
112
  has_one :very_special_comment
98
113
  has_one :very_special_comment_with_post, -> { includes(:post) }, class_name: "VerySpecialComment"
99
114
  has_one :very_special_comment_with_post_with_joins, -> { joins(:post).order("posts.id") }, class_name: "VerySpecialComment"
115
+ has_one :very_special_comment_with_string_joins, -> {
116
+ joins("JOIN posts AS p1 ON comments.post_id = p1.id")
117
+ .where.not(p1: { id: 999999 })
118
+ }, class_name: "VerySpecialComment"
100
119
  has_many :special_comments
101
120
  has_many :nonexistent_comments, -> { where "comments.id < 0" }, class_name: "Comment"
102
121
 
@@ -109,6 +128,13 @@ class Post < ActiveRecord::Base
109
128
  has_and_belongs_to_many :categories
110
129
  has_and_belongs_to_many :special_categories, join_table: "categories_posts", association_foreign_key: "category_id"
111
130
 
131
+ has_many :essays, through: :categories
132
+ has_many :authors_of_essays_named_bob,
133
+ -> { where(name: "Bob") },
134
+ through: :essays,
135
+ source: :writer,
136
+ source_type: "Author"
137
+
112
138
  has_many :taggings, as: :taggable, counter_cache: :tags_count
113
139
  has_many :tags, through: :taggings do
114
140
  def add_joins_and_select
@@ -224,6 +250,7 @@ class FirstPost < ActiveRecord::Base
224
250
 
225
251
  has_many :comments, foreign_key: :post_id
226
252
  has_one :comment, foreign_key: :post_id
253
+ has_one :comment_with_inverse, class_name: "Comment", inverse_of: :post_with_inverse
227
254
  end
228
255
 
229
256
  class PostWithDefaultSelect < ActiveRecord::Base
@@ -318,12 +345,29 @@ end
318
345
  class SubConditionalStiPost < ConditionalStiPost
319
346
  end
320
347
 
348
+ class PostWithDestroyCallback < ActiveRecord::Base
349
+ self.inheritance_column = :disabled
350
+ self.table_name = "posts"
351
+
352
+ before_destroy do
353
+ throw :abort if id == 1
354
+ end
355
+ end
356
+
321
357
  class FakeKlass
322
358
  extend ActiveRecord::Delegation::DelegateCache
323
359
 
324
360
  class << self
325
- def connection
326
- Post.connection
361
+ def scope_registry
362
+ ActiveRecord::Scoping::ScopeRegistry.instance
363
+ end
364
+
365
+ def adapter_class
366
+ Post.adapter_class
367
+ end
368
+
369
+ def lease_connection
370
+ Post.lease_connection
327
371
  end
328
372
 
329
373
  def table_name
@@ -365,7 +409,26 @@ class FakeKlass
365
409
  def base_class?
366
410
  true
367
411
  end
412
+
413
+ def deterministic_encrypted_attributes
414
+ end
368
415
  end
369
416
 
370
417
  inherited self
371
418
  end
419
+
420
+ class Postesque < ActiveRecord::Base
421
+ belongs_to :author, class_name: "Author", foreign_key: :author_name, primary_key: :name
422
+ belongs_to :author_with_address, class_name: "Author", foreign_key: :author_id
423
+ belongs_to :author_with_the_letter_a, class_name: "Author", foreign_key: :author_id
424
+ end
425
+
426
+ class PostRecord < ActiveRecord::Base
427
+ has_many :comments
428
+
429
+ class << self
430
+ def model_name
431
+ ActiveModel::Name.new(self, nil, "Post")
432
+ end
433
+ end
434
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "models/post"
4
+
5
+ class EncryptedPost < Post
6
+ self.table_name = "posts"
7
+
8
+ # We want to modify the key for testing purposes
9
+ class MutableDerivedSecretKeyProvider < ActiveRecord::Encryption::DerivedSecretKeyProvider
10
+ attr_accessor :keys
11
+ end
12
+
13
+ encrypts :title
14
+ encrypts :body, key_provider: MutableDerivedSecretKeyProvider.new("my post body secret!")
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PostWithPrefetchedPk < ActiveRecord::Base
4
+ self.table_name = "posts"
5
+
6
+ class << self
7
+ def prefetch_primary_key?
8
+ true
9
+ end
10
+
11
+ def next_sequence_value
12
+ 123456
13
+ end
14
+ end
15
+ end
@@ -16,6 +16,7 @@ class Project < ActiveRecord::Base
16
16
  has_and_belongs_to_many :well_paid_salary_groups, -> { group("developers.salary").having("SUM(salary) > 10000").select("SUM(salary) as salary") }, class_name: "Developer"
17
17
  belongs_to :firm
18
18
  has_one :lead_developer, through: :firm, inverse_of: :contracted_projects
19
+ has_one :lead_developer_disable_joins, through: :firm, inverse_of: :contracted_projects, source: :lead_developer, disable_joins: true
19
20
 
20
21
  begin
21
22
  previous_value, ActiveRecord::Base.belongs_to_required_by_default =
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Publication < ActiveRecord::Base
4
+ belongs_to :editor_in_chief, class_name: "Editor", inverse_of: :publication, optional: true
5
+ has_many :editorships
6
+ has_many :editors, through: :editorships
7
+
8
+ after_initialize do
9
+ self.editor_in_chief = build_editor_in_chief(name: "John Doe")
10
+ end
11
+
12
+ after_save_commit :touch_name
13
+ def touch_name
14
+ self.name = "#{name} (touched)"
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RaisesArgumentError
4
+ raise ArgumentError
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RaisesNoMethodError
4
+ Object.new.calling_a_non_existing_method
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Recipient < ActiveRecord::Base
4
+ belongs_to :message, touch: true
5
+ end
@@ -21,5 +21,5 @@ end
21
21
 
22
22
  class BadReference < ActiveRecord::Base
23
23
  self.table_name = "references"
24
- default_scope { where(favourite: false) }
24
+ default_scope { where(favorite: false) }
25
25
  end
data/test/models/reply.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require "models/topic"
4
4
 
5
5
  class Reply < Topic
6
- belongs_to :topic, foreign_key: "parent_id", counter_cache: true
6
+ belongs_to :topic, foreign_key: "parent_id", counter_cache: true, inverse_of: :replies
7
7
  belongs_to :topic_with_primary_key, class_name: "Topic", primary_key: "title", foreign_key: "parent_title", counter_cache: "replies_count", touch: true
8
8
  has_many :replies, class_name: "SillyReply", dependent: :destroy, foreign_key: "parent_id"
9
9
  has_many :silly_unique_replies, dependent: :destroy, foreign_key: "parent_id"
data/test/models/room.rb CHANGED
@@ -3,4 +3,7 @@
3
3
  class Room < ActiveRecord::Base
4
4
  belongs_to :user
5
5
  belongs_to :owner, class_name: "User"
6
+
7
+ belongs_to :landlord, class_name: "User", dependent: :destroy, inverse_of: :let_room
8
+ belongs_to :tenant, class_name: "User", dependent: :destroy, inverse_of: :rented_room
6
9
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Models under `Sharded` namespace represent an application that can be sharded by a `blog_id` column.
4
+ # `Blog` model plays the role of a tenant in the application.
5
+ # Being sharded by the `blog_id` means that queries to the database include the `blog_id` column in the clauses
6
+ # which serves as a sharding key allows presumed sharding implementation to route the query to a correct shard.
7
+
8
+ module Sharded
9
+ class Blog < ActiveRecord::Base
10
+ self.table_name = :sharded_blogs
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class BlogPost < ActiveRecord::Base
5
+ self.table_name = :sharded_blog_posts
6
+ query_constraints :blog_id, :id
7
+
8
+ belongs_to :parent, class_name: name, polymorphic: true
9
+ belongs_to :blog
10
+ has_many :comments
11
+ has_many :delete_comments, class_name: "Sharded::Comment", dependent: :delete_all
12
+ has_many :children, class_name: name, as: :parent
13
+
14
+ has_many :blog_post_tags
15
+ has_many :tags, through: :blog_post_tags
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class BlogPostDestroyAsync < ActiveRecord::Base
5
+ self.table_name = :sharded_blog_posts
6
+ query_constraints :blog_id, :id
7
+
8
+ belongs_to :blog
9
+ has_many :comments, dependent: :destroy_async, foreign_key: [:blog_id, :blog_post_id], class_name: "Sharded::CommentDestroyAsync"
10
+
11
+ has_many :blog_post_tags, foreign_key: [:blog_id, :blog_post_id], class_name: "Sharded::BlogPostTag"
12
+ has_many :tags, through: :blog_post_tags, dependent: :destroy_async, class_name: "Sharded::Tag"
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class BlogPostTag < ActiveRecord::Base
5
+ self.table_name = :sharded_blog_posts_tags
6
+ query_constraints :blog_id, :id
7
+
8
+ belongs_to :blog_post
9
+ belongs_to :tag
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ # copy of the original `BlogPost` class, but with a different `query_constraints`
5
+ class BlogPostWithRevision < ActiveRecord::Base
6
+ self.table_name = :sharded_blog_posts
7
+ query_constraints :blog_id, :revision, :id
8
+
9
+ has_many :comments, primary_key: [:blog_id, :id], foreign_key: [:blog_id, :blog_post_id]
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class Comment < ActiveRecord::Base
5
+ self.table_name = :sharded_comments
6
+ query_constraints :blog_id, :id
7
+
8
+ belongs_to :blog_post
9
+ belongs_to :blog_post_by_id, class_name: "Sharded::BlogPost", foreign_key: :blog_post_id, primary_key: :id
10
+ belongs_to :blog
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class CommentDestroyAsync < ActiveRecord::Base
5
+ self.table_name = :sharded_comments
6
+ query_constraints :blog_id, :id
7
+
8
+ belongs_to :blog_post, dependent: :destroy_async, foreign_key: [:blog_id, :blog_post_id], class_name: "Sharded::BlogPostDestroyAsync"
9
+ belongs_to :blog_post_by_id, class_name: "Sharded::BlogPostDestroyAsync", foreign_key: :blog_post_id
10
+ belongs_to :blog
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sharded
4
+ class Tag < ActiveRecord::Base
5
+ self.table_name = :sharded_tags
6
+ query_constraints :blog_id, :id
7
+
8
+ has_many :blog_post_tags
9
+ has_many :blog_posts, through: :blog_post_tags
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sharded/blog"
4
+ require_relative "sharded/blog_post"
5
+ require_relative "sharded/blog_post_with_revision"
6
+ require_relative "sharded/comment"
7
+ require_relative "sharded/tag"
8
+ require_relative "sharded/blog_post_tag"
data/test/models/ship.rb CHANGED
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  class ShipWithoutNestedAttributes < ActiveRecord::Base
26
26
  self.table_name = "ships"
27
- has_many :prisoners, inverse_of: :ship, foreign_key: :ship_id
27
+ has_many :prisoners, inverse_of: :ship
28
28
  has_many :parts, class_name: "ShipPart", foreign_key: :ship_id
29
29
 
30
30
  validates :name, presence: true, if: -> { true }
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ShippingLine < ActiveRecord::Base
4
+ belongs_to :invoice, touch: true
5
+ has_many :discount_applications, class_name: "ShippingLineDiscountApplication"
6
+ end
7
+
8
+ class ShippingLineDiscountApplication < ActiveRecord::Base
9
+ belongs_to :shipping_line
10
+ belongs_to :discount
11
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  class Subscriber < ActiveRecord::Base
4
4
  self.primary_key = "nick"
5
+
5
6
  has_many :subscriptions
6
7
  has_many :books, through: :subscriptions
7
8
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Subscription < ActiveRecord::Base
4
+ self.automatically_invert_plural_associations = true
5
+
4
6
  belongs_to :subscriber, counter_cache: :books_count
5
- belongs_to :book
7
+ belongs_to :book, -> { author_visibility_visible }
6
8
 
7
9
  validates_presence_of :subscriber_id, :book_id
8
10
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TooLongTableName < ActiveRecord::Base
4
+ self.table_name = "toooooooooooooooooooooooooooooooooo_long_table_names"
5
+ end
data/test/models/topic.rb CHANGED
@@ -46,7 +46,7 @@ class Topic < ActiveRecord::Base
46
46
  end
47
47
  end
48
48
 
49
- has_many :replies, dependent: :destroy, foreign_key: "parent_id", autosave: true
49
+ has_many :replies, dependent: :destroy, autosave: true, inverse_of: :topic
50
50
  has_many :approved_replies, -> { approved }, class_name: "Reply", foreign_key: "parent_id", counter_cache: "replies_count"
51
51
  has_many :open_replies, -> { open }, class_name: "Reply", foreign_key: "parent_id"
52
52
 
@@ -144,6 +144,8 @@ end
144
144
 
145
145
  class TitlePrimaryKeyTopic < Topic
146
146
  self.primary_key = :title
147
+
148
+ alias_attribute :id_value, :id
147
149
  end
148
150
 
149
151
  module Web
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TrafficLight < ActiveRecord::Base
4
- serialize :state, Array
5
- serialize :long_state, Array
4
+ serialize :state, type: Array
5
+ serialize :long_state, type: Array
6
6
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ require "models/traffic_light"
5
+
6
+ class EncryptedTrafficLight < TrafficLight
7
+ encrypts :state
8
+ end
9
+
10
+ class EncryptedFirstTrafficLight < ActiveRecord::Base
11
+ self.table_name = "traffic_lights"
12
+
13
+ encrypts :state
14
+ serialize :state, type: Array
15
+ serialize :long_state, type: Array
16
+ end
17
+
18
+ class EncryptedTrafficLightWithStoreState < TrafficLight
19
+ store :state, accessors: %i[ color ], coder: ActiveRecord::Coders::JSON
20
+ encrypts :state
21
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Translation < ActiveRecord::Base
4
+ belongs_to :attachment, optional: true
5
+
6
+ validates :locale, presence: true
7
+ validates :key, presence: true
8
+ validates :value, presence: true
9
+ end
@@ -6,7 +6,7 @@ class Treasure < ActiveRecord::Base
6
6
  # No counter_cache option given
7
7
  belongs_to :ship
8
8
 
9
- has_many :price_estimates, as: :estimate_of
9
+ has_many :price_estimates, as: :estimate_of, autosave: true
10
10
  has_and_belongs_to_many :rich_people, join_table: "peoples_treasures", validate: false
11
11
 
12
12
  accepts_nested_attributes_for :looter
data/test/models/tyre.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Tyre < ActiveRecord::Base
4
- belongs_to :car
4
+ belongs_to :car, counter_cache: { active: true, column: :custom_tyres_count }
5
5
 
6
6
  def self.custom_find(id)
7
7
  find(id)
data/test/models/user.rb CHANGED
@@ -3,6 +3,9 @@
3
3
  require "models/job"
4
4
 
5
5
  class User < ActiveRecord::Base
6
+ has_secure_password validations: false
7
+ has_secure_password :recovery_password, validations: false
8
+
6
9
  has_secure_token
7
10
  has_secure_token :auth_token, length: 36
8
11
 
@@ -15,8 +18,21 @@ class User < ActiveRecord::Base
15
18
  has_one :family_tree, -> { where(token: nil) }, foreign_key: "member_id"
16
19
  has_one :family, through: :family_tree
17
20
  has_many :family_members, through: :family, source: :members
21
+
22
+ has_one :let_room, class_name: "Room", foreign_key: "landlord_id", dependent: :destroy
23
+ has_one :rented_room, class_name: "Room", foreign_key: "tenant_id", dependent: :destroy
18
24
  end
19
25
 
20
26
  class UserWithNotification < User
21
27
  after_create -> { Notification.create! message: "A new user has been created." }
22
28
  end
29
+
30
+ module Nested
31
+ class User < ActiveRecord::Base
32
+ self.table_name = "users"
33
+ end
34
+
35
+ class NestedUser < ActiveRecord::Base
36
+ has_many :nested_users
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserWithInvalidRelation < ActiveRecord::Base
4
+ has_one :not_a_class
5
+
6
+ has_one :class_name_provided_not_a_class, class_name: "NotAClass"
7
+
8
+ has_one :account_invalid
9
+
10
+ has_one :account_class_name, class_name: "AccountInvalid"
11
+
12
+ has_many :user_info_invalid
13
+ has_many :info_invalids, through: :user_info_invalid
14
+
15
+ has_many :infos_class_name, through: :user_info, class_name: "InfoInvalid"
16
+
17
+ has_many :user_infos_class_name, class_name: "UserInfoInvalid"
18
+ has_many :infos_through_class_name, through: :user_infos_class_name, class_name: "InfoInvalid"
19
+ end
20
+
21
+ class AccountInvalid; end
22
+
23
+ class InfoInvalid; end
24
+
25
+ class UserInfoInvalid < ActiveRecord::Base
26
+ belongs_to :info_invalid
27
+ belongs_to :user_invalid
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UuidComment < ActiveRecord::Base
4
+ has_one :uuid_entry, as: :entryable
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UuidEntry < ActiveRecord::Base
4
+ delegated_type :entryable, types: %w[ UuidMessage UuidComment ], primary_key: :uuid, foreign_key: :entryable_uuid
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UuidMessage < ActiveRecord::Base
4
+ has_one :uuid_entry, as: :entryable
5
+ end
data/test/models/zine.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Zine < ActiveRecord::Base
4
- has_many :interests, inverse_of: :zine, foreign_key: "zine_id"
4
+ has_many :interests, inverse_of: :zine
5
+ has_many :polymorphic_humans, through: :interests, source_type: "Human"
5
6
  end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ActiveRecord::Schema.define do
4
- if supports_datetime_with_precision?
5
- create_table :datetime_defaults, force: true do |t|
6
- t.datetime :modified_datetime, default: -> { "CURRENT_TIMESTAMP" }
7
- t.datetime :precise_datetime, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
8
- end
4
+ create_table :datetime_defaults, force: true do |t|
5
+ t.datetime :modified_datetime, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
6
+ t.datetime :precise_datetime, default: -> { "CURRENT_TIMESTAMP(6)" }
7
+ t.datetime :updated_datetime, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
8
+ end
9
9
 
10
- create_table :timestamp_defaults, force: true do |t|
11
- t.timestamp :nullable_timestamp
12
- t.timestamp :modified_timestamp, default: -> { "CURRENT_TIMESTAMP" }
13
- t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
14
- end
10
+ create_table :timestamp_defaults, force: true do |t|
11
+ t.timestamp :nullable_timestamp
12
+ t.timestamp :modified_timestamp, precision: nil, default: -> { "CURRENT_TIMESTAMP" }
13
+ t.timestamp :precise_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6)" }
14
+ t.timestamp :updated_timestamp, precision: 6, default: -> { "CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" }
15
15
  end
16
16
 
17
17
  create_table :defaults, force: true do |t|
@@ -19,8 +19,9 @@ ActiveRecord::Schema.define do
19
19
  t.datetime :fixed_time, default: "2004-01-01 00:00:00"
20
20
  t.column :char1, "char(1)", default: "Y"
21
21
  t.string :char2, limit: 50, default: "a varchar field"
22
- if supports_default_expression?
22
+ if ActiveRecord::TestCase.supports_default_expression?
23
23
  t.binary :uuid, limit: 36, default: -> { "(uuid())" }
24
+ t.string :char2_concatenated, default: -> { "(concat(`char2`, '-'))" }
24
25
  end
25
26
  end
26
27
 
@@ -47,7 +48,7 @@ ActiveRecord::Schema.define do
47
48
  t.index :var_binary
48
49
  end
49
50
 
50
- create_table :key_tests, force: true do |t|
51
+ create_table :key_tests, force: true, options: "CHARSET=utf8 ENGINE=MyISAM" do |t|
51
52
  t.string :awesome
52
53
  t.string :pizza
53
54
  t.string :snacks
@@ -79,4 +80,17 @@ ActiveRecord::Schema.define do
79
80
  SELECT * FROM topics LIMIT num;
80
81
  END
81
82
  SQL
83
+
84
+ if supports_insert_returning?
85
+ create_table :pk_autopopulated_by_a_trigger_records, force: true, id: false do |t|
86
+ t.integer :id, null: false
87
+ end
88
+
89
+ execute <<~SQL
90
+ CREATE TRIGGER before_insert_trigger
91
+ BEFORE INSERT ON pk_autopopulated_by_a_trigger_records
92
+ FOR EACH ROW
93
+ SET NEW.id = (SELECT COALESCE(MAX(id), 0) + 1 FROM pk_autopopulated_by_a_trigger_records);
94
+ SQL
95
+ end
82
96
  end