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
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+
5
+ module ActiveRecord
6
+ class ShardsKeysTest < ActiveRecord::TestCase
7
+ class UnshardedBase < ActiveRecord::Base
8
+ self.abstract_class = true
9
+ end
10
+
11
+ class UnshardedModel < UnshardedBase
12
+ end
13
+
14
+ class ShardedBase < ActiveRecord::Base
15
+ self.abstract_class = true
16
+ end
17
+
18
+ class ShardedModel < ShardedBase
19
+ end
20
+
21
+ def setup
22
+ ActiveRecord::Base.instance_variable_set(:@shard_keys, nil)
23
+ @previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "default_env"
24
+
25
+ config = {
26
+ "default_env" => {
27
+ "primary" => {
28
+ adapter: "sqlite3",
29
+ database: ":memory:"
30
+ },
31
+ "shard_one" => {
32
+ adapter: "sqlite3",
33
+ database: ":memory:"
34
+ },
35
+ "shard_one_reading" => {
36
+ adapter: "sqlite3",
37
+ database: ":memory:"
38
+ },
39
+ "shard_two" => {
40
+ adapter: "sqlite3",
41
+ database: ":memory:"
42
+ },
43
+ "shard_two_reading" => {
44
+ adapter: "sqlite3",
45
+ database: ":memory:"
46
+ },
47
+ }
48
+ }
49
+
50
+ @prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, config
51
+
52
+ UnshardedBase.connects_to database: { writing: :primary }
53
+
54
+ ShardedBase.connects_to shards: {
55
+ shard_one: { writing: :shard_one, reading: :shard_one_reading },
56
+ shard_two: { writing: :shard_two, reading: :shard_two_reading },
57
+ }
58
+ end
59
+
60
+ def teardown
61
+ clean_up_connection_handler
62
+ ActiveRecord::Base.configurations = @prev_configs
63
+ ActiveRecord::Base.establish_connection(:arunit)
64
+ ENV["RAILS_ENV"] = @previous_env
65
+ end
66
+
67
+ def test_connects_to_sets_shard_keys
68
+ assert_empty(ActiveRecord::Base.shard_keys)
69
+ assert_equal([:shard_one, :shard_two], ShardedBase.shard_keys)
70
+ end
71
+
72
+ def test_connects_to_sets_shard_keys_for_descendents
73
+ assert_equal(ShardedBase.shard_keys, ShardedModel.shard_keys)
74
+ end
75
+
76
+ def test_sharded?
77
+ assert_not ActiveRecord::Base.sharded?
78
+ assert_not UnshardedBase.sharded?
79
+ assert_not UnshardedModel.sharded?
80
+
81
+ assert_predicate ShardedBase, :sharded?
82
+ assert_predicate ShardedModel, :sharded?
83
+ end
84
+
85
+ def test_connected_to_all_shards
86
+ unsharded_results = UnshardedBase.connected_to_all_shards do
87
+ UnshardedBase.connection_pool.db_config.name
88
+ end
89
+
90
+ sharded_results = ShardedBase.connected_to_all_shards do
91
+ ShardedBase.connection_pool.db_config.name
92
+ end
93
+
94
+ assert_empty unsharded_results
95
+ assert_equal(["shard_one", "shard_two"], sharded_results)
96
+ end
97
+
98
+ def test_connected_to_all_shards_can_switch_each_to_reading_role
99
+ # We teardown the shared connection pool and call .connects_to again
100
+ # because .setup_shared_connection_pool overwrites our reading configs
101
+ # with the writing role configs.
102
+ teardown_shared_connection_pool
103
+ ShardedBase.connects_to shards: {
104
+ shard_one: { writing: :shard_one, reading: :shard_one_reading },
105
+ shard_two: { writing: :shard_two, reading: :shard_two_reading },
106
+ }
107
+
108
+ results = ShardedBase.connected_to_all_shards(role: :reading) do
109
+ ShardedBase.connection_pool.db_config.name
110
+ end
111
+
112
+ assert_equal(["shard_one_reading", "shard_two_reading"], results)
113
+ end
114
+
115
+ def test_connected_to_all_shards_respects_preventing_writes
116
+ assert_not ShardedBase.current_preventing_writes
117
+
118
+ results = ShardedBase.connected_to_all_shards(role: :writing, prevent_writes: true) do
119
+ ShardedBase.current_preventing_writes
120
+ end
121
+
122
+ assert_equal([true, true], results)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cases/helper"
4
+ require "models/person"
5
+ require "action_dispatch"
6
+
7
+ module ActiveRecord
8
+ class ShardSelectorTest < ActiveRecord::TestCase
9
+ def test_middleware_locks_to_shard_by_default
10
+ middleware = ActiveRecord::Middleware::ShardSelector.new(lambda { |env|
11
+ assert_predicate ActiveRecord::Base, :shard_swapping_prohibited?
12
+ [200, {}, ["body"]]
13
+ }, ->(*) { :shard_one })
14
+
15
+ assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
16
+ end
17
+
18
+ def test_middleware_can_turn_off_lock_option
19
+ middleware = ActiveRecord::Middleware::ShardSelector.new(lambda { |env|
20
+ assert_not_predicate ActiveRecord::Base, :shard_swapping_prohibited?
21
+ [200, {}, ["body"]]
22
+ }, ->(*) { :shard_one }, { lock: false })
23
+
24
+ assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
25
+ end
26
+
27
+ def test_middleware_can_change_shards
28
+ middleware = ActiveRecord::Middleware::ShardSelector.new(lambda { |env|
29
+ assert ActiveRecord::Base.connected_to?(role: :writing, shard: :shard_one)
30
+ [200, {}, ["body"]]
31
+ }, ->(*) { :shard_one })
32
+
33
+ assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
34
+ end
35
+
36
+ def test_middleware_can_handle_string_shards
37
+ middleware = ActiveRecord::Middleware::ShardSelector.new(lambda { |env|
38
+ assert ActiveRecord::Base.connected_to?(role: :writing, shard: :shard_one)
39
+ [200, {}, ["body"]]
40
+ }, ->(*) { "shard_one" })
41
+
42
+ assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
43
+ end
44
+ end
45
+ end
@@ -5,17 +5,30 @@ require "models/account"
5
5
  require "models/company"
