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
@@ -22,12 +22,12 @@ module Arel
22
22
 
23
23
  describe "equality" do
24
24
  it "is equal with equal ivars" do
25
- array = [Or.new("foo", "bar"), Or.new("foo", "bar")]
25
+ array = [Or.new(["foo", "bar"]), Or.new(["foo", "bar"])]
26
26
  assert_equal 1, array.uniq.size
27
27
  end
28
28
 
29
29
  it "is not equal with different ivars" do
30
- array = [Or.new("foo", "bar"), Or.new("foo", "baz")]
30
+ array = [Or.new(["foo", "bar"]), Or.new(["foo", "baz"])]
31
31
  assert_equal 2, array.uniq.size
32
32
  end
33
33
  end
@@ -7,7 +7,7 @@ module Arel
7
7
  module Nodes
8
8
  class SqlLiteralTest < Arel::Spec
9
9
  before do
10
- @visitor = Visitors::ToSql.new Table.engine.connection
10
+ @visitor = Visitors::ToSql.new Table.engine.lease_connection
11
11
  end
12
12
 
13
13
  def compile(node)
@@ -70,6 +70,23 @@ module Arel
70
70
  assert_equal("foo", YAML.load(yaml_literal))
71
71
  end
72
72
  end
73
+
74
+ describe "addition" do
75
+ it "generates a Fragments node" do
76
+ sql1 = Arel.sql "SELECT *"
77
+ sql2 = Arel.sql "FROM users"
78
+ fragments = sql1 + sql2
79
+ _(fragments).must_be_kind_of Arel::Nodes::Fragments
80
+ assert_equal([sql1, sql2], fragments.values)
81
+ end
82
+
83
+ it "fails if joined with something that is not an Arel node" do
84
+ sql = Arel.sql "SELECT *"
85
+ assert_raises ArgumentError do
86
+ sql + "Not a node"
87
+ end
88
+ end
89
+ end
73
90
  end
74
91
  end
75
92
  end
@@ -24,6 +24,18 @@ module Arel
24
24
  assert_equal 2, array.uniq.size
25
25
  end
26
26
  end
27
+
28
+ describe "#to_cte" do
29
+ it "returns a Cte node using the TableAlias's name and relation" do
30
+ relation = Table.new(:users).project(Arel.star)
31
+ table_alias = TableAlias.new(relation, :foo)
32
+ cte = table_alias.to_cte
33
+
34
+ assert_kind_of Arel::Nodes::Cte, cte
35
+ assert_equal :foo, cte.name
36
+ assert_equal relation, cte.relation
37
+ end
38
+ end
27
39
  end
28
40
  end
29
41
  end
@@ -24,7 +24,7 @@ module Arel
24
24
  ordering = operation.desc
25
25
  assert_kind_of Descending, ordering
26
26
  assert_equal operation, ordering.expr
27
- assert ordering.descending?
27
+ assert_predicate ordering, :descending?
28
28
  end
29
29
 
30
30
  def test_equality_with_same_ivars
@@ -27,6 +27,8 @@ describe Arel::Nodes::UpdateStatement do
27
27
  statement1.orders = %w[x y z]
28
28
  statement1.limit = 42
29
29
  statement1.key = "zomg"
30
+ statement1.groups = ["foo"]
31
+ statement1.havings = []
30
32
  statement2 = Arel::Nodes::UpdateStatement.new
31
33
  statement2.relation = "zomg"
32
34
  statement2.wheres = 2
@@ -34,6 +36,8 @@ describe Arel::Nodes::UpdateStatement do
34
36
  statement2.orders = %w[x y z]
35
37
  statement2.limit = 42
36
38
  statement2.key = "zomg"
39
+ statement2.groups = ["foo"]
40
+ statement2.havings = []
37
41
  array = [statement1, statement2]
38
42
  assert_equal 1, array.uniq.size
39
43
  end
@@ -16,11 +16,12 @@ module Arel
16
16
  node_descendants.delete(Arel::Nodes::NodeExpression)
17
17
 
18
18
  bad_node_descendants = node_descendants.reject do |subnode|
19
- eqeq_owner = subnode.instance_method(:==).owner
19
+ eqeq_method = subnode.instance_method(:==)
20
+ eqeq_owner = eqeq_method.owner
20
21
  eql_owner = subnode.instance_method(:eql?).owner
21
22
  hash_owner = subnode.instance_method(:hash).owner
22
23
 
