ibm_db 5.2.0-x86-mingw32 → 5.3.2-x86-mingw32

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 (621) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +15 -13
  5. data/ext/ibm_db.c +62 -57
  6. data/ext/ibm_db.o +0 -0
  7. data/ext/ibm_db.so +0 -0
  8. data/ext/mkmf.log +26 -24
  9. data/ext/ruby_ibm_db_cli.c +1 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  12. data/lib/ibm_db.so +1 -0
  13. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  14. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  15. data/test/activejob/destroy_association_async_test.rb +305 -0
  16. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  17. data/test/activejob/helper.rb +15 -0
  18. data/test/assets/schema_dump_5_1.yml +345 -0
  19. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  20. data/test/cases/adapter_test.rb +432 -218
  21. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  22. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  23. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  24. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  25. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  26. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  27. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  28. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  29. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  30. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  31. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  32. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  33. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  34. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  35. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  36. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  38. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  39. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  40. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  41. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  42. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  43. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  44. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  45. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  46. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  47. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  48. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  49. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  50. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  51. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  52. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  53. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  54. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  55. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  56. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  57. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  58. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  59. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  60. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  61. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  62. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  63. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  64. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  65. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  66. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  67. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  68. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  69. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  70. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  71. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  72. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  73. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  74. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  75. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  76. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  77. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  78. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  79. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  80. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  81. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  82. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  83. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  84. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  85. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  86. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  87. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  88. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  89. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  90. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  91. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  92. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  93. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  94. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  95. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  96. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  97. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  98. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  99. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  100. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  101. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  102. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  103. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  104. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  105. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  106. data/test/cases/aggregations_test.rb +14 -12
  107. data/test/cases/annotate_test.rb +46 -0
  108. data/test/cases/ar_schema_test.rb +153 -86
  109. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  110. data/test/cases/arel/attributes/math_test.rb +83 -0
  111. data/test/cases/arel/attributes_test.rb +27 -0
  112. data/test/cases/arel/collectors/bind_test.rb +40 -0
  113. data/test/cases/arel/collectors/composite_test.rb +47 -0
  114. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  115. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  116. data/test/cases/arel/crud_test.rb +65 -0
  117. data/test/cases/arel/delete_manager_test.rb +53 -0
  118. data/test/cases/arel/factory_methods_test.rb +46 -0
  119. data/test/cases/arel/helper.rb +45 -0
  120. data/test/cases/arel/insert_manager_test.rb +241 -0
  121. data/test/cases/arel/nodes/and_test.rb +30 -0
  122. data/test/cases/arel/nodes/as_test.rb +36 -0
  123. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  124. data/test/cases/arel/nodes/bin_test.rb +35 -0
  125. data/test/cases/arel/nodes/binary_test.rb +29 -0
  126. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  127. data/test/cases/arel/nodes/case_test.rb +96 -0
  128. data/test/cases/arel/nodes/casted_test.rb +18 -0
  129. data/test/cases/arel/nodes/comment_test.rb +22 -0
  130. data/test/cases/arel/nodes/count_test.rb +35 -0
  131. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  132. data/test/cases/arel/nodes/descending_test.rb +46 -0
  133. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  134. data/test/cases/arel/nodes/equality_test.rb +62 -0
  135. data/test/cases/arel/nodes/extract_test.rb +43 -0
  136. data/test/cases/arel/nodes/false_test.rb +21 -0
  137. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  138. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  139. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  140. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  141. data/test/cases/arel/nodes/node_test.rb +22 -0
  142. data/test/cases/arel/nodes/not_test.rb +31 -0
  143. data/test/cases/arel/nodes/or_test.rb +36 -0
  144. data/test/cases/arel/nodes/over_test.rb +69 -0
  145. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  146. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  147. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  148. data/test/cases/arel/nodes/sum_test.rb +35 -0
  149. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  150. data/test/cases/arel/nodes/true_test.rb +21 -0
  151. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  152. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  153. data/test/cases/arel/nodes/window_test.rb +81 -0
  154. data/test/cases/arel/nodes_test.rb +34 -0
  155. data/test/cases/arel/select_manager_test.rb +1238 -0
  156. data/test/cases/arel/support/fake_record.rb +135 -0
  157. data/test/cases/arel/table_test.rb +216 -0
  158. data/test/cases/arel/update_manager_test.rb +126 -0
  159. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  160. data/test/cases/arel/visitors/dot_test.rb +90 -0
  161. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  162. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  163. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  164. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  165. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  166. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  167. data/test/cases/associations/callbacks_test.rb +56 -38
  168. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  169. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  170. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  171. data/test/cases/associations/eager_singularization_test.rb +21 -21
  172. data/test/cases/associations/eager_test.rb +559 -415
  173. data/test/cases/associations/extension_test.rb +18 -12
  174. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  175. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  176. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  177. data/test/cases/associations/has_one_associations_test.rb +294 -129
  178. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  179. data/test/cases/associations/inner_join_association_test.rb +114 -38
  180. data/test/cases/associations/inverse_associations_test.rb +606 -398
  181. data/test/cases/associations/join_model_test.rb +158 -148
  182. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  183. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  184. data/test/cases/associations/required_test.rb +35 -10
  185. data/test/cases/associations_test.rb +241 -110
  186. data/test/cases/attribute_methods/read_test.rb +11 -11
  187. data/test/cases/attribute_methods_test.rb +413 -298
  188. data/test/cases/attributes_test.rb +145 -27
  189. data/test/cases/autosave_association_test.rb +681 -436
  190. data/test/cases/base_prevent_writes_test.rb +229 -0
  191. data/test/cases/base_test.rb +599 -542
  192. data/test/cases/batches_test.rb +288 -82
  193. data/test/cases/binary_test.rb +26 -31
  194. data/test/cases/bind_parameter_test.rb +194 -21
  195. data/test/cases/boolean_test.rb +52 -0
  196. data/test/cases/cache_key_test.rb +110 -5
  197. data/test/cases/calculations_test.rb +740 -177
  198. data/test/cases/callbacks_test.rb +74 -207
  199. data/test/cases/clone_test.rb +15 -10
  200. data/test/cases/coders/json_test.rb +2 -0
  201. data/test/cases/coders/yaml_column_test.rb +16 -13
  202. data/test/cases/collection_cache_key_test.rb +177 -20
  203. data/test/cases/column_alias_test.rb +9 -7
  204. data/test/cases/column_definition_test.rb +10 -68
  205. data/test/cases/comment_test.rb +166 -107
  206. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  207. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  208. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  209. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  210. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  211. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  212. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  213. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  214. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  215. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  216. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  217. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  218. data/test/cases/connection_management_test.rb +13 -11
  219. data/test/cases/connection_pool_test.rb +316 -83
  220. data/test/cases/core_test.rb +82 -58
  221. data/test/cases/counter_cache_test.rb +204 -50
  222. data/test/cases/custom_locking_test.rb +5 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  224. data/test/cases/database_configurations/resolver_test.rb +150 -0
  225. data/test/cases/database_configurations_test.rb +145 -0
  226. data/test/cases/database_selector_test.rb +296 -0
  227. data/test/cases/database_statements_test.rb +18 -16
  228. data/test/cases/date_test.rb +8 -16
  229. data/test/cases/date_time_precision_test.rb +100 -78
  230. data/test/cases/date_time_test.rb +23 -8
  231. data/test/cases/defaults_test.rb +106 -71
  232. data/test/cases/delegated_type_test.rb +57 -0
  233. data/test/cases/dirty_test.rb +419 -223
  234. data/test/cases/disconnected_test.rb +6 -6
  235. data/test/cases/dup_test.rb +54 -27
  236. data/test/cases/enum_test.rb +461 -82
  237. data/test/cases/errors_test.rb +7 -7
  238. data/test/cases/explain_subscriber_test.rb +17 -15
  239. data/test/cases/explain_test.rb +11 -19
  240. data/test/cases/filter_attributes_test.rb +153 -0
  241. data/test/cases/finder_respond_to_test.rb +14 -14
  242. data/test/cases/finder_test.rb +669 -287
  243. data/test/cases/fixture_set/file_test.rb +34 -38
  244. data/test/cases/fixtures_test.rb +833 -176
  245. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  246. data/test/cases/habtm_destroy_order_test.rb +25 -25
  247. data/test/cases/helper.rb +78 -49
  248. data/test/cases/hot_compatibility_test.rb +33 -32
  249. data/test/cases/i18n_test.rb +18 -17
  250. data/test/cases/inheritance_test.rb +180 -115
  251. data/test/cases/insert_all_test.rb +489 -0
  252. data/test/cases/instrumentation_test.rb +101 -0
  253. data/test/cases/integration_test.rb +119 -31
  254. data/test/cases/invalid_connection_test.rb +18 -16
  255. data/test/cases/invertible_migration_test.rb +183 -43
  256. data/test/cases/json_attribute_test.rb +35 -0
  257. data/test/cases/json_serialization_test.rb +57 -58
  258. data/test/cases/json_shared_test_cases.rb +290 -0
  259. data/test/cases/locking_test.rb +413 -119
  260. data/test/cases/log_subscriber_test.rb +68 -26
  261. data/test/cases/marshal_serialization_test.rb +39 -0
  262. data/test/cases/migration/change_schema_test.rb +118 -72
  263. data/test/cases/migration/change_table_test.rb +138 -30
  264. data/test/cases/migration/check_constraint_test.rb +162 -0
  265. data/test/cases/migration/column_attributes_test.rb +45 -35
  266. data/test/cases/migration/column_positioning_test.rb +18 -6
  267. data/test/cases/migration/columns_test.rb +93 -77
  268. data/test/cases/migration/command_recorder_test.rb +121 -34
  269. data/test/cases/migration/compatibility_test.rb +578 -23
  270. data/test/cases/migration/create_join_table_test.rb +35 -25
  271. data/test/cases/migration/foreign_key_test.rb +503 -284
  272. data/test/cases/migration/helper.rb +4 -3
  273. data/test/cases/migration/index_test.rb +119 -70
  274. data/test/cases/migration/logger_test.rb +9 -6
  275. data/test/cases/migration/pending_migrations_test.rb +88 -34
  276. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  277. data/test/cases/migration/references_index_test.rb +38 -19
  278. data/test/cases/migration/references_statements_test.rb +15 -14
  279. data/test/cases/migration/rename_table_test.rb +53 -30
  280. data/test/cases/migration_test.rb +637 -269
  281. data/test/cases/migrator_test.rb +191 -135
  282. data/test/cases/mixin_test.rb +7 -11
  283. data/test/cases/modules_test.rb +36 -34
  284. data/test/cases/multi_db_migrator_test.rb +223 -0
  285. data/test/cases/multiparameter_attributes_test.rb +60 -33
  286. data/test/cases/multiple_db_test.rb +16 -22
  287. data/test/cases/nested_attributes_test.rb +341 -320
  288. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  289. data/test/cases/null_relation_test.rb +84 -0
  290. data/test/cases/numeric_data_test.rb +93 -0
  291. data/test/cases/persistence_test.rb +361 -269
  292. data/test/cases/pooled_connections_test.rb +18 -26
  293. data/test/cases/prepared_statement_status_test.rb +48 -0
  294. data/test/cases/primary_keys_test.rb +210 -104
  295. data/test/cases/query_cache_test.rb +610 -141
  296. data/test/cases/quoting_test.rb +132 -31
  297. data/test/cases/readonly_test.rb +49 -48
  298. data/test/cases/reaper_test.rb +146 -32
  299. data/test/cases/reflection_test.rb +167 -156
  300. data/test/cases/relation/delegation_test.rb +49 -36
  301. data/test/cases/relation/delete_all_test.rb +117 -0
  302. data/test/cases/relation/merging_test.rb +319 -42
  303. data/test/cases/relation/mutation_test.rb +55 -93
  304. data/test/cases/relation/or_test.rb +129 -29
  305. data/test/cases/relation/predicate_builder_test.rb +21 -6
  306. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  307. data/test/cases/relation/select_test.rb +67 -0
  308. data/test/cases/relation/update_all_test.rb +317 -0
  309. data/test/cases/relation/where_chain_test.rb +68 -32
  310. data/test/cases/relation/where_clause_test.rb +136 -61
  311. data/test/cases/relation/where_test.rb +155 -48
  312. data/test/cases/relation_test.rb +266 -112
  313. data/test/cases/relations_test.rb +969 -744
  314. data/test/cases/reload_models_test.rb +13 -9
  315. data/test/cases/reserved_word_test.rb +141 -0
  316. data/test/cases/result_test.rb +68 -17
  317. data/test/cases/sanitize_test.rb +87 -71
  318. data/test/cases/schema_dumper_test.rb +221 -128
  319. data/test/cases/schema_loading_test.rb +3 -2
  320. data/test/cases/scoping/default_scoping_test.rb +185 -144
  321. data/test/cases/scoping/named_scoping_test.rb +177 -89
  322. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  323. data/test/cases/secure_token_test.rb +18 -3
  324. data/test/cases/serialization_test.rb +30 -28
  325. data/test/cases/serialized_attribute_test.rb +133 -42
  326. data/test/cases/signed_id_test.rb +168 -0
  327. data/test/cases/statement_cache_test.rb +41 -24
  328. data/test/cases/statement_invalid_test.rb +42 -0
  329. data/test/cases/store_test.rb +180 -55
  330. data/test/cases/strict_loading_test.rb +473 -0
  331. data/test/cases/suppressor_test.rb +26 -12
  332. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  333. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  334. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  335. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  336. data/test/cases/test_case.rb +51 -40
  337. data/test/cases/test_databases_test.rb +79 -0
  338. data/test/cases/test_fixtures_test.rb +79 -19
  339. data/test/cases/time_precision_test.rb +98 -76
  340. data/test/cases/timestamp_test.rb +102 -99
  341. data/test/cases/touch_later_test.rb +12 -10
  342. data/test/cases/transaction_callbacks_test.rb +344 -90
  343. data/test/cases/transaction_isolation_test.rb +12 -12
  344. data/test/cases/transactions_test.rb +612 -162
  345. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  346. data/test/cases/type/date_time_test.rb +4 -2
  347. data/test/cases/type/integer_test.rb +4 -2
  348. data/test/cases/type/string_test.rb +10 -8
  349. data/test/cases/type/time_test.rb +28 -0
  350. data/test/cases/type/type_map_test.rb +29 -28
  351. data/test/cases/type/unsigned_integer_test.rb +19 -0
  352. data/test/cases/type_test.rb +2 -0
  353. data/test/cases/types_test.rb +3 -1
  354. data/test/cases/unconnected_test.rb +14 -1
  355. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  356. data/test/cases/validations/absence_validation_test.rb +19 -17
  357. data/test/cases/validations/association_validation_test.rb +30 -28
  358. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  359. data/test/cases/validations/i18n_validation_test.rb +22 -21
  360. data/test/cases/validations/length_validation_test.rb +34 -33
  361. data/test/cases/validations/numericality_validation_test.rb +181 -0
  362. data/test/cases/validations/presence_validation_test.rb +21 -19
  363. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  364. data/test/cases/validations_repair_helper.rb +2 -0
  365. data/test/cases/validations_test.rb +61 -26
  366. data/test/cases/view_test.rb +122 -116
  367. data/test/cases/yaml_serialization_test.rb +79 -34
  368. data/test/config.example.yml +19 -19
  369. data/test/config.rb +3 -1
  370. data/test/config.yml +16 -6
  371. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  372. data/test/fixtures/author_addresses.yml +1 -8
  373. data/test/fixtures/authors.yml +1 -7
  374. data/test/fixtures/binaries.yml +4 -0
  375. data/test/fixtures/books.yml +9 -2
  376. data/test/fixtures/categories_posts.yml +3 -0
  377. data/test/fixtures/citations.yml +5 -0
  378. data/test/fixtures/comments.yml +7 -0
  379. data/test/fixtures/companies.yml +5 -0
  380. data/test/fixtures/computers.yml +2 -0
  381. data/test/fixtures/customers.yml +10 -1
  382. data/test/fixtures/developers.yml +1 -1
  383. data/test/fixtures/essays.yml +10 -0
  384. data/test/fixtures/faces.yml +3 -3
  385. data/test/fixtures/humans.yml +5 -0
  386. data/test/fixtures/interests.yml +7 -7
  387. data/test/fixtures/memberships.yml +7 -0
  388. data/test/fixtures/minimalistics.yml +3 -0
  389. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  390. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  391. data/test/fixtures/naked/yml/parrots.yml +1 -0
  392. data/test/fixtures/other_books.yml +26 -0
  393. data/test/fixtures/other_posts.yml +1 -0
  394. data/test/fixtures/parrots.yml +7 -1
  395. data/test/fixtures/pirates.yml +3 -0
  396. data/test/fixtures/posts.yml +11 -3
  397. data/test/fixtures/readers.yml +6 -0
  398. data/test/fixtures/reserved_words/values.yml +2 -2
  399. data/test/fixtures/sponsors.yml +3 -0
  400. data/test/fixtures/strict_zines.yml +2 -0
  401. data/test/fixtures/subscribers.yml +1 -1
  402. data/test/fixtures/tasks.yml +1 -1
  403. data/test/fixtures/warehouse-things.yml +3 -0
  404. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  405. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  406. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  407. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  408. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  409. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  410. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  411. data/test/migrations/rename/1_we_need_things.rb +2 -0
  412. data/test/migrations/rename/2_rename_things.rb +2 -0
  413. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  414. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  415. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  416. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  417. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  418. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  419. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  420. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  421. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  422. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  423. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  424. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  425. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  431. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  432. data/test/models/account.rb +46 -0
  433. data/test/models/admin/account.rb +3 -1
  434. data/test/models/admin/randomly_named_c1.rb +2 -0
  435. data/test/models/admin/user.rb +16 -8
  436. data/test/models/admin.rb +4 -2
  437. data/test/models/aircraft.rb +3 -1
  438. data/test/models/arunit2_model.rb +2 -0
  439. data/test/models/author.rb +153 -102
  440. data/test/models/auto_id.rb +2 -0
  441. data/test/models/autoloadable/extra_firm.rb +2 -0
  442. data/test/models/binary.rb +3 -1
  443. data/test/models/binary_field.rb +6 -0
  444. data/test/models/bird.rb +13 -1
  445. data/test/models/book.rb +14 -4
  446. data/test/models/book_destroy_async.rb +24 -0
  447. data/test/models/boolean.rb +5 -0
  448. data/test/models/bulb.rb +13 -4
  449. data/test/models/cake_designer.rb +2 -0
  450. data/test/models/car.rb +17 -10
  451. data/test/models/carrier.rb +2 -0
  452. data/test/models/cart.rb +5 -0
  453. data/test/models/cat.rb +2 -0
  454. data/test/models/categorization.rb +8 -6
  455. data/test/models/category.rb +28 -16
  456. data/test/models/chef.rb +2 -0
  457. data/test/models/citation.rb +5 -1
  458. data/test/models/club.rb +13 -10
  459. data/test/models/college.rb +4 -2
  460. data/test/models/column.rb +2 -0
  461. data/test/models/column_name.rb +2 -0
  462. data/test/models/comment.rb +32 -10
  463. data/test/models/company.rb +102 -106
  464. data/test/models/company_in_module.rb +27 -26
  465. data/test/models/computer.rb +3 -1
  466. data/test/models/contact.rb +15 -13
  467. data/test/models/content.rb +5 -3
  468. data/test/models/contract.rb +21 -3
  469. data/test/models/country.rb +2 -4
  470. data/test/models/course.rb +3 -1
  471. data/test/models/customer.rb +10 -8
  472. data/test/models/customer_carrier.rb +2 -0
  473. data/test/models/dashboard.rb +2 -0
  474. data/test/models/default.rb +2 -0
  475. data/test/models/department.rb +2 -0
  476. data/test/models/destroy_async_parent.rb +15 -0
  477. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  478. data/test/models/developer.rb +152 -85
  479. data/test/models/dl_keyed_belongs_to.rb +13 -0
  480. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  481. data/test/models/dl_keyed_has_many.rb +5 -0
  482. data/test/models/dl_keyed_has_many_through.rb +5 -0
  483. data/test/models/dl_keyed_has_one.rb +5 -0
  484. data/test/models/dl_keyed_join.rb +10 -0
  485. data/test/models/dog.rb +2 -0
  486. data/test/models/dog_lover.rb +2 -0
  487. data/test/models/doubloon.rb +3 -1
  488. data/test/models/drink_designer.rb +17 -0
  489. data/test/models/edge.rb +4 -2
  490. data/test/models/electron.rb +2 -0
  491. data/test/models/engine.rb +3 -2
  492. data/test/models/entrant.rb +2 -0
  493. data/test/models/entry.rb +5 -0
  494. data/test/models/essay.rb +6 -3
  495. data/test/models/essay_destroy_async.rb +12 -0
  496. data/test/models/event.rb +3 -1
  497. data/test/models/eye.rb +5 -3
  498. data/test/models/face.rb +14 -6
  499. data/test/models/family.rb +6 -0
  500. data/test/models/family_tree.rb +6 -0
  501. data/test/models/friendship.rb +5 -3
  502. data/test/models/frog.rb +8 -0
  503. data/test/models/guid.rb +3 -1
  504. data/test/models/guitar.rb +2 -0
  505. data/test/models/hotel.rb +5 -3
  506. data/test/models/human.rb +39 -0
  507. data/test/models/image.rb +3 -1
  508. data/test/models/interest.rb +14 -3
  509. data/test/models/invoice.rb +4 -2
  510. data/test/models/item.rb +3 -1
  511. data/test/models/job.rb +5 -3
  512. data/test/models/joke.rb +4 -2
  513. data/test/models/keyboard.rb +3 -1
  514. data/test/models/legacy_thing.rb +2 -0
  515. data/test/models/lesson.rb +2 -0
  516. data/test/models/line_item.rb +3 -1
  517. data/test/models/liquid.rb +2 -0
  518. data/test/models/matey.rb +3 -1
  519. data/test/models/measurement.rb +4 -0
  520. data/test/models/member.rb +23 -20
  521. data/test/models/member_detail.rb +3 -0
  522. data/test/models/member_type.rb +2 -0
  523. data/test/models/membership.rb +4 -1
  524. data/test/models/mentor.rb +3 -1
  525. data/test/models/message.rb +5 -0
  526. data/test/models/minimalistic.rb +2 -0
  527. data/test/models/minivan.rb +3 -2
  528. data/test/models/mixed_case_monkey.rb +3 -1
  529. data/test/models/molecule.rb +2 -0
  530. data/test/models/mouse.rb +6 -0
  531. data/test/models/movie.rb +2 -0
  532. data/test/models/node.rb +4 -2
  533. data/test/models/non_primary_key.rb +2 -0
  534. data/test/models/notification.rb +2 -0
  535. data/test/models/numeric_data.rb +12 -0
  536. data/test/models/order.rb +4 -2
  537. data/test/models/organization.rb +9 -7
  538. data/test/models/other_dog.rb +3 -1
  539. data/test/models/owner.rb +6 -4
  540. data/test/models/parrot.rb +12 -4
  541. data/test/models/person.rb +59 -54
  542. data/test/models/personal_legacy_thing.rb +3 -1
  543. data/test/models/pet.rb +4 -2
  544. data/test/models/pet_treasure.rb +2 -0
  545. data/test/models/pirate.rb +67 -43
  546. data/test/models/possession.rb +3 -1
  547. data/test/models/post.rb +184 -86
  548. data/test/models/price_estimate.rb +11 -1
  549. data/test/models/professor.rb +3 -1
  550. data/test/models/project.rb +14 -12
  551. data/test/models/publisher/article.rb +2 -0
  552. data/test/models/publisher/magazine.rb +2 -0
  553. data/test/models/publisher.rb +2 -0
  554. data/test/models/randomly_named_c1.rb +2 -0
  555. data/test/models/rating.rb +5 -1
  556. data/test/models/reader.rb +7 -5
  557. data/test/models/recipe.rb +2 -0
  558. data/test/models/record.rb +2 -0
  559. data/test/models/reference.rb +6 -3
  560. data/test/models/reply.rb +39 -21
  561. data/test/models/room.rb +6 -0
  562. data/test/models/section.rb +6 -0
  563. data/test/models/seminar.rb +6 -0
  564. data/test/models/session.rb +6 -0
  565. data/test/models/ship.rb +12 -9
  566. data/test/models/ship_part.rb +5 -3
  567. data/test/models/shop.rb +4 -2
  568. data/test/models/shop_account.rb +2 -0
  569. data/test/models/speedometer.rb +2 -0
  570. data/test/models/sponsor.rb +8 -5
  571. data/test/models/squeak.rb +6 -0
  572. data/test/models/strict_zine.rb +7 -0
  573. data/test/models/string_key_object.rb +2 -0
  574. data/test/models/student.rb +2 -0
  575. data/test/models/subscriber.rb +4 -2
  576. data/test/models/subscription.rb +5 -1
  577. data/test/models/tag.rb +6 -3
  578. data/test/models/tagging.rb +13 -6
  579. data/test/models/task.rb +2 -0
  580. data/test/models/topic.rb +54 -19
  581. data/test/models/toy.rb +4 -0
  582. data/test/models/traffic_light.rb +2 -0
  583. data/test/models/treasure.rb +5 -3
  584. data/test/models/treaty.rb +2 -4
  585. data/test/models/tree.rb +2 -0
  586. data/test/models/tuning_peg.rb +2 -0
  587. data/test/models/tyre.rb +2 -0
  588. data/test/models/user.rb +12 -4
  589. data/test/models/uuid_child.rb +2 -0
  590. data/test/models/uuid_item.rb +2 -0
  591. data/test/models/uuid_parent.rb +2 -0
  592. data/test/models/vegetables.rb +12 -3
  593. data/test/models/vertex.rb +6 -4
  594. data/test/models/warehouse_thing.rb +2 -0
  595. data/test/models/wheel.rb +3 -1
  596. data/test/models/without_table.rb +3 -1
  597. data/test/models/zine.rb +3 -1
  598. data/test/schema/mysql2_specific_schema.rb +49 -35
  599. data/test/schema/oracle_specific_schema.rb +13 -15
  600. data/test/schema/postgresql_specific_schema.rb +51 -40
  601. data/test/schema/schema.rb +334 -154
  602. data/test/schema/sqlite_specific_schema.rb +9 -16
  603. data/test/support/config.rb +26 -26
  604. data/test/support/connection.rb +14 -8
  605. data/test/support/connection_helper.rb +3 -1
  606. data/test/support/ddl_helper.rb +2 -0
  607. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  608. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  609. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  610. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  617. data/test/support/schema_dumping_helper.rb +2 -0
  618. data/test/support/stubs/strong_parameters.rb +40 -0
  619. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  620. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  621. metadata +190 -14
