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,1238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
4
+
5
+ module Arel
6
+ class SelectManagerTest < Arel::Spec
7
+ def test_join_sources
8
+ manager = Arel::SelectManager.new
9
+ manager.join_sources << Arel::Nodes::StringJoin.new(Nodes.build_quoted("foo"))
10
+ assert_equal "SELECT FROM 'foo'", manager.to_sql
11
+ end
12
+
13
+ describe "backwards compatibility" do
14
+ describe "project" do
15
+ it "accepts symbols as sql literals" do
16
+ table = Table.new :users
17
+ manager = Arel::SelectManager.new
18
+ manager.project :id
19
+ manager.from table
20
+ _(manager.to_sql).must_be_like %{
21
+ SELECT id FROM "users"
22
+ }
23
+ end
24
+ end
25
+
26
+ describe "order" do
27
+ it "accepts symbols" do
28
+ table = Table.new :users
29
+ manager = Arel::SelectManager.new
30
+ manager.project Nodes::SqlLiteral.new "*"
31
+ manager.from table
32
+ manager.order :foo
33
+ _(manager.to_sql).must_be_like %{ SELECT * FROM "users" ORDER BY foo }
34
+ end
35
+ end
36
+
37
+ describe "group" do
38
+ it "takes a symbol" do
39
+ table = Table.new :users
40
+ manager = Arel::SelectManager.new
41
+ manager.from table
42
+ manager.group :foo
43
+ _(manager.to_sql).must_be_like %{ SELECT FROM "users" GROUP BY foo }
44
+ end
45
+ end
46
+
47
+ describe "as" do
48
+ it "makes an AS node by grouping the AST" do
49
+ manager = Arel::SelectManager.new
50
+ as = manager.as(Arel.sql("foo"))
51
+ assert_kind_of Arel::Nodes::Grouping, as.left
52
+ assert_equal manager.ast, as.left.expr
53
+ assert_equal "foo", as.right
54
+ end
55
+
56
+ it "converts right to SqlLiteral if a string" do
57
+ manager = Arel::SelectManager.new
58
+ as = manager.as("foo")
59
+ assert_kind_of Arel::Nodes::SqlLiteral, as.right
60
+ end
61
+
62
+ it "can make a subselect" do
63
+ manager = Arel::SelectManager.new
64
+ manager.project Arel.star
65
+ manager.from Arel.sql("zomg")
66
+ as = manager.as(Arel.sql("foo"))
67
+
68
+ manager = Arel::SelectManager.new
69
+ manager.project Arel.sql("name")
70
+ manager.from as
71
+ _(manager.to_sql).must_be_like "SELECT name FROM (SELECT * FROM zomg) foo"
72
+ end
73
+ end
74
+
75
+ describe "from" do
76
+ it "ignores strings when table of same name exists" do
77
+ table = Table.new :users
78
+ manager = Arel::SelectManager.new
79
+
80
+ manager.from table
81
+ manager.from "users"
82
+ manager.project table["id"]
83
+ _(manager.to_sql).must_be_like 'SELECT "users"."id" FROM users'
84
+ end
85
+
86
+ it "should support any ast" do
87
+ table = Table.new :users
88
+ manager1 = Arel::SelectManager.new
89
+
90
+ manager2 = Arel::SelectManager.new
91
+ manager2.project(Arel.sql("*"))
92
+ manager2.from table
93
+
94
+ manager1.project Arel.sql("lol")
95
+ as = manager2.as Arel.sql("omg")
96
+ manager1.from(as)
97
+
98
+ _(manager1.to_sql).must_be_like %{
99
+ SELECT lol FROM (SELECT * FROM "users") omg
100
+ }
101
+ end
102
+ end
103
+
104
+ describe "having" do
105
+ it "converts strings to SQLLiterals" do
106
+ table = Table.new :users
107
+ mgr = table.from
108
+ mgr.having Arel.sql("foo")
109
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" HAVING foo }
110
+ end
111
+
112
+ it "can have multiple items specified separately" do
113
+ table = Table.new :users
114
+ mgr = table.from
115
+ mgr.having Arel.sql("foo")
116
+ mgr.having Arel.sql("bar")
117
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" HAVING foo AND bar }
118
+ end
119
+
120
+ it "can receive any node" do
121
+ table = Table.new :users
122
+ mgr = table.from
123
+ mgr.having Arel::Nodes::And.new([Arel.sql("foo"), Arel.sql("bar")])
124
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" HAVING foo AND bar }
125
+ end
126
+ end
127
+
128
+ describe "on" do
129
+ it "converts to sqlliterals" do
130
+ table = Table.new :users
131
+ right = table.alias
132
+ mgr = table.from
133
+ mgr.join(right).on("omg")
134
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" INNER JOIN "users" "users_2" ON omg }
135
+ end
136
+
137
+ it "converts to sqlliterals with multiple items" do
138
+ table = Table.new :users
139
+ right = table.alias
140
+ mgr = table.from
141
+ mgr.join(right).on("omg", "123")
142
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" INNER JOIN "users" "users_2" ON omg AND 123 }
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "clone" do
148
+ it "creates new cores" do
149
+ table = Table.new :users, as: "foo"
150
+ mgr = table.from
151
+ m2 = mgr.clone
152
+ m2.project "foo"
153
+ _(mgr.to_sql).wont_equal m2.to_sql
154
+ end
155
+
156
+ it "makes updates to the correct copy" do
157
+ table = Table.new :users, as: "foo"
158
+ mgr = table.from
159
+ m2 = mgr.clone
160
+ m3 = m2.clone
161
+ m2.project "foo"
162
+ _(mgr.to_sql).wont_equal m2.to_sql
163
+ _(m3.to_sql).must_equal mgr.to_sql
164
+ end
165
+ end
166
+
167
+ describe "initialize" do
168
+ it "uses alias in sql" do
169
+ table = Table.new :users, as: "foo"
170
+ mgr = table.from
171
+ mgr.skip 10
172
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" "foo" OFFSET 10 }
173
+ end
174
+ end
175
+
176
+ describe "skip" do
177
+ it "should add an offset" do
178
+ table = Table.new :users
179
+ mgr = table.from
180
+ mgr.skip 10
181
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" OFFSET 10 }
182
+ end
183
+
184
+ it "should chain" do
185
+ table = Table.new :users
186
+ mgr = table.from
187
+ _(mgr.skip(10).to_sql).must_be_like %{ SELECT FROM "users" OFFSET 10 }
188
+ end
189
+ end
190
+
191
+ describe "offset" do
192
+ it "should add an offset" do
193
+ table = Table.new :users
194
+ mgr = table.from
195
+ mgr.offset = 10
196
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" OFFSET 10 }
197
+ end
198
+
199
+ it "should remove an offset" do
200
+ table = Table.new :users
201
+ mgr = table.from
202
+ mgr.offset = 10
203
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" OFFSET 10 }
204
+
205
+ mgr.offset = nil
206
+ _(mgr.to_sql).must_be_like %{ SELECT FROM "users" }
207
+ end
208
+
209
+ it "should return the offset" do
210
+ table = Table.new :users
211
+ mgr = table.from
212
+ mgr.offset = 10
213
+ assert_equal 10, mgr.offset
214
+ end
215
+ end
216
+
217
+ describe "exists" do
218
+ it "should create an exists clause" do
219
+ table = Table.new(:users)
220
+ manager = Arel::SelectManager.new table
221
+ manager.project Nodes::SqlLiteral.new "*"
222
+ m2 = Arel::SelectManager.new
223
+ m2.project manager.exists
224
+ _(m2.to_sql).must_be_like %{ SELECT EXISTS (#{manager.to_sql}) }
225
+ end
226
+
227
+ it "can be aliased" do
228
+ table = Table.new(:users)
229
+ manager = Arel::SelectManager.new table
230
+ manager.project Nodes::SqlLiteral.new "*"
231
+ m2 = Arel::SelectManager.new
232
+ m2.project manager.exists.as("foo")
233
+ _(m2.to_sql).must_be_like %{ SELECT EXISTS (#{manager.to_sql}) AS foo }
234
+ end
235
+ end
236
+
237
+ describe "union" do
238
+ before do
239
+ table = Table.new :users
240
+ @m1 = Arel::SelectManager.new table
241
+ @m1.project Arel.star
242
+ @m1.where(table[:age].lt(18))
243
+
244
+ @m2 = Arel::SelectManager.new table
245
+ @m2.project Arel.star
246
+ @m2.where(table[:age].gt(99))
247
+ end
248
+
249
+ it "should union two managers" do
250
+ # FIXME should this union "managers" or "statements" ?
251
+ # FIXME this probably shouldn't return a node
252
+ node = @m1.union @m2
253
+
254
+ # maybe FIXME: decide when wrapper parens are needed
255
+ _(node.to_sql).must_be_like %{
256
+ ( SELECT * FROM "users" WHERE "users"."age" < 18 UNION SELECT * FROM "users" WHERE "users"."age" > 99 )
257
+ }
258
+ end
259
+
260
+ it "should union all" do
261
+ node = @m1.union :all, @m2
262
+
263
+ _(node.to_sql).must_be_like %{
264
+ ( SELECT * FROM "users" WHERE "users"."age" < 18 UNION ALL SELECT * FROM "users" WHERE "users"."age" > 99 )
265
+ }
266
+ end
267
+ end
268
+
269
+ describe "intersect" do
270
+ before do
271
+ table = Table.new :users
272
+ @m1 = Arel::SelectManager.new table
273
+ @m1.project Arel.star
274
+ @m1.where(table[:age].gt(18))
275
+
276
+ @m2 = Arel::SelectManager.new table
277
+ @m2.project Arel.star
278
+ @m2.where(table[:age].lt(99))
279
+ end
280
+
281
+ it "should intersect two managers" do
282
+ # FIXME should this intersect "managers" or "statements" ?
283
+ # FIXME this probably shouldn't return a node
284
+ node = @m1.intersect @m2
285
+
286
+ # maybe FIXME: decide when wrapper parens are needed
287
+ _(node.to_sql).must_be_like %{
288
+ ( SELECT * FROM "users" WHERE "users"."age" > 18 INTERSECT SELECT * FROM "users" WHERE "users"."age" < 99 )
289
+ }
290
+ end
291
+ end
292
+
293
+ describe "except" do
294
+ before do
295
+ table = Table.new :users
296
+ @m1 = Arel::SelectManager.new table
297
+ @m1.project Arel.star
298
+ @m1.where(table[:age].between(18..60))
299
+
300
+ @m2 = Arel::SelectManager.new table
301
+ @m2.project Arel.star
302
+ @m2.where(table[:age].between(40..99))
303
+ end
304
+
305
+ it "should except two managers" do
306
+ # FIXME should this except "managers" or "statements" ?
307
+ # FIXME this probably shouldn't return a node
308
+ node = @m1.except @m2
309
+
310
+ # maybe FIXME: decide when wrapper parens are needed
311
+ _(node.to_sql).must_be_like %{
312
+ ( SELECT * FROM "users" WHERE "users"."age" BETWEEN 18 AND 60 EXCEPT SELECT * FROM "users" WHERE "users"."age" BETWEEN 40 AND 99 )
313
+ }
314
+ end
315
+ end
316
+
317
+ describe "with" do
318
+ it "should support basic WITH" do
319
+ users = Table.new(:users)
320
+ users_top = Table.new(:users_top)
321
+ comments = Table.new(:comments)
322
+
323
+ top = users.project(users[:id]).where(users[:karma].gt(100))
324
+ users_as = Arel::Nodes::As.new(users_top, top)
325
+ select_manager = comments.project(Arel.star).with(users_as)
326
+ .where(comments[:author_id].in(users_top.project(users_top[:id])))
327
+
328
+ _(select_manager.to_sql).must_be_like %{
329
+ WITH "users_top" AS (SELECT "users"."id" FROM "users" WHERE "users"."karma" > 100) SELECT * FROM "comments" WHERE "comments"."author_id" IN (SELECT "users_top"."id" FROM "users_top")
330
+ }
331
+ end
332
+
333
+ it "should support WITH RECURSIVE" do
334
+ comments = Table.new(:comments)
335
+ comments_id = comments[:id]
336
+ comments_parent_id = comments[:parent_id]
337
+
338
+ replies = Table.new(:replies)
339
+ replies_id = replies[:id]
340
+
341
+ recursive_term = Arel::SelectManager.new
342
+ recursive_term.from(comments).project(comments_id, comments_parent_id).where(comments_id.eq 42)
343
+
344
+ non_recursive_term = Arel::SelectManager.new
345
+ non_recursive_term.from(comments).project(comments_id, comments_parent_id).join(replies).on(comments_parent_id.eq replies_id)
346
+
347
+ union = recursive_term.union(non_recursive_term)
348
+
349
+ as_statement = Arel::Nodes::As.new replies, union
350
+
351
+ manager = Arel::SelectManager.new
352
+ manager.with(:recursive, as_statement).from(replies).project(Arel.star)
353
+
354
+ sql = manager.to_sql
355
+ _(sql).must_be_like %{
356
+ WITH RECURSIVE "replies" AS (
357
+ SELECT "comments"."id", "comments"."parent_id" FROM "comments" WHERE "comments"."id" = 42
358
+ UNION
359
+ SELECT "comments"."id", "comments"."parent_id" FROM "comments" INNER JOIN "replies" ON "comments"."parent_id" = "replies"."id"
360
+ )
361
+ SELECT * FROM "replies"
362
+ }
363
+ end
364
+ end
365
+
366
+ describe "ast" do
367
+ it "should return the ast" do
368
+ table = Table.new :users
369
+ mgr = table.from
370
+ assert mgr.ast
371
+ end
372
+ end
373
+
374
+ describe "taken" do
375
+ it "should return limit" do
376
+ manager = Arel::SelectManager.new
377
+ manager.take 10
378
+ _(manager.taken).must_equal 10
379
+ end
380
+ end
381
+
382
+ describe "lock" do
383
+ # This should fail on other databases
384
+ it "adds a lock node" do
385
+ table = Table.new :users
386
+ mgr = table.from
387
+ _(mgr.lock.to_sql).must_be_like %{ SELECT FROM "users" FOR UPDATE }
388
+ end
389
+ end
390
+
391
+ describe "orders" do
392
+ it "returns order clauses" do
393
+ table = Table.new :users
394
+ manager = Arel::SelectManager.new
395
+ order = table[:id]
396
+ manager.order table[:id]
397
+ _(manager.orders).must_equal [order]
398
+ end
399
+ end
400
+
401
+ describe "order" do
402
+ it "generates order clauses" do
403
+ table = Table.new :users
404
+ manager = Arel::SelectManager.new
405
+ manager.project Nodes::SqlLiteral.new "*"
406
+ manager.from table
407
+ manager.order table[:id]
408
+ _(manager.to_sql).must_be_like %{
409
+ SELECT * FROM "users" ORDER BY "users"."id"
410
+ }
411
+ end
412
+
413
+ # FIXME: I would like to deprecate this
414
+ it "takes *args" do
415
+ table = Table.new :users
416
+ manager = Arel::SelectManager.new
417
+ manager.project Nodes::SqlLiteral.new "*"
418
+ manager.from table
419
+ manager.order table[:id], table[:name]
420
+ _(manager.to_sql).must_be_like %{
421
+ SELECT * FROM "users" ORDER BY "users"."id", "users"."name"
422
+ }
423
+ end
424
+
425
+ it "chains" do
426
+ table = Table.new :users
427
+ manager = Arel::SelectManager.new
428
+ _(manager.order(table[:id])).must_equal manager
429
+ end
430
+
431
+ it "has order attributes" do
432
+ table = Table.new :users
433
+ manager = Arel::SelectManager.new
434
+ manager.project Nodes::SqlLiteral.new "*"
435
+ manager.from table
436
+ manager.order table[:id].desc
437
+ _(manager.to_sql).must_be_like %{
438
+ SELECT * FROM "users" ORDER BY "users"."id" DESC
439
+ }
440
+ end
441
+ end
442
+
443
+ describe "on" do
444
+ it "takes two params" do
445
+ left = Table.new :users
446
+ right = left.alias
447
+ predicate = left[:id].eq(right[:id])
448
+ manager = Arel::SelectManager.new
449
+
450
+ manager.from left
451
+ manager.join(right).on(predicate, predicate)
452
+ _(manager.to_sql).must_be_like %{
453
+ SELECT FROM "users"
454
+ INNER JOIN "users" "users_2"
455
+ ON "users"."id" = "users_2"."id" AND
456
+ "users"."id" = "users_2"."id"
457
+ }
458
+ end
459
+
460
+ it "takes three params" do
461
+ left = Table.new :users
462
+ right = left.alias
463
+ predicate = left[:id].eq(right[:id])
464
+ manager = Arel::SelectManager.new
465
+
466
+ manager.from left
467
+ manager.join(right).on(
468
+ predicate,
469
+ predicate,
470
+ left[:name].eq(right[:name])
471
+ )
472
+ _(manager.to_sql).must_be_like %{
473
+ SELECT FROM "users"
474
+ INNER JOIN "users" "users_2"
475
+ ON "users"."id" = "users_2"."id" AND
476
+ "users"."id" = "users_2"."id" AND
477
+ "users"."name" = "users_2"."name"
478
+ }
479
+ end
480
+ end
481
+
482
+ it "should hand back froms" do
483
+ relation = Arel::SelectManager.new
484
+ assert_equal [], relation.froms
485
+ end
486
+
487
+ it "should create and nodes" do
488
+ relation = Arel::SelectManager.new
489
+ children = ["foo", "bar", "baz"]
490
+ clause = relation.create_and children
491
+ assert_kind_of Arel::Nodes::And, clause
492
+ assert_equal children, clause.children
493
+ end
494
+
495
+ it "should create insert managers" do
496
+ relation = Arel::SelectManager.new
497
+ insert = relation.create_insert
498
+ assert_kind_of Arel::InsertManager, insert
499
+ end
500
+
501
+ it "should create join nodes" do
502
+ relation = Arel::SelectManager.new
503
+ join = relation.create_join "foo", "bar"
504
+ assert_kind_of Arel::Nodes::InnerJoin, join
505
+ assert_equal "foo", join.left
506
+ assert_equal "bar", join.right
507
+ end
508
+
509
+ it "should create join nodes with a full outer join klass" do
510
+ relation = Arel::SelectManager.new
511
+ join = relation.create_join "foo", "bar", Arel::Nodes::FullOuterJoin
512
+ assert_kind_of Arel::Nodes::FullOuterJoin, join
513
+ assert_equal "foo", join.left
514
+ assert_equal "bar", join.right
515
+ end
516
+
517
+ it "should create join nodes with an outer join klass" do
518
+ relation = Arel::SelectManager.new
519
+ join = relation.create_join "foo", "bar", Arel::Nodes::OuterJoin
520
+ assert_kind_of Arel::Nodes::OuterJoin, join
521
+ assert_equal "foo", join.left
522
+ assert_equal "bar", join.right
523
+ end
524
+
525
+ it "should create join nodes with a right outer join klass" do
526
+ relation = Arel::SelectManager.new
527
+ join = relation.create_join "foo", "bar", Arel::Nodes::RightOuterJoin
528
+ assert_kind_of Arel::Nodes::RightOuterJoin, join
529
+ assert_equal "foo", join.left
530
+ assert_equal "bar", join.right
531
+ end
532
+
533
+ describe "join" do
534
+ it "responds to join" do
535
+ left = Table.new :users
536
+ right = left.alias
537
+ predicate = left[:id].eq(right[:id])
538
+ manager = Arel::SelectManager.new
539
+
540
+ manager.from left
541
+ manager.join(right).on(predicate)
542
+ _(manager.to_sql).must_be_like %{
543
+ SELECT FROM "users"
544
+ INNER JOIN "users" "users_2"
545
+ ON "users"."id" = "users_2"."id"
546
+ }
547
+ end
548
+
549
+ it "takes a class" do
550
+ left = Table.new :users
551
+ right = left.alias
552
+ predicate = left[:id].eq(right[:id])
553
+ manager = Arel::SelectManager.new
554
+
555
+ manager.from left
556
+ manager.join(right, Nodes::OuterJoin).on(predicate)
557
+ _(manager.to_sql).must_be_like %{
558
+ SELECT FROM "users"
559
+ LEFT OUTER JOIN "users" "users_2"
560
+ ON "users"."id" = "users_2"."id"
561
+ }
562
+ end
563
+
564
+ it "takes the full outer join class" do
565
+ left = Table.new :users
566
+ right = left.alias
567
+ predicate = left[:id].eq(right[:id])
568
+ manager = Arel::SelectManager.new
569
+
570
+ manager.from left
571
+ manager.join(right, Nodes::FullOuterJoin).on(predicate)
572
+ _(manager.to_sql).must_be_like %{
573
+ SELECT FROM "users"
574
+ FULL OUTER JOIN "users" "users_2"
575
+ ON "users"."id" = "users_2"."id"
576
+ }
577
+ end
578
+
579
+ it "takes the right outer join class" do
580
+ left = Table.new :users
581
+ right = left.alias
582
+ predicate = left[:id].eq(right[:id])
583
+ manager = Arel::SelectManager.new
584
+
585
+ manager.from left
586
+ manager.join(right, Nodes::RightOuterJoin).on(predicate)
587
+ _(manager.to_sql).must_be_like %{
588
+ SELECT FROM "users"
589
+ RIGHT OUTER JOIN "users" "users_2"
590
+ ON "users"."id" = "users_2"."id"
591
+ }
592
+ end
593
+
594
+ it "noops on nil" do
595
+ manager = Arel::SelectManager.new
596
+ _(manager.join(nil)).must_equal manager
597
+ end
598
+
599
+ it "raises EmptyJoinError on empty" do
600
+ left = Table.new :users
601
+ manager = Arel::SelectManager.new
602
+
603
+ manager.from left
604
+ assert_raises(EmptyJoinError) do
605
+ manager.join("")
606
+ end
607
+ end
608
+ end
609
+
610
+ describe "outer join" do
611
+ it "responds to join" do
612
+ left = Table.new :users
613
+ right = left.alias
614
+ predicate = left[:id].eq(right[:id])
615
+ manager = Arel::SelectManager.new
616
+
617
+ manager.from left
618
+ manager.outer_join(right).on(predicate)
619
+ _(manager.to_sql).must_be_like %{
620
+ SELECT FROM "users"
621
+ LEFT OUTER JOIN "users" "users_2"
622
+ ON "users"."id" = "users_2"."id"
623
+ }
624
+ end
625
+
626
+ it "noops on nil" do
627
+ manager = Arel::SelectManager.new
628
+ _(manager.outer_join(nil)).must_equal manager
629
+ end
630
+ end
631
+
632
+ describe "joins" do
633
+ it "returns inner join sql" do
634
+ table = Table.new :users
635
+ aliaz = table.alias
636
+ manager = Arel::SelectManager.new
637
+ manager.from Nodes::InnerJoin.new(aliaz, table[:id].eq(aliaz[:id]))
638
+ assert_match 'INNER JOIN "users" "users_2" "users"."id" = "users_2"."id"',
639
+ manager.to_sql
640
+ end
641
+
642
+ it "returns outer join sql" do
643
+ table = Table.new :users
644
+ aliaz = table.alias
645
+ manager = Arel::SelectManager.new
646
+ manager.from Nodes::OuterJoin.new(aliaz, table[:id].eq(aliaz[:id]))
647
+ assert_match 'LEFT OUTER JOIN "users" "users_2" "users"."id" = "users_2"."id"',
648
+ manager.to_sql
649
+ end
650
+
651
+ it "can have a non-table alias as relation name" do
652
+ users = Table.new :users
653
+ comments = Table.new :comments
654
+
655
+ counts = comments.from.
656
+ group(comments[:user_id]).
657
+ project(
658
+ comments[:user_id].as("user_id"),
659
+ comments[:user_id].count.as("count")
660
+ ).as("counts")
661
+
662
+ joins = users.join(counts).on(counts[:user_id].eq(10))
663
+ _(joins.to_sql).must_be_like %{
664
+ SELECT FROM "users" INNER JOIN (SELECT "comments"."user_id" AS user_id, COUNT("comments"."user_id") AS count FROM "comments" GROUP BY "comments"."user_id") counts ON counts."user_id" = 10
665
+ }
666
+ end
667
+
668
+ it "joins itself" do
669
+ left = Table.new :users
670
+ right = left.alias
671
+ predicate = left[:id].eq(right[:id])
672
+
673
+ mgr = left.join(right)
674
+ mgr.project Nodes::SqlLiteral.new("*")
675
+ _(mgr.on(predicate)).must_equal mgr
676
+
677
+ _(mgr.to_sql).must_be_like %{
678
+ SELECT * FROM "users"
679
+ INNER JOIN "users" "users_2"
680
+ ON "users"."id" = "users_2"."id"
681
+ }
682
+ end
683
+
684
+ it "returns string join sql" do
685
+ manager = Arel::SelectManager.new
686
+ manager.from Nodes::StringJoin.new(Nodes.build_quoted("hello"))
687
+ assert_match "'hello'", manager.to_sql
688
+ end
689
+ end
690
+
691
+ describe "group" do
692
+ it "takes an attribute" do
693
+ table = Table.new :users
694
+ manager = Arel::SelectManager.new
695
+ manager.from table
696
+ manager.group table[:id]
697
+ _(manager.to_sql).must_be_like %{
698
+ SELECT FROM "users" GROUP BY "users"."id"
699
+ }
700
+ end
701
+
702
+ it "chains" do
703
+ table = Table.new :users
704
+ manager = Arel::SelectManager.new
705
+ _(manager.group(table[:id])).must_equal manager
706
+ end
707
+
708
+ it "takes multiple args" do
709
+ table = Table.new :users
710
+ manager = Arel::SelectManager.new
711
+ manager.from table
712
+ manager.group table[:id], table[:name]
713
+ _(manager.to_sql).must_be_like %{
714
+ SELECT FROM "users" GROUP BY "users"."id", "users"."name"
715
+ }
716
+ end
717
+
718
+ # FIXME: backwards compat
719
+ it "makes strings literals" do
720
+ table = Table.new :users
721
+ manager = Arel::SelectManager.new
722
+ manager.from table
723
+ manager.group "foo"
724
+ _(manager.to_sql).must_be_like %{ SELECT FROM "users" GROUP BY foo }
725
+ end
726
+ end
727
+
728
+ describe "window definition" do
729
+ it "can be empty" do
730
+ table = Table.new :users
731
+ manager = Arel::SelectManager.new
732
+ manager.from table
733
+ manager.window("a_window")
734
+ _(manager.to_sql).must_be_like %{
735
+ SELECT FROM "users" WINDOW "a_window" AS ()
736
+ }
737
+ end
738
+
739
+ it "takes an order" do
740
+ table = Table.new :users
741
+ manager = Arel::SelectManager.new
742
+ manager.from table
743
+ manager.window("a_window").order(table["foo"].asc)
744
+ _(manager.to_sql).must_be_like %{
745
+ SELECT FROM "users" WINDOW "a_window" AS (ORDER BY "users"."foo" ASC)
746
+ }
747
+ end
748
+
749
+ it "takes an order with multiple columns" do
750
+ table = Table.new :users
751
+ manager = Arel::SelectManager.new
752
+ manager.from table
753
+ manager.window("a_window").order(table["foo"].asc, table["bar"].desc)
754
+ _(manager.to_sql).must_be_like %{
755
+ SELECT FROM "users" WINDOW "a_window" AS (ORDER BY "users"."foo" ASC, "users"."bar" DESC)
756
+ }
757
+ end
758
+
759
+ it "takes a partition" do
760
+ table = Table.new :users
761
+ manager = Arel::SelectManager.new
762
+ manager.from table
763
+ manager.window("a_window").partition(table["bar"])
764
+ _(manager.to_sql).must_be_like %{
765
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar")
766
+ }
767
+ end
768
+
769
+ it "takes a partition and an order" do
770
+ table = Table.new :users
771
+ manager = Arel::SelectManager.new
772
+ manager.from table
773
+ manager.window("a_window").partition(table["foo"]).order(table["foo"].asc)
774
+ _(manager.to_sql).must_be_like %{
775
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."foo"
776
+ ORDER BY "users"."foo" ASC)
777
+ }
778
+ end
779
+
780
+ it "takes a partition with multiple columns" do
781
+ table = Table.new :users
782
+ manager = Arel::SelectManager.new
783
+ manager.from table
784
+ manager.window("a_window").partition(table["bar"], table["baz"])
785
+ _(manager.to_sql).must_be_like %{
786
+ SELECT FROM "users" WINDOW "a_window" AS (PARTITION BY "users"."bar", "users"."baz")
787
+ }
788
+ end
789
+
790
+ it "takes a rows frame, unbounded preceding" do
791
+ table = Table.new :users
792
+ manager = Arel::SelectManager.new
793
+ manager.from table
794
+ manager.window("a_window").rows(Arel::Nodes::Preceding.new)
795
+ _(manager.to_sql).must_be_like %{
796
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS UNBOUNDED PRECEDING)
797
+ }
798
+ end
799
+
800
+ it "takes a rows frame, bounded preceding" do
801
+ table = Table.new :users
802
+ manager = Arel::SelectManager.new
803
+ manager.from table
804
+ manager.window("a_window").rows(Arel::Nodes::Preceding.new(5))
805
+ _(manager.to_sql).must_be_like %{
806
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS 5 PRECEDING)
807
+ }
808
+ end
809
+
810
+ it "takes a rows frame, unbounded following" do
811
+ table = Table.new :users
812
+ manager = Arel::SelectManager.new
813
+ manager.from table
814
+ manager.window("a_window").rows(Arel::Nodes::Following.new)
815
+ _(manager.to_sql).must_be_like %{
816
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS UNBOUNDED FOLLOWING)
817
+ }
818
+ end
819
+
820
+ it "takes a rows frame, bounded following" do
821
+ table = Table.new :users
822
+ manager = Arel::SelectManager.new
823
+ manager.from table
824
+ manager.window("a_window").rows(Arel::Nodes::Following.new(5))
825
+ _(manager.to_sql).must_be_like %{
826
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS 5 FOLLOWING)
827
+ }
828
+ end
829
+
830
+ it "takes a rows frame, current row" do
831
+ table = Table.new :users
832
+ manager = Arel::SelectManager.new
833
+ manager.from table
834
+ manager.window("a_window").rows(Arel::Nodes::CurrentRow.new)
835
+ _(manager.to_sql).must_be_like %{
836
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS CURRENT ROW)
837
+ }
838
+ end
839
+
840
+ it "takes a rows frame, between two delimiters" do
841
+ table = Table.new :users
842
+ manager = Arel::SelectManager.new
843
+ manager.from table
844
+ window = manager.window("a_window")
845
+ window.frame(
846
+ Arel::Nodes::Between.new(
847
+ window.rows,
848
+ Nodes::And.new([
849
+ Arel::Nodes::Preceding.new,
850
+ Arel::Nodes::CurrentRow.new
851
+ ])))
852
+ _(manager.to_sql).must_be_like %{
853
+ SELECT FROM "users" WINDOW "a_window" AS (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
854
+ }
855
+ end
856
+
857
+ it "takes a range frame, unbounded preceding" do
858
+ table = Table.new :users
859
+ manager = Arel::SelectManager.new
860
+ manager.from table
861
+ manager.window("a_window").range(Arel::Nodes::Preceding.new)
862
+ _(manager.to_sql).must_be_like %{
863
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE UNBOUNDED PRECEDING)
864
+ }
865
+ end
866
+
867
+ it "takes a range frame, bounded preceding" do
868
+ table = Table.new :users
869
+ manager = Arel::SelectManager.new
870
+ manager.from table
871
+ manager.window("a_window").range(Arel::Nodes::Preceding.new(5))
872
+ _(manager.to_sql).must_be_like %{
873
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE 5 PRECEDING)
874
+ }
875
+ end
876
+
877
+ it "takes a range frame, unbounded following" do
878
+ table = Table.new :users
879
+ manager = Arel::SelectManager.new
880
+ manager.from table
881
+ manager.window("a_window").range(Arel::Nodes::Following.new)
882
+ _(manager.to_sql).must_be_like %{
883
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE UNBOUNDED FOLLOWING)
884
+ }
885
+ end
886
+
887
+ it "takes a range frame, bounded following" do
888
+ table = Table.new :users
889
+ manager = Arel::SelectManager.new
890
+ manager.from table
891
+ manager.window("a_window").range(Arel::Nodes::Following.new(5))
892
+ _(manager.to_sql).must_be_like %{
893
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE 5 FOLLOWING)
894
+ }
895
+ end
896
+
897
+ it "takes a range frame, current row" do
898
+ table = Table.new :users
899
+ manager = Arel::SelectManager.new
900
+ manager.from table
901
+ manager.window("a_window").range(Arel::Nodes::CurrentRow.new)
902
+ _(manager.to_sql).must_be_like %{
903
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE CURRENT ROW)
904
+ }
905
+ end
906
+
907
+ it "takes a range frame, between two delimiters" do
908
+ table = Table.new :users
909
+ manager = Arel::SelectManager.new
910
+ manager.from table
911
+ window = manager.window("a_window")
912
+ window.frame(
913
+ Arel::Nodes::Between.new(
914
+ window.range,
915
+ Nodes::And.new([
916
+ Arel::Nodes::Preceding.new,
917
+ Arel::Nodes::CurrentRow.new
918
+ ])))
919
+ _(manager.to_sql).must_be_like %{
920
+ SELECT FROM "users" WINDOW "a_window" AS (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
921
+ }
922
+ end
923
+ end
924
+
925
+ describe "delete" do
926
+ it "copies from" do
927
+ table = Table.new :users
928
+ manager = Arel::SelectManager.new
929
+ manager.from table
930
+ stmt = manager.compile_delete
931
+
932
+ _(stmt.to_sql).must_be_like %{ DELETE FROM "users" }
933
+ end
934
+
935
+ it "copies where" do
936
+ table = Table.new :users
937
+ manager = Arel::SelectManager.new
938
+ manager.from table
939
+ manager.where table[:id].eq 10
940
+ stmt = manager.compile_delete
941
+
942
+ _(stmt.to_sql).must_be_like %{
943
+ DELETE FROM "users" WHERE "users"."id" = 10
944
+ }
945
+ end
946
+ end
947
+
948
+ describe "where_sql" do
949
+ it "gives me back the where sql" do
950
+ table = Table.new :users
951
+ manager = Arel::SelectManager.new
952
+ manager.from table
953
+ manager.where table[:id].eq 10
954
+ _(manager.where_sql).must_be_like %{ WHERE "users"."id" = 10 }
955
+ end
956
+
957
+ it "joins wheres with AND" do
958
+ table = Table.new :users
959
+ manager = Arel::SelectManager.new
960
+ manager.from table
961
+ manager.where table[:id].eq 10
962
+ manager.where table[:id].eq 11
963
+ _(manager.where_sql).must_be_like %{ WHERE "users"."id" = 10 AND "users"."id" = 11}
964
+ end
965
+
966
+ it "handles database specific statements" do
967
+ old_visitor = Table.engine.connection.visitor
968
+ Table.engine.connection.visitor = Visitors::PostgreSQL.new Table.engine.connection
969
+ table = Table.new :users
970
+ manager = Arel::SelectManager.new
971
+ manager.from table
972
+ manager.where table[:id].eq 10
973
+ manager.where table[:name].matches "foo%"
974
+ _(manager.where_sql).must_be_like %{ WHERE "users"."id" = 10 AND "users"."name" ILIKE 'foo%' }
975
+ Table.engine.connection.visitor = old_visitor
976
+ end
977
+
978
+ it "returns nil when there are no wheres" do
979
+ table = Table.new :users
980
+ manager = Arel::SelectManager.new
981
+ manager.from table
982
+ _(manager.where_sql).must_be_nil
983
+ end
984
+ end
985
+
986
+ describe "update" do
987
+ it "creates an update statement" do
988
+ table = Table.new :users
989
+ manager = Arel::SelectManager.new
990
+ manager.from table
991
+ stmt = manager.compile_update({ table[:id] => 1 }, Arel::Attributes::Attribute.new(table, "id"))
992
+
993
+ _(stmt.to_sql).must_be_like %{
994
+ UPDATE "users" SET "id" = 1
995
+ }
996
+ end
997
+
998
+ it "takes a string" do
999
+ table = Table.new :users
1000
+ manager = Arel::SelectManager.new
1001
+ manager.from table
1002
+ stmt = manager.compile_update(Nodes::SqlLiteral.new("foo = bar"), Arel::Attributes::Attribute.new(table, "id"))
1003
+
1004
+ _(stmt.to_sql).must_be_like %{ UPDATE "users" SET foo = bar }
1005
+ end
1006
+
1007
+ it "copies limits" do
1008
+ table = Table.new :users
1009
+ manager = Arel::SelectManager.new
1010
+ manager.from table
1011
+ manager.take 1
1012
+ stmt = manager.compile_update(Nodes::SqlLiteral.new("foo = bar"), Arel::Attributes::Attribute.new(table, "id"))
1013
+ stmt.key = table["id"]
1014
+
1015
+ _(stmt.to_sql).must_be_like %{
1016
+ UPDATE "users" SET foo = bar
1017
+ WHERE "users"."id" IN (SELECT "users"."id" FROM "users" LIMIT 1)
1018
+ }
1019
+ end
1020
+
1021
+ it "copies order" do
1022
+ table = Table.new :users
1023
+ manager = Arel::SelectManager.new
1024
+ manager.from table
1025
+ manager.order :foo
1026
+ stmt = manager.compile_update(Nodes::SqlLiteral.new("foo = bar"), Arel::Attributes::Attribute.new(table, "id"))
1027
+ stmt.key = table["id"]
1028
+
1029
+ _(stmt.to_sql).must_be_like %{
1030
+ UPDATE "users" SET foo = bar
1031
+ WHERE "users"."id" IN (SELECT "users"."id" FROM "users" ORDER BY foo)
1032
+ }
1033
+ end
1034
+
1035
+ it "copies where clauses" do
1036
+ table = Table.new :users
1037
+ manager = Arel::SelectManager.new
1038
+ manager.where table[:id].eq 10
1039
+ manager.from table
1040
+ stmt = manager.compile_update({ table[:id] => 1 }, Arel::Attributes::Attribute.new(table, "id"))
1041
+
1042
+ _(stmt.to_sql).must_be_like %{
1043
+ UPDATE "users" SET "id" = 1 WHERE "users"."id" = 10
1044
+ }
1045
+ end
1046
+
1047
+ it "copies where clauses when nesting is triggered" do
1048
+ table = Table.new :users
1049
+ manager = Arel::SelectManager.new
1050
+ manager.where table[:foo].eq 10
1051
+ manager.take 42
1052
+ manager.from table
1053
+ stmt = manager.compile_update({ table[:id] => 1 }, Arel::Attributes::Attribute.new(table, "id"))
1054
+
1055
+ _(stmt.to_sql).must_be_like %{
1056
+ UPDATE "users" SET "id" = 1 WHERE "users"."id" IN (SELECT "users"."id" FROM "users" WHERE "users"."foo" = 10 LIMIT 42)
1057
+ }
1058
+ end
1059
+ end
1060
+
1061
+ describe "project" do
1062
+ it "takes sql literals" do
1063
+ manager = Arel::SelectManager.new
1064
+ manager.project Nodes::SqlLiteral.new "*"
1065
+ _(manager.to_sql).must_be_like %{ SELECT * }
1066
+ end
1067
+
1068
+ it "takes multiple args" do
1069
+ manager = Arel::SelectManager.new
1070
+ manager.project Nodes::SqlLiteral.new("foo"),
1071
+ Nodes::SqlLiteral.new("bar")
1072
+ _(manager.to_sql).must_be_like %{ SELECT foo, bar }
1073
+ end
1074
+
1075
+ it "takes strings" do
1076
+ manager = Arel::SelectManager.new
1077
+ manager.project "*"
1078
+ _(manager.to_sql).must_be_like %{ SELECT * }
1079
+ end
1080
+ end
1081
+
1082
+ describe "projections" do
1083
+ it "reads projections" do
1084
+ manager = Arel::SelectManager.new
1085
+ manager.project Arel.sql("foo"), Arel.sql("bar")
1086
+ _(manager.projections).must_equal [Arel.sql("foo"), Arel.sql("bar")]
1087
+ end
1088
+ end
1089
+
1090
+ describe "projections=" do
1091
+ it "overwrites projections" do
1092
+ manager = Arel::SelectManager.new
1093
+ manager.project Arel.sql("foo")
1094
+ manager.projections = [Arel.sql("bar")]
1095
+ _(manager.to_sql).must_be_like %{ SELECT bar }
1096
+ end
1097
+ end
1098
+
1099
+ describe "take" do
1100
+ it "knows take" do
1101
+ table = Table.new :users
1102
+ manager = Arel::SelectManager.new
1103
+ manager.from(table).project(table["id"])
1104
+ manager.where(table["id"].eq(1))
1105
+ manager.take 1
1106
+
1107
+ _(manager.to_sql).must_be_like %{
1108
+ SELECT "users"."id"
1109
+ FROM "users"
1110
+ WHERE "users"."id" = 1
1111
+ LIMIT 1
1112
+ }
1113
+ end
1114
+
1115
+ it "chains" do
1116
+ manager = Arel::SelectManager.new
1117
+ _(manager.take(1)).must_equal manager
1118
+ end
1119
+
1120
+ it "removes LIMIT when nil is passed" do
1121
+ manager = Arel::SelectManager.new
1122
+ manager.limit = 10
1123
+ assert_match("LIMIT", manager.to_sql)
1124
+
1125
+ manager.limit = nil
1126
+ assert_no_match("LIMIT", manager.to_sql)
1127
+ end
1128
+ end
1129
+
1130
+ describe "where" do
1131
+ it "knows where" do
1132
+ table = Table.new :users
1133
+ manager = Arel::SelectManager.new
1134
+ manager.from(table).project(table["id"])
1135
+ manager.where(table["id"].eq(1))
1136
+ _(manager.to_sql).must_be_like %{
1137
+ SELECT "users"."id"
1138
+ FROM "users"
1139
+ WHERE "users"."id" = 1
1140
+ }
1141
+ end
1142
+
1143
+ it "chains" do
1144
+ table = Table.new :users
1145
+ manager = Arel::SelectManager.new
1146
+ manager.from(table)
1147
+ _(manager.project(table["id"]).where(table["id"].eq 1)).must_equal manager
1148
+ end
1149
+ end
1150
+
1151
+ describe "from" do
1152
+ it "makes sql" do
1153
+ table = Table.new :users
1154
+ manager = Arel::SelectManager.new
1155
+
1156
+ manager.from table
1157
+ manager.project table["id"]
1158
+ _(manager.to_sql).must_be_like 'SELECT "users"."id" FROM "users"'
1159
+ end
1160
+
1161
+ it "chains" do
1162
+ table = Table.new :users
1163
+ manager = Arel::SelectManager.new
1164
+ _(manager.from(table).project(table["id"])).must_equal manager
1165
+ _(manager.to_sql).must_be_like 'SELECT "users"."id" FROM "users"'
1166
+ end
1167
+ end
1168
+
1169
+ describe "source" do
1170
+ it "returns the join source of the select core" do
1171
+ manager = Arel::SelectManager.new
1172
+ _(manager.source).must_equal manager.ast.cores.last.source
1173
+ end
1174
+ end
1175
+
1176
+ describe "distinct" do
1177
+ it "sets the quantifier" do
1178
+ manager = Arel::SelectManager.new
1179
+
1180
+ manager.distinct
1181
+ _(manager.ast.cores.last.set_quantifier.class).must_equal Arel::Nodes::Distinct
1182
+
1183
+ manager.distinct(false)
1184
+ _(manager.ast.cores.last.set_quantifier).must_be_nil
1185
+ end
1186
+
1187
+ it "chains" do
1188
+ manager = Arel::SelectManager.new
1189
+ _(manager.distinct).must_equal manager
1190
+ _(manager.distinct(false)).must_equal manager
1191
+ end
1192
+ end
1193
+
1194
+ describe "distinct_on" do
1195
+ it "sets the quantifier" do
1196
+ manager = Arel::SelectManager.new
1197
+ table = Table.new :users
1198
+
1199
+ manager.distinct_on(table["id"])
1200
+ _(manager.ast.cores.last.set_quantifier).must_equal Arel::Nodes::DistinctOn.new(table["id"])
1201
+
1202
+ manager.distinct_on(false)
1203
+ _(manager.ast.cores.last.set_quantifier).must_be_nil
1204
+ end
1205
+
1206
+ it "chains" do
1207
+ manager = Arel::SelectManager.new
1208
+ table = Table.new :users
1209
+
1210
+ _(manager.distinct_on(table["id"])).must_equal manager
1211
+ _(manager.distinct_on(false)).must_equal manager
1212
+ end
1213
+ end
1214
+
1215
+ describe "comment" do
1216
+ it "chains" do
1217
+ manager = Arel::SelectManager.new
1218
+ _(manager.comment("selecting")).must_equal manager
1219
+ end
1220
+
1221
+ it "appends a comment to the generated query" do
1222
+ manager = Arel::SelectManager.new
1223
+ table = Table.new :users
1224
+ manager.from(table).project(table["id"])
1225
+
1226
+ manager.comment("selecting")
1227
+ _(manager.to_sql).must_be_like %{
1228
+ SELECT "users"."id" FROM "users" /* selecting */
1229
+ }
1230
+
1231
+ manager.comment("selecting", "with", "comment")
1232
+ _(manager.to_sql).must_be_like %{
1233
+ SELECT "users"."id" FROM "users" /* selecting */ /* with */ /* comment */
1234
+ }
1235
+ end
1236
+ end
1237
+ end
1238
+ end