23
- eqeq_owner < Arel::Nodes::Node &&
24
+ eqeq_method.super_method && # Not using the ruby default #== method
24
25
  eqeq_owner == eql_owner &&
25
26
  eqeq_owner == hash_owner
26
27
  end
@@ -338,13 +338,13 @@ module Arel
338
338
  replies = Table.new(:replies)
339
339
  replies_id = replies[:id]
340
340
 
341
- recursive_term = Arel::SelectManager.new
342
- recursive_term.from(comments).project(comments_id, comments_parent_id).where(comments_id.eq 42)
343
-
344
341
  non_recursive_term = Arel::SelectManager.new
345
- non_recursive_term.from(comments).project(comments_id, comments_parent_id).join(replies).on(comments_parent_id.eq replies_id)
342
+ non_recursive_term.from(comments).project(comments_id, comments_parent_id).where(comments_id.eq 42)
343
+
344
+ recursive_term = Arel::SelectManager.new
345
+ recursive_term.from(comments).project(comments_id, comments_parent_id).join(replies).on(comments_parent_id.eq replies_id)
346
346
 
347
- union = recursive_term.union(non_recursive_term)
347
+ union = non_recursive_term.union(recursive_term)
348
348
 
349
349
  as_statement = Arel::Nodes::As.new replies, union
350
350
 
@@ -963,16 +963,16 @@ module Arel
963
963
  _(manager.where_sql).must_be_like %{ WHERE "users"."id" = 10 AND "users"."id" = 11}
964
964
  end
965
965
 
966
- it "handles database specific statements" do
967
- old_visitor = Table.engine.connection.visitor
968
- Table.engine.connection.visitor = Visitors::PostgreSQL.new Table.engine.connection
966
+ it "handles database-specific statements" do
967
+ old_visitor = Table.engine.lease_connection.visitor
968
+ Table.engine.lease_connection.visitor = Visitors::PostgreSQL.new Table.engine.lease_connection
969
969
  table = Table.new :users
970
970
  manager = Arel::SelectManager.new
971
971
  manager.from table
972
972
  manager.where table[:id].eq 10
973
973
  manager.where table[:name].matches "foo%"
974
974
  _(manager.where_sql).must_be_like %{ WHERE "users"."id" = 10 AND "users"."name" ILIKE 'foo%' }
975
- Table.engine.connection.visitor = old_visitor
975
+ Table.engine.lease_connection.visitor = old_visitor
976
976
  end
977
977
 
978
978
  it "returns nil when there are no wheres" do
@@ -1014,7 +1014,7 @@ module Arel
1014
1014
 
1015
1015
  _(stmt.to_sql).must_be_like %{
1016
1016
  UPDATE "users" SET foo = bar
1017
- WHERE "users"."id" IN (SELECT "users"."id" FROM "users" LIMIT 1)
1017
+ WHERE ("users"."id") IN (SELECT "users"."id" FROM "users" LIMIT 1)
1018
1018
  }
1019
1019
  end
1020
1020
 
@@ -1028,7 +1028,7 @@ module Arel
1028
1028
 
1029
1029
  _(stmt.to_sql).must_be_like %{
1030
1030
  UPDATE "users" SET foo = bar
1031
- WHERE "users"."id" IN (SELECT "users"."id" FROM "users" ORDER BY foo)
1031
+ WHERE ("users"."id") IN (SELECT "users"."id" FROM "users" ORDER BY foo)
1032
1032
  }
1033
1033
  end
1034
1034
 
@@ -1053,7 +1053,7 @@ module Arel
1053
1053
  stmt = manager.compile_update({ table[:id] => 1 }, Arel::Attributes::Attribute.new(table, "id"))
1054
1054
 
1055
1055
  _(stmt.to_sql).must_be_like %{
1056
- UPDATE "users" SET "id" = 1 WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE "users"."foo" = 10 LIMIT 42)
1056
+ UPDATE "users" SET "id" = 1 WHERE ("users"."id") IN (SELECT "users"."id" FROM "users" WHERE "users"."foo" = 10 LIMIT 42)
1057
1057
  }
1058
1058
  end
1059
1059
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/enumerable"
4
-
5
4
  require "date"
5
+
6
6
  module FakeRecord
7
7
  class Column < Struct.new(:name, :type)
8
8
  end
@@ -11,7 +11,7 @@ module FakeRecord
11
11
  attr_reader :tables
12
12
  attr_accessor :visitor
13
13
 
14
- def initialize(visitor = nil)
14
+ def initialize
15
15
  @tables = %w{ users photos developers products}
