sequel 5.8.0 → 5.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -1,70 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Sequel::Deprecated" do
4
- before do
5
- @d = Sequel::Deprecation
6
- @prev_prefix = @d.prefix
7
- @prev_output = @d.output
8
- @prev_backtrace_filter = @d.backtrace_filter
9
- @output = []
10
- def @output.puts(s)
11
- self << s
12
- end
13
- @d.prefix = false
14
- @d.output = @output
15
- @d.backtrace_filter = false
16
- end
17
- after do
18
- @d.prefix = @prev_prefix
19
- @d.output = @prev_output
20
- @d.backtrace_filter = @prev_backtrace_filter
21
- end
22
-
23
- it "should output full messages to the given output" do
24
- @d.deprecate("foo")
25
- @output.must_equal ['foo']
26
- end
27
-
28
- it "should consider two arguments to be a method name and additional text" do
29
- @d.deprecate("foo", "Use bar instead")
30
- @output.must_equal ['foo is deprecated and will be removed in Sequel 5.1. Use bar instead.']
31
- end
32
-
33
- it "should include a prefix if set" do
34
- @d.prefix = "DEPWARN: "
35
- @d.deprecate("foo")
36
- @output.must_equal ['DEPWARN: foo']
37
- end
38
-
39
- it "should not output anything if output is false" do
40
- @d.output = false
41
- @d.deprecate("foo")
42
- end
43
-
44
- it "should include full backtrace if backtrace_filter is true" do
45
- @d.backtrace_filter = true
46
- @d.deprecate("foo")
47
- @output.first.must_equal 'foo'
48
- (4..100).must_include(@output.count)
49
- end
50
-
51
- it "should include given lines of backtrace if backtrace_filter is an integer" do
52
- @d.backtrace_filter = 1
53
- @d.deprecate("foo")
54
- @output.first.must_equal 'foo'
55
- @output.count.must_equal 2
56
-
57
- @output.clear
58
- @d.backtrace_filter = 3
59
- @d.deprecate("foo")
60
- @output.first.must_equal 'foo'
61
- @output.count.must_equal 4
62
- end
63
-
64
- it "should select backtrace lines if backtrace_filter is a proc" do
65
- @d.backtrace_filter = lambda{|line, line_no| line_no < 3 && line =~ /./}
66
- @d.deprecate("foo")
67
- @output.first.must_equal 'foo'
68
- @output.count.must_equal 4
69
- end
70
- end
@@ -1,1344 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Blockless Ruby Filters" do
4
- before do
5
- db = Sequel.mock
6
- @d = db[:items].with_extend do
7
- def l(*args, &block)
8
- literal(filter_expr(*args, &block))
9
- end
10
- def lit(*args)
11
- literal(*args)
12
- end
13
- end
14
- end
15
-
16
- it "should support boolean columns directly" do
17
- x = Sequel[:x]
18
- x.dup.must_be_same_as x
19
- x.clone.must_be_same_as x
20
- end
21
-
22
- it "should support boolean columns directly" do
23
- @d.l(:x).must_equal 'x'
24
- end
25
-
26
- with_symbol_splitting "should support qualified columns and aliased columns using symbols" do
27
- @d.l(:x__y).must_equal 'x.y'
28
- @d.l(:x___y).must_equal 'x AS y'
29
- @d.l(:x__y___z).must_equal 'x.y AS z'
30
- end
31
-
32
- with_symbol_splitting "should support qualified columns using virtual rows" do
33
- @d.l(Sequel.expr{x__y}).must_equal 'x.y'
34
- end
35
-
36
- it "should not split symbols or virtual row methods if symbol splitting is disabled" do
37
- @d.l(:x__y).must_equal 'x__y'
38
- @d.l(:x___y).must_equal 'x___y'
39
- @d.l(:x__y___z).must_equal 'x__y___z'
40
- @d.l(Sequel.expr{x__y}).must_equal 'x__y'
41
- end
42
-
43
- it "should support NOT with SQL functions" do
44
- @d.l(~Sequel.function(:is_blah)).must_equal 'NOT is_blah()'
45
- @d.l(~Sequel.function(:is_blah, :x)).must_equal 'NOT is_blah(x)'
46
- @d.l(~Sequel.function(:is_blah, Sequel[:x][:y])).must_equal 'NOT is_blah(x.y)'
47
- @d.l(~Sequel.function(:is_blah, :x, Sequel[:x][:y])).must_equal 'NOT is_blah(x, x.y)'
48
- end
49
-
50
- it "should handle multiple ~" do
51
- @d.l(~Sequel.~(:x)).must_equal 'x'
52
- @d.l(~~Sequel.~(:x)).must_equal 'NOT x'
53
- @d.l(~~Sequel.&(:x, :y)).must_equal '(x AND y)'
54
- @d.l(~~Sequel.|(:x, :y)).must_equal '(x OR y)'
55
- end
56
-
57
- it "should support = via Hash" do
58
- @d.l(:x => 100).must_equal '(x = 100)'
59
- @d.l(:x => 'a').must_equal '(x = \'a\')'
60
- @d.l(:x => true).must_equal '(x IS TRUE)'
61
- @d.l(:x => false).must_equal '(x IS FALSE)'
62
- @d.l(:x => nil).must_equal '(x IS NULL)'
63
- @d.l(:x => [1,2,3]).must_equal '(x IN (1, 2, 3))'
64
- end
65
-
66
- it "should use = 't' and != 't' OR IS NULL if IS TRUE is not supported" do
67
- @d = @d.with_extend{def supports_is_true?; false end}
68
- @d.l(:x => true).must_equal "(x = 't')"
69
- @d.l(~Sequel.expr(:x => true)).must_equal "((x != 't') OR (x IS NULL))"
70
- @d.l(:x => false).must_equal "(x = 'f')"
71
- @d.l(~Sequel.expr(:x => false)).must_equal "((x != 'f') OR (x IS NULL))"
72
- end
73
-
74
- it "should support != via inverted Hash" do
75
- @d.l(~Sequel.expr(:x => 100)).must_equal '(x != 100)'
76
- @d.l(~Sequel.expr(:x => 'a')).must_equal '(x != \'a\')'
77
- @d.l(~Sequel.expr(:x => true)).must_equal '(x IS NOT TRUE)'
78
- @d.l(~Sequel.expr(:x => false)).must_equal '(x IS NOT FALSE)'
79
- @d.l(~Sequel.expr(:x => nil)).must_equal '(x IS NOT NULL)'
80
- end
81
-
82
- it "should support = and similar operations via =~ method" do
83
- @d.l{x =~ 100}.must_equal '(x = 100)'
84
- @d.l{x =~ 'a'}.must_equal '(x = \'a\')'
85
- @d.l{x =~ true}.must_equal '(x IS TRUE)'
86
- @d.l{x =~ false}.must_equal '(x IS FALSE)'
87
- @d.l{x =~ nil}.must_equal '(x IS NULL)'
88
- @d.l{x =~ (1...5)}.must_equal '((x >= 1) AND (x < 5))'
89
- @d.l{x =~ [1,2,3]}.must_equal '(x IN (1, 2, 3))'
90
-
91
- @d.l{(x + y) =~ 100}.must_equal '((x + y) = 100)'
92
- @d.l{(x + y) =~ 'a'}.must_equal '((x + y) = \'a\')'
93
- @d.l{(x + y) =~ true}.must_equal '((x + y) IS TRUE)'
94
- @d.l{(x + y) =~ false}.must_equal '((x + y) IS FALSE)'
95
- @d.l{(x + y) =~ nil}.must_equal '((x + y) IS NULL)'
96
- @d.l{(x + y) =~ (1...5)}.must_equal '(((x + y) >= 1) AND ((x + y) < 5))'
97
- @d.l{(x + y) =~ [1,2,3]}.must_equal '((x + y) IN (1, 2, 3))'
98
-
99
- @d = @d.with_extend{def supports_regexp?; true end}
100
- @d.l{x =~ /blah/}.must_equal '(x ~ \'blah\')'
101
- @d.l{(x + y) =~ /blah/}.must_equal '((x + y) ~ \'blah\')'
102
- end
103
-
104
- it "should support != and similar inversions via !~ method" do
105
- @d.l{x !~ 100}.must_equal '(x != 100)'
106
- @d.l{x !~ 'a'}.must_equal '(x != \'a\')'
107
- @d.l{x !~ true}.must_equal '(x IS NOT TRUE)'
108
- @d.l{x !~ false}.must_equal '(x IS NOT FALSE)'
109
- @d.l{x !~ nil}.must_equal '(x IS NOT NULL)'
110
- @d.l{x !~ (1...5)}.must_equal '((x < 1) OR (x >= 5))'
111
- @d.l{x !~ [1,2,3]}.must_equal '(x NOT IN (1, 2, 3))'
112
-
113
- @d.l{(x + y) !~ 100}.must_equal '((x + y) != 100)'
114
- @d.l{(x + y) !~ 'a'}.must_equal '((x + y) != \'a\')'
115
- @d.l{(x + y) !~ true}.must_equal '((x + y) IS NOT TRUE)'
116
- @d.l{(x + y) !~ false}.must_equal '((x + y) IS NOT FALSE)'
117
- @d.l{(x + y) !~ nil}.must_equal '((x + y) IS NOT NULL)'
118
- @d.l{(x + y) !~ (1...5)}.must_equal '(((x + y) < 1) OR ((x + y) >= 5))'
119
- @d.l{(x + y) !~ [1,2,3]}.must_equal '((x + y) NOT IN (1, 2, 3))'
120
-
121
- @d = @d.with_extend{def supports_regexp?; true end}
122
- @d.l{x !~ /blah/}.must_equal '(x !~ \'blah\')'
123
- @d.l{(x + y) !~ /blah/}.must_equal '((x + y) !~ \'blah\')'
124
- end
125
-
126
- it "should support ~ via Hash and Regexp (if supported by database)" do
127
- @d = @d.with_extend{def supports_regexp?; true end}
128
- @d.l(:x => /blah/).must_equal '(x ~ \'blah\')'
129
- end
130
-
131
- it "should support !~ via inverted Hash and Regexp" do
132
- @d = @d.with_extend{def supports_regexp?; true end}
133
- @d.l(~Sequel.expr(:x => /blah/)).must_equal '(x !~ \'blah\')'
134
- end
135
-
136
- it "should support negating ranges" do
137
- @d.l(~Sequel.expr(:x => 1..5)).must_equal '((x < 1) OR (x > 5))'
138
- @d.l(~Sequel.expr(:x => 1...5)).must_equal '((x < 1) OR (x >= 5))'
139
- end
140
-
141
- it "should support negating IN with Dataset or Array" do
142
- @d.l(~Sequel.expr(:x => @d.select(:i))).must_equal '(x NOT IN (SELECT i FROM items))'
143
- @d.l(~Sequel.expr(:x => [1,2,3])).must_equal '(x NOT IN (1, 2, 3))'
144
- end
145
-
146
- it "should not add ~ method to string expressions" do
147
- proc{~Sequel.expr(:x).sql_string}.must_raise(NoMethodError)
148
- end
149
-
150
- it "should only allow combining associative operators" do
151
- @d.lit(Sequel.expr{a + b + c}).must_equal '(a + b + c)'
152
- @d.lit(Sequel.expr{a - b - c}).must_equal '((a - b) - c)'
153
- @d.lit(Sequel.expr{a * b * c}).must_equal '(a * b * c)'
154
- @d.lit(Sequel.expr{a / b / c}).must_equal '((a / b) / c)'
155
- @d.lit(Sequel.expr{a & b & c}).must_equal '(a AND b AND c)'
156
- @d.lit(Sequel.expr{a | b | c}).must_equal '(a OR b OR c)'
157
- @d.lit(Sequel.expr{a.sql_string + b + c}).must_equal '(a || b || c)'
158
- @d.lit(Sequel.expr{a.sql_number >> b >> c}).must_equal '((a >> b) >> c)'
159
- @d.lit(Sequel.expr{a.sql_number << b << c}).must_equal '((a << b) << c)'
160
- @d.lit(Sequel.expr{a.sql_number % b % c}).must_equal '((a % b) % c)'
161
- @d.lit(Sequel.expr{a.sql_number & b & c}).must_equal '(a & b & c)'
162
- @d.lit(Sequel.expr{a.sql_number | b | c}).must_equal '(a | b | c)'
163
- end
164
-
165
- it "should allow mathematical or string operations on true, false, or nil" do
166
- @d.lit(Sequel.expr(:x) + 1).must_equal '(x + 1)'
167
- @d.lit(Sequel.expr(:x) - true).must_equal "(x - 't')"
168
- @d.lit(Sequel.expr(:x) / false).must_equal "(x / 'f')"
169
- @d.lit(Sequel.expr(:x) * nil).must_equal '(x * NULL)'
170
- @d.lit(Sequel.expr(:x) ** 1).must_equal 'power(x, 1)'
171
- @d.lit(Sequel.join([:x, nil])).must_equal '(x || NULL)'
172
- end
173
-
174
- it "should allow mathematical or string operations on boolean complex expressions" do
175
- @d.lit(Sequel.expr(:x) + (Sequel.expr(:y) + 1)).must_equal '(x + y + 1)'
176
- @d.lit(Sequel.expr(:x) - ~Sequel.expr(:y)).must_equal '(x - NOT y)'
177
- @d.lit(Sequel.expr(:x) / (Sequel.expr(:y) & :z)).must_equal '(x / (y AND z))'
178
- @d.lit(Sequel.expr(:x) * (Sequel.expr(:y) | :z)).must_equal '(x * (y OR z))'
179
- @d.lit(Sequel.expr(:x) + Sequel.expr(:y).like('a')).must_equal "(x + (y LIKE 'a' ESCAPE '\\'))"
180
- @d.lit(Sequel.expr(:x) - ~Sequel.expr(:y).like('a')).must_equal "(x - (y NOT LIKE 'a' ESCAPE '\\'))"
181
- @d.lit(Sequel.join([:x, ~Sequel.expr(:y).like('a')])).must_equal "(x || (y NOT LIKE 'a' ESCAPE '\\'))"
182
- @d.lit(Sequel.expr(:x) ** (Sequel.expr(:y) + 1)).must_equal 'power(x, (y + 1))'
183
- end
184
-
185
- it "should allow mathematical or string operations on numerics when argument is a generic or numeric expressions" do
186
- @d.lit(1 + Sequel.expr(:x)).must_equal '(1 + x)'
187
- @d.lit(2**65 - Sequel.+(:x, 1)).must_equal "(#{2**65} - (x + 1))"
188
- @d.lit(1.0 / Sequel.function(:x)).must_equal '(1.0 / x())'
189
- @d.lit(BigDecimal.new('1.0') * Sequel[:a][:y]).must_equal '(1.0 * a.y)'
190
- @d.lit(2 ** Sequel.cast(:x, Integer)).must_equal 'power(2, CAST(x AS integer))'
191
- @d.lit(1 + Sequel.lit('x')).must_equal '(1 + x)'
192
- @d.lit(1 + Sequel.lit('?', :x)).must_equal '(1 + x)'
193
- end
194
-
195
- it "should raise a NoMethodError if coerce is called with a non-Numeric" do
196
- proc{Sequel.expr(:x).coerce(:a)}.must_raise NoMethodError
197
- end
198
-
199
- it "should support AND conditions via &" do
200
- @d.l(Sequel.expr(:x) & :y).must_equal '(x AND y)'
201
- @d.l(Sequel.expr(:x).sql_boolean & :y).must_equal '(x AND y)'
202
- @d.l(Sequel.expr(:x) & :y & :z).must_equal '(x AND y AND z)'
203
- @d.l(Sequel.expr(:x) & {:y => :z}).must_equal '(x AND (y = z))'
204
- @d.l((Sequel.expr(:x) + 200 < 0) & (Sequel.expr(:y) - 200 < 0)).must_equal '(((x + 200) < 0) AND ((y - 200) < 0))'
205
- @d.l(Sequel.expr(:x) & ~Sequel.expr(:y)).must_equal '(x AND NOT y)'
206
- @d.l(~Sequel.expr(:x) & :y).must_equal '(NOT x AND y)'
207
- @d.l(~Sequel.expr(:x) & ~Sequel.expr(:y)).must_equal '(NOT x AND NOT y)'
208
- end
209
-
210
- it "should support OR conditions via |" do
211
- @d.l(Sequel.expr(:x) | :y).must_equal '(x OR y)'
212
- @d.l(Sequel.expr(:x).sql_boolean | :y).must_equal '(x OR y)'
213
- @d.l(Sequel.expr(:x) | :y | :z).must_equal '(x OR y OR z)'
214
- @d.l(Sequel.expr(:x) | {:y => :z}).must_equal '(x OR (y = z))'
215
- @d.l((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y).sql_number < 200)).must_equal '((x > 200) OR (y < 200))'
216
- end
217
-
218
- it "should support & | combinations" do
219
- @d.l((Sequel.expr(:x) | :y) & :z).must_equal '((x OR y) AND z)'
220
- @d.l(Sequel.expr(:x) | (Sequel.expr(:y) & :z)).must_equal '(x OR (y AND z))'
221
- @d.l((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z)).must_equal '((x AND w) OR (y AND z))'
222
- end
223
-
224
- it "should support & | with ~" do
225
- @d.l(~((Sequel.expr(:x) | :y) & :z)).must_equal '((NOT x AND NOT y) OR NOT z)'
226
- @d.l(~(Sequel.expr(:x) | (Sequel.expr(:y) & :z))).must_equal '(NOT x AND (NOT y OR NOT z))'
227
- @d.l(~((Sequel.expr(:x) & :w) | (Sequel.expr(:y) & :z))).must_equal '((NOT x OR NOT w) AND (NOT y OR NOT z))'
228
- @d.l(~((Sequel.expr(:x).sql_number > 200) | (Sequel.expr(:y) & :z))).must_equal '((x <= 200) AND (NOT y OR NOT z))'
229
- end
230
-
231
- it "should support LiteralString" do
232
- @d.l(Sequel.lit('x')).must_equal '(x)'
233
- @d.l(~Sequel.lit('x')).must_equal 'NOT x'
234
- @d.l(~~Sequel.lit('x')).must_equal 'x'
235
- @d.l(~((Sequel.lit('x') | :y) & :z)).must_equal '((NOT x AND NOT y) OR NOT z)'
236
- @d.l(~(Sequel.expr(:x) | Sequel.lit('y'))).must_equal '(NOT x AND NOT y)'
237
- @d.l(~(Sequel.lit('x') & Sequel.lit('y'))).must_equal '(NOT x OR NOT y)'
238
- @d.l(Sequel.expr(Sequel.lit('y') => Sequel.lit('z')) & Sequel.lit('x')).must_equal '((y = z) AND x)'
239
- @d.l((Sequel.lit('x') > 200) & (Sequel.lit('y') < 200)).must_equal '((x > 200) AND (y < 200))'
240
- @d.l(~(Sequel.lit('x') + 1 > 100)).must_equal '((x + 1) <= 100)'
241
- @d.l(Sequel.lit('x').like('a')).must_equal '(x LIKE \'a\' ESCAPE \'\\\')'
242
- @d.l(Sequel.lit('x') + 1 > 100).must_equal '((x + 1) > 100)'
243
- @d.l((Sequel.lit('x') * :y) < 100.01).must_equal '((x * y) < 100.01)'
244
- @d.l((Sequel.lit('x') ** :y) < 100.01).must_equal '(power(x, y) < 100.01)'
245
- @d.l((Sequel.lit('x') - Sequel.expr(:y)/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
246
- @d.l((Sequel.lit('z') * ((Sequel.lit('x') / :y)/(Sequel.expr(:x) + :y))) <= 100).must_equal '((z * ((x / y) / (x + y))) <= 100)'
247
- @d.l(~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
248
- end
249
-
250
- it "should have LiteralString#inspect show it is a literal string" do
251
- Sequel.lit('x').inspect.must_equal "#<Sequel::LiteralString \"x\">"
252
- end
253
-
254
- it "should support hashes by ANDing the conditions" do
255
- @d.l(:x => 100, :y => 'a')[1...-1].split(' AND ').sort.must_equal ['(x = 100)', '(y = \'a\')']
256
- @d.l(:x => true, :y => false)[1...-1].split(' AND ').sort.must_equal ['(x IS TRUE)', '(y IS FALSE)']
257
- @d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.must_equal ['(x IS NULL)', '(y IN (1, 2, 3))']
258
- end
259
-
260
- it "should support arrays with all two pairs the same as hashes" do
261
- @d.l([[:x, 100],[:y, 'a']]).must_equal '((x = 100) AND (y = \'a\'))'
262
- @d.l([[:x, true], [:y, false]]).must_equal '((x IS TRUE) AND (y IS FALSE))'
263
- @d.l([[:x, nil], [:y, [1,2,3]]]).must_equal '((x IS NULL) AND (y IN (1, 2, 3)))'
264
- end
265
-
266
- it "should emulate columns for array values" do
267
- @d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).must_equal '((x, y) IN ((1, 2), (3, 4)))'
268
- @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).must_equal '((x, y, z) IN ((1, 2, 5), (3, 4, 6)))'
269
- end
270
-
271
- it "should emulate multiple column in if not supported" do
272
- @d = @d.with_extend{def supports_multiple_column_in?; false end}
273
- @d.l([:x, :y]=>Sequel.value_list([[1,2], [3,4]])).must_equal '(((x = 1) AND (y = 2)) OR ((x = 3) AND (y = 4)))'
274
- @d.l([:x, :y, :z]=>[[1,2,5], [3,4,6]]).must_equal '(((x = 1) AND (y = 2) AND (z = 5)) OR ((x = 3) AND (y = 4) AND (z = 6)))'
275
- end
276
-
277
- it "should have SQL::ValueList#inspect show it is a value list" do
278
- Sequel.value_list([[1,2], [3,4]]).inspect.must_equal "#<Sequel::SQL::ValueList [[1, 2], [3, 4]]>"
279
- end
280
-
281
- it "should support StringExpression#+ for concatenation of SQL strings" do
282
- @d.lit(Sequel.expr(:x).sql_string + :y).must_equal '(x || y)'
283
- @d.lit(Sequel.join([:x]) + :y).must_equal '(x || y)'
284
- @d.lit(Sequel.join([:x, :z], ' ') + :y).must_equal "(x || ' ' || z || y)"
285
- end
286
-
287
- it "should be supported inside blocks" do
288
- @d.l{Sequel.or([[:x, nil], [:y, [1,2,3]]])}.must_equal '((x IS NULL) OR (y IN (1, 2, 3)))'
289
- @d.l{Sequel.~([[:x, nil], [:y, [1,2,3]]])}.must_equal '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
290
- @d.l{~((((Sequel.lit('x') - :y)/(Sequel.expr(:x) + :y))*:z) <= 100)}.must_equal '((((x - y) / (x + y)) * z) > 100)'
291
- @d.l{Sequel.&({:x => :a}, {:y => :z})}.must_equal '((x = a) AND (y = z))'
292
- end
293
-
294
- it "should support &, |, ^, ~, <<, and >> for NumericExpressions" do
295
- @d.l(Sequel.expr(:x).sql_number & 1 > 100).must_equal '((x & 1) > 100)'
296
- @d.l(Sequel.expr(:x).sql_number | 1 > 100).must_equal '((x | 1) > 100)'
297
- @d.l(Sequel.expr(:x).sql_number ^ 1 > 100).must_equal '((x ^ 1) > 100)'
298
- @d.l(~Sequel.expr(:x).sql_number > 100).must_equal '(~x > 100)'
299
- @d.l(Sequel.expr(:x).sql_number << 1 > 100).must_equal '((x << 1) > 100)'
300
- @d.l(Sequel.expr(:x).sql_number >> 1 > 100).must_equal '((x >> 1) > 100)'
301
- @d.l((Sequel.expr(:x) + 1) & 1 > 100).must_equal '(((x + 1) & 1) > 100)'
302
- @d.l((Sequel.expr(:x) + 1) | 1 > 100).must_equal '(((x + 1) | 1) > 100)'
303
- @d.l((Sequel.expr(:x) + 1) ^ 1 > 100).must_equal '(((x + 1) ^ 1) > 100)'
304
- @d.l(~(Sequel.expr(:x) + 1) > 100).must_equal '(~(x + 1) > 100)'
305
- @d.l((Sequel.expr(:x) + 1) << 1 > 100).must_equal '(((x + 1) << 1) > 100)'
306
- @d.l((Sequel.expr(:x) + 1) >> 1 > 100).must_equal '(((x + 1) >> 1) > 100)'
307
- @d.l((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + 2) > 100).must_equal '(((x + 1) & (x + 2)) > 100)'
308
- end
309
-
310
- it "should allow using a Bitwise method on a ComplexExpression that isn't a NumericExpression" do
311
- @d.lit((Sequel.expr(:x) + 1) & (Sequel.expr(:x) + '2')).must_equal "((x + 1) & (x || '2'))"
312
- end
313
-
314
- it "should allow using a Boolean method on a ComplexExpression that isn't a BooleanExpression" do
315
- @d.l(Sequel.expr(:x) & (Sequel.expr(:x) + '2')).must_equal "(x AND (x || '2'))"
316
- end
317
-
318
- it "should raise an error if attempting to invert a ComplexExpression that isn't a BooleanExpression" do
319
- proc{Sequel::SQL::BooleanExpression.invert(Sequel.expr(:x) + 2)}.must_raise(Sequel::Error)
320
- end
321
-
322
- it "should support SQL::Constants" do
323
- @d.l({:x => Sequel::NULL}).must_equal '(x IS NULL)'
324
- @d.l({:x => Sequel::NOTNULL}).must_equal '(x IS NOT NULL)'
325
- @d.l({:x => Sequel::TRUE}).must_equal '(x IS TRUE)'
326
- @d.l({:x => Sequel::FALSE}).must_equal '(x IS FALSE)'
327
- @d.l({:x => Sequel::SQLTRUE}).must_equal '(x IS TRUE)'
328
- @d.l({:x => Sequel::SQLFALSE}).must_equal '(x IS FALSE)'
329
- end
330
-
331
- it "should support negation of SQL::Constants" do
332
- @d.l(Sequel.~(:x => Sequel::NULL)).must_equal '(x IS NOT NULL)'
333
- @d.l(Sequel.~(:x => Sequel::NOTNULL)).must_equal '(x IS NULL)'
334
- @d.l(Sequel.~(:x => Sequel::TRUE)).must_equal '(x IS NOT TRUE)'
335
- @d.l(Sequel.~(:x => Sequel::FALSE)).must_equal '(x IS NOT FALSE)'
336
- @d.l(Sequel.~(:x => Sequel::SQLTRUE)).must_equal '(x IS NOT TRUE)'
337
- @d.l(Sequel.~(:x => Sequel::SQLFALSE)).must_equal '(x IS NOT FALSE)'
338
- end
339
-
340
- it "should support direct negation of SQL::Constants" do
341
- @d.l({:x => ~Sequel::NULL}).must_equal '(x IS NOT NULL)'
342
- @d.l({:x => ~Sequel::NOTNULL}).must_equal '(x IS NULL)'
343
- @d.l({:x => ~Sequel::TRUE}).must_equal '(x IS FALSE)'
344
- @d.l({:x => ~Sequel::FALSE}).must_equal '(x IS TRUE)'
345
- @d.l({:x => ~Sequel::SQLTRUE}).must_equal '(x IS FALSE)'
346
- @d.l({:x => ~Sequel::SQLFALSE}).must_equal '(x IS TRUE)'
347
- end
348
-
349
- it "should raise an error if trying to invert an invalid SQL::Constant" do
350
- proc{~Sequel::CURRENT_DATE}.must_raise(Sequel::Error)
351
- end
352
-
353
- it "should raise an error if trying to create an invalid complex expression" do
354
- proc{Sequel::SQL::ComplexExpression.new(:BANG, 1, 2)}.must_raise(Sequel::Error)
355
- end
356
-
357
- it "should use a string concatentation for + if given a string" do
358
- @d.lit(Sequel.expr(:x) + '1').must_equal "(x || '1')"
359
- @d.lit(Sequel.expr(:x) + '1' + '1').must_equal "(x || '1' || '1')"
360
- end
361
-
362
- it "should use an addition for + if given a literal string" do
363
- @d.lit(Sequel.expr(:x) + Sequel.lit('1')).must_equal "(x + 1)"
364
- @d.lit(Sequel.expr(:x) + Sequel.lit('1') + Sequel.lit('1')).must_equal "(x + 1 + 1)"
365
- end
366
-
367
- it "should use a bitwise operator for & and | if given an integer" do
368
- @d.lit(Sequel.expr(:x) & 1).must_equal "(x & 1)"
369
- @d.lit(Sequel.expr(:x) | 1).must_equal "(x | 1)"
370
- @d.lit(Sequel.expr(:x) & 1 & 1).must_equal "(x & 1 & 1)"
371
- @d.lit(Sequel.expr(:x) | 1 | 1).must_equal "(x | 1 | 1)"
372
- end
373
-
374
- it "should allow adding a string to an integer expression" do
375
- @d.lit(Sequel.expr(:x) + 1 + 'a').must_equal "(x + 1 + 'a')"
376
- end
377
-
378
- it "should allow adding an integer to an string expression" do
379
- @d.lit(Sequel.expr(:x) + 'a' + 1).must_equal "(x || 'a' || 1)"
380
- end
381
-
382
- it "should allow adding a boolean to an integer expression" do
383
- @d.lit(Sequel.expr(:x) + 1 + true).must_equal "(x + 1 + 't')"
384
- end
385
-
386
- it "should allow adding a boolean to an string expression" do
387
- @d.lit(Sequel.expr(:x) + 'a' + true).must_equal "(x || 'a' || 't')"
388
- end
389
-
390
- it "should allow using a boolean operation with an integer on an boolean expression" do
391
- @d.lit(Sequel.expr(:x) & :a & 1).must_equal "(x AND a AND 1)"
392
- end
393
-
394
- it "should allow using a boolean operation with a string on an boolean expression" do
395
- @d.lit(Sequel.expr(:x) & :a & 'a').must_equal "(x AND a AND 'a')"
396
- end
397
-
398
- it "should allowing AND of boolean expression and literal string" do
399
- @d.lit(Sequel.expr(:x) & :a & Sequel.lit('a')).must_equal "(x AND a AND a)"
400
- end
401
-
402
- it "should allowing + of integer expression and literal string" do
403
- @d.lit(Sequel.expr(:x) + :a + Sequel.lit('a')).must_equal "(x + a + a)"
404
- end
405
-
406
- it "should allowing + of string expression and literal string" do
407
- @d.lit(Sequel.expr(:x) + 'a' + Sequel.lit('a')).must_equal "(x || 'a' || a)"
408
- end
409
-
410
- it "should allow sql_{string,boolean,number} methods on numeric expressions" do
411
- @d.lit((Sequel.expr(:x) + 1).sql_string + 'a').must_equal "((x + 1) || 'a')"
412
- @d.lit((Sequel.expr(:x) + 1).sql_boolean & 1).must_equal "((x + 1) AND 1)"
413
- @d.lit((Sequel.expr(:x) + 1).sql_number + 'a').must_equal "(x + 1 + 'a')"
414
- end
415
-
416
- it "should allow sql_{string,boolean,number} methods on string expressions" do
417
- @d.lit((Sequel.expr(:x) + 'a').sql_string + 'a').must_equal "(x || 'a' || 'a')"
418
- @d.lit((Sequel.expr(:x) + 'a').sql_boolean & 1).must_equal "((x || 'a') AND 1)"
419
- @d.lit((Sequel.expr(:x) + 'a').sql_number + 'a').must_equal "((x || 'a') + 'a')"
420
- end
421
-
422
- it "should allow sql_{string,boolean,number} methods on boolean expressions" do
423
- @d.lit((Sequel.expr(:x) & :y).sql_string + 'a').must_equal "((x AND y) || 'a')"
424
- @d.lit((Sequel.expr(:x) & :y).sql_boolean & 1).must_equal "(x AND y AND 1)"
425
- @d.lit((Sequel.expr(:x) & :y).sql_number + 'a').must_equal "((x AND y) + 'a')"
426
- end
427
-
428
- it "should raise an error if trying to literalize an invalid complex expression" do
429
- ce = Sequel::SQL::ComplexExpression.allocate
430
- ce.instance_eval do
431
- @op = :BANG
432
- @args = [:x, 1]
433
- end
434
- proc{@d.lit(ce)}.must_raise(Sequel::InvalidOperation)
435
- end
436
-
437
- it "should support equality comparison of two expressions" do
438
- e1 = ~Sequel.like(:comment, '%:hidden:%')
439
- e2 = ~Sequel.like(:comment, '%:hidden:%')
440
- e1.must_equal e2
441
- end
442
-
443
- it "should support expression filter methods on Datasets" do
444
- d = @d.select(:a)
445
-
446
- @d.lit(d + 1).must_equal '((SELECT a FROM items) + 1)'
447
- @d.lit(d - 1).must_equal '((SELECT a FROM items) - 1)'
448
- @d.lit(d * 1).must_equal '((SELECT a FROM items) * 1)'
449
- @d.lit(d / 1).must_equal '((SELECT a FROM items) / 1)'
450
- @d.lit(d ** 1).must_equal 'power((SELECT a FROM items), 1)'
451
-
452
- @d.lit(d => 1).must_equal '((SELECT a FROM items) = 1)'
453
- @d.lit(Sequel.~(d => 1)).must_equal '((SELECT a FROM items) != 1)'
454
- @d.lit(d > 1).must_equal '((SELECT a FROM items) > 1)'
455
- @d.lit(d < 1).must_equal '((SELECT a FROM items) < 1)'
456
- @d.lit(d >= 1).must_equal '((SELECT a FROM items) >= 1)'
457
- @d.lit(d <= 1).must_equal '((SELECT a FROM items) <= 1)'
458
-
459
- @d.lit(d.as(:b)).must_equal '(SELECT a FROM items) AS b'
460
-
461
- @d.lit(d & :b).must_equal '((SELECT a FROM items) AND b)'
462
- @d.lit(d | :b).must_equal '((SELECT a FROM items) OR b)'
463
- @d.lit(~d).must_equal 'NOT (SELECT a FROM items)'
464
-
465
- @d.lit(d.cast(Integer)).must_equal 'CAST((SELECT a FROM items) AS integer)'
466
- @d.lit(d.cast_numeric).must_equal 'CAST((SELECT a FROM items) AS integer)'
467
- @d.lit(d.cast_string).must_equal 'CAST((SELECT a FROM items) AS varchar(255))'
468
- @d.lit(d.cast_numeric << :b).must_equal '(CAST((SELECT a FROM items) AS integer) << b)'
469
- @d.lit(d.cast_string + :b).must_equal '(CAST((SELECT a FROM items) AS varchar(255)) || b)'
470
-
471
- @d.lit(d.extract(:year)).must_equal 'extract(year FROM (SELECT a FROM items))'
472
- @d.lit(d.sql_boolean & :b).must_equal '((SELECT a FROM items) AND b)'
473
- @d.lit(d.sql_number << :b).must_equal '((SELECT a FROM items) << b)'
474
- @d.lit(d.sql_string + :b).must_equal '((SELECT a FROM items) || b)'
475
-
476
- @d.lit(d.asc).must_equal '(SELECT a FROM items) ASC'
477
- @d.lit(d.desc).must_equal '(SELECT a FROM items) DESC'
478
-
479
- @d.lit(d.like(:b)).must_equal '((SELECT a FROM items) LIKE b ESCAPE \'\\\')'
480
- @d.lit(d.ilike(:b)).must_equal '(UPPER((SELECT a FROM items)) LIKE UPPER(b) ESCAPE \'\\\')'
481
- end
482
-
483
- it "should handled emulated char_length function" do
484
- @d.lit(Sequel.char_length(:a)).must_equal 'char_length(a)'
485
- end
486
-
487
- it "should handled emulated trim function" do
488
- @d.lit(Sequel.trim(:a)).must_equal 'trim(a)'
489
- end
490
-
491
- it "should handled emulated function where only name is emulated" do
492
- ds = Sequel.mock[:a]
493
- ds.literal(Sequel.trim(:a)).must_equal 'trim(a)'
494
- ds.with_extend{def native_function_name(f) 'foo' end}.literal(Sequel.trim(:a)).must_equal 'foo(a)'
495
- end
496
-
497
- it "should handled emulated function needing full emulation" do
498
- dsc = Class.new(Sequel::Dataset) do
499
- def emulate_function?(n) n == :trim end
500
- def emulate_function_sql_append(sql, f)
501
- sql << "#{f.name}FOO(lower(#{f.args.first}))"
502
- end
503
- end
504
- dsc.new(@d.db).literal(Sequel.trim(:a)).must_equal 'trimFOO(lower(a))'
505
- end
506
- end
507
-
508
- describe Sequel::SQL::VirtualRow do
509
- before do
510
- @d = Sequel.mock[:items].with_quote_identifiers(true).with_extend do
511
- def supports_window_functions?; true end
512
- def l(*args, &block)
513
- literal(filter_expr(*args, &block))
514
- end
515
- end
516
- end
517
-
518
- it "should treat methods without arguments as identifiers" do
519
- @d.l{column}.must_equal '"column"'
520
- end
521
-
522
- with_symbol_splitting "should treat methods without arguments that have embedded double underscores as qualified identifiers" do
523
- @d.l{table__column}.must_equal '"table"."column"'
524
- end
525
-
526
- it "should treat methods with arguments as functions with the arguments" do
527
- @d.l{function(arg1, 10, 'arg3')}.must_equal 'function("arg1", 10, \'arg3\')'
528
- end
529
-
530
-
531
- it "should treat methods followed by function as a function call with no arguments" do
532
- @d.l{version.function}.must_equal 'version()'
533
- end
534
-
535
- it "should treat methods followed by function.* as a function call with * argument" do
536
- @d.l{count.function.*}.must_equal 'count(*)'
537
- end
538
-
539
- it "should support * method on functions to raise error if function already has an argument" do
540
- proc{@d.l{count(1).*}}.must_raise(Sequel::Error)
541
- end
542
-
543
- it "should support * method on functions to use * as the argument" do
544
- @d.l{count.function.*}.must_equal 'count(*)'
545
- @d.literal(Sequel.expr{sum(1) * 2}).must_equal '(sum(1) * 2)'
546
- end
547
-
548
- it "should support distinct methods on functions to use DISTINCT before the arguments" do
549
- @d.l{count(column1).distinct}.must_equal 'count(DISTINCT "column1")'
550
- @d.l{count(column1, column2).distinct}.must_equal 'count(DISTINCT "column1", "column2")'
551
- end
552
-
553
- it "should handle method.function.over as a window function call" do
554
- @d.l{rank.function.over}.must_equal 'rank() OVER ()'
555
- end
556
-
557
- it "should handle method.function.over(:partition) as a window function call" do
558
- @d.l{rank.function.over(:partition=>column1)}.must_equal 'rank() OVER (PARTITION BY "column1")'
559
- @d.l{rank.function.over(:partition=>[column1, column2])}.must_equal 'rank() OVER (PARTITION BY "column1", "column2")'
560
- end
561
-
562
- it "should handle method(arg).over options as a window function call" do
563
- @d.l{avg(column1).over}.must_equal 'avg("column1") OVER ()'
564
- @d.l{avg(column1, column2).over}.must_equal 'avg("column1", "column2") OVER ()'
565
- end
566
-
567
- it "should handle method.function.over(:order) as a window function call" do
568
- @d.l{rank.function.over(:order=>column1)}.must_equal 'rank() OVER (ORDER BY "column1")'
569
- @d.l{rank.function.over(:order=>[column1, column2])}.must_equal 'rank() OVER (ORDER BY "column1", "column2")'
570
- end
571
-
572
- it "should handle method.function.over(:window) as a window function call" do
573
- @d.l{rank.function.over(:window=>:win)}.must_equal 'rank() OVER ("win")'
574
- end
575
-
576
- it "should handle method.function.*.over as a window function call" do
577
- @d.l{count.function.*.over}.must_equal 'count(*) OVER ()'
578
- end
579
-
580
- it "should handle method.function.over(:frame=>:all) as a window function call" do
581
- @d.l{rank.function.over(:frame=>:all)}.must_equal 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)'
582
- end
583
-
584
- it "should handle method.function.over(:frame=>:rows) as a window function call" do
585
- @d.l{rank.function.over(:frame=>:rows)}.must_equal 'rank() OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
586
- end
587
-
588
- it "should handle method.function.over(:frame=>'some string') as a window function call" do
589
- @d.l{rank.function.over(:frame=>'RANGE BETWEEN 3 PRECEDING AND CURRENT ROW')}.must_equal 'rank() OVER (RANGE BETWEEN 3 PRECEDING AND CURRENT ROW)'
590
- end
591
-
592
- it "should raise an error if an invalid :frame option is used" do
593
- proc{@d.l{rank.function.over(:frame=>:blah)}}.must_raise(Sequel::Error)
594
- end
595
-
596
- it "should support all over options together" do
597
- @d.l{count.function.*.over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}.must_equal 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
598
- end
599
-
600
- it "should support order method on functions to specify orders for aggregate functions" do
601
- @d.l{rank(:c).order(:a, :b)}.must_equal 'rank("c" ORDER BY "a", "b")'
602
- end
603
-
604
- it "should support over method on functions to create window functions" do
605
- @d.l{sum(c).over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}.must_equal 'sum("c") OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
606
- end
607
-
608
- it "should support over method with a Window argument" do
609
- @d.l{sum(c).over(Sequel::SQL::Window.new(:partition=>a, :order=>b, :window=>:win, :frame=>:rows))}.must_equal 'sum("c") OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)'
610
- end
611
-
612
- it "should raise error if over is called on a function that already has a window " do
613
- proc{@d.l{rank.function.over.over}}.must_raise(Sequel::Error)
614
- end
615
-
616
- it "should raise an error if window functions are not supported" do
617
- proc{@d.with_extend{def supports_window_functions?; false end}.l{count.function.*.over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}}.must_raise(Sequel::Error)
618
- proc{Sequel.mock.dataset.filter{count.function.*.over(:partition=>a, :order=>b, :window=>:win, :frame=>:rows)}.sql}.must_raise(Sequel::Error)
619
- end
620
-
621
- it "should handle lateral function calls" do
622
- @d.l{rank.function.lateral}.must_equal 'LATERAL rank()'
623
- end
624
-
625
- it "should handle ordered-set and hypothetical-set function calls" do
626
- @d.l{mode.function.within_group(:a)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a")'
627
- @d.l{mode.function.within_group(:a, :b)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a", "b")'
628
- end
629
-
630
- it "should handle filtered aggregate function calls" do
631
- @d.l{count.function.*.filter(Sequel.&(:a, :b))}.must_equal 'count(*) FILTER (WHERE ("a" AND "b"))'
632
- @d.l{count.function.*.filter(:a=>1)}.must_equal 'count(*) FILTER (WHERE ("a" = 1))'
633
- @d.l{count.function.*.filter{b > 1}}.must_equal 'count(*) FILTER (WHERE ("b" > 1))'
634
- @d.l{count.function.*.filter(:a=>1){b > 1}}.must_equal 'count(*) FILTER (WHERE (("a" = 1) AND ("b" > 1)))'
635
- end
636
-
637
- it "should handle fitlered ordered-set and hypothetical-set function calls" do
638
- @d.l{mode.function.within_group(:a).filter(:a=>1)}.must_equal 'mode() WITHIN GROUP (ORDER BY "a") FILTER (WHERE ("a" = 1))'
639
- end
640
-
641
- it "should handle function calls with ordinality" do
642
- @d.l{foo.function.with_ordinality}.must_equal 'foo() WITH ORDINALITY'
643
- end
644
-
645
- it "should support function method on identifiers to create functions" do
646
- @d.l{rank.function}.must_equal 'rank()'
647
- @d.l{sum.function(c)}.must_equal 'sum("c")'
648
- @d.l{sum.function(c, 1)}.must_equal 'sum("c", 1)'
649
- end
650
-
651
- with_symbol_splitting "should support function method on foo__bar methods to create functions" do
652
- @d.l{sch__rank.function}.must_equal 'sch.rank()'
653
- @d.l{sch__sum.function(c)}.must_equal 'sch.sum("c")'
654
- @d.l{sch__sum.function(c, 1)}.must_equal 'sch.sum("c", 1)'
655
- @d.l{Sequel.qualify(sch[:sum], x[:y]).function(c, 1)}.must_equal 'sch.sum.x.y("c", 1)'
656
- end
657
-
658
- it "should support function method on qualified identifiers to create functions" do
659
- @d.l{sch[rank].function}.must_equal 'sch.rank()'
660
- @d.l{sch[sum].function(c)}.must_equal 'sch.sum("c")'
661
- @d.l{sch[sum].function(c, 1)}.must_equal 'sch.sum("c", 1)'
662
- @d.l{Sequel.qualify(sch[:sum], x[:y]).function(c, 1)}.must_equal 'sch.sum.x.y("c", 1)'
663
- end
664
-
665
- with_symbol_splitting "should support function method on qualified identifiers to create functions" do
666
- @d.l{Sequel.qualify(sch__sum, :x__y).function(c, 1)}.must_equal 'sch.sum.x.y("c", 1)'
667
- end
668
-
669
- it "should not quote function names created from identifiers by default" do
670
- @d = @d.with_extend{def supports_quoted_function_names?; true end}
671
- @d.l{rank.function}.must_equal 'rank()'
672
- end
673
-
674
- with_symbol_splitting "should handle quoted function names when using double underscores" do
675
- @d = @d.with_extend{def supports_quoted_function_names?; true end}
676
- @d.l{sch__rank.function}.must_equal '"sch"."rank"()'
677
- end
678
-
679
- it "should quote function names if a quoted function is used and database supports quoted function names" do
680
- @d = @d.with_extend{def supports_quoted_function_names?; true end}
681
- @d.l{rank(1).quoted}.must_equal '"rank"(1)'
682
- @d.l{rank.function.quoted}.must_equal '"rank"()'
683
- @d.l{sch__rank(1).quoted}.must_equal '"sch__rank"(1)'
684
- end
685
-
686
- it "should not quote function names created from qualified identifiers if an unquoted function is used" do
687
- @d = @d.with_extend{def supports_quoted_function_names?; true end}
688
- @d.l{sch[rank].function.unquoted}.must_equal 'sch.rank()'
689
- end
690
-
691
- it "should deal with classes without requiring :: prefix" do
692
- @d.l{date < Date.today}.must_equal "(\"date\" < '#{Date.today}')"
693
- @d.l{date < Sequel::CURRENT_DATE}.must_equal "(\"date\" < CURRENT_DATE)"
694
- @d.l{num < Math::PI.to_i}.must_equal "(\"num\" < 3)"
695
- end
696
-
697
- it "should have operator methods defined that produce Sequel expression objects" do
698
- @d.l{|o| o.&({:a=>1}, :b)}.must_equal '(("a" = 1) AND "b")'
699
- @d.l{|o| o.|({:a=>1}, :b)}.must_equal '(("a" = 1) OR "b")'
700
- @d.l{|o| o.+(1, :b) > 2}.must_equal '((1 + "b") > 2)'
701
- @d.l{|o| o.-(1, :b) < 2}.must_equal '((1 - "b") < 2)'
702
- @d.l{|o| o.*(1, :b) >= 2}.must_equal '((1 * "b") >= 2)'
703
- @d.l{|o| o.**(1, :b) >= 2}.must_equal '(power(1, "b") >= 2)'
704
- @d.l{|o| o./(1, :b) <= 2}.must_equal '((1 / "b") <= 2)'
705
- @d.l{|o| o.~(:a=>1)}.must_equal '("a" != 1)'
706
- @d.l{|o| o.~([[:a, 1], [:b, 2]])}.must_equal '(("a" != 1) OR ("b" != 2))'
707
- @d.l{|o| o.<(1, :b)}.must_equal '(1 < "b")'
708
- @d.l{|o| o.>(1, :b)}.must_equal '(1 > "b")'
709
- @d.l{|o| o.<=(1, :b)}.must_equal '(1 <= "b")'
710
- @d.l{|o| o.>=(1, :b)}.must_equal '(1 >= "b")'
711
- end
712
- end
713
-
714
- describe "Sequel core extension replacements" do
715
- before do
716
- @db = Sequel.mock
717
- @ds = @db.dataset.with_extend{def supports_regexp?; true end}
718
- @o = Object.new
719
- def @o.sql_literal(ds) 'foo' end
720
- end
721
-
722
- def l(arg, should)
723
- @ds.literal(arg).must_equal should
724
- end
725
-
726
- it "Sequel.expr should return items wrapped in Sequel objects" do
727
- Sequel.expr(1).must_be_kind_of(Sequel::SQL::NumericExpression)
728
- Sequel.expr('a').must_be_kind_of(Sequel::SQL::StringExpression)
729
- Sequel.expr(true).must_be_kind_of(Sequel::SQL::BooleanExpression)
730
- Sequel.expr(nil).must_be_kind_of(Sequel::SQL::Wrapper)
731
- Sequel.expr({1=>2}).must_be_kind_of(Sequel::SQL::BooleanExpression)
732
- Sequel.expr([[1, 2]]).must_be_kind_of(Sequel::SQL::BooleanExpression)
733
- Sequel.expr([1]).must_be_kind_of(Sequel::SQL::Wrapper)
734
- Sequel.expr{|o| o.a}.must_be_kind_of(Sequel::SQL::Identifier)
735
- Sequel.expr{a}.must_be_kind_of(Sequel::SQL::Identifier)
736
- Sequel.expr(:a).must_be_kind_of(Sequel::SQL::Identifier)
737
- end
738
-
739
- with_symbol_splitting "Sequel.expr should return items wrapped in Sequel objects for splittable symbols" do
740
- Sequel.expr(:a__b).must_be_kind_of(Sequel::SQL::QualifiedIdentifier)
741
- Sequel.expr(:a___c).must_be_kind_of(Sequel::SQL::AliasedExpression)
742
- Sequel.expr(:a___c).expression.must_be_kind_of(Sequel::SQL::Identifier)
743
- Sequel.expr(:a__b___c).must_be_kind_of(Sequel::SQL::AliasedExpression)
744
- Sequel.expr(:a__b___c).expression.must_be_kind_of(Sequel::SQL::QualifiedIdentifier)
745
- end
746
-
747
- it "Sequel.expr should return an appropriate wrapped object" do
748
- l(Sequel.expr(1) + 1, "(1 + 1)")
749
- l(Sequel.expr('a') + 'b', "('a' || 'b')")
750
- l(Sequel.expr(:b) & nil, "(b AND NULL)")
751
- l(Sequel.expr(nil) & true, "(NULL AND 't')")
752
- l(Sequel.expr(false) & true, "('f' AND 't')")
753
- l(Sequel.expr(true) | false, "('t' OR 'f')")
754
- l(Sequel.expr(@o) + 1, "(foo + 1)")
755
- end
756
-
757
- it "Sequel.expr should handle condition specifiers" do
758
- l(Sequel.expr(:a=>1) & nil, "((a = 1) AND NULL)")
759
- l(Sequel.expr([[:a, 1]]) & nil, "((a = 1) AND NULL)")
760
- l(Sequel.expr([[:a, 1], [:b, 2]]) & nil, "((a = 1) AND (b = 2) AND NULL)")
761
- end
762
-
763
- it "Sequel.expr should handle arrays that are not condition specifiers" do
764
- l(Sequel.expr([1]), "(1)")
765
- l(Sequel.expr([1, 2]), "(1, 2)")
766
- end
767
-
768
- it "Sequel.expr should treat blocks/procs as virtual rows and wrap the output" do
769
- l(Sequel.expr{1} + 1, "(1 + 1)")
770
- l(Sequel.expr{o[a]} + 1, "(o.a + 1)")
771
- l(Sequel.expr{[[:a, 1]]} & nil, "((a = 1) AND NULL)")
772
- l(Sequel.expr{|v| @o} + 1, "(foo + 1)")
773
-
774
- l(Sequel.expr(proc{1}) + 1, "(1 + 1)")
775
- l(Sequel.expr(proc{o[a]}) + 1, "(o.a + 1)")
776
- l(Sequel.expr(proc{[[:a, 1]]}) & nil, "((a = 1) AND NULL)")
777
- l(Sequel.expr(proc{|v| @o}) + 1, "(foo + 1)")
778
- end
779
-
780
- it "Sequel.expr should handle lambda proc virtual rows" do
781
- l(Sequel.expr(&lambda{1}), "1")
782
- l(Sequel.expr(&lambda{|| 1}), "1")
783
- end
784
-
785
- it "Sequel.expr should raise an error if given an argument and a block" do
786
- proc{Sequel.expr(nil){}}.must_raise(Sequel::Error)
787
- end
788
-
789
- it "Sequel.expr should raise an error if given neither an argument nor a block" do
790
- proc{Sequel.expr}.must_raise(Sequel::Error)
791
- end
792
-
793
- it "Sequel.expr should return existing Sequel expressions directly" do
794
- o = Sequel.expr(1)
795
- Sequel.expr(o).must_be_same_as(o)
796
- o = Sequel.lit('1')
797
- Sequel.expr(o).must_be_same_as(o)
798
- end
799
-
800
- it "Sequel.~ should invert the given object" do
801
- l(Sequel.~(nil), 'NOT NULL')
802
- l(Sequel.~(:a=>1), "(a != 1)")
803
- l(Sequel.~([[:a, 1]]), "(a != 1)")
804
- l(Sequel.~([[:a, 1], [:b, 2]]), "((a != 1) OR (b != 2))")
805
- l(Sequel.~(Sequel.expr([[:a, 1], [:b, 2]]) & nil), "((a != 1) OR (b != 2) OR NOT NULL)")
806
- end
807
-
808
- it "Sequel.case should use a CASE expression" do
809
- l(Sequel.case({:a=>1}, 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
810
- l(Sequel.case({:a=>1}, 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
811
- l(Sequel.case([[:a, 1]], 2), "(CASE WHEN a THEN 1 ELSE 2 END)")
812
- l(Sequel.case([[:a, 1]], 2, :b), "(CASE b WHEN a THEN 1 ELSE 2 END)")
813
- l(Sequel.case([[:a, 1], [:c, 3]], 2), "(CASE WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
814
- l(Sequel.case([[:a, 1], [:c, 3]], 2, :b), "(CASE b WHEN a THEN 1 WHEN c THEN 3 ELSE 2 END)")
815
- end
816
-
817
- it "Sequel.case should raise an error if not given a condition specifier" do
818
- proc{Sequel.case(1, 2)}.must_raise(Sequel::Error)
819
- end
820
-
821
- it "Sequel.value_list should use an SQL value list" do
822
- l(Sequel.value_list([[1, 2]]), "((1, 2))")
823
- end
824
-
825
- it "Sequel.value_list raise an error if not given an array" do
826
- proc{Sequel.value_list(1)}.must_raise(Sequel::Error)
827
- end
828
-
829
- it "Sequel.negate should negate all entries in conditions specifier and join with AND" do
830
- l(Sequel.negate(:a=>1), "(a != 1)")
831
- l(Sequel.negate([[:a, 1]]), "(a != 1)")
832
- l(Sequel.negate([[:a, 1], [:b, 2]]), "((a != 1) AND (b != 2))")
833
- end
834
-
835
- it "Sequel.negate should raise an error if not given a conditions specifier" do
836
- proc{Sequel.negate(1)}.must_raise(Sequel::Error)
837
- end
838
-
839
- it "Sequel.or should join all entries in conditions specifier with OR" do
840
- l(Sequel.or(:a=>1), "(a = 1)")
841
- l(Sequel.or([[:a, 1]]), "(a = 1)")
842
- l(Sequel.or([[:a, 1], [:b, 2]]), "((a = 1) OR (b = 2))")
843
- end
844
-
845
- it "Sequel.or should raise an error if not given a conditions specifier" do
846
- proc{Sequel.or(1)}.must_raise(Sequel::Error)
847
- end
848
-
849
- it "Sequel.join should should use SQL string concatenation to join array" do
850
- l(Sequel.join([]), "''")
851
- l(Sequel.join(['a']), "('a')")
852
- l(Sequel.join(['a', 'b']), "('a' || 'b')")
853
- l(Sequel.join(['a', 'b'], 'c'), "('a' || 'c' || 'b')")
854
- l(Sequel.join([true, :b], :c), "('t' || c || b)")
855
- l(Sequel.join([false, nil], Sequel.lit('c')), "('f' || c || NULL)")
856
- l(Sequel.join([Sequel.expr('a'), Sequel.lit('d')], 'c'), "('a' || 'c' || d)")
857
- end
858
-
859
- it "Sequel.join should raise an error if not given an array" do
860
- proc{Sequel.join(1)}.must_raise(Sequel::Error)
861
- end
862
-
863
- it "Sequel.& should join all arguments given with AND" do
864
- l(Sequel.&(:a), "a")
865
- l(Sequel.&(:a, :b=>:c), "(a AND (b = c))")
866
- l(Sequel.&(:a, {:b=>:c}, Sequel.lit('d')), "(a AND (b = c) AND d)")
867
- end
868
-
869
- it "Sequel.& should raise an error if given no arguments" do
870
- proc{Sequel.&}.must_raise(Sequel::Error)
871
- end
872
-
873
- it "Sequel.| should join all arguments given with OR" do
874
- l(Sequel.|(:a), "a")
875
- l(Sequel.|(:a, :b=>:c), "(a OR (b = c))")
876
- l(Sequel.|(:a, {:b=>:c}, Sequel.lit('d')), "(a OR (b = c) OR d)")
877
- end
878
-
879
- it "Sequel.| should raise an error if given no arguments" do
880
- proc{Sequel.|}.must_raise(Sequel::Error)
881
- end
882
-
883
- it "Sequel.as should return an aliased expression" do
884
- l(Sequel.as(:a, :b), "a AS b")
885
- end
886
-
887
- it "Sequel.cast should return a CAST expression" do
888
- l(Sequel.cast(:a, :int), "CAST(a AS int)")
889
- l(Sequel.cast(:a, Integer), "CAST(a AS integer)")
890
- end
891
-
892
- it "Sequel.cast_numeric should return a CAST expression treated as a number" do
893
- l(Sequel.cast_numeric(:a), "CAST(a AS integer)")
894
- l(Sequel.cast_numeric(:a, :int), "CAST(a AS int)")
895
- l(Sequel.cast_numeric(:a) << 2, "(CAST(a AS integer) << 2)")
896
- end
897
-
898
- it "Sequel.cast_string should return a CAST expression treated as a string" do
899
- l(Sequel.cast_string(:a), "CAST(a AS varchar(255))")
900
- l(Sequel.cast_string(:a, :text), "CAST(a AS text)")
901
- l(Sequel.cast_string(:a) + 'a', "(CAST(a AS varchar(255)) || 'a')")
902
- end
903
-
904
- it "Sequel.lit should return a literal string" do
905
- l(Sequel.lit('a'), "a")
906
- end
907
-
908
- it "Sequel.lit should return the argument if given a single literal string" do
909
- o = Sequel.lit('a')
910
- Sequel.lit(o).must_be_same_as(o)
911
- end
912
-
913
- it "Sequel.lit should accept multiple arguments for a placeholder literal string" do
914
- l(Sequel.lit('a = ?', 1), "a = 1")
915
- l(Sequel.lit('? = ?', :a, 1), "a = 1")
916
- l(Sequel.lit('a = :a', :a=>1), "a = 1")
917
- end
918
-
919
- it "Sequel.lit should work with an array for the placeholder string" do
920
- l(Sequel.lit(['a = '], 1), "a = 1")
921
- l(Sequel.lit(['', ' = '], :a, 1), "a = 1")
922
- end
923
-
924
- it "Sequel.blob should return an SQL::Blob" do
925
- l(Sequel.blob('a'), "'a'")
926
- Sequel.blob('a').must_be_kind_of(Sequel::SQL::Blob)
927
- end
928
-
929
- it "Sequel.blob should return the given argument if given a blob" do
930
- o = Sequel.blob('a')
931
- Sequel.blob(o).must_be_same_as(o)
932
- end
933
-
934
- it "Sequel.blob#inspect output should indicate it is a blob and the size" do
935
- o = Sequel.blob('a')
936
- o.inspect.must_equal "#<Sequel::SQL::Blob:0x#{'%x' % o.object_id} bytes=1 content=\"a\">"
937
- o = Sequel.blob(('a'..'z').to_a.join)
938
- o.inspect.must_equal "#<Sequel::SQL::Blob:0x#{'%x' % o.object_id} bytes=26 start=\"abcdefghij\" end=\"qrstuvwxyz\">"
939
- o = Sequel.blob(255.chr)
940
- o.inspect.must_equal "#<Sequel::SQL::Blob:0x#{'%x' % o.object_id} bytes=1 content=\"\\xFF\">"
941
- o = Sequel.blob((230..255).map(&:chr).join)
942
- o.inspect.must_equal "#<Sequel::SQL::Blob:0x#{'%x' % o.object_id} bytes=26 start=\"\\xE6\\xE7\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF\" end=\"\\xF6\\xF7\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\">"
943
- end
944
-
945
- it "Sequel.deep_qualify should do a deep qualification into nested structors" do
946
- l(Sequel.deep_qualify(:t, Sequel.+(:c, 1)), "(t.c + 1)")
947
- end
948
-
949
- it "Sequel.qualify should return a qualified identifier" do
950
- l(Sequel.qualify(:t, :c), "t.c")
951
- end
952
-
953
- it "Sequel::SQL::Identifier#[] should return a qualified identifier" do
954
- l(Sequel[:t][:c], "t.c")
955
- end
956
-
957
- it "Sequel::SQL::QualifiedIdentifier#[] should return a nested qualified identifier" do
958
- l(Sequel[:s][:t][:c], "s.t.c")
959
- end
960
-
961
- it "Sequel.identifier should return an identifier" do
962
- l(Sequel.identifier(:t__c), "t__c")
963
- end
964
-
965
- it "Sequel.asc should return an ASC ordered expression" do
966
- l(Sequel.asc(:a), "a ASC")
967
- l(Sequel.asc(:a, :nulls=>:first), "a ASC NULLS FIRST")
968
- end
969
-
970
- it "Sequel.desc should return a DESC ordered expression " do
971
- l(Sequel.desc(:a), "a DESC")
972
- l(Sequel.desc(:a, :nulls=>:last), "a DESC NULLS LAST")
973
- end
974
-
975
- it "Sequel.{+,-,*,/} should accept arguments and use the appropriate operator" do
976
- %w'+ - * /'.each do |op|
977
- l(Sequel.send(op, 1), '1')
978
- l(Sequel.send(op, 1, 2), "(1 #{op} 2)")
979
- l(Sequel.send(op, 1, 2, 3), "(1 #{op} 2 #{op} 3)")
980
- end
981
- end
982
-
983
- it "Sequel.{+,-,*,/} should raise if given no arguments" do
984
- %w'+ - * /'.each do |op|
985
- proc{Sequel.send(op)}.must_raise(Sequel::Error)
986
- end
987
- end
988
-
989
- it "Sequel.** should use power function if given 2 arguments" do
990
- l(Sequel.**(1, 2), 'power(1, 2)')
991
- end
992
-
993
- it "Sequel.** should raise if not given 2 arguments" do
994
- proc{Sequel.**}.must_raise(ArgumentError)
995
- proc{Sequel.**(1)}.must_raise(ArgumentError)
996
- proc{Sequel.**(1, 2, 3)}.must_raise(ArgumentError)
997
- end
998
-
999
- it "Sequel.like should use a LIKE expression" do
1000
- l(Sequel.like('a', 'b'), "('a' LIKE 'b' ESCAPE '\\')")
1001
- l(Sequel.like(:a, :b), "(a LIKE b ESCAPE '\\')")
1002
- l(Sequel.like(:a, /b/), "(a ~ 'b')")
1003
- l(Sequel.like(:a, 'c', /b/), "((a LIKE 'c' ESCAPE '\\') OR (a ~ 'b'))")
1004
- end
1005
-
1006
- it "Sequel.ilike should use an ILIKE expression" do
1007
- l(Sequel.ilike('a', 'b'), "(UPPER('a') LIKE UPPER('b') ESCAPE '\\')")
1008
- l(Sequel.ilike(:a, :b), "(UPPER(a) LIKE UPPER(b) ESCAPE '\\')")
1009
- l(Sequel.ilike(:a, /b/), "(a ~* 'b')")
1010
- l(Sequel.ilike(:a, 'c', /b/), "((UPPER(a) LIKE UPPER('c') ESCAPE '\\') OR (a ~* 'b'))")
1011
- end
1012
-
1013
- it "Sequel.subscript should use an SQL subscript" do
1014
- l(Sequel.subscript(:a, 1), 'a[1]')
1015
- l(Sequel.subscript(:a, 1, 2), 'a[1, 2]')
1016
- l(Sequel.subscript(:a, [1, 2]), 'a[1, 2]')
1017
- l(Sequel.subscript(:a, 1..2), 'a[1:2]')
1018
- l(Sequel.subscript(:a, 1...3), 'a[1:2]')
1019
- end
1020
-
1021
- it "Sequel.subscript.f should be subscript expression for backwards compatibility" do
1022
- Sequel.subscript(:a, 1).f.must_equal :a
1023
- end
1024
-
1025
- it "Sequel.function should return an SQL function" do
1026
- l(Sequel.function(:a), 'a()')
1027
- l(Sequel.function(:a, 1), 'a(1)')
1028
- l(Sequel.function(:a, :b, 2), 'a(b, 2)')
1029
- end
1030
-
1031
- it "Sequel.extract should use a date/time extraction" do
1032
- l(Sequel.extract(:year, :a), 'extract(year FROM a)')
1033
- end
1034
-
1035
- it "#* with no arguments should use a ColumnAll for Identifier and QualifiedIdentifier" do
1036
- l(Sequel.expr(:a).*, 'a.*')
1037
- l(Sequel[:a][:b].*, 'a.b.*')
1038
- end
1039
-
1040
- it "SQL::Blob should be aliasable and castable by default" do
1041
- b = Sequel.blob('a')
1042
- l(b.as(:a), "'a' AS a")
1043
- l(b.cast(Integer), "CAST('a' AS integer)")
1044
- end
1045
-
1046
- it "SQL::Blob should be convertable to a literal string by default" do
1047
- b = Sequel.blob('a ?')
1048
- l(b.lit, "a ?")
1049
- l(b.lit(1), "a 1")
1050
- end
1051
- end
1052
-
1053
- describe "Sequel::SQL::Function#==" do
1054
- it "should be true for functions with the same name and arguments, false otherwise" do
1055
- a = Sequel.function(:date, :t)
1056
- b = Sequel.function(:date, :t)
1057
- a.must_equal b
1058
- (a == b).must_equal true
1059
- c = Sequel.function(:date, :c)
1060
- a.wont_equal c
1061
- (a == c).must_equal false
1062
- d = Sequel.function(:time, :c)
1063
- a.wont_equal d
1064
- c.wont_equal d
1065
- (a == d).must_equal false
1066
- (c == d).must_equal false
1067
- end
1068
- end
1069
-
1070
- describe "Sequel::SQL::OrderedExpression" do
1071
- it "should #desc" do
1072
- @oe = Sequel.asc(:column)
1073
- @oe.descending.must_equal false
1074
- @oe.desc.descending.must_equal true
1075
- end
1076
-
1077
- it "should #asc" do
1078
- @oe = Sequel.desc(:column)
1079
- @oe.descending.must_equal true
1080
- @oe.asc.descending.must_equal false
1081
- end
1082
-
1083
- it "should #invert" do
1084
- @oe = Sequel.desc(:column)
1085
- @oe.invert.descending.must_equal false
1086
- @oe.invert.invert.descending.must_equal true
1087
- end
1088
- end
1089
-
1090
- describe "Expression" do
1091
- it "should consider objects == only if they have the same attributes" do
1092
- Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.must_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
1093
- Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.wont_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
1094
-
1095
- Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.must_equal(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
1096
- Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.wont_equal(Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc)
1097
- end
1098
-
1099
- it "should use the same hash value for objects that have the same attributes" do
1100
- Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash.must_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
1101
- Sequel.qualify(:table, :other_column).cast(:type).*(:numeric_column).asc.hash.wont_equal Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc.hash
1102
-
1103
- h = {}
1104
- a = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
1105
- b = Sequel.qualify(:table, :column).cast(:type).*(:numeric_column).asc
1106
- h[a] = 1
1107
- h[b] = 2
1108
- h[a].must_equal 2
1109
- h[b].must_equal 2
1110
- end
1111
- end
1112
-
1113
- describe "Sequel::SQLTime" do
1114
- before do
1115
- @db = Sequel.mock
1116
- end
1117
- after do
1118
- Sequel::application_timezone = Sequel::SQLTime.date = nil
1119
- end
1120
-
1121
- it ".create should create from hour, minutes, seconds and optional microseconds" do
1122
- @db.literal(Sequel::SQLTime.create(1, 2, 3)).must_equal "'01:02:03.000000'"
1123
- @db.literal(Sequel::SQLTime.create(1, 2, 3, 500000)).must_equal "'01:02:03.500000'"
1124
- end
1125
-
1126
- it ".create should use utc is that is the application_timezone setting" do
1127
- Sequel::SQLTime.create(1, 2, 3).utc?.must_equal false
1128
- Sequel::application_timezone = :local
1129
- Sequel::SQLTime.create(1, 2, 3).utc?.must_equal false
1130
- Sequel::application_timezone = :utc
1131
- Sequel::SQLTime.create(1, 2, 3).utc?.must_equal true
1132
- end
1133
-
1134
- it ".create should use today's date by default" do
1135
- Sequel::SQLTime.create(1, 2, 3).strftime('%Y-%m-%d').must_equal Date.today.strftime('%Y-%m-%d')
1136
- end
1137
-
1138
- it ".create should use specific date if set" do
1139
- Sequel::SQLTime.date = Date.new(2000)
1140
- Sequel::SQLTime.create(1, 2, 3).strftime('%Y-%m-%d').must_equal Date.new(2000).strftime('%Y-%m-%d')
1141
- end
1142
-
1143
- it "#inspect should show class and time by default" do
1144
- Sequel::SQLTime.create(1, 2, 3).inspect.must_equal "#<Sequel::SQLTime 01:02:03>"
1145
- Sequel::SQLTime.create(13, 24, 35).inspect.must_equal "#<Sequel::SQLTime 13:24:35>"
1146
- end
1147
-
1148
- it "#to_s should include hour, minute, and second by default" do
1149
- Sequel::SQLTime.create(1, 2, 3).to_s.must_equal "01:02:03"
1150
- Sequel::SQLTime.create(1, 2, 3, 500000).to_s.must_equal "01:02:03"
1151
- end
1152
-
1153
- it "#to_s should handle arguments with super" do
1154
- t = Sequel::SQLTime.create(1, 2, 3)
1155
- begin
1156
- Time.now.to_s('%F')
1157
- rescue
1158
- proc{t.to_s('%F')}.must_raise ArgumentError
1159
- else
1160
- t.to_s('%F')
1161
- end
1162
- end
1163
- end
1164
-
1165
- describe "Sequel::SQL::Wrapper" do
1166
- before do
1167
- @ds = Sequel.mock.dataset
1168
- end
1169
-
1170
- it "should wrap objects so they can be used by the Sequel DSL" do
1171
- o = Object.new
1172
- def o.sql_literal(ds) 'foo' end
1173
- s = Sequel::SQL::Wrapper.new(o)
1174
- @ds.literal(s).must_equal "foo"
1175
- @ds.literal(s+1).must_equal "(foo + 1)"
1176
- @ds.literal(s**1).must_equal "power(foo, 1)"
1177
- @ds.literal(s & true).must_equal "(foo AND 't')"
1178
- @ds.literal(s < 1).must_equal "(foo < 1)"
1179
- @ds.literal(s.sql_subscript(1)).must_equal "foo[1]"
1180
- @ds.literal(s.like('a')).must_equal "(foo LIKE 'a' ESCAPE '\\')"
1181
- @ds.literal(s.as(:a)).must_equal "foo AS a"
1182
- @ds.literal(s.cast(Integer)).must_equal "CAST(foo AS integer)"
1183
- @ds.literal(s.desc).must_equal "foo DESC"
1184
- @ds.literal(s.sql_string + '1').must_equal "(foo || '1')"
1185
- end
1186
- end
1187
-
1188
- describe "Sequel::SQL::Blob#to_sequel_blob" do
1189
- it "should return self" do
1190
- c = Sequel::SQL::Blob.new('a')
1191
- c.to_sequel_blob.must_be_same_as(c)
1192
- end
1193
- end
1194
-
1195
- describe Sequel::SQL::Subscript do
1196
- before do
1197
- @s = Sequel::SQL::Subscript.new(:a, [1])
1198
- @ds = Sequel.mock.dataset
1199
- end
1200
-
1201
- it "should have | return a new non-nested subscript" do
1202
- s = (@s | 2)
1203
- @ds.literal(s).must_equal 'a[1, 2]'
1204
- end
1205
-
1206
- it "should have [] return a new nested subscript" do
1207
- s = @s[2]
1208
- @ds.literal(s).must_equal 'a[1][2]'
1209
- end
1210
- end
1211
-
1212
- describe Sequel::SQL::CaseExpression, "#with_merged_expression" do
1213
- it "should return self if it has no expression" do
1214
- c = Sequel.case({1=>0}, 3)
1215
- c.with_merged_expression.must_be_same_as(c)
1216
- end
1217
-
1218
- it "should merge expression into conditions if it has an expression" do
1219
- db = Sequel::Database.new
1220
- c = Sequel.case({1=>0}, 3, 4)
1221
- db.literal(c.with_merged_expression).must_equal db.literal(Sequel.case({{4=>1}=>0}, 3))
1222
- end
1223
- end
1224
-
1225
- describe "Sequel.recursive_map" do
1226
- it "should recursively convert an array using a callable" do
1227
- Sequel.recursive_map(['1'], proc{|s| s.to_i}).must_equal [1]
1228
- Sequel.recursive_map([['1']], proc{|s| s.to_i}).must_equal [[1]]
1229
- end
1230
-
1231
- it "should not call callable if value is nil" do
1232
- Sequel.recursive_map([nil], proc{|s| s.to_i}).must_equal [nil]
1233
- Sequel.recursive_map([[nil]], proc{|s| s.to_i}).must_equal [[nil]]
1234
- end
1235
-
1236
- it "should call callable for falsey value" do
1237
- Sequel.recursive_map([false], proc{|s| s.to_s}).must_equal ['false']
1238
- Sequel.recursive_map([[false]], proc{|s| s.to_s}).must_equal [['false']]
1239
- end
1240
- end
1241
-
1242
- describe "Sequel.delay" do
1243
- before do
1244
- @o = Class.new do
1245
- def a
1246
- @a ||= 0
1247
- @a += 1
1248
- end
1249
- def _a
1250
- @a if defined?(@a)
1251
- end
1252
-
1253
- attr_accessor :b
1254
- end.new
1255
- end
1256
-
1257
- it "should delay calling the block until literalization" do
1258
- ds = Sequel.mock[:b].where(:a=>Sequel.delay{@o.a})
1259
- @o._a.must_be_nil
1260
- ds.sql.must_equal "SELECT * FROM b WHERE (a = 1)"
1261
- @o._a.must_equal 1
1262
- ds.sql.must_equal "SELECT * FROM b WHERE (a = 2)"
1263
- @o._a.must_equal 2
1264
- end
1265
-
1266
- it "should call the block with the current dataset if it accepts one argument" do
1267
- ds = Sequel.mock[:b].where(Sequel.delay{|x| x.first_source})
1268
- ds.sql.must_equal "SELECT * FROM b WHERE b"
1269
- ds.from(:c).sql.must_equal "SELECT * FROM c WHERE c"
1270
- end
1271
-
1272
- it "should have the condition specifier handling respect delayed evaluations" do
1273
- ds = Sequel.mock[:b].where(:a=>Sequel.delay{@o.b})
1274
- ds.sql.must_equal "SELECT * FROM b WHERE (a IS NULL)"
1275
- @o.b = 1
1276
- ds.sql.must_equal "SELECT * FROM b WHERE (a = 1)"
1277
- @o.b = [1, 2]
1278
- ds.sql.must_equal "SELECT * FROM b WHERE (a IN (1, 2))"
1279
- end
1280
-
1281
- it "should have the condition specifier handling call block with the current dataset if it accepts one argument" do
1282
- ds = Sequel.mock[:b].where(:a=>Sequel.delay{|x| x.first_source})
1283
- ds.sql.must_equal "SELECT * FROM b WHERE (a = b)"
1284
- ds.from(:c).sql.must_equal "SELECT * FROM c WHERE (a = c)"
1285
- end
1286
-
1287
- it "should raise if called without a block" do
1288
- proc{Sequel.delay}.must_raise(Sequel::Error)
1289
- end
1290
- end
1291
-
1292
- describe Sequel do
1293
- before do
1294
- Sequel::JSON = Class.new do
1295
- self::ParserError = Sequel
1296
- def self.parse(json, opts={})
1297
- [json, opts]
1298
- end
1299
- end
1300
- end
1301
- after do
1302
- Sequel.send(:remove_const, :JSON)
1303
- end
1304
-
1305
- it ".parse_json should parse json correctly" do
1306
- Sequel.parse_json('[]').must_equal ['[]', {:create_additions=>false}]
1307
- end
1308
-
1309
- it ".json_parser_error_class should return the related parser error class" do
1310
- Sequel.json_parser_error_class.must_equal Sequel
1311
- end
1312
-
1313
- it ".object_to_json should return a json version of the object" do
1314
- o = Object.new
1315
- def o.to_json(*args); [1, args]; end
1316
- Sequel.object_to_json(o, :foo).must_equal [1, [:foo]]
1317
- end
1318
- end
1319
-
1320
- describe "Sequel::LiteralString" do
1321
- before do
1322
- @s = Sequel::LiteralString.new("? = ?")
1323
- end
1324
-
1325
- it "should have lit return self if no arguments" do
1326
- @s.lit.must_be_same_as(@s)
1327
- end
1328
-
1329
- it "should have lit return self if return a placeholder literal string if arguments" do
1330
- @s.lit(1, 2).must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
1331
- Sequel.mock.literal(@s.lit(1, :a)).must_equal '1 = a'
1332
- end
1333
-
1334
- it "should have to_sequel_blob convert to blob" do
1335
- @s.to_sequel_blob.must_equal @s
1336
- @s.to_sequel_blob.must_be_kind_of(Sequel::SQL::Blob)
1337
- end
1338
- end
1339
-
1340
- describe "Sequel core extensions" do
1341
- it "should have Sequel.core_extensions? be false by default" do
1342
- Sequel.core_extensions?.must_equal false
1343
- end
1344
- end