6
6
  require "models/toy"
7
7
  require "models/matey"
8
+ require "models/cpk"
8
9
 
9
10
  SIGNED_ID_VERIFIER_TEST_SECRET = -> { "This is normally set by the railtie initializer when used with Rails!" }
10
11
 
11
12
  ActiveRecord::Base.signed_id_verifier_secret = SIGNED_ID_VERIFIER_TEST_SECRET
12
13
 
13
14
  class SignedIdTest < ActiveRecord::TestCase
14
- fixtures :accounts, :toys, :companies
15
+ class GetSignedIDInCallback < ActiveRecord::Base
16
+ self.table_name = "accounts"
17
+ after_create :set_signed_id
18
+ attr_reader :signed_id_from_callback
19
+
20
+ private
21
+ def set_signed_id
22
+ @signed_id_from_callback = signed_id
23
+ end
24
+ end
25
+
26
+ fixtures :accounts, :toys, :companies, :cpk_orders
15
27
 
16
28
  setup do
17
29
  @account = Account.first
18
30
  @toy = Toy.first
31
+ @cpk_order = Cpk::Order.first
19
32
  end
20
33
 
21
34
  test "find signed record" do
@@ -32,6 +45,16 @@ class SignedIdTest < ActiveRecord::TestCase
32
45
  assert_equal @toy, Toy.find_signed(@toy.signed_id)
33
46
  end
34
47
 
48
+ test "find signed record with composite primary key" do
49
+ assert_equal @cpk_order, Cpk::Order.find_signed(@cpk_order.signed_id)
50
+ end
51
+
52
+ test "find signed record on relation with composite primary key" do
53
+ assert_equal @cpk_order, Cpk::Order.where("1=1").find_signed(@cpk_order.signed_id)
54
+
55
+ assert_nil Cpk::Order.where("1=0").find_signed(@cpk_order.signed_id)
56
+ end
57
+
35
58
  test "find signed record for single table inheritance (STI Models)" do
