sequel 5.8.0 → 5.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -1,395 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "constraint_validations extension" do
4
- def parse_insert(s)
5
- m = /\AINSERT INTO "?sequel_constraint_validations"? \("?(.*)"?\) VALUES \((.*)\)\z/.match(s)
6
- Hash[*m[1].split(/"?, "?/).map{|v| v.to_sym}.zip(m[2].split(/"?, "?/).map{|v| parse_insert_value(v)}).reject{|k, v| v.nil?}.flatten]
7
- end
8
-
9
- def parse_insert_value(s)
10
- case s
11
- when 'NULL'
12
- nil
13
- when /\A'(.*)'\z/
14
- $1
15
- else
16
- raise Sequel::Error, "unhandled insert value: #{s.inspect}"
17
- end
18
- end
19
-
20
- before do
21
- @db = Sequel.mock
22
- @db.extend(Module.new{attr_writer :schema; def schema(table, *) execute("parse schema for #{table}"); @schema; end})
23
- @db.extension(:constraint_validations)
24
- end
25
-
26
- it "should allow creating the sequel_constraint_validations table" do
27
- @db.create_constraint_validations_table
28
- @db.sqls.must_equal ["CREATE TABLE sequel_constraint_validations (table varchar(255) NOT NULL, constraint_name varchar(255), validation_type varchar(255) NOT NULL, column varchar(255) NOT NULL, argument varchar(255), message varchar(255), allow_nil boolean)"]
29
- end
30
-
31
- it "should allow creating the sequel_constraint_validations table with a non-default table name" do
32
- @db.constraint_validations_table = :foo
33
- @db.create_constraint_validations_table
34
- @db.sqls.must_equal ["CREATE TABLE foo (table varchar(255) NOT NULL, constraint_name varchar(255), validation_type varchar(255) NOT NULL, column varchar(255) NOT NULL, argument varchar(255), message varchar(255), allow_nil boolean)"]
35
- end
36
-
37
- it "should allow dropping the sequel_constraint_validations table" do
38
- @db.drop_constraint_validations_table
39
- @db.sqls.must_equal ["DROP TABLE sequel_constraint_validations"]
40
- end
41
-
42
- it "should allow dropping the sequel_constraint_validations table with a non-default table name" do
43
- @db.constraint_validations_table = :foo
44
- @db.drop_constraint_validations_table
45
- @db.sqls.must_equal ["DROP TABLE foo"]
46
- end
47
-
48
- it "should allow dropping validations for a given table" do
49
- @db.drop_constraint_validations_for(:table=>:foo)
50
- @db.sqls.must_equal ["DELETE FROM sequel_constraint_validations WHERE (table = 'foo')"]
51
- end
52
-
53
- it "should allow dropping validations for a given table and column" do
54
- @db.drop_constraint_validations_for(:table=>:foo, :column=>:bar)
55
- @db.sqls.must_equal ["DELETE FROM sequel_constraint_validations WHERE ((table = 'foo') AND (column = 'bar'))"]
56
- end
57
-
58
- it "should allow dropping validations for a given table and constraint" do
59
- @db.drop_constraint_validations_for(:table=>:foo, :constraint=>:bar)
60
- @db.sqls.must_equal ["DELETE FROM sequel_constraint_validations WHERE ((table = 'foo') AND (constraint_name = 'bar'))"]
61
- end
62
-
63
- it "should allow dropping validations for a non-default constraint_validations table" do
64
- @db.constraint_validations_table = :cv
65
- @db.drop_constraint_validations_for(:table=>:foo)
66
- @db.sqls.must_equal ["DELETE FROM cv WHERE (table = 'foo')"]
67
- end
68
-
69
- it "should raise an error without deleting if attempting to drop validations without table, column, or constraint" do
70
- proc{@db.drop_constraint_validations_for({})}.must_raise(Sequel::Error)
71
- @db.sqls.must_equal []
72
- end
73
-
74
- it "should allow adding constraint validations via create_table validate" do
75
- @db.create_table(:foo){String :name; validate{presence :name}}
76
- sqls = @db.sqls
77
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
78
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) != '')))"]
79
- end
80
-
81
- it "should allow adding constraint validations via alter_table validate" do
82
- @db.schema = [[:name, {:type=>:string}]]
83
- @db.alter_table(:foo){validate{presence :name}}
84
- sqls = @db.sqls
85
- parse_insert(sqls.slice!(2)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
86
- sqls.must_equal ["parse schema for foo", "BEGIN", "COMMIT", "ALTER TABLE foo ADD CHECK ((name IS NOT NULL) AND (trim(name) != ''))"]
87
- end
88
-
89
- it "should handle :message option when adding validations" do
90
- @db.create_table(:foo){String :name; validate{presence :name, :message=>'not there'}}
91
- sqls = @db.sqls
92
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo", :message=>'not there')
93
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) != '')))"]
94
- end
95
-
96
- it "should handle :allow_nil option when adding validations" do
97
- @db.create_table(:foo){String :name; validate{presence :name, :allow_nil=>true}}
98
- sqls = @db.sqls
99
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo", :allow_nil=>'t')
100
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NULL) OR (trim(name) != '')))"]
101
- end
102
-
103
- it "should handle :name option when adding validations" do
104
- @db.create_table(:foo){String :name; validate{presence :name, :name=>'cons'}}
105
- sqls = @db.sqls
106
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo", :constraint_name=>'cons')
107
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CONSTRAINT cons CHECK ((name IS NOT NULL) AND (trim(name) != '')))"]
108
- end
109
-
110
- it "should handle multiple columns when adding validations" do
111
- @db.create_table(:foo){String :name; String :bar; validate{presence [:name, :bar]}}
112
- sqls = @db.sqls
113
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
114
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"bar", :table=>"foo")
115
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), bar varchar(255), CHECK ((name IS NOT NULL) AND (bar IS NOT NULL) AND (trim(name) != '') AND (trim(bar) != '')))"]
116
- end
117
-
118
- it "should handle presence validation on non-String columns" do
119
- @db.create_table(:foo){Integer :name; validate{presence :name}}
120
- sqls = @db.sqls
121
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
122
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK (name IS NOT NULL))"]
123
-
124
- @db.schema = [[:name, {:type=>:integer}]]
125
- @db.alter_table(:foo){validate{presence :name}}
126
- sqls = @db.sqls
127
- parse_insert(sqls.slice!(2)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
128
- sqls.must_equal ["parse schema for foo", "BEGIN", "COMMIT", "ALTER TABLE foo ADD CHECK (name IS NOT NULL)"]
129
- end
130
-
131
- it "should handle presence validation on Oracle with IS NOT NULL instead of != ''" do
132
- @db = Sequel.mock(:host=>'oracle')
133
- @db.extend_datasets do
134
- def quote_identifiers?; false end
135
- def input_identifier(v) v.to_s end
136
- end
137
- @db.extension(:constraint_validations)
138
- @db.create_table(:foo){String :name; validate{presence :name}}
139
- sqls = @db.sqls
140
- s = sqls.slice!(1).upcase
141
- m = /\AINSERT INTO sequel_constraint_validations \((.*)\) SELECT (.*) FROM DUAL\z/i.match(s)
142
- Hash[*m[1].split(', ').map{|v| v.downcase.to_sym}.zip(m[2].split(', ').map{|v| parse_insert_value(v.downcase.gsub('null', 'NULL'))}).reject{|k, v| v.nil?}.flatten].must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo")
143
- sqls.must_equal ["BEGIN", "COMMIT", 'CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) IS NOT NULL)))']
144
- end
145
-
146
- it "should assume column is not a String if it can't determine the type" do
147
- @db.create_table(:foo){Integer :name; validate{presence :bar}}
148
- sqls = @db.sqls
149
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"bar", :table=>"foo")
150
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK (bar IS NOT NULL))"]
151
-
152
- @db.schema = [[:name, {:type=>:integer}]]
153
- @db.alter_table(:foo){validate{presence :bar}}
154
- sqls = @db.sqls
155
- parse_insert(sqls.slice!(2)).must_equal(:validation_type=>"presence", :column=>"bar", :table=>"foo")
156
- sqls.must_equal ["parse schema for foo", "BEGIN", "COMMIT", "ALTER TABLE foo ADD CHECK (bar IS NOT NULL)"]
157
- end
158
-
159
- it "should handle presence validation on non-String columns with :allow_nil option" do
160
- @db.create_table(:foo){Integer :name; validate{presence :name, :allow_nil=>true}}
161
- sqls = @db.sqls
162
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"foo", :allow_nil=>'t')
163
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer)"]
164
- end
165
-
166
- it "should support :exact_length constraint validation" do
167
- @db.create_table(:foo){String :name; validate{exact_length 5, :name}}
168
- sqls = @db.sqls
169
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"exact_length", :column=>"name", :table=>"foo", :argument=>'5')
170
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (char_length(name) = 5)))"]
171
- end
172
-
173
- it "should support :min_length constraint validation" do
174
- @db.create_table(:foo){String :name; validate{min_length 5, :name}}
175
- sqls = @db.sqls
176
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"min_length", :column=>"name", :table=>"foo", :argument=>'5')
177
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (char_length(name) >= 5)))"]
178
- end
179
-
180
- it "should support :max_length constraint validation" do
181
- @db.create_table(:foo){String :name; validate{max_length 5, :name}}
182
- sqls = @db.sqls
183
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"max_length", :column=>"name", :table=>"foo", :argument=>'5')
184
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (char_length(name) <= 5)))"]
185
- end
186
-
187
- it "should support :length_range constraint validation" do
188
- @db.create_table(:foo){String :name; validate{length_range 3..5, :name}}
189
- sqls = @db.sqls
190
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"length_range", :column=>"name", :table=>"foo", :argument=>'3..5')
191
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (char_length(name) >= 3) AND (char_length(name) <= 5)))"]
192
-
193
- @db.create_table(:foo){String :name; validate{length_range 3...5, :name}}
194
- sqls = @db.sqls
195
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"length_range", :column=>"name", :table=>"foo", :argument=>'3...5')
196
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (char_length(name) >= 3) AND (char_length(name) < 5)))"]
197
- end
198
-
199
- it "should support :format constraint validation" do
200
- @db = Sequel.mock(:host=>'postgres')
201
- @db.extend_datasets{def quote_identifiers?; false end}
202
- @db.extension(:constraint_validations)
203
- @db.create_table(:foo){String :name; validate{format(/^foo.*/, :name)}}
204
- sqls = @db.sqls
205
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"format", :column=>"name", :table=>"foo", :argument=>'^foo.*')
206
- sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~ '^foo.*')))]]
207
- end
208
-
209
- it "should support :format constraint validation with case insensitive format" do
210
- @db = Sequel.mock(:host=>'postgres')
211
- @db.extend_datasets{def quote_identifiers?; false end}
212
- @db.extension(:constraint_validations)
213
- @db.create_table(:foo){String :name; validate{format(/^foo.*/i, :name)}}
214
- sqls = @db.sqls
215
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"iformat", :column=>"name", :table=>"foo", :argument=>'^foo.*')
216
- sqls.must_equal ["BEGIN", "COMMIT", %[CREATE TABLE foo (name text, CHECK ((name IS NOT NULL) AND (name ~* '^foo.*')))]]
217
- end
218
-
219
- it "should support :includes constraint validation with an array of strings" do
220
- @db.create_table(:foo){String :name; validate{includes %w'a b c', :name}}
221
- sqls = @db.sqls
222
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"includes_str_array", :column=>"name", :table=>"foo", :argument=>'a,b,c')
223
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name IN ('a', 'b', 'c'))))"]
224
- end
225
-
226
- it "should support :includes constraint validation with an array of integers" do
227
- @db.create_table(:foo){String :name; validate{includes [1, 2, 3], :name}}
228
- sqls = @db.sqls
229
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"includes_int_array", :column=>"name", :table=>"foo", :argument=>'1,2,3')
230
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name IN (1, 2, 3))))"]
231
- end
232
-
233
- it "should support :includes constraint validation with a inclusive range of integers" do
234
- @db.create_table(:foo){String :name; validate{includes 3..5, :name}}
235
- sqls = @db.sqls
236
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"includes_int_range", :column=>"name", :table=>"foo", :argument=>'3..5')
237
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name >= 3) AND (name <= 5)))"]
238
- end
239
-
240
- it "should support :includes constraint validation with a exclusive range of integers" do
241
- @db.create_table(:foo){String :name; validate{includes 3...5, :name}}
242
- sqls = @db.sqls
243
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"includes_int_range", :column=>"name", :table=>"foo", :argument=>'3...5')
244
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name >= 3) AND (name < 5)))"]
245
- end
246
-
247
- it "should support :like constraint validation" do
248
- @db.create_table(:foo){String :name; validate{like 'foo%', :name}}
249
- sqls = @db.sqls
250
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"like", :column=>"name", :table=>"foo", :argument=>'foo%')
251
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name LIKE 'foo%' ESCAPE '\\')))"]
252
- end
253
-
254
- it "should support :ilike constraint validation" do
255
- @db.create_table(:foo){String :name; validate{ilike 'foo%', :name}}
256
- sqls = @db.sqls
257
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"ilike", :column=>"name", :table=>"foo", :argument=>'foo%')
258
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (UPPER(name) LIKE UPPER('foo%') ESCAPE '\\')))"]
259
- end
260
-
261
- it "should support :operator :< constraint validation with string" do
262
- @db.create_table(:foo){String :name; validate{operator :<, 'a', :name}}
263
- sqls = @db.sqls
264
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"str_lt", :column=>"name", :table=>"foo", :argument=>'a')
265
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name < 'a')))"]
266
- end
267
-
268
- it "should support :operator :<= constraint validation with string" do
269
- @db.create_table(:foo){String :name; validate{operator :<=, 'a', :name}}
270
- sqls = @db.sqls
271
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"str_lte", :column=>"name", :table=>"foo", :argument=>'a')
272
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name <= 'a')))"]
273
- end
274
-
275
- it "should support :operator :> constraint validation with string" do
276
- @db.create_table(:foo){String :name; validate{operator :>, 'a', :name}}
277
- sqls = @db.sqls
278
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"str_gt", :column=>"name", :table=>"foo", :argument=>'a')
279
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name > 'a')))"]
280
- end
281
-
282
- it "should support :operator :>= constraint validation with string" do
283
- @db.create_table(:foo){String :name; validate{operator :>=, 'a', :name}}
284
- sqls = @db.sqls
285
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"str_gte", :column=>"name", :table=>"foo", :argument=>'a')
286
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), CHECK ((name IS NOT NULL) AND (name >= 'a')))"]
287
- end
288
-
289
- it "should support :operator :< constraint validation with integer" do
290
- @db.create_table(:foo){Integer :name; validate{operator :<, 2, :name}}
291
- sqls = @db.sqls
292
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"int_lt", :column=>"name", :table=>"foo", :argument=>'2')
293
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK ((name IS NOT NULL) AND (name < 2)))"]
294
- end
295
-
296
- it "should support :operator :<= constraint validation with integer" do
297
- @db.create_table(:foo){Integer :name; validate{operator :<=, 2, :name}}
298
- sqls = @db.sqls
299
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"int_lte", :column=>"name", :table=>"foo", :argument=>'2')
300
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK ((name IS NOT NULL) AND (name <= 2)))"]
301
- end
302
-
303
- it "should support :operator :> constraint validation with integer" do
304
- @db.create_table(:foo){Integer :name; validate{operator :>, 2, :name}}
305
- sqls = @db.sqls
306
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"int_gt", :column=>"name", :table=>"foo", :argument=>'2')
307
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK ((name IS NOT NULL) AND (name > 2)))"]
308
- end
309
-
310
- it "should support :operator :>= constraint validation with integer" do
311
- @db.create_table(:foo){Integer :name; validate{operator :>=, 2, :name}}
312
- sqls = @db.sqls
313
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"int_gte", :column=>"name", :table=>"foo", :argument=>'2')
314
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name integer, CHECK ((name IS NOT NULL) AND (name >= 2)))"]
315
- end
316
-
317
- it "should support :unique constraint validation" do
318
- @db.create_table(:foo){String :name; validate{unique :name}}
319
- sqls = @db.sqls
320
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"unique", :column=>"name", :table=>"foo")
321
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), UNIQUE (name))"]
322
- end
323
-
324
- it "should support :unique constraint validation with multiple columns" do
325
- @db.create_table(:foo){String :name; Integer :id; validate{unique [:name, :id]}}
326
- sqls = @db.sqls
327
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"unique", :column=>"name,id", :table=>"foo")
328
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE foo (name varchar(255), id integer, UNIQUE (name, id))"]
329
- end
330
-
331
- it "should support :unique constraint validation in alter_table" do
332
- @db.alter_table(:foo){validate{unique :name}}
333
- sqls = @db.sqls
334
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"unique", :column=>"name", :table=>"foo")
335
- sqls.must_equal ["BEGIN", "COMMIT", "ALTER TABLE foo ADD UNIQUE (name)"]
336
- end
337
-
338
- it "should drop constraints and validations when dropping a constraint validation" do
339
- @db.alter_table(:foo){String :name; validate{drop :bar}}
340
- @db.sqls.must_equal ["DELETE FROM sequel_constraint_validations WHERE ((table, constraint_name) IN (('foo', 'bar')))", "ALTER TABLE foo DROP CONSTRAINT bar"]
341
- end
342
-
343
- it "should drop constraints and validations before adding new ones" do
344
- @db.alter_table(:foo){String :name; validate{unique :name; drop :bar}}
345
- sqls = @db.sqls
346
- parse_insert(sqls.slice!(2)).must_equal(:validation_type=>"unique", :column=>"name", :table=>"foo")
347
- sqls.must_equal ["DELETE FROM sequel_constraint_validations WHERE ((table, constraint_name) IN (('foo', 'bar')))", "BEGIN", "COMMIT", "ALTER TABLE foo ADD UNIQUE (name)", "ALTER TABLE foo DROP CONSTRAINT bar"]
348
- end
349
-
350
- it "should raise an error if attempting to validate inclusion with a range of non-integers" do
351
- proc{@db.create_table(:foo){String :name; validate{includes 'a'..'z', :name}}}.must_raise(Sequel::Error)
352
- end
353
-
354
- it "should raise an error if attempting to validate inclusion with a range of non-integers or strings" do
355
- proc{@db.create_table(:foo){String :name; validate{includes [1.0, 2.0], :name}}}.must_raise(Sequel::Error)
356
- end
357
-
358
- it "should raise an error if attempting to validate inclusion with a unsupported object" do
359
- proc{@db.create_table(:foo){String :name; validate{includes 'a', :name}}}.must_raise(Sequel::Error)
360
- end
361
-
362
- it "should raise an error if attempting attempting to process an operator validation with an unsupported operator" do
363
- proc{@db.alter_table(:foo){String :name; validate{operator :===, 'a', :name}}}.must_raise(Sequel::Error)
364
- end
365
-
366
- it "should raise an error if attempting attempting to process an operator validation with an unsupported argument" do
367
- proc{@db.alter_table(:foo){String :name; validate{operator :>, [], :name}}}.must_raise(Sequel::Error)
368
- end
369
-
370
- it "should raise an error if attempting to drop a constraint validation in a create_table generator" do
371
- proc{@db.create_table(:foo){String :name; validate{drop :foo}}}.must_raise(Sequel::Error)
372
- end
373
-
374
- it "should raise an error if attempting to drop a constraint validation without a name" do
375
- proc{@db.alter_table(:foo){String :name; validate{drop nil}}}.must_raise(Sequel::Error)
376
- end
377
-
378
- it "should raise an error if attempting attempting to process a constraint validation with an unsupported type" do
379
- proc{@db.alter_table(:foo){String :name; validations << {:type=>:foo}}}.must_raise(Sequel::Error)
380
- end
381
-
382
- it "should allow adding constraint validations for tables specified as a SQL::Identifier" do
383
- @db.create_table(Sequel.identifier(:sch__foo)){String :name; validate{presence :name}}
384
- sqls = @db.sqls
385
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"sch__foo")
386
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE sch__foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) != '')))"]
387
- end
388
-
389
- it "should allow adding constraint validations for tables specified as a SQL::QualifiedIdentifier" do
390
- @db.create_table(Sequel.qualify(:sch, :foo)){String :name; validate{presence :name}}
391
- sqls = @db.sqls
392
- parse_insert(sqls.slice!(1)).must_equal(:validation_type=>"presence", :column=>"name", :table=>"sch.foo")
393
- sqls.must_equal ["BEGIN", "COMMIT", "CREATE TABLE sch.foo (name varchar(255), CHECK ((name IS NOT NULL) AND (trim(name) != '')))"]
394
- end
395
- end
@@ -1,528 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- if (RUBY_VERSION >= '2.0.0' && RUBY_ENGINE == 'ruby') # || (RUBY_VERSION >= '2.3.0' && RUBY_ENGINE == 'jruby')
4
- Sequel.extension :core_refinements, :pg_array, :pg_hstore, :pg_row, :pg_range, :pg_row_ops, :pg_range_ops, :pg_array_ops, :pg_hstore_ops, :pg_json, :pg_json_ops
5
- using Sequel::CoreRefinements
6
-
7
- describe "Core refinements" do
8
- before do
9
- db = Sequel.mock
10
- @d = db[:items].with_extend do
11
- def supports_regexp?; true end
12
- def l(*args, &block)
13
- literal(filter_expr(*args, &block))
14
- end
15
- def lit(*args)
16
- literal(*args)
17
- end
18
- end
19
- end
20
-
21
- it "should support NOT via Symbol#~" do
22
- @d.l(~:x).must_equal 'NOT x'
23
- end
24
-
25
- with_symbol_splitting "should support NOT via Symbol#~ for splittable symbols" do
26
- @d.l(~:x__y).must_equal 'NOT x.y'
27
- end
28
-
29
- it "should support + - * / power via Symbol#+,-,*,/,**" do
30
- @d.l(:x + 1 > 100).must_equal '((x + 1) > 100)'
31
- @d.l((:x * :y) < 100.01).must_equal '((x * y) < 100.01)'
32
- @d.l((:x - :y/2) >= 100000000000000000000000000000000000).must_equal '((x - (y / 2)) >= 100000000000000000000000000000000000)'
33
- @d.l((((:x - :y)/(:x + :y))*:z) <= 100).must_equal '((((x - y) / (x + y)) * z) <= 100)'
34
- @d.l(~((((:x - :y)/(:x + :y))*:z) <= 100)).must_equal '((((x - y) / (x + y)) * z) > 100)'
35
- @d.l(~((((:x ** :y)/(:x + :y))*:z) <= 100)).must_equal '(((power(x, y) / (x + y)) * z) > 100)'
36
- end
37
-
38
- it "should support LIKE via Symbol#like" do
39
- @d.l(:x.like('a')).must_equal '(x LIKE \'a\' ESCAPE \'\\\')'
40
- @d.l(:x.like(/a/)).must_equal '(x ~ \'a\')'
41
- @d.l(:x.like('a', 'b')).must_equal '((x LIKE \'a\' ESCAPE \'\\\') OR (x LIKE \'b\' ESCAPE \'\\\'))'
42
- @d.l(:x.like(/a/, /b/i)).must_equal '((x ~ \'a\') OR (x ~* \'b\'))'
43
- @d.l(:x.like('a', /b/)).must_equal '((x LIKE \'a\' ESCAPE \'\\\') OR (x ~ \'b\'))'
44
- end
45
-
46
- it "should support NOT LIKE via Symbol#like and Symbol#~" do
47
- @d.l(~:x.like('a')).must_equal '(x NOT LIKE \'a\' ESCAPE \'\\\')'
48
- @d.l(~:x.like(/a/)).must_equal '(x !~ \'a\')'
49
- @d.l(~:x.like('a', 'b')).must_equal '((x NOT LIKE \'a\' ESCAPE \'\\\') AND (x NOT LIKE \'b\' ESCAPE \'\\\'))'
50
- @d.l(~:x.like(/a/, /b/i)).must_equal '((x !~ \'a\') AND (x !~* \'b\'))'
51
- @d.l(~:x.like('a', /b/)).must_equal '((x NOT LIKE \'a\' ESCAPE \'\\\') AND (x !~ \'b\'))'
52
- end
53
-
54
- it "should support ILIKE via Symbol#ilike" do
55
- @d.l(:x.ilike('a')).must_equal '(UPPER(x) LIKE UPPER(\'a\') ESCAPE \'\\\')'
56
- @d.l(:x.ilike(/a/)).must_equal '(x ~* \'a\')'
57
- @d.l(:x.ilike('a', 'b')).must_equal '((UPPER(x) LIKE UPPER(\'a\') ESCAPE \'\\\') OR (UPPER(x) LIKE UPPER(\'b\') ESCAPE \'\\\'))'
58
- @d.l(:x.ilike(/a/, /b/i)).must_equal '((x ~* \'a\') OR (x ~* \'b\'))'
59
- @d.l(:x.ilike('a', /b/)).must_equal '((UPPER(x) LIKE UPPER(\'a\') ESCAPE \'\\\') OR (x ~* \'b\'))'
60
- end
61
-
62
- it "should support NOT ILIKE via Symbol#ilike and Symbol#~" do
63
- @d.l(~:x.ilike('a')).must_equal '(UPPER(x) NOT LIKE UPPER(\'a\') ESCAPE \'\\\')'
64
- @d.l(~:x.ilike(/a/)).must_equal '(x !~* \'a\')'
65
- @d.l(~:x.ilike('a', 'b')).must_equal '((UPPER(x) NOT LIKE UPPER(\'a\') ESCAPE \'\\\') AND (UPPER(x) NOT LIKE UPPER(\'b\') ESCAPE \'\\\'))'
66
- @d.l(~:x.ilike(/a/, /b/i)).must_equal '((x !~* \'a\') AND (x !~* \'b\'))'
67
- @d.l(~:x.ilike('a', /b/)).must_equal '((UPPER(x) NOT LIKE UPPER(\'a\') ESCAPE \'\\\') AND (x !~* \'b\'))'
68
- end
69
-
70
- it "should support sql_expr on arrays with all two pairs" do
71
- @d.l([[:x, 100],[:y, 'a']].sql_expr).must_equal '((x = 100) AND (y = \'a\'))'
72
- @d.l([[:x, true], [:y, false]].sql_expr).must_equal '((x IS TRUE) AND (y IS FALSE))'
73
- @d.l([[:x, nil], [:y, [1,2,3]]].sql_expr).must_equal '((x IS NULL) AND (y IN (1, 2, 3)))'
74
- end
75
-
76
- it "should support sql_negate on arrays with all two pairs" do
77
- @d.l([[:x, 100],[:y, 'a']].sql_negate).must_equal '((x != 100) AND (y != \'a\'))'
78
- @d.l([[:x, true], [:y, false]].sql_negate).must_equal '((x IS NOT TRUE) AND (y IS NOT FALSE))'
79
- @d.l([[:x, nil], [:y, [1,2,3]]].sql_negate).must_equal '((x IS NOT NULL) AND (y NOT IN (1, 2, 3)))'
80
- end
81
-
82
- it "should support ~ on arrays with all two pairs" do
83
- @d.l(~[[:x, 100],[:y, 'a']]).must_equal '((x != 100) OR (y != \'a\'))'
84
- @d.l(~[[:x, true], [:y, false]]).must_equal '((x IS NOT TRUE) OR (y IS NOT FALSE))'
85
- @d.l(~[[:x, nil], [:y, [1,2,3]]]).must_equal '((x IS NOT NULL) OR (y NOT IN (1, 2, 3)))'
86
- end
87
-
88
- it "should support sql_or on arrays with all two pairs" do
89
- @d.l([[:x, 100],[:y, 'a']].sql_or).must_equal '((x = 100) OR (y = \'a\'))'
90
- @d.l([[:x, true], [:y, false]].sql_or).must_equal '((x IS TRUE) OR (y IS FALSE))'
91
- @d.l([[:x, nil], [:y, [1,2,3]]].sql_or).must_equal '((x IS NULL) OR (y IN (1, 2, 3)))'
92
- end
93
-
94
- it "should support Array#sql_string_join for concatenation of SQL strings" do
95
- @d.lit([:x].sql_string_join).must_equal '(x)'
96
- @d.lit([:x].sql_string_join(', ')).must_equal '(x)'
97
- @d.lit([:x, :y].sql_string_join).must_equal '(x || y)'
98
- @d.lit([:x, :y].sql_string_join(', ')).must_equal "(x || ', ' || y)"
99
- @d.lit([:x.sql_function(1), :y.sql_subscript(1)].sql_string_join).must_equal '(x(1) || y[1])'
100
- @d.lit([:x.sql_function(1), 'y.z'.lit].sql_string_join(', ')).must_equal "(x(1) || ', ' || y.z)"
101
- @d.lit([:x, 1, :y].sql_string_join).must_equal "(x || '1' || y)"
102
- @d.lit([:x, 1, :y].sql_string_join(', ')).must_equal "(x || ', ' || '1' || ', ' || y)"
103
- @d.lit([:x, 1, :y].sql_string_join(Sequel[:y][:z])).must_equal "(x || y.z || '1' || y.z || y)"
104
- @d.lit([:x, 1, :y].sql_string_join(1)).must_equal "(x || '1' || '1' || '1' || y)"
105
- @d.lit([:x, :y].sql_string_join('y.x || x.y'.lit)).must_equal "(x || y.x || x.y || y)"
106
- @d.lit([[:x, :y].sql_string_join, [:a, :b].sql_string_join].sql_string_join).must_equal "(x || y || a || b)"
107
- end
108
-
109
- it "should support sql_expr on hashes" do
110
- @d.l({:x => 100, :y => 'a'}.sql_expr)[1...-1].split(' AND ').sort.must_equal ['(x = 100)', '(y = \'a\')']
111
- @d.l({:x => true, :y => false}.sql_expr)[1...-1].split(' AND ').sort.must_equal ['(x IS TRUE)', '(y IS FALSE)']
112
- @d.l({:x => nil, :y => [1,2,3]}.sql_expr)[1...-1].split(' AND ').sort.must_equal ['(x IS NULL)', '(y IN (1, 2, 3))']
113
- end
114
-
115
- it "should support sql_negate on hashes" do
116
- @d.l({:x => 100, :y => 'a'}.sql_negate)[1...-1].split(' AND ').sort.must_equal ['(x != 100)', '(y != \'a\')']
117
- @d.l({:x => true, :y => false}.sql_negate)[1...-1].split(' AND ').sort.must_equal ['(x IS NOT TRUE)', '(y IS NOT FALSE)']
118
- @d.l({:x => nil, :y => [1,2,3]}.sql_negate)[1...-1].split(' AND ').sort.must_equal ['(x IS NOT NULL)', '(y NOT IN (1, 2, 3))']
119
- end
120
-
121
- it "should support ~ on hashes" do
122
- @d.l(~{:x => 100, :y => 'a'})[1...-1].split(' OR ').sort.must_equal ['(x != 100)', '(y != \'a\')']
123
- @d.l(~{:x => true, :y => false})[1...-1].split(' OR ').sort.must_equal ['(x IS NOT TRUE)', '(y IS NOT FALSE)']
124
- @d.l(~{:x => nil, :y => [1,2,3]})[1...-1].split(' OR ').sort.must_equal ['(x IS NOT NULL)', '(y NOT IN (1, 2, 3))']
125
- end
126
-
127
- it "should support sql_or on hashes" do
128
- @d.l({:x => 100, :y => 'a'}.sql_or)[1...-1].split(' OR ').sort.must_equal ['(x = 100)', '(y = \'a\')']
129
- @d.l({:x => true, :y => false}.sql_or)[1...-1].split(' OR ').sort.must_equal ['(x IS TRUE)', '(y IS FALSE)']
130
- @d.l({:x => nil, :y => [1,2,3]}.sql_or)[1...-1].split(' OR ').sort.must_equal ['(x IS NULL)', '(y IN (1, 2, 3))']
131
- end
132
-
133
- it "should Hash#& and Hash#|" do
134
- @d.l({:y => :z} & :x).must_equal '((y = z) AND x)'
135
- @d.l({:x => :a} & {:y => :z}).must_equal '((x = a) AND (y = z))'
136
- @d.l({:y => :z} | :x).must_equal '((y = z) OR x)'
137
- @d.l({:x => :a} | {:y => :z}).must_equal '((x = a) OR (y = z))'
138
- end
139
- end
140
-
141
- describe "Array#case and Hash#case" do
142
- before do
143
- @d = Sequel.mock.dataset
144
- end
145
-
146
- it "should return SQL CASE expression" do
147
- @d.literal({:x=>:y}.case(:z)).must_equal '(CASE WHEN x THEN y ELSE z END)'
148
- @d.literal({:x=>:y}.case(:z, :exp)).must_equal '(CASE exp WHEN x THEN y ELSE z END)'
149
- ['(CASE WHEN x THEN y WHEN a THEN b ELSE z END)',
150
- '(CASE WHEN a THEN b WHEN x THEN y ELSE z END)'].must_include(@d.literal({:x=>:y, :a=>:b}.case(:z)))
151
- @d.literal([[:x, :y]].case(:z)).must_equal '(CASE WHEN x THEN y ELSE z END)'
152
- @d.literal([[:x, :y], [:a, :b]].case(:z)).must_equal '(CASE WHEN x THEN y WHEN a THEN b ELSE z END)'
153
- @d.literal([[:x, :y], [:a, :b]].case(:z, :exp)).must_equal '(CASE exp WHEN x THEN y WHEN a THEN b ELSE z END)'
154
- @d.literal([[:x, :y], [:a, :b]].case(:z, Sequel[:exp][:w])).must_equal '(CASE exp.w WHEN x THEN y WHEN a THEN b ELSE z END)'
155
- end
156
-
157
- it "should return SQL CASE expression with expression even if nil" do
158
- @d.literal({:x=>:y}.case(:z, nil)).must_equal '(CASE NULL WHEN x THEN y ELSE z END)'
159
- end
160
-
161
- it "should raise an error if an array that isn't all two pairs is used" do
162
- proc{[:b].case(:a)}.must_raise(Sequel::Error)
163
- proc{[:b, :c].case(:a)}.must_raise(Sequel::Error)
164
- proc{[[:b, :c], :d].case(:a)}.must_raise(Sequel::Error)
165
- end
166
-
167
- it "should raise an error if an empty array/hash is used" do
168
- proc{[].case(:a)}.must_raise(Sequel::Error)
169
- proc{{}.case(:a)}.must_raise(Sequel::Error)
170
- end
171
- end
172
-
173
- describe "Array#sql_value_list and #sql_array" do
174
- before do
175
- @d = Sequel.mock.dataset
176
- end
177
-
178
- it "should treat the array as an SQL value list instead of conditions when used as a placeholder value" do
179
- @d.filter(Sequel.lit("(a, b) IN ?", [[:x, 1], [:y, 2]])).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x = 1) AND (y = 2)))'
180
- @d.filter(Sequel.lit("(a, b) IN ?", [[:x, 1], [:y, 2]].sql_value_list)).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
181
- end
182
-
183
- it "should be no difference when used as a hash value" do
184
- @d.filter([:a, :b]=>[[:x, 1], [:y, 2]]).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
185
- @d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_value_list).sql.must_equal 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
186
- end
187
- end
188
-
189
- describe "String#lit" do
190
- before do
191
- @ds = Sequel.mock[:t]
192
- end
193
-
194
- it "should return an LiteralString object" do
195
- 'xyz'.lit.must_be_kind_of(Sequel::LiteralString)
196
- 'xyz'.lit.to_s.must_equal 'xyz'
197
- end
198
-
199
- it "should inhibit string literalization" do
200
- @ds.update_sql(:stamp => "NOW()".lit).must_equal "UPDATE t SET stamp = NOW()"
201
- end
202
-
203
- it "should return a PlaceholderLiteralString object if args are given" do
204
- a = 'DISTINCT ?'.lit(:a)
205
- a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
206
- @ds.literal(a).must_equal 'DISTINCT a'
207
- @ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
208
- end
209
-
210
- it "should handle named placeholders if given a single argument hash" do
211
- a = 'DISTINCT :b'.lit(:b=>:a)
212
- a.must_be_kind_of(Sequel::SQL::PlaceholderLiteralString)
213
- @ds.literal(a).must_equal 'DISTINCT a'
214
- @ds.with_quote_identifiers(true).literal(a).must_equal 'DISTINCT "a"'
215
- end
216
-
217
- it "should treat placeholder literal strings as generic expressions" do
218
- a = ':b'.lit(:b=>:a)
219
- @ds.literal(a + 1).must_equal "(a + 1)"
220
- @ds.literal(a & :b).must_equal "(a AND b)"
221
- @ds.literal(a.sql_string + :b).must_equal "(a || b)"
222
- end
223
- end
224
-
225
- describe "String#to_sequel_blob" do
226
- it "should return a Blob object" do
227
- 'xyz'.to_sequel_blob.must_be_kind_of(::Sequel::SQL::Blob)
228
- 'xyz'.to_sequel_blob.must_equal 'xyz'
229
- end
230
-
231
- it "should retain binary data" do
232
- "\1\2\3\4".to_sequel_blob.must_equal "\1\2\3\4"
233
- end
234
- end
235
-
236
- describe "#desc" do
237
- before do
238
- @ds = Sequel.mock.dataset
239
- end
240
-
241
- it "should format a DESC clause for a column ref" do
242
- @ds.literal(:test.desc).must_equal 'test DESC'
243
- end
244
-
245
- with_symbol_splitting "should format a DESC clause for a column ref with splittable symbol" do
246
- @ds.literal(:items__price.desc).must_equal 'items.price DESC'
247
- end
248
-
249
- it "should format a DESC clause for a function" do
250
- @ds.literal(:avg.sql_function(:test).desc).must_equal 'avg(test) DESC'
251
- end
252
- end
253
-
254
- describe "#asc" do
255
- before do
256
- @ds = Sequel.mock.dataset
257
- end
258
-
259
- it "should format a ASC clause for a column ref" do
260
- @ds.literal(:test.asc).must_equal 'test ASC'
261
- end
262
-
263
- with_symbol_splitting "should format a ASC clause for a column ref with splittable symbol" do
264
- @ds.literal(:items__price.asc).must_equal 'items.price ASC'
265
- end
266
-
267
- it "should format a ASC clause for a function" do
268
- @ds.literal(:avg.sql_function(:test).asc).must_equal 'avg(test) ASC'
269
- end
270
- end
271
-
272
- describe "#as" do
273
- before do
274
- @ds = Sequel.mock.dataset
275
- end
276
-
277
- it "should format a AS clause for a column ref" do
278
- @ds.literal(:test.as(:t)).must_equal 'test AS t'
279
- end
280
-
281
- with_symbol_splitting "should format a AS clause for a column ref with splittable symbols" do
282
- @ds.literal(:items__price.as(:p)).must_equal 'items.price AS p'
283
- end
284
-
285
- it "should format a AS clause for a function" do
286
- @ds.literal(:avg.sql_function(:test).as(:avg)).must_equal 'avg(test) AS avg'
287
- end
288
-
289
- it "should format a AS clause for a literal value" do
290
- @ds.literal('abc'.as(:abc)).must_equal "'abc' AS abc"
291
- end
292
- end
293
-
294
- describe "Column references" do
295
- before do
296
- @ds = Sequel.mock.dataset.with_quote_identifiers(true).with_extend{def quoted_identifier_append(sql, c) sql << "`#{c}`" end}
297
- end
298
-
299
- it "should be quoted properly" do
300
- @ds.literal(:xyz).must_equal "`xyz`"
301
- @ds.literal(:xyz.as(:x)).must_equal "`xyz` AS `x`"
302
- end
303
-
304
- it "should be quoted properly in SQL functions" do
305
- @ds.literal(:avg.sql_function(:xyz)).must_equal "avg(`xyz`)"
306
- @ds.literal(:avg.sql_function(:xyz, 1)).must_equal "avg(`xyz`, 1)"
307
- @ds.literal(:avg.sql_function(:xyz).as(:a)).must_equal "avg(`xyz`) AS `a`"
308
- end
309
-
310
- it "should be quoted properly in ASC/DESC clauses" do
311
- @ds.literal(:xyz.asc).must_equal "`xyz` ASC"
312
- @ds.literal(:avg.sql_function(:xyz, 1).desc).must_equal "avg(`xyz`, 1) DESC"
313
- end
314
-
315
- it "should be quoted properly in a cast function" do
316
- @ds.literal(:x.cast(:integer)).must_equal "CAST(`x` AS integer)"
317
- end
318
-
319
- with_symbol_splitting "should be quoted properly when using splittable symbols" do
320
- @ds.literal(:xyz__abc).must_equal "`xyz`.`abc`"
321
- @ds.literal(:xyz__abc.as(:x)).must_equal "`xyz`.`abc` AS `x`"
322
- @ds.literal(:xyz___x).must_equal "`xyz` AS `x`"
323
- @ds.literal(:xyz__abc___x).must_equal "`xyz`.`abc` AS `x`"
324
- @ds.literal(:x__y.cast('varchar(20)')).must_equal "CAST(`x`.`y` AS varchar(20))"
325
- end
326
- end
327
-
328
- describe "Blob" do
329
- it "#to_sequel_blob should return self" do
330
- blob = "x".to_sequel_blob
331
- blob.to_sequel_blob.object_id.must_equal blob.object_id
332
- end
333
- end
334
-
335
- describe "Symbol#*" do
336
- before do
337
- @ds = Sequel.mock.dataset
338
- end
339
-
340
- it "should format a qualified wildcard if no argument" do
341
- @ds.literal(:xyz.*).must_equal 'xyz.*'
342
- @ds.literal(:abc.*).must_equal 'abc.*'
343
- end
344
-
345
- it "should format a filter expression if an argument" do
346
- @ds.literal(:xyz.*(3)).must_equal '(xyz * 3)'
347
- @ds.literal(:abc.*(5)).must_equal '(abc * 5)'
348
- end
349
-
350
- with_symbol_splitting "should support qualified symbols if no argument" do
351
- @ds.literal(:xyz__abc.*).must_equal 'xyz.abc.*'
352
- end
353
- end
354
-
355
- describe "Symbol" do
356
- before do
357
- @ds = Sequel.mock.dataset.with_quote_identifiers(true)
358
- end
359
-
360
- it "#identifier should format an identifier" do
361
- @ds.literal(:xyz__abc.identifier).must_equal '"xyz__abc"'
362
- end
363
-
364
- it "#qualify should format a qualified column" do
365
- @ds.literal(:xyz.qualify(:abc)).must_equal '"abc"."xyz"'
366
- end
367
-
368
- it "#qualify should work on QualifiedIdentifiers" do
369
- @ds.literal(:xyz.qualify(:abc).qualify(:def)).must_equal '"def"."abc"."xyz"'
370
- end
371
-
372
- it "should be able to qualify an identifier" do
373
- @ds.literal(:xyz.identifier.qualify(Sequel[:xyz][:abc])).must_equal '"xyz"."abc"."xyz"'
374
- end
375
-
376
- with_symbol_splitting "should be able to qualify an identifier with qualified symbol" do
377
- @ds.literal(:xyz.identifier.qualify(:xyz__abc)).must_equal '"xyz"."abc"."xyz"'
378
- end
379
-
380
- it "should be able to specify a schema.table.column" do
381
- @ds.literal(:column.qualify(:table.qualify(:schema))).must_equal '"schema"."table"."column"'
382
- @ds.literal(:column.qualify(:table__name.identifier.qualify(:schema))).must_equal '"schema"."table__name"."column"'
383
- end
384
-
385
- it "should be able to specify order" do
386
- @oe = :xyz.desc
387
- @oe.class.must_equal Sequel::SQL::OrderedExpression
388
- @oe.descending.must_equal true
389
- @oe = :xyz.asc
390
- @oe.class.must_equal Sequel::SQL::OrderedExpression
391
- @oe.descending.must_equal false
392
- end
393
-
394
- it "should work correctly with objects" do
395
- o = Object.new
396
- def o.sql_literal(ds) "(foo)" end
397
- @ds.literal(:column.qualify(o)).must_equal '(foo)."column"'
398
- end
399
- end
400
-
401
- describe "Symbol" do
402
- before do
403
- @ds = Sequel.mock.dataset
404
- end
405
-
406
- it "should support sql_function method" do
407
- @ds.literal(:COUNT.sql_function('1')).must_equal "COUNT('1')"
408
- @ds.select(:COUNT.sql_function('1')).sql.must_equal "SELECT COUNT('1')"
409
- end
410
-
411
- it "should support cast method" do
412
- @ds.literal(:abc.cast(:integer)).must_equal "CAST(abc AS integer)"
413
- end
414
-
415
- with_symbol_splitting "should support sql array accesses via sql_subscript for splittable symbols" do
416
- @ds.literal(:abc__def.sql_subscript(1)).must_equal "abc.def[1]"
417
- end
418
-
419
- it "should support sql array accesses via sql_subscript" do
420
- @ds.literal(:abc.sql_subscript(1)).must_equal "abc[1]"
421
- @ds.literal(:abc.sql_subscript(1)|2).must_equal "abc[1, 2]"
422
- @ds.literal(:abc.sql_subscript(1)[2]).must_equal "abc[1][2]"
423
- end
424
-
425
- it "should support cast_numeric and cast_string" do
426
- x = :abc.cast_numeric
427
- x.must_be_kind_of(Sequel::SQL::NumericExpression)
428
- @ds.literal(x).must_equal "CAST(abc AS integer)"
429
-
430
- x = :abc.cast_numeric(:real)
431
- x.must_be_kind_of(Sequel::SQL::NumericExpression)
432
- @ds.literal(x).must_equal "CAST(abc AS real)"
433
-
434
- x = :abc.cast_string
435
- x.must_be_kind_of(Sequel::SQL::StringExpression)
436
- @ds.literal(x).must_equal "CAST(abc AS varchar(255))"
437
-
438
- x = :abc.cast_string(:varchar)
439
- x.must_be_kind_of(Sequel::SQL::StringExpression)
440
- @ds.literal(x).must_equal "CAST(abc AS varchar(255))"
441
- end
442
-
443
- it "should allow database independent types when casting" do
444
- db = @ds.db
445
- def db.cast_type_literal(type)
446
- return :foo if type == Integer
447
- return :bar if type == String
448
- type
449
- end
450
- @ds.literal(:abc.cast(String)).must_equal "CAST(abc AS bar)"
451
- @ds.literal(:abc.cast(String)).must_equal "CAST(abc AS bar)"
452
- @ds.literal(:abc.cast_string).must_equal "CAST(abc AS bar)"
453
- @ds.literal(:abc.cast_string(Integer)).must_equal "CAST(abc AS foo)"
454
- @ds.literal(:abc.cast_numeric).must_equal "CAST(abc AS foo)"
455
- @ds.literal(:abc.cast_numeric(String)).must_equal "CAST(abc AS bar)"
456
- end
457
-
458
- it "should support SQL EXTRACT function via #extract " do
459
- @ds.literal(:abc.extract(:year)).must_equal "extract(year FROM abc)"
460
- end
461
- end
462
-
463
- describe "Postgres extensions integration" do
464
- before do
465
- @db = Sequel.mock
466
- end
467
-
468
- it "Symbol#pg_array should return an ArrayOp" do
469
- @db.literal(:a.pg_array.unnest).must_equal "unnest(a)"
470
- end
471
-
472
- it "Symbol#pg_row should return a PGRowOp" do
473
- @db.literal(:a.pg_row[:a]).must_equal "(a).a"
474
- end
475
-
476
- it "Symbol#hstore should return an HStoreOp" do
477
- @db.literal(:a.hstore['a']).must_equal "(a -> 'a')"
478
- end
479
-
480
- it "Symbol#pg_json should return an JSONOp" do
481
- @db.literal(:a.pg_json[%w'a b']).must_equal "(a #> ARRAY['a','b'])"
482
- @db.literal(:a.pg_json.extract('a')).must_equal "json_extract_path(a, 'a')"
483
- end
484
-
485
- it "Symbol#pg_jsonb should return an JSONBOp" do
486
- @db.literal(:a.pg_jsonb[%w'a b']).must_equal "(a #> ARRAY['a','b'])"
487
- @db.literal(:a.pg_jsonb.extract('a')).must_equal "jsonb_extract_path(a, 'a')"
488
- end
489
-
490
- it "Symbol#pg_range should return a RangeOp" do
491
- @db.literal(:a.pg_range.lower).must_equal "lower(a)"
492
- end
493
-
494
- it "Array#pg_array should return a PGArray" do
495
- @db.literal([1].pg_array.op.unnest).must_equal "unnest(ARRAY[1])"
496
- @db.literal([1].pg_array(:int4).op.unnest).must_equal "unnest(ARRAY[1]::int4[])"
497
- end
498
-
499
- it "Array#pg_json should return a JSONArray" do
500
- @db.literal([1].pg_json).must_equal "'[1]'::json"
501
- end
502
-
503
- it "Array#pg_jsonb should return a JSONBArray" do
504
- @db.literal([1].pg_jsonb).must_equal "'[1]'::jsonb"
505
- end
506
-
507
- it "Array#pg_row should return a ArrayRow" do
508
- @db.literal([1].pg_row).must_equal "ROW(1)"
509
- end
510
-
511
- it "Hash#hstore should return an HStore" do
512
- @db.literal({'a'=>1}.hstore.op['a']).must_equal '(\'"a"=>"1"\'::hstore -> \'a\')'
513
- end
514
-
515
- it "Hash#pg_json should return an JSONHash" do
516
- @db.literal({'a'=>'b'}.pg_json).must_equal "'{\"a\":\"b\"}'::json"
517
- end
518
-
519
- it "Hash#pg_jsonb should return an JSONBHash" do
520
- @db.literal({'a'=>'b'}.pg_jsonb).must_equal "'{\"a\":\"b\"}'::jsonb"
521
- end
522
-
523
- it "Range#pg_range should return an PGRange" do
524
- @db.literal((1..2).pg_range).must_equal "'[1,2]'"
525
- @db.literal((1..2).pg_range(:int4range)).must_equal "int4range(1,2,'[]')"
526
- end
527
- end
528
- end