ibm_db 5.1.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 (624) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +9 -0
  3. data/LICENSE +55 -18
  4. data/ext/Makefile +14 -14
  5. data/ext/extconf.rb +4 -4
  6. data/ext/ibm_db.c +62 -57
  7. data/ext/ibm_db.o +0 -0
  8. data/ext/ibm_db.so +0 -0
  9. data/ext/mkmf.log +11 -11
  10. data/ext/ruby_ibm_db_cli.c +1 -0
  11. data/ext/ruby_ibm_db_cli.o +0 -0
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1463 -1279
  13. data/lib/ibm_db.so +1 -0
  14. data/lib/mswin32/ibm_db.rb +7 -3
  15. data/lib/mswin32/rb2x/i386/ruby25/ibm_db.so +0 -0
  16. data/lib/mswin32/rb3x/i386/ruby30/ibm_db.so +0 -0
  17. data/test/active_record/connection_adapters/fake_adapter.rb +5 -2
  18. data/test/activejob/destroy_association_async_test.rb +305 -0
  19. data/test/activejob/destroy_async_job_not_present_test.rb +31 -0
  20. data/test/activejob/helper.rb +15 -0
  21. data/test/assets/schema_dump_5_1.yml +345 -0
  22. data/test/cases/adapter_prevent_writes_test.rb +334 -0
  23. data/test/cases/adapter_test.rb +432 -218
  24. data/test/cases/adapters/mysql2/active_schema_test.rb +85 -75
  25. data/test/cases/adapters/mysql2/auto_increment_test.rb +34 -0
  26. data/test/cases/adapters/mysql2/bind_parameter_test.rb +5 -3
  27. data/test/cases/adapters/mysql2/boolean_test.rb +6 -4
  28. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +26 -24
  29. data/test/cases/adapters/mysql2/charset_collation_test.rb +20 -17
  30. data/test/cases/adapters/mysql2/connection_test.rb +48 -50
  31. data/test/cases/adapters/mysql2/count_deleted_rows_with_lock_test.rb +28 -0
  32. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +23 -19
  33. data/test/cases/adapters/mysql2/enum_test.rb +32 -11
  34. data/test/cases/adapters/mysql2/explain_test.rb +13 -11
  35. data/test/cases/adapters/mysql2/json_test.rb +17 -188
  36. data/test/cases/adapters/mysql2/mysql2_adapter_prevent_writes_test.rb +208 -0
  37. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +183 -28
  38. data/test/cases/adapters/mysql2/nested_deadlock_test.rb +75 -0
  39. data/test/cases/adapters/mysql2/optimizer_hints_test.rb +69 -0
  40. data/test/cases/adapters/mysql2/schema_migrations_test.rb +26 -21
  41. data/test/cases/adapters/mysql2/schema_test.rb +24 -22
  42. data/test/cases/adapters/mysql2/set_test.rb +32 -0
  43. data/test/cases/adapters/mysql2/sp_test.rb +10 -8
  44. data/test/cases/adapters/mysql2/sql_types_test.rb +8 -6
  45. data/test/cases/adapters/mysql2/table_options_test.rb +93 -10
  46. data/test/cases/adapters/mysql2/transaction_test.rb +151 -0
  47. data/test/cases/adapters/mysql2/unsigned_type_test.rb +11 -9
  48. data/test/cases/adapters/mysql2/virtual_column_test.rb +66 -0
  49. data/test/cases/adapters/postgresql/active_schema_test.rb +40 -25
  50. data/test/cases/adapters/postgresql/array_test.rb +118 -63
  51. data/test/cases/adapters/postgresql/bit_string_test.rb +12 -10
  52. data/test/cases/adapters/postgresql/bytea_test.rb +26 -25
  53. data/test/cases/adapters/postgresql/case_insensitive_test.rb +10 -9
  54. data/test/cases/adapters/postgresql/change_schema_test.rb +7 -5
  55. data/test/cases/adapters/postgresql/cidr_test.rb +2 -0
  56. data/test/cases/adapters/postgresql/citext_test.rb +58 -58
  57. data/test/cases/adapters/postgresql/collation_test.rb +17 -15
  58. data/test/cases/adapters/postgresql/composite_test.rb +25 -23
  59. data/test/cases/adapters/postgresql/connection_test.rb +73 -85
  60. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +74 -0
  61. data/test/cases/adapters/postgresql/datatype_test.rb +19 -22
  62. data/test/cases/adapters/postgresql/date_test.rb +42 -0
  63. data/test/cases/adapters/postgresql/domain_test.rb +9 -7
  64. data/test/cases/adapters/postgresql/enum_test.rb +12 -10
  65. data/test/cases/adapters/postgresql/explain_test.rb +10 -8
  66. data/test/cases/adapters/postgresql/extension_migration_test.rb +13 -12
  67. data/test/cases/adapters/postgresql/foreign_table_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/full_text_test.rb +8 -6
  69. data/test/cases/adapters/postgresql/geometric_test.rb +57 -63
  70. data/test/cases/adapters/postgresql/hstore_test.rb +288 -280
  71. data/test/cases/adapters/postgresql/infinity_test.rb +54 -15
  72. data/test/cases/adapters/postgresql/integer_test.rb +2 -0
  73. data/test/cases/adapters/postgresql/interval_test.rb +99 -0
  74. data/test/cases/adapters/postgresql/json_test.rb +16 -201
  75. data/test/cases/adapters/postgresql/ltree_test.rb +14 -16
  76. data/test/cases/adapters/postgresql/money_test.rb +47 -16
  77. data/test/cases/adapters/postgresql/network_test.rb +36 -28
  78. data/test/cases/adapters/postgresql/numbers_test.rb +7 -5
  79. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +71 -0
  80. data/test/cases/adapters/postgresql/partitions_test.rb +22 -0
  81. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +205 -0
  82. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +178 -136
  83. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +27 -0
  84. data/test/cases/adapters/postgresql/quoting_test.rb +12 -6
  85. data/test/cases/adapters/postgresql/range_test.rb +406 -292
  86. data/test/cases/adapters/postgresql/referential_integrity_test.rb +16 -15
  87. data/test/cases/adapters/postgresql/rename_table_test.rb +9 -8
  88. data/test/cases/adapters/postgresql/schema_authorization_test.rb +14 -23
  89. data/test/cases/adapters/postgresql/schema_test.rb +207 -91
  90. data/test/cases/adapters/postgresql/serial_test.rb +9 -7
  91. data/test/cases/adapters/postgresql/statement_pool_test.rb +26 -6
  92. data/test/cases/adapters/postgresql/timestamp_test.rb +17 -15
  93. data/test/cases/adapters/postgresql/transaction_nested_test.rb +114 -0
  94. data/test/cases/adapters/postgresql/transaction_test.rb +189 -0
  95. data/test/cases/adapters/postgresql/type_lookup_test.rb +12 -10
  96. data/test/cases/adapters/postgresql/utils_test.rb +11 -9
  97. data/test/cases/adapters/postgresql/uuid_test.rb +226 -109
  98. data/test/cases/adapters/postgresql/xml_test.rb +10 -14
  99. data/test/cases/adapters/sqlite3/collation_test.rb +26 -15
  100. data/test/cases/adapters/sqlite3/copy_table_test.rb +31 -28
  101. data/test/cases/adapters/sqlite3/explain_test.rb +13 -11
  102. data/test/cases/adapters/sqlite3/json_test.rb +29 -0
  103. data/test/cases/adapters/sqlite3/quoting_test.rb +35 -57
  104. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +186 -0
  105. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +318 -131
  106. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +11 -11
  107. data/test/cases/adapters/sqlite3/statement_pool_test.rb +7 -6
  108. data/test/cases/adapters/sqlite3/transaction_test.rb +123 -0
  109. data/test/cases/aggregations_test.rb +14 -12
  110. data/test/cases/annotate_test.rb +46 -0
  111. data/test/cases/ar_schema_test.rb +153 -86
  112. data/test/cases/arel/attributes/attribute_test.rb +1145 -0
  113. data/test/cases/arel/attributes/math_test.rb +83 -0
  114. data/test/cases/arel/attributes_test.rb +27 -0
  115. data/test/cases/arel/collectors/bind_test.rb +40 -0
  116. data/test/cases/arel/collectors/composite_test.rb +47 -0
  117. data/test/cases/arel/collectors/sql_string_test.rb +41 -0
  118. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +48 -0
  119. data/test/cases/arel/crud_test.rb +65 -0
  120. data/test/cases/arel/delete_manager_test.rb +53 -0
  121. data/test/cases/arel/factory_methods_test.rb +46 -0
  122. data/test/cases/arel/helper.rb +45 -0
  123. data/test/cases/arel/insert_manager_test.rb +241 -0
  124. data/test/cases/arel/nodes/and_test.rb +30 -0
  125. data/test/cases/arel/nodes/as_test.rb +36 -0
  126. data/test/cases/arel/nodes/ascending_test.rb +46 -0
  127. data/test/cases/arel/nodes/bin_test.rb +35 -0
  128. data/test/cases/arel/nodes/binary_test.rb +29 -0
  129. data/test/cases/arel/nodes/bind_param_test.rb +22 -0
  130. data/test/cases/arel/nodes/case_test.rb +96 -0
  131. data/test/cases/arel/nodes/casted_test.rb +18 -0
  132. data/test/cases/arel/nodes/comment_test.rb +22 -0
  133. data/test/cases/arel/nodes/count_test.rb +35 -0
  134. data/test/cases/arel/nodes/delete_statement_test.rb +36 -0
  135. data/test/cases/arel/nodes/descending_test.rb +46 -0
  136. data/test/cases/arel/nodes/distinct_test.rb +21 -0
  137. data/test/cases/arel/nodes/equality_test.rb +62 -0
  138. data/test/cases/arel/nodes/extract_test.rb +43 -0
  139. data/test/cases/arel/nodes/false_test.rb +21 -0
  140. data/test/cases/arel/nodes/grouping_test.rb +26 -0
  141. data/test/cases/arel/nodes/infix_operation_test.rb +42 -0
  142. data/test/cases/arel/nodes/insert_statement_test.rb +44 -0
  143. data/test/cases/arel/nodes/named_function_test.rb +48 -0
  144. data/test/cases/arel/nodes/node_test.rb +22 -0
  145. data/test/cases/arel/nodes/not_test.rb +31 -0
  146. data/test/cases/arel/nodes/or_test.rb +36 -0
  147. data/test/cases/arel/nodes/over_test.rb +69 -0
  148. data/test/cases/arel/nodes/select_core_test.rb +79 -0
  149. data/test/cases/arel/nodes/select_statement_test.rb +51 -0
  150. data/test/cases/arel/nodes/sql_literal_test.rb +75 -0
  151. data/test/cases/arel/nodes/sum_test.rb +35 -0
  152. data/test/cases/arel/nodes/table_alias_test.rb +29 -0
  153. data/test/cases/arel/nodes/true_test.rb +21 -0
  154. data/test/cases/arel/nodes/unary_operation_test.rb +41 -0
  155. data/test/cases/arel/nodes/update_statement_test.rb +60 -0
  156. data/test/cases/arel/nodes/window_test.rb +81 -0
  157. data/test/cases/arel/nodes_test.rb +34 -0
  158. data/test/cases/arel/select_manager_test.rb +1238 -0
  159. data/test/cases/arel/support/fake_record.rb +135 -0
  160. data/test/cases/arel/table_test.rb +216 -0
  161. data/test/cases/arel/update_manager_test.rb +126 -0
  162. data/test/cases/arel/visitors/dispatch_contamination_test.rb +78 -0
  163. data/test/cases/arel/visitors/dot_test.rb +90 -0
  164. data/test/cases/arel/visitors/mysql_test.rb +157 -0
  165. data/test/cases/arel/visitors/postgres_test.rb +366 -0
  166. data/test/cases/arel/visitors/sqlite_test.rb +75 -0
  167. data/test/cases/arel/visitors/to_sql_test.rb +750 -0
  168. data/test/cases/associations/belongs_to_associations_test.rb +510 -158
  169. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +4 -2
  170. data/test/cases/associations/callbacks_test.rb +56 -38
  171. data/test/cases/associations/cascaded_eager_loading_test.rb +118 -61
  172. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +138 -18
  173. data/test/cases/associations/eager_load_nested_include_test.rb +38 -37
  174. data/test/cases/associations/eager_singularization_test.rb +21 -21
  175. data/test/cases/associations/eager_test.rb +559 -415
  176. data/test/cases/associations/extension_test.rb +18 -12
  177. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +234 -213
  178. data/test/cases/associations/has_many_associations_test.rb +1038 -465
  179. data/test/cases/associations/has_many_through_associations_test.rb +558 -249
  180. data/test/cases/associations/has_one_associations_test.rb +294 -129
  181. data/test/cases/associations/has_one_through_associations_test.rb +121 -75
  182. data/test/cases/associations/inner_join_association_test.rb +114 -38
  183. data/test/cases/associations/inverse_associations_test.rb +606 -398
  184. data/test/cases/associations/join_model_test.rb +158 -148
  185. data/test/cases/associations/left_outer_join_association_test.rb +59 -24
  186. data/test/cases/associations/nested_through_associations_test.rb +166 -109
  187. data/test/cases/associations/required_test.rb +35 -10
  188. data/test/cases/associations_test.rb +241 -110
  189. data/test/cases/attribute_methods/read_test.rb +11 -11
  190. data/test/cases/attribute_methods_test.rb +413 -298
  191. data/test/cases/attributes_test.rb +145 -27
  192. data/test/cases/autosave_association_test.rb +681 -436
  193. data/test/cases/base_prevent_writes_test.rb +229 -0
  194. data/test/cases/base_test.rb +599 -542
  195. data/test/cases/batches_test.rb +288 -82
  196. data/test/cases/binary_test.rb +26 -31
  197. data/test/cases/bind_parameter_test.rb +194 -21
  198. data/test/cases/boolean_test.rb +52 -0
  199. data/test/cases/cache_key_test.rb +110 -5
  200. data/test/cases/calculations_test.rb +740 -177
  201. data/test/cases/callbacks_test.rb +74 -207
  202. data/test/cases/clone_test.rb +15 -10
  203. data/test/cases/coders/json_test.rb +2 -0
  204. data/test/cases/coders/yaml_column_test.rb +16 -13
  205. data/test/cases/collection_cache_key_test.rb +177 -20
  206. data/test/cases/column_alias_test.rb +9 -7
  207. data/test/cases/column_definition_test.rb +10 -68
  208. data/test/cases/comment_test.rb +166 -107
  209. data/test/cases/connection_adapters/adapter_leasing_test.rb +14 -10
  210. data/test/cases/connection_adapters/connection_handler_test.rb +358 -51
  211. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +400 -0
  212. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +103 -0
  213. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +499 -0
  214. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +457 -0
  215. data/test/cases/connection_adapters/legacy_connection_handlers_multi_db_test.rb +486 -0
  216. data/test/cases/connection_adapters/legacy_connection_handlers_sharding_db_test.rb +586 -0
  217. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +319 -138
  218. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +62 -50
  219. data/test/cases/connection_adapters/schema_cache_test.rb +259 -26
  220. data/test/cases/connection_adapters/type_lookup_test.rb +96 -95
  221. data/test/cases/connection_management_test.rb +13 -11
  222. data/test/cases/connection_pool_test.rb +316 -83
  223. data/test/cases/core_test.rb +82 -58
  224. data/test/cases/counter_cache_test.rb +204 -50
  225. data/test/cases/custom_locking_test.rb +5 -3
  226. data/test/cases/database_configurations/hash_config_test.rb +74 -0
  227. data/test/cases/database_configurations/resolver_test.rb +150 -0
  228. data/test/cases/database_configurations_test.rb +145 -0
  229. data/test/cases/database_selector_test.rb +296 -0
  230. data/test/cases/database_statements_test.rb +18 -16
  231. data/test/cases/date_test.rb +8 -16
  232. data/test/cases/date_time_precision_test.rb +100 -78
  233. data/test/cases/date_time_test.rb +23 -8
  234. data/test/cases/defaults_test.rb +106 -71
  235. data/test/cases/delegated_type_test.rb +57 -0
  236. data/test/cases/dirty_test.rb +419 -223
  237. data/test/cases/disconnected_test.rb +6 -6
  238. data/test/cases/dup_test.rb +54 -27
  239. data/test/cases/enum_test.rb +461 -82
  240. data/test/cases/errors_test.rb +7 -7
  241. data/test/cases/explain_subscriber_test.rb +17 -15
  242. data/test/cases/explain_test.rb +11 -19
  243. data/test/cases/filter_attributes_test.rb +153 -0
  244. data/test/cases/finder_respond_to_test.rb +14 -14
  245. data/test/cases/finder_test.rb +669 -287
  246. data/test/cases/fixture_set/file_test.rb +34 -38
  247. data/test/cases/fixtures_test.rb +833 -176
  248. data/test/cases/forbidden_attributes_protection_test.rb +32 -67
  249. data/test/cases/habtm_destroy_order_test.rb +25 -25
  250. data/test/cases/helper.rb +78 -49
  251. data/test/cases/hot_compatibility_test.rb +33 -32
  252. data/test/cases/i18n_test.rb +18 -17
  253. data/test/cases/inheritance_test.rb +180 -115
  254. data/test/cases/insert_all_test.rb +489 -0
  255. data/test/cases/instrumentation_test.rb +101 -0
  256. data/test/cases/integration_test.rb +119 -31
  257. data/test/cases/invalid_connection_test.rb +18 -16
  258. data/test/cases/invertible_migration_test.rb +183 -43
  259. data/test/cases/json_attribute_test.rb +35 -0
  260. data/test/cases/json_serialization_test.rb +57 -58
  261. data/test/cases/json_shared_test_cases.rb +290 -0
  262. data/test/cases/locking_test.rb +413 -119
  263. data/test/cases/log_subscriber_test.rb +68 -26
  264. data/test/cases/marshal_serialization_test.rb +39 -0
  265. data/test/cases/migration/change_schema_test.rb +118 -72
  266. data/test/cases/migration/change_table_test.rb +138 -30
  267. data/test/cases/migration/check_constraint_test.rb +162 -0
  268. data/test/cases/migration/column_attributes_test.rb +45 -35
  269. data/test/cases/migration/column_positioning_test.rb +18 -6
  270. data/test/cases/migration/columns_test.rb +93 -77
  271. data/test/cases/migration/command_recorder_test.rb +121 -34
  272. data/test/cases/migration/compatibility_test.rb +578 -23
  273. data/test/cases/migration/create_join_table_test.rb +35 -25
  274. data/test/cases/migration/foreign_key_test.rb +503 -284
  275. data/test/cases/migration/helper.rb +4 -3
  276. data/test/cases/migration/index_test.rb +119 -70
  277. data/test/cases/migration/logger_test.rb +9 -6
  278. data/test/cases/migration/pending_migrations_test.rb +88 -34
  279. data/test/cases/migration/references_foreign_key_test.rb +164 -150
  280. data/test/cases/migration/references_index_test.rb +38 -19
  281. data/test/cases/migration/references_statements_test.rb +15 -14
  282. data/test/cases/migration/rename_table_test.rb +53 -30
  283. data/test/cases/migration_test.rb +637 -269
  284. data/test/cases/migrator_test.rb +191 -135
  285. data/test/cases/mixin_test.rb +7 -11
  286. data/test/cases/modules_test.rb +36 -34
  287. data/test/cases/multi_db_migrator_test.rb +223 -0
  288. data/test/cases/multiparameter_attributes_test.rb +60 -33
  289. data/test/cases/multiple_db_test.rb +16 -22
  290. data/test/cases/nested_attributes_test.rb +341 -320
  291. data/test/cases/nested_attributes_with_callbacks_test.rb +26 -24
  292. data/test/cases/null_relation_test.rb +84 -0
  293. data/test/cases/numeric_data_test.rb +93 -0
  294. data/test/cases/persistence_test.rb +361 -269
  295. data/test/cases/pooled_connections_test.rb +18 -26
  296. data/test/cases/prepared_statement_status_test.rb +48 -0
  297. data/test/cases/primary_keys_test.rb +210 -104
  298. data/test/cases/query_cache_test.rb +610 -141
  299. data/test/cases/quoting_test.rb +132 -31
  300. data/test/cases/readonly_test.rb +49 -48
  301. data/test/cases/reaper_test.rb +146 -32
  302. data/test/cases/reflection_test.rb +167 -156
  303. data/test/cases/relation/delegation_test.rb +49 -36
  304. data/test/cases/relation/delete_all_test.rb +117 -0
  305. data/test/cases/relation/merging_test.rb +319 -42
  306. data/test/cases/relation/mutation_test.rb +55 -93
  307. data/test/cases/relation/or_test.rb +129 -29
  308. data/test/cases/relation/predicate_builder_test.rb +21 -6
  309. data/test/cases/relation/record_fetch_warning_test.rb +5 -3
  310. data/test/cases/relation/select_test.rb +67 -0
  311. data/test/cases/relation/update_all_test.rb +317 -0
  312. data/test/cases/relation/where_chain_test.rb +68 -32
  313. data/test/cases/relation/where_clause_test.rb +136 -61
  314. data/test/cases/relation/where_test.rb +155 -48
  315. data/test/cases/relation_test.rb +266 -112
  316. data/test/cases/relations_test.rb +969 -744
  317. data/test/cases/reload_models_test.rb +13 -9
  318. data/test/cases/reserved_word_test.rb +141 -0
  319. data/test/cases/result_test.rb +68 -17
  320. data/test/cases/sanitize_test.rb +87 -71
  321. data/test/cases/schema_dumper_test.rb +221 -128
  322. data/test/cases/schema_loading_test.rb +3 -2
  323. data/test/cases/scoping/default_scoping_test.rb +185 -144
  324. data/test/cases/scoping/named_scoping_test.rb +177 -89
  325. data/test/cases/scoping/relation_scoping_test.rb +197 -75
  326. data/test/cases/secure_token_test.rb +18 -3
  327. data/test/cases/serialization_test.rb +30 -28
  328. data/test/cases/serialized_attribute_test.rb +133 -42
  329. data/test/cases/signed_id_test.rb +168 -0
  330. data/test/cases/statement_cache_test.rb +41 -24
  331. data/test/cases/statement_invalid_test.rb +42 -0
  332. data/test/cases/store_test.rb +180 -55
  333. data/test/cases/strict_loading_test.rb +473 -0
  334. data/test/cases/suppressor_test.rb +26 -12
  335. data/test/cases/tasks/database_tasks_test.rb +1258 -194
  336. data/test/cases/tasks/mysql_rake_test.rb +370 -298
  337. data/test/cases/tasks/postgresql_rake_test.rb +481 -251
  338. data/test/cases/tasks/sqlite_rake_test.rb +225 -178
  339. data/test/cases/test_case.rb +51 -40
  340. data/test/cases/test_databases_test.rb +79 -0
  341. data/test/cases/test_fixtures_test.rb +79 -19
  342. data/test/cases/time_precision_test.rb +98 -76
  343. data/test/cases/timestamp_test.rb +102 -99
  344. data/test/cases/touch_later_test.rb +12 -10
  345. data/test/cases/transaction_callbacks_test.rb +344 -90
  346. data/test/cases/transaction_isolation_test.rb +12 -12
  347. data/test/cases/transactions_test.rb +612 -162
  348. data/test/cases/type/adapter_specific_registry_test.rb +14 -2
  349. data/test/cases/type/date_time_test.rb +4 -2
  350. data/test/cases/type/integer_test.rb +4 -2
  351. data/test/cases/type/string_test.rb +10 -8
  352. data/test/cases/type/time_test.rb +28 -0
  353. data/test/cases/type/type_map_test.rb +29 -28
  354. data/test/cases/type/unsigned_integer_test.rb +19 -0
  355. data/test/cases/type_test.rb +2 -0
  356. data/test/cases/types_test.rb +3 -1
  357. data/test/cases/unconnected_test.rb +14 -1
  358. data/test/cases/unsafe_raw_sql_test.rb +274 -0
  359. data/test/cases/validations/absence_validation_test.rb +19 -17
  360. data/test/cases/validations/association_validation_test.rb +30 -28
  361. data/test/cases/validations/i18n_generate_message_validation_test.rb +34 -16
  362. data/test/cases/validations/i18n_validation_test.rb +22 -21
  363. data/test/cases/validations/length_validation_test.rb +34 -33
  364. data/test/cases/validations/numericality_validation_test.rb +181 -0
  365. data/test/cases/validations/presence_validation_test.rb +21 -19
  366. data/test/cases/validations/uniqueness_validation_test.rb +156 -86
  367. data/test/cases/validations_repair_helper.rb +2 -0
  368. data/test/cases/validations_test.rb +61 -26
  369. data/test/cases/view_test.rb +122 -116
  370. data/test/cases/yaml_serialization_test.rb +79 -34
  371. data/test/config.example.yml +19 -19
  372. data/test/config.rb +3 -1
  373. data/test/config.yml +16 -6
  374. data/test/fixtures/all/namespaced/accounts.yml +2 -0
  375. data/test/fixtures/author_addresses.yml +1 -8
  376. data/test/fixtures/authors.yml +1 -7
  377. data/test/fixtures/binaries.yml +4 -0
  378. data/test/fixtures/books.yml +9 -2
  379. data/test/fixtures/categories_posts.yml +3 -0
  380. data/test/fixtures/citations.yml +5 -0
  381. data/test/fixtures/comments.yml +7 -0
  382. data/test/fixtures/companies.yml +5 -0
  383. data/test/fixtures/computers.yml +2 -0
  384. data/test/fixtures/customers.yml +10 -1
  385. data/test/fixtures/developers.yml +1 -1
  386. data/test/fixtures/essays.yml +10 -0
  387. data/test/fixtures/faces.yml +3 -3
  388. data/test/fixtures/humans.yml +5 -0
  389. data/test/fixtures/interests.yml +7 -7
  390. data/test/fixtures/memberships.yml +7 -0
  391. data/test/fixtures/minimalistics.yml +3 -0
  392. data/test/fixtures/mixed_case_monkeys.yml +2 -2
  393. data/test/fixtures/naked/yml/courses_with_invalid_key.yml +3 -0
  394. data/test/fixtures/naked/yml/parrots.yml +1 -0
  395. data/test/fixtures/other_books.yml +26 -0
  396. data/test/fixtures/other_posts.yml +1 -0
  397. data/test/fixtures/parrots.yml +7 -1
  398. data/test/fixtures/pirates.yml +3 -0
  399. data/test/fixtures/posts.yml +11 -3
  400. data/test/fixtures/readers.yml +6 -0
  401. data/test/fixtures/reserved_words/values.yml +2 -2
  402. data/test/fixtures/sponsors.yml +3 -0
  403. data/test/fixtures/strict_zines.yml +2 -0
  404. data/test/fixtures/subscribers.yml +1 -1
  405. data/test/fixtures/tasks.yml +1 -1
  406. data/test/fixtures/warehouse-things.yml +3 -0
  407. data/test/migrations/10_urban/9_add_expressions.rb +2 -0
  408. data/test/migrations/decimal/1_give_me_big_numbers.rb +6 -4
  409. data/test/migrations/magic/1_currencies_have_symbols.rb +3 -2
  410. data/test/migrations/missing/1000_people_have_middle_names.rb +2 -0
  411. data/test/migrations/missing/1_people_have_last_names.rb +2 -0
  412. data/test/migrations/missing/3_we_need_reminders.rb +2 -0
  413. data/test/migrations/missing/4_innocent_jointable.rb +3 -1
  414. data/test/migrations/rename/1_we_need_things.rb +2 -0
  415. data/test/migrations/rename/2_rename_things.rb +2 -0
  416. data/test/migrations/to_copy/1_people_have_hobbies.rb +3 -1
  417. data/test/migrations/to_copy/2_people_have_descriptions.rb +3 -1
  418. data/test/migrations/to_copy2/1_create_articles.rb +2 -0
  419. data/test/migrations/to_copy2/2_create_comments.rb +3 -1
  420. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +3 -1
  421. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +3 -1
  422. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +3 -1
  423. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +2 -0
  424. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +2 -0
  425. data/test/migrations/valid/1_valid_people_have_last_names.rb +2 -0
  426. data/test/migrations/valid/2_we_need_reminders.rb +2 -0
  427. data/test/migrations/valid/3_innocent_jointable.rb +3 -1
  428. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +2 -0
  429. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +2 -0
  430. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +3 -1
  431. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +2 -0
  432. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +2 -0
  433. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +3 -1
  434. data/test/migrations/version_check/20131219224947_migration_version_check.rb +2 -0
  435. data/test/models/account.rb +46 -0
  436. data/test/models/admin/account.rb +3 -1
  437. data/test/models/admin/randomly_named_c1.rb +2 -0
  438. data/test/models/admin/user.rb +16 -8
  439. data/test/models/admin.rb +4 -2
  440. data/test/models/aircraft.rb +3 -1
  441. data/test/models/arunit2_model.rb +2 -0
  442. data/test/models/author.rb +153 -102
  443. data/test/models/auto_id.rb +2 -0
  444. data/test/models/autoloadable/extra_firm.rb +2 -0
  445. data/test/models/binary.rb +3 -1
  446. data/test/models/binary_field.rb +6 -0
  447. data/test/models/bird.rb +13 -1
  448. data/test/models/book.rb +14 -4
  449. data/test/models/book_destroy_async.rb +24 -0
  450. data/test/models/boolean.rb +5 -0
  451. data/test/models/bulb.rb +13 -4
  452. data/test/models/cake_designer.rb +2 -0
  453. data/test/models/car.rb +17 -10
  454. data/test/models/carrier.rb +2 -0
  455. data/test/models/cart.rb +5 -0
  456. data/test/models/cat.rb +2 -0
  457. data/test/models/categorization.rb +8 -6
  458. data/test/models/category.rb +28 -16
  459. data/test/models/chef.rb +2 -0
  460. data/test/models/citation.rb +5 -1
  461. data/test/models/club.rb +13 -10
  462. data/test/models/college.rb +4 -2
  463. data/test/models/column.rb +2 -0
  464. data/test/models/column_name.rb +2 -0
  465. data/test/models/comment.rb +32 -10
  466. data/test/models/company.rb +102 -106
  467. data/test/models/company_in_module.rb +27 -26
  468. data/test/models/computer.rb +3 -1
  469. data/test/models/contact.rb +15 -13
  470. data/test/models/content.rb +5 -3
  471. data/test/models/contract.rb +21 -3
  472. data/test/models/country.rb +2 -4
  473. data/test/models/course.rb +3 -1
  474. data/test/models/customer.rb +10 -8
  475. data/test/models/customer_carrier.rb +2 -0
  476. data/test/models/dashboard.rb +2 -0
  477. data/test/models/default.rb +2 -0
  478. data/test/models/department.rb +2 -0
  479. data/test/models/destroy_async_parent.rb +15 -0
  480. data/test/models/destroy_async_parent_soft_delete.rb +20 -0
  481. data/test/models/developer.rb +152 -85
  482. data/test/models/dl_keyed_belongs_to.rb +13 -0
  483. data/test/models/dl_keyed_belongs_to_soft_delete.rb +19 -0
  484. data/test/models/dl_keyed_has_many.rb +5 -0
  485. data/test/models/dl_keyed_has_many_through.rb +5 -0
  486. data/test/models/dl_keyed_has_one.rb +5 -0
  487. data/test/models/dl_keyed_join.rb +10 -0
  488. data/test/models/dog.rb +2 -0
  489. data/test/models/dog_lover.rb +2 -0
  490. data/test/models/doubloon.rb +3 -1
  491. data/test/models/drink_designer.rb +17 -0
  492. data/test/models/edge.rb +4 -2
  493. data/test/models/electron.rb +2 -0
  494. data/test/models/engine.rb +3 -2
  495. data/test/models/entrant.rb +2 -0
  496. data/test/models/entry.rb +5 -0
  497. data/test/models/essay.rb +6 -3
  498. data/test/models/essay_destroy_async.rb +12 -0
  499. data/test/models/event.rb +3 -1
  500. data/test/models/eye.rb +5 -3
  501. data/test/models/face.rb +14 -6
  502. data/test/models/family.rb +6 -0
  503. data/test/models/family_tree.rb +6 -0
  504. data/test/models/friendship.rb +5 -3
  505. data/test/models/frog.rb +8 -0
  506. data/test/models/guid.rb +3 -1
  507. data/test/models/guitar.rb +2 -0
  508. data/test/models/hotel.rb +5 -3
  509. data/test/models/human.rb +39 -0
  510. data/test/models/image.rb +3 -1
  511. data/test/models/interest.rb +14 -3
  512. data/test/models/invoice.rb +4 -2
  513. data/test/models/item.rb +3 -1
  514. data/test/models/job.rb +5 -3
  515. data/test/models/joke.rb +4 -2
  516. data/test/models/keyboard.rb +3 -1
  517. data/test/models/legacy_thing.rb +2 -0
  518. data/test/models/lesson.rb +2 -0
  519. data/test/models/line_item.rb +3 -1
  520. data/test/models/liquid.rb +2 -0
  521. data/test/models/matey.rb +3 -1
  522. data/test/models/measurement.rb +4 -0
  523. data/test/models/member.rb +23 -20
  524. data/test/models/member_detail.rb +3 -0
  525. data/test/models/member_type.rb +2 -0
  526. data/test/models/membership.rb +4 -1
  527. data/test/models/mentor.rb +3 -1
  528. data/test/models/message.rb +5 -0
  529. data/test/models/minimalistic.rb +2 -0
  530. data/test/models/minivan.rb +3 -2
  531. data/test/models/mixed_case_monkey.rb +3 -1
  532. data/test/models/molecule.rb +2 -0
  533. data/test/models/mouse.rb +6 -0
  534. data/test/models/movie.rb +2 -0
  535. data/test/models/node.rb +4 -2
  536. data/test/models/non_primary_key.rb +2 -0
  537. data/test/models/notification.rb +2 -0
  538. data/test/models/numeric_data.rb +12 -0
  539. data/test/models/order.rb +4 -2
  540. data/test/models/organization.rb +9 -7
  541. data/test/models/other_dog.rb +3 -1
  542. data/test/models/owner.rb +6 -4
  543. data/test/models/parrot.rb +12 -4
  544. data/test/models/person.rb +59 -54
  545. data/test/models/personal_legacy_thing.rb +3 -1
  546. data/test/models/pet.rb +4 -2
  547. data/test/models/pet_treasure.rb +2 -0
  548. data/test/models/pirate.rb +67 -43
  549. data/test/models/possession.rb +3 -1
  550. data/test/models/post.rb +184 -86
  551. data/test/models/price_estimate.rb +11 -1
  552. data/test/models/professor.rb +3 -1
  553. data/test/models/project.rb +14 -12
  554. data/test/models/publisher/article.rb +2 -0
  555. data/test/models/publisher/magazine.rb +2 -0
  556. data/test/models/publisher.rb +2 -0
  557. data/test/models/randomly_named_c1.rb +2 -0
  558. data/test/models/rating.rb +5 -1
  559. data/test/models/reader.rb +7 -5
  560. data/test/models/recipe.rb +2 -0
  561. data/test/models/record.rb +2 -0
  562. data/test/models/reference.rb +6 -3
  563. data/test/models/reply.rb +39 -21
  564. data/test/models/room.rb +6 -0
  565. data/test/models/section.rb +6 -0
  566. data/test/models/seminar.rb +6 -0
  567. data/test/models/session.rb +6 -0
  568. data/test/models/ship.rb +12 -9
  569. data/test/models/ship_part.rb +5 -3
  570. data/test/models/shop.rb +4 -2
  571. data/test/models/shop_account.rb +2 -0
  572. data/test/models/speedometer.rb +2 -0
  573. data/test/models/sponsor.rb +8 -5
  574. data/test/models/squeak.rb +6 -0
  575. data/test/models/strict_zine.rb +7 -0
  576. data/test/models/string_key_object.rb +2 -0
  577. data/test/models/student.rb +2 -0
  578. data/test/models/subscriber.rb +4 -2
  579. data/test/models/subscription.rb +5 -1
  580. data/test/models/tag.rb +6 -3
  581. data/test/models/tagging.rb +13 -6
  582. data/test/models/task.rb +2 -0
  583. data/test/models/topic.rb +54 -19
  584. data/test/models/toy.rb +4 -0
  585. data/test/models/traffic_light.rb +2 -0
  586. data/test/models/treasure.rb +5 -3
  587. data/test/models/treaty.rb +2 -4
  588. data/test/models/tree.rb +2 -0
  589. data/test/models/tuning_peg.rb +2 -0
  590. data/test/models/tyre.rb +2 -0
  591. data/test/models/user.rb +12 -4
  592. data/test/models/uuid_child.rb +2 -0
  593. data/test/models/uuid_item.rb +2 -0
  594. data/test/models/uuid_parent.rb +2 -0
  595. data/test/models/vegetables.rb +12 -3
  596. data/test/models/vertex.rb +6 -4
  597. data/test/models/warehouse_thing.rb +2 -0
  598. data/test/models/wheel.rb +3 -1
  599. data/test/models/without_table.rb +3 -1
  600. data/test/models/zine.rb +3 -1
  601. data/test/schema/mysql2_specific_schema.rb +49 -35
  602. data/test/schema/oracle_specific_schema.rb +13 -15
  603. data/test/schema/postgresql_specific_schema.rb +51 -40
  604. data/test/schema/schema.rb +334 -154
  605. data/test/schema/sqlite_specific_schema.rb +9 -16
  606. data/test/support/config.rb +26 -26
  607. data/test/support/connection.rb +14 -8
  608. data/test/support/connection_helper.rb +3 -1
  609. data/test/support/ddl_helper.rb +2 -0
  610. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic.dump +0 -0
  611. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_0_topic_associations.dump +0 -0
  612. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic.dump +0 -0
  613. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_0_topic_associations.dump +0 -0
  614. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic.dump +0 -0
  615. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_0_topic_associations.dump +0 -0
  616. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic.dump +0 -0
  617. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_0_topic_associations.dump +0 -0
  618. data/test/support/marshal_compatibility_fixtures/legacy_6_0_record_mysql.dump +0 -0
  619. data/test/support/marshal_compatibility_fixtures/legacy_relation.dump +0 -0
  620. data/test/support/schema_dumping_helper.rb +2 -0
  621. data/test/support/stubs/strong_parameters.rb +40 -0
  622. data/test/support/yaml_compatibility_fixtures/rails_v1_mysql.yml +206 -0
  623. data/test/support/yaml_compatibility_fixtures/rails_v2.yml +55 -0
  624. metadata +196 -11
@@ -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