36
59
  assert_equal Company.first, Company.find_signed(Company.first.signed_id)
37
60
  end
@@ -59,6 +82,10 @@ class SignedIdTest < ActiveRecord::TestCase
59
82
  assert_equal @toy, Toy.find_signed!(@toy.signed_id)
60
83
  end
61
84
 
85
+ test "find signed record with a bang with composite primary key" do
86
+ assert_equal @cpk_order, Cpk::Order.find_signed!(@cpk_order.signed_id)
87
+ end
88
+
62
89
  test "find signed record with a bang for single table inheritance (STI Models)" do
63
90
  assert_equal Company.first, Company.find_signed!(Company.first.signed_id)
64
91
  end
@@ -67,11 +94,11 @@ class SignedIdTest < ActiveRecord::TestCase
67
94
  assert_nil Account.find_signed("this won't find anything")
68
95
  end
69
96
 
70
- test "find signed record within expiration date" do
97
+ test "find signed record within expiration duration" do
71
98
  assert_equal @account, Account.find_signed(@account.signed_id(expires_in: 1.minute))
72
99
  end
73
100
 
74
- test "fail to find signed record within expiration date" do
101
+ test "fail to find signed record within expiration duration" do
75
102
  signed_id = @account.signed_id(expires_in: 1.minute)
76
103
  travel 2.minutes
77
104
  assert_nil Account.find_signed(signed_id)
@@ -83,6 +110,16 @@ class SignedIdTest < ActiveRecord::TestCase
83
110
  assert_nil Account.find_signed signed_id
84
111
  end
85
112
 
113
+ test "find signed record within expiration time" do
114
+ assert_equal @account, Account.find_signed(@account.signed_id(expires_at: 1.minute.from_now))
115
+ end
116
+
117
+ test "fail to find signed record within expiration time" do
118
+ signed_id = @account.signed_id(expires_at: 1.minute.from_now)
119
+ travel 2.minutes
120
+ assert_nil Account.find_signed(signed_id)
121
+ end
122
+
86
123
  test "find signed record with purpose" do
87
124
  assert_equal @account, Account.find_signed(@account.signed_id(purpose: :v1), purpose: :v1)
88
125
  end
@@ -99,11 +136,11 @@ class SignedIdTest < ActiveRecord::TestCase
99
136
  end
100
137
  end
101
138
 
102
- test "find signed record with a bang within expiration date" do
139
+ test "find signed record with a bang within expiration duration" do
103
140
  assert_equal @account, Account.find_signed!(@account.signed_id(expires_in: 1.minute))
104
141
  end
105
142
 
106
- test "finding signed record outside expiration date raises on the bang" do
143
+ test "finding signed record outside expiration duration raises on the bang" do
107
144
  signed_id = @account.signed_id(expires_in: 1.minute)
108
145
  travel 2.minutes
109
146
 
@@ -157,6 +194,11 @@ class SignedIdTest < ActiveRecord::TestCase
157
194
  ActiveRecord::Base.signed_id_verifier_secret = SIGNED_ID_VERIFIER_TEST_SECRET
158
195
  end
159
196
 
197
+ test "always output url_safe" do
198
+ signed_id = @account.signed_id(purpose: "~~~~~~~~~")
199
+ assert_not signed_id.include?("+")
200
+ end
201
+
160
202
  test "use a custom verifier" do
161
203
  old_verifier = Account.signed_id_verifier
162
204
  Account.signed_id_verifier = ActiveSupport::MessageVerifier.new("sekret")
@@ -165,4 +207,14 @@ class SignedIdTest < ActiveRecord::TestCase
165
207
  ensure
166
208
  Account.signed_id_verifier = old_verifier
167
209
  end
