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