@@ -0,0 +1,750 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../helper"
4
+ require "bigdecimal"
5
+
6
+ module Arel
7
+ module Visitors
8
+ describe "the to_sql visitor" do
9
+ before do
10
+ @conn = FakeRecord::Base.new
11
+ @visitor = ToSql.new @conn.connection
12
+ @table = Table.new(:users)
13
+ @attr = @table[:id]
14
+ end
15
+
16
+ def compile(node)
17
+ @visitor.accept(node, Collectors::SQLString.new).value
18
+ end
19
+
20
+ it "works with BindParams" do
21
+ node = Nodes::BindParam.new(1)
22
+ sql = compile node
23
+ _(sql).must_be_like "?"
24
+ end
25
+
26
+ it "does not quote BindParams used as part of a ValuesList" do
27
+ bp = Nodes::BindParam.new(1)
28
+ values = Nodes::ValuesList.new([[bp]])
29
+ sql = compile values
30
+ _(sql).must_be_like "VALUES (?)"
31
+ end
32
+
33
+ it "can define a dispatch method" do
34
+ visited = false
35
+ viz = Class.new(Arel::Visitors::Visitor) {
36
+ define_method(:hello) do |node, c|
37
+ visited = true
38
+ end
39
+
40
+ def dispatch
41
+ { Arel::Table => "hello" }
42
+ end
43
+ }.new
44
+
45
+ viz.accept(@table, Collectors::SQLString.new)
46
+ assert visited, "hello method was called"
47
+ end
48
+
49
+ it "should not quote sql literals" do
50
+ node = @table[Arel.star]
51
+ sql = compile node
52
+ _(sql).must_be_like '"users".*'
53
+ end
54
+
55
+ it "should visit named functions" do
56
+ function = Nodes::NamedFunction.new("omg", [Arel.star])
57
+ assert_equal "omg(*)", compile(function)
58
+ end
59
+
60
+ it "should chain predications on named functions" do
61
+ function = Nodes::NamedFunction.new("omg", [Arel.star])
62
+ sql = compile(function.eq(2))
63
+ _(sql).must_be_like %{ omg(*) = 2 }
64
+ end
65
+
66
+ it "should handle nil with named functions" do
67
+ function = Nodes::NamedFunction.new("omg", [Arel.star])
68
+ sql = compile(function.eq(nil))
69
+ _(sql).must_be_like %{ omg(*) IS NULL }
70
+ end
71
+
72
+ it "should visit built-in functions" do
73
+ function = Nodes::Count.new([Arel.star])
74
+ assert_equal "COUNT(*)", compile(function)
75
+
76
+ function = Nodes::Sum.new([Arel.star])
77
+ assert_equal "SUM(*)", compile(function)
78
+
79
+ function = Nodes::Max.new([Arel.star])
80
+ assert_equal "MAX(*)", compile(function)
81
+
82
+ function = Nodes::Min.new([Arel.star])
83
+ assert_equal "MIN(*)", compile(function)
84
+
85
+ function = Nodes::Avg.new([Arel.star])
86
+ assert_equal "AVG(*)", compile(function)
87
+ end
88
+
89
+ it "should visit built-in functions operating on distinct values" do
90
+ function = Nodes::Count.new([Arel.star])
91
+ function.distinct = true
92
+ assert_equal "COUNT(DISTINCT *)", compile(function)
93
+
94
+ function = Nodes::Sum.new([Arel.star])
95
+ function.distinct = true
96
+ assert_equal "SUM(DISTINCT *)", compile(function)
97
+
98
+ function = Nodes::Max.new([Arel.star])
99
+ function.distinct = true
100
+ assert_equal "MAX(DISTINCT *)", compile(function)
101
+
102
+ function = Nodes::Min.new([Arel.star])
103
+ function.distinct = true
104
+ assert_equal "MIN(DISTINCT *)", compile(function)
105
+
106
+ function = Nodes::Avg.new([Arel.star])
107
+ function.distinct = true
108
+ assert_equal "AVG(DISTINCT *)", compile(function)
109
+ end
110
+
111
+ it "works with lists" do
112
+ function = Nodes::NamedFunction.new("omg", [Arel.star, Arel.star])
113
+ assert_equal "omg(*, *)", compile(function)
114
+ end
115
+
116
+ describe "Nodes::Equality" do
117
+ it "should escape strings" do
118
+ test = Table.new(:users)[:name].eq "Aaron Patterson"
119
+ _(compile(test)).must_be_like %{
120
+ "users"."name" = 'Aaron Patterson'
121
+ }
122
+ end
123
+
124
+ it "should handle false" do
125
+ table = Table.new(:users)
126
+ val = Nodes.build_quoted(false, table[:active])
127
+ sql = compile Nodes::Equality.new(val, val)
128
+ _(sql).must_be_like %{ 'f' = 'f' }
129
+ end
130
+
131
+ it "should handle nil" do
132
+ sql = compile Nodes::Equality.new(@table[:name], nil)
133
+ _(sql).must_be_like %{ "users"."name" IS NULL }
134
+ end
135
+ end
136
+
137
+ describe "Nodes::Grouping" do
138
+ it "wraps nested groupings in brackets only once" do
139
+ sql = compile Nodes::Grouping.new(Nodes::Grouping.new(Nodes.build_quoted("foo")))
140
+ _(sql).must_equal "('foo')"
141
+ end
142
+ end
143
+
144
+ describe "Nodes::NotEqual" do
145
+ it "should handle false" do
146
+ val = Nodes.build_quoted(false, @table[:active])
147
+ sql = compile Nodes::NotEqual.new(@table[:active], val)
148
+ _(sql).must_be_like %{ "users"."active" != 'f' }
149
+ end
150
+
151
+ it "should handle nil" do
152
+ val = Nodes.build_quoted(nil, @table[:active])
153
+ sql = compile Nodes::NotEqual.new(@table[:name], val)
154
+ _(sql).must_be_like %{ "users"."name" IS NOT NULL }
155
+ end
156
+ end
157
+
158
+ describe "Nodes::IsNotDistinctFrom" do
159
+ it "should construct a valid generic SQL statement" do
160
+ test = Table.new(:users)[:name].is_not_distinct_from "Aaron Patterson"
161
+ _(compile(test)).must_be_like %{
162
+ CASE WHEN "users"."name" = 'Aaron Patterson' OR ("users"."name" IS NULL AND 'Aaron Patterson' IS NULL) THEN 0 ELSE 1 END = 0
163
+ }
164
+ end
165
+
166
+ it "should handle column names on both sides" do
167
+ test = Table.new(:users)[:first_name].is_not_distinct_from Table.new(:users)[:last_name]
168
+ _(compile(test)).must_be_like %{
169
+ CASE WHEN "users"."first_name" = "users"."last_name" OR ("users"."first_name" IS NULL AND "users"."last_name" IS NULL) THEN 0 ELSE 1 END = 0
170
+ }
171
+ end
172
+
173
+ it "should handle nil" do
174
+ val = Nodes.build_quoted(nil, @table[:active])
175
+ sql = compile Nodes::IsNotDistinctFrom.new(@table[:name], val)
176
+ _(sql).must_be_like %{ "users"."name" IS NULL }
177
+ end
178
+ end
179
+
180
+ describe "Nodes::IsDistinctFrom" do
181
+ it "should handle column names on both sides" do
182
+ test = Table.new(:users)[:first_name].is_distinct_from Table.new(:users)[:last_name]
183
+ _(compile(test)).must_be_like %{
184
+ CASE WHEN "users"."first_name" = "users"."last_name" OR ("users"."first_name" IS NULL AND "users"."last_name" IS NULL) THEN 0 ELSE 1 END = 1
185
+ }
186
+ end
187
+
188
+ it "should handle nil" do
189
+ val = Nodes.build_quoted(nil, @table[:active])
190
+ sql = compile Nodes::IsDistinctFrom.new(@table[:name], val)
191
+ _(sql).must_be_like %{ "users"."name" IS NOT NULL }
192
+ end
193
+ end
194
+
195
+ it "should visit string subclass" do
196
+ [
197
+ Class.new(String).new(":'("),
198
+ Class.new(Class.new(String)).new(":'("),
199
+ ].each do |obj|
200
+ val = Nodes.build_quoted(obj, @table[:active])
201
+ sql = compile Nodes::NotEqual.new(@table[:name], val)
202
+ _(sql).must_be_like %{ "users"."name" != ':\\'(' }
203
+ end
204
+ end
205
+
206
+ it "should visit_Class" do
207
+ _(compile(Nodes.build_quoted(DateTime))).must_equal "'DateTime'"
208
+ end
209
+
210
+ it "should escape LIMIT" do
211
+ sc = Arel::Nodes::SelectStatement.new
212
+ sc.limit = Arel::Nodes::Limit.new(Nodes.build_quoted("omg"))
213
+ assert_match(/LIMIT 'omg'/, compile(sc))
214
+ end
215
+
216
+ it "should contain a single space before ORDER BY" do
217
+ table = Table.new(:users)
218
+ test = table.order(table[:name])
219
+ sql = compile test
220
+ assert_match(/"users" ORDER BY/, sql)
221
+ end
222
+
223
+ it "should quote LIMIT without column type coercion" do
224
+ table = Table.new(:users)
225
+ sc = table.where(table[:name].eq(0)).take(1).ast
226
+ assert_match(/WHERE "users"."name" = 0 LIMIT 1/, compile(sc))
227
+ end
228
+
229
+ it "should visit_DateTime" do
230
+ dt = DateTime.now
231
+ table = Table.new(:users)
232
+ test = table[:created_at].eq dt
233
+ sql = compile test
234
+
235
+ _(sql).must_be_like %{"users"."created_at" = '#{dt.strftime("%Y-%m-%d %H:%M:%S")}'}
236
+ end
237
+
238
+ it "should visit_Float" do
239
+ test = Table.new(:products)[:price].eq 2.14
240
+ sql = compile test
241
+ _(sql).must_be_like %{"products"."price" = 2.14}
242
+ end
243
+
244
+ it "should visit_Not" do
245
+ sql = compile Nodes::Not.new(Arel.sql("foo"))
246
+ _(sql).must_be_like "NOT (foo)"
247
+ end
248
+
249
+ it "should apply Not to the whole expression" do
250
+ node = Nodes::And.new [@attr.eq(10), @attr.eq(11)]
251
+ sql = compile Nodes::Not.new(node)
252
+ _(sql).must_be_like %{NOT ("users"."id" = 10 AND "users"."id" = 11)}
253
+ end
254
+
255
+ it "should visit_As" do
256
+ as = Nodes::As.new(Arel.sql("foo"), Arel.sql("bar"))
257
+ sql = compile as
258
+ _(sql).must_be_like "foo AS bar"
259
+ end
260
+
261
+ it "should visit_Integer" do
262
+ compile 8787878092
263
+ end
264
+
265
+ it "should visit_Hash" do
266
+ compile(Nodes.build_quoted(a: 1))
267
+ end
268
+
269
+ it "should visit_Set" do
270
+ compile Nodes.build_quoted(Set.new([1, 2]))
271
+ end
272
+
273
+ it "should visit_BigDecimal" do
274
+ compile Nodes.build_quoted(BigDecimal("2.14"))
275
+ end
276
+
277
+ it "should visit_Date" do
278
+ dt = Date.today
279
+ table = Table.new(:users)
280
+ test = table[:created_at].eq dt
281
+ sql = compile test
282
+
283
+ _(sql).must_be_like %{"users"."created_at" = '#{dt.strftime("%Y-%m-%d")}'}
284
+ end
285
+
286
+ it "should visit_NilClass" do
287
+ _(compile(Nodes.build_quoted(nil))).must_be_like "NULL"
288
+ end
289
+
290
+ it "unsupported input should raise UnsupportedVisitError" do
291
+ error = assert_raises(UnsupportedVisitError) { compile(nil) }
292
+ assert_match(/\AUnsupported/, error.message)
293
+ end
294
+
295
+ it "should visit_Arel_SelectManager, which is a subquery" do
296
+ mgr = Table.new(:foo).project(:bar)
297
+ _(compile(mgr)).must_be_like '(SELECT bar FROM "foo")'
298
+ end
299
+
300
+ it "should visit_Arel_Nodes_And" do
301
+ node = Nodes::And.new [@attr.eq(10), @attr.eq(11)]
302
+ _(compile(node)).must_be_like %{
303
+ "users"."id" = 10 AND "users"."id" = 11
304
+ }
305
+ end
306
+
307
+ it "should visit_Arel_Nodes_Or" do
308
+ node = Nodes::Or.new @attr.eq(10), @attr.eq(11)
309
+ _(compile(node)).must_be_like %{
310
+ "users"."id" = 10 OR "users"."id" = 11
311
+ }
312
+ end
313
+
314
+ it "should visit_Arel_Nodes_Assignment" do
315
+ column = @table["id"]
316
+ node = Nodes::Assignment.new(
317
+ Nodes::UnqualifiedColumn.new(column),
318
+ Nodes::UnqualifiedColumn.new(column)
319
+ )
320
+ _(compile(node)).must_be_like %{
321
+ "id" = "id"
322
+ }
323
+ end
324
+
325
+ it "should visit visit_Arel_Attributes_Time" do
326
+ attr = Attributes::Time.new(@attr.relation, @attr.name)
327
+ compile attr
328
+ end
329
+
330
+ it "should visit_TrueClass" do
331
+ test = Table.new(:users)[:bool].eq(true)
332
+ _(compile(test)).must_be_like %{ "users"."bool" = 't' }
333
+ end
334
+
335
+ describe "Nodes::Matches" do
336
+ it "should know how to visit" do
337
+ node = @table[:name].matches("foo%")
338
+ _(compile(node)).must_be_like %{
339
+ "users"."name" LIKE 'foo%'
340
+ }
341
+ end
342
+
343
+ it "can handle ESCAPE" do
344
+ node = @table[:name].matches("foo!%", "!")
345
+ _(compile(node)).must_be_like %{
346
+ "users"."name" LIKE 'foo!%' ESCAPE '!'
347
+ }
348
+ end
349
+
350
+ it "can handle subqueries" do
351
+ subquery = @table.project(:id).where(@table[:name].matches("foo%"))
352
+ node = @attr.in subquery
353
+ _(compile(node)).must_be_like %{
354
+ "users"."id" IN (SELECT id FROM "users" WHERE "users"."name" LIKE 'foo%')
355
+ }
356
+ end
357
+ end
358
+
359
+ describe "Nodes::DoesNotMatch" do
360
+ it "should know how to visit" do
361
+ node = @table[:name].does_not_match("foo%")
362
+ _(compile(node)).must_be_like %{
363
+ "users"."name" NOT LIKE 'foo%'
364
+ }
365
+ end
366
+
367
+ it "can handle ESCAPE" do
368
+ node = @table[:name].does_not_match("foo!%", "!")
369
+ _(compile(node)).must_be_like %{
370
+ "users"."name" NOT LIKE 'foo!%' ESCAPE '!'
371
+ }
372
+ end
373
+
374
+ it "can handle subqueries" do
375
+ subquery = @table.project(:id).where(@table[:name].does_not_match("foo%"))
376
+ node = @attr.in subquery
377
+ _(compile(node)).must_be_like %{
378
+ "users"."id" IN (SELECT id FROM "users" WHERE "users"."name" NOT LIKE 'foo%')
379
+ }
380
+ end
381
+ end
382
+
383
+ describe "Nodes::Ordering" do
384
+ it "should know how to visit" do
385
+ node = @attr.desc
386
+ _(compile(node)).must_be_like %{
387
+ "users"."id" DESC
388
+ }
389
+ end
390
+ end
391
+
392
+ describe "Nodes::In" do
393
+ it "should know how to visit" do
394
+ node = @attr.in [1, 2, 3]
395
+ _(compile(node)).must_be_like %{
396
+ "users"."id" IN (1, 2, 3)
397
+ }
398
+ end
399
+
400
+ it "should return 1=0 when empty right which is always false" do
401
+ node = @attr.in []
402
+ _(compile(node)).must_equal "1=0"
403
+ end
404
+
405
+ it "can handle two dot ranges" do
406
+ node = @attr.between 1..3
407
+ _(compile(node)).must_be_like %{
408
+ "users"."id" BETWEEN 1 AND 3
409
+ }
410
+ end
411
+
412
+ it "can handle three dot ranges" do
413
+ node = @attr.between 1...3
414
+ _(compile(node)).must_be_like %{
415
+ "users"."id" >= 1 AND "users"."id" < 3
416
+ }
417
+ end
418
+
419
+ it "can handle ranges bounded by infinity" do
420
+ node = @attr.between 1..Float::INFINITY
421
+ _(compile(node)).must_be_like %{
422
+ "users"."id" >= 1
423
+ }
424
+ node = @attr.between(-Float::INFINITY..3)
425
+ _(compile(node)).must_be_like %{
426
+ "users"."id" <= 3
427
+ }
428
+ node = @attr.between(-Float::INFINITY...3)
429
+ _(compile(node)).must_be_like %{
430
+ "users"."id" < 3
431
+ }
432
+ node = @attr.between(-Float::INFINITY..Float::INFINITY)
433
+ _(compile(node)).must_be_like %{1=1}
434
+ end
435
+
436
+ it "can handle subqueries" do
437
+ table = Table.new(:users)
438
+ subquery = table.project(:id).where(table[:name].eq("Aaron"))
439
+ node = @attr.in subquery
440
+ _(compile(node)).must_be_like %{
441
+ "users"."id" IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
442
+ }
443
+ end
444
+ end
445
+
446
+ describe "Nodes::InfixOperation" do
447
+ it "should handle Multiplication" do
448
+ node = Arel::Attributes::Decimal.new(Table.new(:products), :price) * Arel::Attributes::Decimal.new(Table.new(:currency_rates), :rate)
449
+ _(compile(node)).must_equal %("products"."price" * "currency_rates"."rate")
450
+ end
451
+
452
+ it "should handle Division" do
453
+ node = Arel::Attributes::Decimal.new(Table.new(:products), :price) / 5
454
+ _(compile(node)).must_equal %("products"."price" / 5)
455
+ end
456
+
457
+ it "should handle Addition" do
458
+ node = Arel::Attributes::Decimal.new(Table.new(:products), :price) + 6
459
+ _(compile(node)).must_equal %(("products"."price" + 6))
460
+ end
461
+
462
+ it "should handle Subtraction" do
463
+ node = Arel::Attributes::Decimal.new(Table.new(:products), :price) - 7
464
+ _(compile(node)).must_equal %(("products"."price" - 7))
465
+ end
466
+
467
+ it "should handle Concatenation" do
468
+ table = Table.new(:users)
469
+ node = table[:name].concat(table[:name])
470
+ _(compile(node)).must_equal %("users"."name" || "users"."name")
471
+ end
472
+
473
+ it "should handle Contains" do
474
+ table = Table.new(:users)
475
+ node = table[:name].contains(table[:name])
476
+ _(compile(node)).must_equal %("users"."name" @> "users"."name")
477
+ end
478
+
479
+ it "should handle Overlaps" do
480
+ table = Table.new(:users)
481
+ node = table[:name].overlaps(table[:name])
482
+ _(compile(node)).must_equal %("users"."name" && "users"."name")
483
+ end
484
+
485
+ it "should handle BitwiseAnd" do
486
+ node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) & 16
487
+ _(compile(node)).must_equal %(("products"."bitmap" & 16))
488
+ end
489
+
490
+ it "should handle BitwiseOr" do
491
+ node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) | 16
492
+ _(compile(node)).must_equal %(("products"."bitmap" | 16))
493
+ end
494
+
495
+ it "should handle BitwiseXor" do
496
+ node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) ^ 16
497
+ _(compile(node)).must_equal %(("products"."bitmap" ^ 16))
498
+ end
499
+
500
+ it "should handle BitwiseShiftLeft" do
501
+ node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) << 4
502
+ _(compile(node)).must_equal %(("products"."bitmap" << 4))
503
+ end
504
+
505
+ it "should handle BitwiseShiftRight" do
506
+ node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) >> 4
507
+ _(compile(node)).must_equal %(("products"."bitmap" >> 4))
508
+ end
509
+
510
+ it "should handle arbitrary operators" do
511
+ node = Arel::Nodes::InfixOperation.new(
512
+ "&&",
513
+ Arel::Attributes::String.new(Table.new(:products), :name),
514
+ Arel::Attributes::String.new(Table.new(:products), :name)
515
+ )
516
+ _(compile(node)).must_equal %("products"."name" && "products"."name")
517
+ end
518
+ end
519
+
520
+ describe "Nodes::UnaryOperation" do
521
+ it "should handle BitwiseNot" do
522
+ node = ~ Arel::Attributes::Integer.new(Table.new(:products), :bitmap)
523
+ _(compile(node)).must_equal %( ~ "products"."bitmap")
524
+ end
525
+
526
+ it "should handle arbitrary operators" do
527
+ node = Arel::Nodes::UnaryOperation.new("!", Arel::Attributes::String.new(Table.new(:products), :active))
528
+ _(compile(node)).must_equal %( ! "products"."active")
529
+ end
530
+ end
531
+
532
+ describe "Nodes::Union" do
533
+ it "squashes parenthesis on multiple unions" do
534
+ subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
535
+ node = Nodes::Union.new subnode, Arel.sql("topright")
536
+ assert_equal("( left UNION right UNION topright )", compile(node))
537
+ subnode = Nodes::Union.new Arel.sql("left"), Arel.sql("right")
538
+ node = Nodes::Union.new Arel.sql("topleft"), subnode
539
+ assert_equal("( topleft UNION left UNION right )", compile(node))
540
+ end
541
+ end
542
+
543
+ describe "Nodes::UnionAll" do
544
+ it "squashes parenthesis on multiple union alls" do
545
+ subnode = Nodes::UnionAll.new Arel.sql("left"), Arel.sql("right")
546
+ node = Nodes::UnionAll.new subnode, Arel.sql("topright")
547
+ assert_equal("( left UNION ALL right UNION ALL topright )", compile(node))
548
+ subnode = Nodes::UnionAll.new Arel.sql("left"), Arel.sql("right")
549
+ node = Nodes::UnionAll.new Arel.sql("topleft"), subnode
550
+ assert_equal("( topleft UNION ALL left UNION ALL right )", compile(node))
551
+ end
552
+ end
553
+
554
+ describe "Nodes::NotIn" do
555
+ it "should know how to visit" do
556
+ node = @attr.not_in [1, 2, 3]
557
+ _(compile(node)).must_be_like %{
558
+ "users"."id" NOT IN (1, 2, 3)
559
+ }
560
+ end
561
+
562
+ it "should return 1=1 when empty right which is always true" do
563
+ node = @attr.not_in []
564
+ _(compile(node)).must_equal "1=1"
565
+ end
566
+
567
+ it "can handle two dot ranges" do
568
+ node = @attr.not_between 1..3
569
+ _(compile(node)).must_equal(
570
+ %{("users"."id" < 1 OR "users"."id" > 3)}
571
+ )
572
+ end
573
+
574
+ it "can handle three dot ranges" do
575
+ node = @attr.not_between 1...3
576
+ _(compile(node)).must_equal(
577
+ %{("users"."id" < 1 OR "users"."id" >= 3)}
578
+ )
579
+ end
580
+
581
+ it "can handle ranges bounded by infinity" do
582
+ node = @attr.not_between 1..Float::INFINITY
583
+ _(compile(node)).must_be_like %{
584
+ "users"."id" < 1
585
+ }
586
+ node = @attr.not_between(-Float::INFINITY..3)
587
+ _(compile(node)).must_be_like %{
588
+ "users"."id" > 3
589
+ }
590
+ node = @attr.not_between(-Float::INFINITY...3)
591
+ _(compile(node)).must_be_like %{
592
+ "users"."id" >= 3
593
+ }
594
+ node = @attr.not_between(-Float::INFINITY..Float::INFINITY)
595
+ _(compile(node)).must_be_like %{1=0}
596
+ end
597
+
598
+ it "can handle subqueries" do
599
+ table = Table.new(:users)
600
+ subquery = table.project(:id).where(table[:name].eq("Aaron"))
601
+ node = @attr.not_in subquery
602
+ _(compile(node)).must_be_like %{
603
+ "users"."id" NOT IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
604
+ }
605
+ end
606
+ end
607
+
608
+ describe "Constants" do
609
+ it "should handle true" do
610
+ test = Table.new(:users).create_true
611
+ _(compile(test)).must_be_like %{
612
+ TRUE
613
+ }
614
+ end
615
+
616
+ it "should handle false" do
617
+ test = Table.new(:users).create_false
618
+ _(compile(test)).must_be_like %{
619
+ FALSE
620
+ }
621
+ end
622
+ end
623
+
624
+ describe "TableAlias" do
625
+ it "should use the underlying table for checking columns" do
626
+ test = Table.new(:users).alias("zomgusers")[:id].eq "3"
627
+ _(compile(test)).must_be_like %{
628
+ "zomgusers"."id" = '3'
629
+ }
630
+ end
631
+ end
632
+
633
+ describe "distinct on" do
634
+ it "raises not implemented error" do
635
+ core = Arel::Nodes::SelectCore.new
636
+ core.set_quantifier = Arel::Nodes::DistinctOn.new(Arel.sql("aaron"))
637
+
638
+ assert_raises(NotImplementedError) do
639
+ compile(core)
640
+ end
641
+ end
642
+ end
643
+
644
+ describe "Nodes::Regexp" do
645
+ it "raises not implemented error" do
646
+ node = Arel::Nodes::Regexp.new(@table[:name], Nodes.build_quoted("foo%"))
647
+
648
+ assert_raises(NotImplementedError) do
649
+ compile(node)
650
+ end
651
+ end
652
+ end
653
+
654
+ describe "Nodes::NotRegexp" do
655
+ it "raises not implemented error" do
656
+ node = Arel::Nodes::NotRegexp.new(@table[:name], Nodes.build_quoted("foo%"))
657
+
658
+ assert_raises(NotImplementedError) do
659
+ compile(node)
660
+ end
661
+ end
662
+ end
663
+
664
+ describe "Nodes::Case" do
665
+ it "supports simple case expressions" do
666
+ node = Arel::Nodes::Case.new(@table[:name])
667
+ .when("foo").then(1)
668
+ .else(0)
669
+
670
+ _(compile(node)).must_be_like %{
671
+ CASE "users"."name" WHEN 'foo' THEN 1 ELSE 0 END
672
+ }
673
+ end
674
+
675
+ it "supports extended case expressions" do
676
+ node = Arel::Nodes::Case.new
677
+ .when(@table[:name].in(%w(foo bar))).then(1)
678
+ .else(0)
679
+
680
+ _(compile(node)).must_be_like %{
681
+ CASE WHEN "users"."name" IN ('foo', 'bar') THEN 1 ELSE 0 END
682
+ }
683
+ end
684
+
685
+ it "works without default branch" do
686
+ node = Arel::Nodes::Case.new(@table[:name])
687
+ .when("foo").then(1)
688
+
689
+ _(compile(node)).must_be_like %{
690
+ CASE "users"."name" WHEN 'foo' THEN 1 END
691
+ }
692
+ end
693
+
694
+ it "allows chaining multiple conditions" do
695
+ node = Arel::Nodes::Case.new(@table[:name])
696
+ .when("foo").then(1)
697
+ .when("bar").then(2)
698
+ .else(0)
699
+
700
+ _(compile(node)).must_be_like %{
701
+ CASE "users"."name" WHEN 'foo' THEN 1 WHEN 'bar' THEN 2 ELSE 0 END
702
+ }
703
+ end
704
+
705
+ it "supports #when with two arguments and no #then" do
706
+ node = Arel::Nodes::Case.new @table[:name]
707
+
708
+ { foo: 1, bar: 0 }.reduce(node) { |_node, pair| _node.when(*pair) }
709
+
710
+ _(compile(node)).must_be_like %{
711
+ CASE "users"."name" WHEN 'foo' THEN 1 WHEN 'bar' THEN 0 END
712
+ }
713
+ end
714
+
715
+ it "can be chained as a predicate" do
716
+ node = @table[:name].when("foo").then("bar").else("baz")
717
+
718
+ _(compile(node)).must_be_like %{
719
+ CASE "users"."name" WHEN 'foo' THEN 'bar' ELSE 'baz' END
720
+ }
721
+ end
722
+ end
723
+
724
+ describe "Nodes::With" do
725
+ it "handles table aliases" do
726
+ manager = Table.new(:foo).project(Arel.star).from(Arel.sql("expr2"))
727
+ expr1 = Table.new(:bar).project(Arel.star).as("expr1")
728
+ expr2 = Table.new(:baz).project(Arel.star).as("expr2")
729
+ manager.with(expr1, expr2)
730
+
731
+ _(compile(manager.ast)).must_be_like %{
732
+ WITH expr1 AS (SELECT * FROM "bar"), expr2 AS (SELECT * FROM "baz") SELECT * FROM expr2
733
+ }
734
+ end
735
+ end
736
+
737
+ describe "Nodes::WithRecursive" do
738
+ it "handles table aliases" do
739
+ manager = Table.new(:foo).project(Arel.star).from(Arel.sql("expr1"))
740
+ expr1 = Table.new(:bar).project(Arel.star).as("expr1")
741
+ manager.with(:recursive, expr1)
742
+
743
+ _(compile(manager.ast)).must_be_like %{
744
+ WITH RECURSIVE expr1 AS (SELECT * FROM "bar") SELECT * FROM expr1
745
+ }
746
+ end
747
+ end
748
+ end
749
+ end
750
+ end