210
+
211
+ test "cannot get a signed ID for a new record" do
212
+ assert_raises ArgumentError, match: /Cannot get a signed_id for a new record/ do
213
+ Account.new.signed_id
214
+ end
215
+ end
216
+
217
+ test "can get a signed ID in an after_create" do
218
+ assert_not_nil GetSignedIDInCallback.create.signed_id_from_callback
219
+ end
168
220
  end
@@ -6,24 +6,25 @@ require "models/liquid"
6
6
  require "models/molecule"
7
7
  require "models/numeric_data"
8
8
  require "models/electron"
9
+ require "models/clothing_item"
9
10
 
10
11
  module ActiveRecord
11
12
  class StatementCacheTest < ActiveRecord::TestCase
12
13
  def setup
13
- @connection = ActiveRecord::Base.connection
14
+ @connection = ActiveRecord::Base.lease_connection
14
15
  end
15
16
 
16
17
  def test_statement_cache
17
18
  Book.create(name: "my book")
18
19
  Book.create(name: "my other book")
19
20
 
20
- cache = StatementCache.create(Book.connection) do |params|
21
+ cache = StatementCache.create(ClothingItem.lease_connection) do |params|
21
22
  Book.where(name: params.bind)
22
23
  end
23
24
 
24
- b = cache.execute([ "my book" ], Book.connection)
25
+ b = cache.execute([ "my book" ], ClothingItem.lease_connection)
25
26
  assert_equal "my book", b[0].name
26
- b = cache.execute([ "my other book" ], Book.connection)
27
+ b = cache.execute([ "my other book" ], ClothingItem.lease_connection)
27
28
  assert_equal "my other book", b[0].name
28
29
  end
29
30
 
@@ -31,13 +32,13 @@ module ActiveRecord
31
32
  b1 = Book.create(name: "my book")
32
33
  b2 = Book.create(name: "my other book")
33
34
 
34
- cache = StatementCache.create(Book.connection) do |params|
35
+ cache = StatementCache.create(ClothingItem.lease_connection) do |params|
35
36
  Book.where(id: params.bind)
36
37
  end
37
38
 
38
- b = cache.execute([ b1.id ], Book.connection)
39
+ b = cache.execute([ b1.id ], ClothingItem.lease_connection)
39
40
  assert_equal b1.name, b[0].name
40
- b = cache.execute([ b2.id ], Book.connection)
41
+ b = cache.execute([ b2.id ], ClothingItem.lease_connection)
41
42
  assert_equal b2.name, b[0].name
42
43
  end
43
44
 
@@ -52,18 +53,18 @@ module ActiveRecord
52
53
  end
53
54
 
54
55
  def test_statement_cache_with_simple_statement
55
- cache = ActiveRecord::StatementCache.create(Book.connection) do |params|
56
+ cache = ActiveRecord::StatementCache.create(ClothingItem.lease_connection) do |params|
56
57
  Book.where(name: "my book").where("author_id > 3")
57
58
  end
58
59
 
59
60
  Book.create(name: "my book", author_id: 4)
60
61
 
61
- books = cache.execute([], Book.connection)
62
+ books = cache.execute([], ClothingItem.lease_connection)
62
63
  assert_equal "my book", books[0].name
63
64
  end
64
65
 
65
66
  def test_statement_cache_with_complex_statement
66
- cache = ActiveRecord::StatementCache.create(Book.connection) do |params|
67
+ cache = ActiveRecord::StatementCache.create(ClothingItem.lease_connection) do |params|
67
68
  Liquid.joins(molecules: :electrons).where("molecules.name" => "dioxane", "electrons.name" => "lepton")
68
69
  end
69
70
 
@@ -71,7 +72,7 @@ module ActiveRecord
71
72
  molecule = salty.molecules.create(name: "dioxane")
72
73
  molecule.electrons.create(name: "lepton")
73
74
 
74
- liquids = cache.execute([], Book.connection)
75
+ liquids = cache.execute([], ClothingItem.lease_connection)
75
76
  assert_equal "salty", liquids[0].name
76
77
  end
77
78
 
@@ -81,22 +82,22 @@ module ActiveRecord
81
82
  end
82
83
 