16
16
  @columns = {
17
17
  "users" => [
@@ -33,7 +33,7 @@ module FakeRecord
33
33
  "users" => "id",
34
34
  "products" => "id"
35
35
  }
36
- @visitor = visitor
36
+ @visitor = Arel::Visitors::ToSql.new(self)
37
37
  end
38
38
 
39
39
  def columns_hash(table_name)
@@ -86,38 +86,39 @@ module FakeRecord
86
86
  "'#{thing.to_s.gsub("'", "\\\\'")}'"
87
87
  end
88
88
  end
89
- end
90
89
 
91
- class ConnectionPool
92
- class Spec < Struct.new(:adapter, keyword_init: true)
90
+ def cast_bound_value(thing)
91
+ thing
93
92
  end
93
+ end
94
94
 
95
- attr_reader :spec, :connection
96
-
95
+ class ConnectionPool
97
96
  def initialize
98
- @spec = Spec.new(adapter: "america")
99
97
  @connection = Connection.new
100
- @connection.visitor = Arel::Visitors::ToSql.new(connection)
98
+ end
99
+
100
+ def lease_connection
101
+ @connection
101
102
  end
102
103
 
103
104
  def with_connection
104
- yield connection
105
+ yield @connection
105
106
  end
106
107
 
107
108
  def table_exists?(name)
108
- connection.tables.include? name.to_s
109
+ @connection.tables.include? name.to_s
109
110
  end
110
111
 
111
112
  def columns_hash
112
- connection.columns_hash
113
+ @connection.columns_hash
113
114
  end
114
115
 
115
116
  def schema_cache
116
- connection
117
+ @connection
117
118
  end
118
119
 
119
120
  def quote(thing)
120
- connection.quote thing
121
+ @connection.quote thing
121
122
  end
122
123
  end
123
124
 
@@ -128,8 +129,12 @@ module FakeRecord
128
129
  @connection_pool = ConnectionPool.new
129
130
  end
130
131
 
131
- def connection
132
- connection_pool.connection
132
+ def with_connection(...)
133
+ connection_pool.with_connection(...)
134
+ end
135
+
136
+ def lease_connection
137
+ connection_pool.lease_connection
133
138
  end
134
139
  end
135
140
  end
@@ -8,12 +8,6 @@ module Arel
8
8
  @relation = Table.new(:users)
9
9
  end
10
10
 
11
- it "should create join nodes" do
12
- join = @relation.create_string_join "foo"
13
- assert_kind_of Arel::Nodes::StringJoin, join
14
- assert_equal "foo", join.left
15
- end
16
-
17
11
  it "should create join nodes" do
18
12
  join = @relation.create_join "foo", "bar"
19
13
  assert_kind_of Arel::Nodes::InnerJoin, join
@@ -42,13 +36,6 @@ module Arel
42
36
  assert_equal "bar", join.right
43
37
  end
44
38
 
45
- it "should return an insert manager" do
46
- im = @relation.compile_insert "VALUES(NULL)"
47
- assert_kind_of Arel::InsertManager, im
48
- im.into Table.new(:users)
49
- assert_equal "INSERT INTO \"users\" VALUES(NULL)", im.to_sql
50
- end
51
-
52
39
  describe "skip" do
53
40
  it "should add an offset" do
54
41
  sm = @relation.skip 2
@@ -134,6 +121,17 @@ module Arel
134
121
  rel = Table.new :users, as: "users"
135
122
  _(rel.table_alias).must_be_nil
136
123
  end
124
+
125
+ it "should accept literal SQL" do
126
+ rel = Table.new Arel.sql("generate_series(4, 2)")
127
+ assert_equal Arel.sql("generate_series(4, 2)"), rel.name
128
+ end
129
+
130
+ it "should accept Arel nodes" do
131
+ node = Arel::Nodes::NamedFunction.new("generate_series", [4, 2])
132
+ rel = Table.new node
133
+ assert_equal node, rel.name
134
+ end
137
135
  end
138
136
 
139
137
  describe "order" do
@@ -180,10 +178,6 @@ module Arel
180
178
  _(@relation.name).must_equal "users"
181
179
  end
182
180
 
183
- it "should have a table name" do
184
- _(@relation.table_name).must_equal "users"
185
- end
186
-
187
181
  describe "[]" do
188
182
  describe "when given a Symbol" do
189
183
  it "manufactures an attribute if the symbol names an attribute within the relation" do
@@ -195,19 +189,15 @@ module Arel
195
189
 
196
190
  describe "equality" do
197
191
  it "is equal with equal ivars" do
198
- relation1 = Table.new(:users)
199
- relation1.table_alias = "zomg"
200
- relation2 = Table.new(:users)
201
- relation2.table_alias = "zomg"
192
+ relation1 = Table.new(:users, as: "zomg")
193
+ relation2 = Table.new(:users, as: "zomg")
202
194
  array = [relation1, relation2]
203
195
  assert_equal 1, array.uniq.size
204
196
  end
205
197
 
206
198
  it "is not equal with different ivars" do
207
- relation1 = Table.new(:users)
208
- relation1.table_alias = "zomg"
209
- relation2 = Table.new(:users)
210
- relation2.table_alias = "zomg2"
199
+ relation1 = Table.new(:users, as: "zomg")
200
+ relation2 = Table.new(:users, as: "zomg2")
211
201
  array = [relation1, relation2]
212
202
  assert_equal 2, array.uniq.size
213
203
  end
@@ -4,12 +4,6 @@ require_relative "helper"
4
4
 
5
5
  module Arel
6
6
  class UpdateManagerTest < Arel::Spec
7
- describe "new" do
8
- it "takes an engine" do
9
- Arel::UpdateManager.new
10
- end
11
- end
12
-
13
7
  it "should not quote sql literals" do
14
8
  table = Table.new(:users)
15
9
  um = Arel::UpdateManager.new
@@ -28,6 +22,57 @@ module Arel
28
22
  assert_match(/LIMIT 10/, um.to_sql)
29
23
  end
30
24
 
25
+ describe "having" do
26
+ it "sets having" do
27
+ users_table = Table.new(:users)
28
+ posts_table = Table.new(:posts)
29
+ join_source = Arel::Nodes::InnerJoin.new(users_table, posts_table)
30
+
31
+ update_manager = Arel::UpdateManager.new
32
+ update_manager.table(join_source)
33
+ update_manager.group(["posts.id"])
34
+ update_manager.having("count(posts.id) >= 2")
35
+
36
+ assert_equal(["count(posts.id) >= 2"], update_manager.ast.havings)
37
+ end
38
+ end
39
+
40
+ describe "group" do
41
+ it "adds columns to the AST when group value is a String" do
42
+ users_table = Table.new(:users)
43
+ posts_table = Table.new(:posts)
44
+ join_source = Arel::Nodes::InnerJoin.new(users_table, posts_table)
45
+
46
+ update_manager = Arel::UpdateManager.new
47
+ update_manager.table(join_source)
48
+ update_manager.group(["posts.id"])
49
+ update_manager.having("count(posts.id) >= 2")
50
+
51
+ assert_equal(1, update_manager.ast.groups.count)
52
+ group_ast = update_manager.ast.groups.first
53
+ _(group_ast).must_be_kind_of Nodes::Group
54
+ assert_equal("posts.id", group_ast.expr)
55
+ assert_equal(["count(posts.id) >= 2"], update_manager.ast.havings)
56
+ end
57
+
58
+ it "adds columns to the AST when group value is a Symbol" do
59
+ users_table = Table.new(:users)
60
+ posts_table = Table.new(:posts)
61
+ join_source = Arel::Nodes::InnerJoin.new(users_table, posts_table)
62
+
63
+ update_manager = Arel::UpdateManager.new
64
+ update_manager.table(join_source)
65
+ update_manager.group([:"posts.id"])
66
+ update_manager.having("count(posts.id) >= 2")
67
+
68
+ assert_equal(1, update_manager.ast.groups.count)
69
+ group_ast = update_manager.ast.groups.first
70
+ _(group_ast).must_be_kind_of Nodes::Group
71
+ assert_equal("posts.id", group_ast.expr)
72
+ assert_equal(["count(posts.id) >= 2"], update_manager.ast.havings)
73
+ end
74
+ end
75
+
31
76
  describe "set" do
32
77
  it "updates with null" do
33
78
  table = Table.new(:users)
@@ -40,7 +40,7 @@ module Arel
40
40
 
41
41
  class DispatchContaminationTest < Arel::Spec
42
42
  before do
43
- @connection = Table.engine.connection
43
+ @connection = Table.engine.lease_connection
44
44
  @table = Table.new(:users)
45
45
  end
46
46
 
@@ -10,6 +10,10 @@ module Arel
10
10
  @visitor = Visitors::Dot.new
11
11
  end
12
12
 
13
+ def assert_edge(edge_name, dot_string)
14
+ assert_match(/->.*label="#{edge_name}"/, dot_string)
15
+ end
16
+
13
17
  # functions
14
18
  [
15
19
  Nodes::Sum,
@@ -21,12 +25,14 @@ module Arel
21
25
  define_method("test_#{klass.name.gsub('::', '_')}") do
22
26
  op = klass.new(:a, "z")
23
27
  @visitor.accept op, Collectors::PlainString.new
28
+ pass
24
29
  end
25
30
  end
26
31
 
27
32
  def test_named_function
28
33
  func = Nodes::NamedFunction.new "omg", "omg"
29
34
  @visitor.accept func, Collectors::PlainString.new
35
+ pass
30
36
  end
31
37
 
32
38
  # unary ops
@@ -44,6 +50,7 @@ module Arel
44
50
  define_method("test_#{klass.name.gsub('::', '_')}") do
45
51
  op = klass.new(:a)
46
52
  @visitor.accept op, Collectors::PlainString.new
53
+ pass
47
54
  end
48
55
  end
49
56
 
@@ -61,16 +68,27 @@ module Arel
61
68
  Arel::Nodes::Matches,
62
69
  Arel::Nodes::NotEqual,
63
70
  Arel::Nodes::NotIn,
64
- Arel::Nodes::Or,
65
71
  Arel::Nodes::TableAlias,
66
72
  Arel::Nodes::As,
67
- Arel::Nodes::DeleteStatement,
68
73
  Arel::Nodes::JoinSource,
69
74
  Arel::Nodes::Casted,
70
75
  ].each do |klass|
71
76
  define_method("test_#{klass.name.gsub('::', '_')}") do
72
77
  binary = klass.new(:a, :b)
73
78
  @visitor.accept binary, Collectors::PlainString.new
79
+ pass
80
+ end
81
+ end
82
+
83
+ # nary ops
84
+ [
85
+ Arel::Nodes::And,
86
+ Arel::Nodes::Or,
87
+ ].each do |klass|
88
+ define_method("test_#{klass.name.gsub('::', '_')}") do
89
+ binary = klass.new([:a, :b])
90
+ @visitor.accept binary, Collectors::PlainString.new
91
+ pass
74
92
  end
75
93
  end
76
94
 
@@ -85,6 +103,163 @@ module Arel
85
103
  collector = Collectors::PlainString.new
86
104
  assert_match '[label="<f0>ActiveModel::Attribute::WithCastValue"]', @visitor.accept(node, collector).value
87
105
  end
106
+
107
+ def test_Arel_Nodes_CurrentRow
108
+ node = Arel::Nodes::CurrentRow.new
109
+ collector = Collectors::PlainString.new
110
+ assert_match '[label="<f0>Arel::Nodes::CurrentRow"]', @visitor.accept(node, collector).value
111
+ end
112
+
113
+ def test_Arel_Nodes_Distinct
114
+ node = Arel::Nodes::Distinct.new
115
+ collector = Collectors::PlainString.new
116
+ assert_match '[label="<f0>Arel::Nodes::Distinct"]', @visitor.accept(node, collector).value
117
+ end
118
+
119
+ def test_Arel_Nodes_Case_and_friends
120
+ foo = Arel::Nodes.build_quoted("foo")
121
+ node = Arel::Nodes::Case.new(foo)
122
+ node.conditions = [Arel::Nodes::When.new(foo, Arel::Nodes.build_quoted(1))]
123
+ node.default = Arel::Nodes::Else.new(Arel::Nodes.build_quoted(0))
124
+
125
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
126
+
127
+ assert_match '[label="<f0>Arel::Nodes::Case"]', dot
128
+ assert_edge("case", dot)
129
+ assert_edge("conditions", dot)
130
+ assert_edge("default", dot)
131
+ assert_match '[label="<f0>Arel::Nodes::When"]', dot
132
+ assert_match '[label="<f0>Arel::Nodes::Else"]', dot
133
+ assert_match '[label="<f0>Arel::Nodes::Else"]', dot
134
+ end
135
+
136
+ def test_Arel_Nodes_InfixOperation
137
+ node = Arel::Nodes::InfixOperation.new("&&", Arel::Nodes.build_quoted(1), Arel::Nodes.build_quoted(2))
138
+
139
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
140
+
141
+ assert_match '[label="<f0>Arel::Nodes::InfixOperation"]', dot
142
+ assert_edge("operator", dot)
143
+ assert_edge("left", dot)
144
+ assert_edge("right", dot)
145
+ end
146
+
147
+ def test_Arel_Nodes_RegExp
148
+ table = Table.new(:users)
149
+ node = Arel::Nodes::Regexp.new(table[:name], Nodes.build_quoted("foo%"))
150
+
151
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
152
+
153
+ assert_match '[label="<f0>Arel::Nodes::Regexp"]', dot
154
+ assert_edge("left", dot)
155
+ assert_edge("right", dot)
156
+ assert_edge("case_sensitive", dot)
157
+ end
158
+
159
+ def test_Arel_Nodes_NotRegExp
160
+ table = Table.new(:users)
161
+ node = Arel::Nodes::NotRegexp.new(table[:name], Nodes.build_quoted("foo%"))
162
+
163
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
164
+
165
+ assert_match '[label="<f0>Arel::Nodes::NotRegexp"]', dot
166
+ assert_edge("left", dot)
167
+ assert_edge("right", dot)
168
+ assert_edge("case_sensitive", dot)
169
+ end
170
+
171
+ def test_Arel_Nodes_UnaryOperation
172
+ node = Arel::Nodes::UnaryOperation.new(:-, 1)
173
+
174
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
175
+
176
+ assert_match '[label="<f0>Arel::Nodes::UnaryOperation"]', dot
177
+ assert_edge("operator", dot)
178
+ assert_edge("expr", dot)
179
+ end
180
+
181
+ def test_Arel_Nodes_With
182
+ node = Arel::Nodes::With.new(["query1", "query2", "query3"])
183
+
184
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
185
+
186
+ assert_match '[label="<f0>Arel::Nodes::With"]', dot
187
+ assert_edge("0", dot)
188
+ assert_edge("1", dot)
189
+ assert_edge("2", dot)
190
+ end
191
+
192
+ def test_Arel_Nodes_SelectCore
193
+ node = Arel::Nodes::SelectCore.new
194
+
195
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
196
+
197
+ assert_match '[label="<f0>Arel::Nodes::SelectCore"]', dot
198
+ assert_edge("source", dot)
199
+ assert_edge("projections", dot)
200
+ assert_edge("wheres", dot)
201
+ assert_edge("windows", dot)
202
+ assert_edge("groups", dot)
203
+ assert_edge("comment", dot)
204
+ assert_edge("havings", dot)
205
+ assert_edge("set_quantifier", dot)
206
+ assert_edge("optimizer_hints", dot)
207
+ end
208
+
209
+ def test_Arel_Nodes_SelectStatement
210
+ node = Arel::Nodes::SelectStatement.new
211
+
212
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
213
+
214
+ assert_match '[label="<f0>Arel::Nodes::SelectStatement"]', dot
215
+ assert_edge("cores", dot)
216
+ assert_edge("limit", dot)
217
+ assert_edge("orders", dot)
218
+ assert_edge("offset", dot)
219
+ assert_edge("lock", dot)
220
+ assert_edge("with", dot)
221
+ end
222
+
223
+ def test_Arel_Nodes_InsertStatement
224
+ node = Arel::Nodes::InsertStatement.new
225
+
226
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
227
+
228
+ assert_match '[label="<f0>Arel::Nodes::InsertStatement"]', dot
229
+ assert_edge("relation", dot)
230
+ assert_edge("columns", dot)
231
+ assert_edge("values", dot)
232
+ assert_edge("select", dot)
233
+ end
234
+
235
+ def test_Arel_Nodes_UpdateStatement
236
+ node = Arel::Nodes::UpdateStatement.new
237
+
238
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
239
+
240
+ assert_match '[label="<f0>Arel::Nodes::UpdateStatement"]', dot
241
+ assert_edge("relation", dot)
242
+ assert_edge("wheres", dot)
243
+ assert_edge("values", dot)
244
+ assert_edge("orders", dot)
245
+ assert_edge("limit", dot)
246
+ assert_edge("offset", dot)
247
+ assert_edge("key", dot)
248
+ end
249
+
250
+ def test_Arel_Nodes_DeleteStatement
251
+ node = Arel::Nodes::DeleteStatement.new
252
+
253
+ dot = @visitor.accept(node, Arel::Collectors::PlainString.new).value
254
+
255
+ assert_match '[label="<f0>Arel::Nodes::DeleteStatement"]', dot
256
+ assert_edge("relation", dot)
257
+ assert_edge("wheres", dot)
258
+ assert_edge("orders", dot)
259
+ assert_edge("limit", dot)
260
+ assert_edge("offset", dot)
261
+ assert_edge("key", dot)
262
+ end
88
263
  end
89
264
  end
90
265
  end