83
84
  def test_statement_cache_values_differ
84
- cache = ActiveRecord::StatementCache.create(Book.connection) do |params|
85
+ cache = ActiveRecord::StatementCache.create(ClothingItem.lease_connection) do |params|
85
86
  Book.where(name: "my book")
86
87
  end
87
88
 
88
- 3.times do
89
- Book.create(name: "my book")
89
+ 3.times do |i|
90
+ Book.create(name: "my book", author_id: i)
90
91
  end
91
92
 
92
- first_books = cache.execute([], Book.connection)
93
+ first_books = cache.execute([], ClothingItem.lease_connection)
93
94
 
94
- 3.times do
95
- Book.create(name: "my book")
95
+ 3.times do |i|
96
+ Book.create(name: "my book", author_id: i + 3)
96
97
  end
97
98
 
98
- additional_books = cache.execute([], Book.connection)
99
- assert first_books != additional_books
99
+ additional_books = cache.execute([], ClothingItem.lease_connection)
100
+ assert_not_equal first_books, additional_books
100
101
  end
101
102
 
102
103
  def test_unprepared_statements_dont_share_a_cache_with_prepared_statements
@@ -104,7 +105,7 @@ module ActiveRecord
104
105
  Book.create(name: "my other book")
105
106
 
106
107
  book = Book.find_by(name: "my book")
107
- other_book = Book.connection.unprepared_statement do
108
+ other_book = Book.lease_connection.unprepared_statement do
108
109
  Book.find_by(name: "my other book")
109
110
  end
110
111
 
@@ -112,29 +113,29 @@ module ActiveRecord
112
113
  end
113
114
 
114
115
  def test_find_by_does_not_use_statement_cache_if_table_name_is_changed
115
- book = Book.create(name: "my book")
116
+ liquid = Liquid.create(name: "salty")
116
117
 
117
- Book.find_by(name: book.name) # warming the statement cache.
118
+ Liquid.find_by(name: liquid.name) # warming the statement cache.
118
119
 
119
120
  # changing the table name should change the query that is not cached.
120
- Book.table_name = :birds
121
- assert_nil Book.find_by(name: book.name)
121
+ Liquid.table_name = :birds
122
+ assert_nil Liquid.find_by(name: liquid.name)
122
123
  ensure
123
- Book.table_name = :books
124
+ Liquid.table_name = :liquid
124
125
  end
125
126
 
126
127
  def test_find_does_not_use_statement_cache_if_table_name_is_changed
127
- book = Book.create(name: "my book")
128
+ liquid = Liquid.create(name: "salty")
128
129
 
129
- Book.find(book.id) # warming the statement cache.
130
+ Liquid.find(liquid.id) # warming the statement cache.
130
131
 
131
132
  # changing the table name should change the query that is not cached.
132
- Book.table_name = :birds
133
+ Liquid.table_name = :birds
133
134
  assert_raise ActiveRecord::RecordNotFound do
134
- Book.find(book.id)
135
+ Liquid.find(liquid.id)
135
136
  end
136
137
  ensure
137
- Book.table_name = :books
138
+ Liquid.table_name = :liquid
138
139
  end
139
140
 
140
141
  def test_find_association_does_not_use_statement_cache_if_table_name_is_changed
@@ -20,8 +20,10 @@ module ActiveRecord
20
20
  test "message contains no sql" do
21
21
  sql = Book.where(author_id: 96, cover: "hard").to_sql
22
22
  error = assert_raises(ActiveRecord::StatementInvalid) do
23
- Book.connection.send(:log, sql, Book.name) do
24
- raise MockDatabaseError
23
+ Book.lease_connection.send(:log, sql, Book.name) do
24
+ Book.lease_connection.send(:with_raw_connection) do
25
+ raise MockDatabaseError
26
+ end
25
27
  end
26
28
  end
27
29
  assert_not error.message.include?("SELECT")
@@ -31,8 +33,10 @@ module ActiveRecord
31
33
  sql = Book.where(author_id: 96, cover: "hard").to_sql
32
34
  binds = [Minitest::Mock.new, Minitest::Mock.new]
33
35
  error = assert_raises(ActiveRecord::StatementInvalid) do
34
- Book.connection.send(:log, sql, Book.name, binds) do
35
- raise MockDatabaseError
36
+ Book.lease_connection.send(:log, sql, Book.name, binds) do
37
+ Book.lease_connection.send(:with_raw_connection) do
38
+ raise MockDatabaseError
39
+ end
36
40
  end
37
41
  end
38
42
  assert_equal error.sql, sql
@@ -3,6 +3,8 @@
3
3
  require "cases/helper"
4
4
  require "models/admin"
5
5
  require "models/admin/user"
6
+ require "models/admin/user_json"
7
+ require "models/account"
6
8
 
7
9
  class StoreTest < ActiveRecord::TestCase
8
10
  fixtures :'admin/users'
@@ -29,6 +31,12 @@ class StoreTest < ActiveRecord::TestCase
29
31
  assert_equal "37signals.com", @john.homepage
30
32
  end
31
33
 
34
+ test "writing store attributes does not update unchanged value" do
35
+ admin_user = Admin::User.new(homepage: nil)
36
+ admin_user.homepage = nil
37
+ assert_equal({}, admin_user.settings)
38
+ end
39
+
32
40
  test "reading store attributes through accessors with prefix" do
33
41
  assert_equal "Quinn", @john.parent_name
34
42
  assert_nil @john.parent_birthday
@@ -81,7 +89,7 @@ class StoreTest < ActiveRecord::TestCase
81
89
 
82
90
  test "updating the store will mark accessor as changed" do
83
91
  @john.color = "red"
84
- assert @john.color_changed?
92
+ assert_predicate @john, :color_changed?
85
93
  end
86
94
 
87
95
  test "new record and no accessors changes" do
@@ -91,17 +99,25 @@ class StoreTest < ActiveRecord::TestCase
91
99
  assert_nil user.color_change
92
100
 
93
101
  user.color = "red"
94
- assert user.color_changed?
102
+ assert_predicate user, :color_changed?
95
103
  assert_nil user.color_was
96
104
  assert_equal "red", user.color_change[1]
97
105
  end
98
106
 
99
107
  test "updating the store won't mark accessor as changed if the whole store was updated" do
100
108
  @john.settings = { color: @john.color, some: "thing" }
101
- assert @john.settings_changed?
109
+ assert_predicate @john, :settings_changed?
102
110
  assert_not @john.color_changed?
103
111
  end
104
112
 
113
+ test "updating the store and changing it back won't mark accessor as changed" do
114
+ @john.color = "red"
115
+ assert_equal "black", @john.color_was
116
+ @john.color = "black"
117
+ assert_not_predicate @john, :settings_changed?
118
+ assert_not_predicate @john, :color_changed?
119
+ end
120
+
105
121
  test "updating the store populates the accessor changed array correctly" do
106
122
  @john.color = "red"
107
123
  assert_equal "black", @john.color_was
@@ -117,36 +133,53 @@ class StoreTest < ActiveRecord::TestCase
117
133
  test "nullifying the store mark accessor as changed" do
118
134
  color = @john.color
119
135
  @john.settings = nil
120
- assert @john.color_changed?
136
+ assert_predicate @john, :color_changed?
121
137
  assert_equal color, @john.color_was
122
138
  assert_equal [color, nil], @john.color_change
123
139
  end
124
140
 
125
141
  test "dirty methods for suffixed accessors" do
126
142
  @john.configs[:two_factor_auth] = true
127
- assert @john.two_factor_auth_configs_changed?
143
+ assert_predicate @john, :two_factor_auth_configs_changed?
128
144
  assert_nil @john.two_factor_auth_configs_was
129
145
  assert_equal [nil, true], @john.two_factor_auth_configs_change
130
146
  end
131
147
 
132
148
  test "dirty methods for prefixed accessors" do
133
149
  @john.spouse[:name] = "Lena"
134
- assert @john.partner_name_changed?
150
+ assert_predicate @john, :partner_name_changed?
135
151
  assert_equal "Dallas", @john.partner_name_was
136
152
  assert_equal ["Dallas", "Lena"], @john.partner_name_change
137
153
  end
138
154
 
139
155
  test "saved changes tracking for accessors" do
140
156
  @john.spouse[:name] = "Lena"
141
- assert @john.partner_name_changed?
157
+ assert_predicate @john, :partner_name_changed?
142
158
 
143
159
  @john.save!
144
160
  assert_not @john.partner_name_change
145
- assert @john.saved_change_to_partner_name?
161
+ assert_predicate @john, :saved_change_to_partner_name?
146
162
  assert_equal ["Dallas", "Lena"], @john.saved_change_to_partner_name
147
163
  assert_equal "Dallas", @john.partner_name_before_last_save
148
164
  end
149
165
 
166
+ test "saved changes tracking for accessors with json column" do
167
+ if current_adapter?(:Mysql2Adapter, :TrilogyAdapter) && ActiveRecord::Base.lease_connection.mariadb?
168
+ skip "MariaDB doesn't support JSON store_accessor"
169
+ end
170
+ @john.enable_friend_requests = true
171
+ assert_predicate @john, :enable_friend_requests_changed?
172
+
173
+ @john.save!
174
+ assert_not @john.enable_friend_requests_change
175
+ assert_predicate @john, :saved_change_to_enable_friend_requests?
176
+ assert_equal [nil, true], @john.saved_change_to_enable_friend_requests
177
+ # Make a second change to test key_before_last_save
178
+ @john.enable_friend_requests = false
179
+ @john.save
180
+ assert_equal true, @john.enable_friend_requests_before_last_save
181
+ end
182
+
150
183
  test "object initialization with not nullable column" do
151
184
  assert_equal true, @john.remember_login
152
185
  end
@@ -178,7 +211,24 @@ class StoreTest < ActiveRecord::TestCase
178
211
  assert_equal "heavy", @john.json_data["weight"]
179
212
  end
180
213
 
181
- test "convert store attributes from Hash to HashWithIndifferentAccess saving the data and access attributes indifferently" do
214
+ test "serialize stored nested attributes" do
215
+ user = Admin::User.find_by_name("Jamis")
216
+ user.update(settings: { "color" => { "jenny" => "blue" }, homepage: "rails" })
217
+
218
+ assert_equal true, user.settings.instance_of?(ActiveSupport::HashWithIndifferentAccess)
219
+ assert_equal "blue", user.settings[:color][:jenny]
220
+ assert_equal "blue", user.color[:jenny]
221
+ end
222
+
223
+ test "store takes precedence when updating store and accessor" do
224
+ user = Admin::User.find_by_name("Jamis")
225
+ user.update(settings: { homepage: "rails" }, homepage: "not rails")
226
+
227
+ assert_equal "rails", user.settings[:homepage]
228
+ assert_equal "rails", user.homepage
229
+ end
230
+
231
+ def test_convert_store_attributes_from_Hash_to_HashWithIndifferentAccess_saving_the_data_and_access_attributes_indifferently
182
232
  user = Admin::User.find_by_name("Jamis")
183
233
  assert_equal "symbol", user.settings[:symbol]
184
234
  assert_equal "symbol", user.settings["symbol"]
@@ -317,4 +367,18 @@ class StoreTest < ActiveRecord::TestCase
317
367
  test "prefix/suffix do not affect stored attributes" do
318
368
  assert_equal [:secret_question, :two_factor_auth, :login_retry], Admin::User.stored_attributes[:configs]
319
369
  end
370
+
371
+ test "store_accessor raises an exception if the column is not either serializable or a structured type" do
372
+ user = Class.new(Admin::User) do
373
+ store_accessor :name, :color
374
+ end.new
375
+
376
+ assert_raises ActiveRecord::ConfigurationError do
377
+ user.color
378
+ end
379
+
380
+ assert_raises ActiveRecord::ConfigurationError do
381
+ user.color = "blue"
382
+ end
383
+ end
320
384
  end