sequel 5.29.0 → 5.30.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 (323) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +8 -1922
  3. data/doc/release_notes/5.30.0.txt +20 -0
  4. data/lib/sequel/adapters/shared/sqlite.rb +7 -1
  5. data/lib/sequel/database/transactions.rb +5 -9
  6. data/lib/sequel/version.rb +1 -1
  7. metadata +4 -368
  8. data/Rakefile +0 -151
  9. data/doc/release_notes/4.0.0.txt +0 -262
  10. data/doc/release_notes/4.1.0.txt +0 -85
  11. data/doc/release_notes/4.10.0.txt +0 -226
  12. data/doc/release_notes/4.11.0.txt +0 -147
  13. data/doc/release_notes/4.12.0.txt +0 -105
  14. data/doc/release_notes/4.13.0.txt +0 -169
  15. data/doc/release_notes/4.14.0.txt +0 -68
  16. data/doc/release_notes/4.15.0.txt +0 -56
  17. data/doc/release_notes/4.16.0.txt +0 -36
  18. data/doc/release_notes/4.17.0.txt +0 -38
  19. data/doc/release_notes/4.18.0.txt +0 -36
  20. data/doc/release_notes/4.19.0.txt +0 -45
  21. data/doc/release_notes/4.2.0.txt +0 -129
  22. data/doc/release_notes/4.20.0.txt +0 -79
  23. data/doc/release_notes/4.21.0.txt +0 -94
  24. data/doc/release_notes/4.22.0.txt +0 -72
  25. data/doc/release_notes/4.23.0.txt +0 -65
  26. data/doc/release_notes/4.24.0.txt +0 -99
  27. data/doc/release_notes/4.25.0.txt +0 -181
  28. data/doc/release_notes/4.26.0.txt +0 -44
  29. data/doc/release_notes/4.27.0.txt +0 -78
  30. data/doc/release_notes/4.28.0.txt +0 -57
  31. data/doc/release_notes/4.29.0.txt +0 -41
  32. data/doc/release_notes/4.3.0.txt +0 -40
  33. data/doc/release_notes/4.30.0.txt +0 -37
  34. data/doc/release_notes/4.31.0.txt +0 -57
  35. data/doc/release_notes/4.32.0.txt +0 -132
  36. data/doc/release_notes/4.33.0.txt +0 -88
  37. data/doc/release_notes/4.34.0.txt +0 -86
  38. data/doc/release_notes/4.35.0.txt +0 -130
  39. data/doc/release_notes/4.36.0.txt +0 -116
  40. data/doc/release_notes/4.37.0.txt +0 -50
  41. data/doc/release_notes/4.38.0.txt +0 -67
  42. data/doc/release_notes/4.39.0.txt +0 -127
  43. data/doc/release_notes/4.4.0.txt +0 -92
  44. data/doc/release_notes/4.40.0.txt +0 -179
  45. data/doc/release_notes/4.41.0.txt +0 -77
  46. data/doc/release_notes/4.42.0.txt +0 -221
  47. data/doc/release_notes/4.43.0.txt +0 -87
  48. data/doc/release_notes/4.44.0.txt +0 -125
  49. data/doc/release_notes/4.45.0.txt +0 -370
  50. data/doc/release_notes/4.46.0.txt +0 -404
  51. data/doc/release_notes/4.47.0.txt +0 -56
  52. data/doc/release_notes/4.48.0.txt +0 -293
  53. data/doc/release_notes/4.49.0.txt +0 -222
  54. data/doc/release_notes/4.5.0.txt +0 -34
  55. data/doc/release_notes/4.6.0.txt +0 -30
  56. data/doc/release_notes/4.7.0.txt +0 -103
  57. data/doc/release_notes/4.8.0.txt +0 -175
  58. data/doc/release_notes/4.9.0.txt +0 -190
  59. data/spec/adapter_spec.rb +0 -4
  60. data/spec/adapters/db2_spec.rb +0 -170
  61. data/spec/adapters/mssql_spec.rb +0 -828
  62. data/spec/adapters/mysql_spec.rb +0 -1060
  63. data/spec/adapters/oracle_spec.rb +0 -371
  64. data/spec/adapters/postgres_spec.rb +0 -4476
  65. data/spec/adapters/spec_helper.rb +0 -44
  66. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  67. data/spec/adapters/sqlite_spec.rb +0 -652
  68. data/spec/bin_spec.rb +0 -278
  69. data/spec/core/connection_pool_spec.rb +0 -1250
  70. data/spec/core/database_spec.rb +0 -2915
  71. data/spec/core/dataset_spec.rb +0 -5544
  72. data/spec/core/deprecated_spec.rb +0 -70
  73. data/spec/core/expression_filters_spec.rb +0 -1498
  74. data/spec/core/mock_adapter_spec.rb +0 -722
  75. data/spec/core/object_graph_spec.rb +0 -336
  76. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  77. data/spec/core/schema_generator_spec.rb +0 -214
  78. data/spec/core/schema_spec.rb +0 -1844
  79. data/spec/core/spec_helper.rb +0 -24
  80. data/spec/core/version_spec.rb +0 -14
  81. data/spec/core_extensions_spec.rb +0 -763
  82. data/spec/core_model_spec.rb +0 -2
  83. data/spec/core_spec.rb +0 -1
  84. data/spec/deprecation_helper.rb +0 -30
  85. data/spec/extensions/accessed_columns_spec.rb +0 -51
  86. data/spec/extensions/active_model_spec.rb +0 -99
  87. data/spec/extensions/after_initialize_spec.rb +0 -28
  88. data/spec/extensions/any_not_empty_spec.rb +0 -23
  89. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  90. data/spec/extensions/association_dependencies_spec.rb +0 -125
  91. data/spec/extensions/association_multi_add_remove_spec.rb +0 -1041
  92. data/spec/extensions/association_pks_spec.rb +0 -423
  93. data/spec/extensions/association_proxies_spec.rb +0 -100
  94. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  95. data/spec/extensions/auto_validations_spec.rb +0 -229
  96. data/spec/extensions/blacklist_security_spec.rb +0 -95
  97. data/spec/extensions/blank_spec.rb +0 -69
  98. data/spec/extensions/boolean_readers_spec.rb +0 -93
  99. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  100. data/spec/extensions/caching_spec.rb +0 -273
  101. data/spec/extensions/caller_logging_spec.rb +0 -52
  102. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  103. data/spec/extensions/column_conflicts_spec.rb +0 -75
  104. data/spec/extensions/column_select_spec.rb +0 -129
  105. data/spec/extensions/columns_introspection_spec.rb +0 -90
  106. data/spec/extensions/columns_updated_spec.rb +0 -35
  107. data/spec/extensions/composition_spec.rb +0 -248
  108. data/spec/extensions/connection_expiration_spec.rb +0 -151
  109. data/spec/extensions/connection_validator_spec.rb +0 -144
  110. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  111. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  112. data/spec/extensions/constraint_validations_spec.rb +0 -439
  113. data/spec/extensions/core_refinements_spec.rb +0 -528
  114. data/spec/extensions/csv_serializer_spec.rb +0 -183
  115. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  116. data/spec/extensions/dataset_associations_spec.rb +0 -365
  117. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  118. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  119. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  120. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  121. data/spec/extensions/defaults_setter_spec.rb +0 -150
  122. data/spec/extensions/delay_add_association_spec.rb +0 -73
  123. data/spec/extensions/dirty_spec.rb +0 -222
  124. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  125. data/spec/extensions/eager_each_spec.rb +0 -62
  126. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  127. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  128. data/spec/extensions/empty_failure_backtraces_spec.rb +0 -60
  129. data/spec/extensions/error_splitter_spec.rb +0 -18
  130. data/spec/extensions/error_sql_spec.rb +0 -20
  131. data/spec/extensions/escaped_like_spec.rb +0 -40
  132. data/spec/extensions/eval_inspect_spec.rb +0 -81
  133. data/spec/extensions/exclude_or_null_spec.rb +0 -15
  134. data/spec/extensions/finder_spec.rb +0 -260
  135. data/spec/extensions/force_encoding_spec.rb +0 -126
  136. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  137. data/spec/extensions/graph_each_spec.rb +0 -113
  138. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  139. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  140. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  141. data/spec/extensions/index_caching_spec.rb +0 -66
  142. data/spec/extensions/inflector_spec.rb +0 -183
  143. data/spec/extensions/input_transformer_spec.rb +0 -69
  144. data/spec/extensions/insert_conflict_spec.rb +0 -103
  145. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  146. data/spec/extensions/instance_filters_spec.rb +0 -79
  147. data/spec/extensions/instance_hooks_spec.rb +0 -246
  148. data/spec/extensions/integer64_spec.rb +0 -22
  149. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  150. data/spec/extensions/json_serializer_spec.rb +0 -346
  151. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  152. data/spec/extensions/list_spec.rb +0 -291
  153. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  154. data/spec/extensions/many_through_many_spec.rb +0 -2177
  155. data/spec/extensions/migration_spec.rb +0 -864
  156. data/spec/extensions/modification_detection_spec.rb +0 -93
  157. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  158. data/spec/extensions/named_timezones_spec.rb +0 -218
  159. data/spec/extensions/nested_attributes_spec.rb +0 -815
  160. data/spec/extensions/null_dataset_spec.rb +0 -85
  161. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  162. data/spec/extensions/pagination_spec.rb +0 -116
  163. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  164. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  165. data/spec/extensions/pg_array_spec.rb +0 -398
  166. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -209
  167. data/spec/extensions/pg_enum_spec.rb +0 -118
  168. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  169. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  170. data/spec/extensions/pg_hstore_spec.rb +0 -219
  171. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  172. data/spec/extensions/pg_inet_spec.rb +0 -72
  173. data/spec/extensions/pg_interval_spec.rb +0 -103
  174. data/spec/extensions/pg_json_ops_spec.rb +0 -356
  175. data/spec/extensions/pg_json_spec.rb +0 -451
  176. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  177. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  178. data/spec/extensions/pg_range_spec.rb +0 -600
  179. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  180. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  181. data/spec/extensions/pg_row_spec.rb +0 -363
  182. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  183. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  184. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  185. data/spec/extensions/prepared_statements_spec.rb +0 -177
  186. data/spec/extensions/pretty_table_spec.rb +0 -123
  187. data/spec/extensions/query_spec.rb +0 -94
  188. data/spec/extensions/rcte_tree_spec.rb +0 -387
  189. data/spec/extensions/round_timestamps_spec.rb +0 -39
  190. data/spec/extensions/s_spec.rb +0 -60
  191. data/spec/extensions/schema_caching_spec.rb +0 -64
  192. data/spec/extensions/schema_dumper_spec.rb +0 -870
  193. data/spec/extensions/select_remove_spec.rb +0 -38
  194. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  195. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  196. data/spec/extensions/serialization_spec.rb +0 -365
  197. data/spec/extensions/server_block_spec.rb +0 -135
  198. data/spec/extensions/server_logging_spec.rb +0 -45
  199. data/spec/extensions/sharding_spec.rb +0 -197
  200. data/spec/extensions/shared_caching_spec.rb +0 -151
  201. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  202. data/spec/extensions/singular_table_names_spec.rb +0 -22
  203. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  204. data/spec/extensions/spec_helper.rb +0 -70
  205. data/spec/extensions/split_array_nil_spec.rb +0 -24
  206. data/spec/extensions/split_values_spec.rb +0 -57
  207. data/spec/extensions/sql_comments_spec.rb +0 -33
  208. data/spec/extensions/sql_expr_spec.rb +0 -59
  209. data/spec/extensions/static_cache_cache_spec.rb +0 -35
  210. data/spec/extensions/static_cache_spec.rb +0 -471
  211. data/spec/extensions/string_agg_spec.rb +0 -90
  212. data/spec/extensions/string_date_time_spec.rb +0 -95
  213. data/spec/extensions/string_stripper_spec.rb +0 -68
  214. data/spec/extensions/subclasses_spec.rb +0 -79
  215. data/spec/extensions/subset_conditions_spec.rb +0 -38
  216. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  217. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  218. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  219. data/spec/extensions/table_select_spec.rb +0 -83
  220. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  221. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  222. data/spec/extensions/throw_failures_spec.rb +0 -74
  223. data/spec/extensions/timestamps_spec.rb +0 -209
  224. data/spec/extensions/to_dot_spec.rb +0 -153
  225. data/spec/extensions/touch_spec.rb +0 -226
  226. data/spec/extensions/tree_spec.rb +0 -334
  227. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  228. data/spec/extensions/unlimited_update_spec.rb +0 -21
  229. data/spec/extensions/update_or_create_spec.rb +0 -83
  230. data/spec/extensions/update_primary_key_spec.rb +0 -105
  231. data/spec/extensions/update_refresh_spec.rb +0 -59
  232. data/spec/extensions/uuid_spec.rb +0 -101
  233. data/spec/extensions/validate_associated_spec.rb +0 -52
  234. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  235. data/spec/extensions/validation_contexts_spec.rb +0 -31
  236. data/spec/extensions/validation_helpers_spec.rb +0 -525
  237. data/spec/extensions/whitelist_security_spec.rb +0 -157
  238. data/spec/extensions/xml_serializer_spec.rb +0 -213
  239. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  240. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  241. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  242. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  243. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  244. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  245. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  246. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  247. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  248. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  249. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  250. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  251. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  252. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  253. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  254. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  255. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  256. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  257. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  258. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  259. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  260. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  261. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  262. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  263. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  264. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  265. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  266. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  267. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  268. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  269. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  270. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  271. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  272. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  273. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  274. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  275. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  276. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  277. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  278. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  279. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  280. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  281. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  282. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  283. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  284. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  285. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  286. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  287. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  288. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  289. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  290. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  291. data/spec/guards_helper.rb +0 -59
  292. data/spec/integration/associations_test.rb +0 -2597
  293. data/spec/integration/database_test.rb +0 -113
  294. data/spec/integration/dataset_test.rb +0 -2037
  295. data/spec/integration/eager_loader_test.rb +0 -687
  296. data/spec/integration/migrator_test.rb +0 -262
  297. data/spec/integration/model_test.rb +0 -203
  298. data/spec/integration/plugin_test.rb +0 -2423
  299. data/spec/integration/prepared_statement_test.rb +0 -405
  300. data/spec/integration/schema_test.rb +0 -903
  301. data/spec/integration/spec_helper.rb +0 -71
  302. data/spec/integration/timezone_test.rb +0 -86
  303. data/spec/integration/transaction_test.rb +0 -603
  304. data/spec/integration/type_test.rb +0 -127
  305. data/spec/model/association_reflection_spec.rb +0 -803
  306. data/spec/model/associations_spec.rb +0 -4738
  307. data/spec/model/base_spec.rb +0 -875
  308. data/spec/model/class_dataset_methods_spec.rb +0 -146
  309. data/spec/model/dataset_methods_spec.rb +0 -198
  310. data/spec/model/eager_loading_spec.rb +0 -2377
  311. data/spec/model/hooks_spec.rb +0 -370
  312. data/spec/model/inflector_spec.rb +0 -26
  313. data/spec/model/model_spec.rb +0 -956
  314. data/spec/model/plugins_spec.rb +0 -429
  315. data/spec/model/record_spec.rb +0 -2118
  316. data/spec/model/spec_helper.rb +0 -46
  317. data/spec/model/validations_spec.rb +0 -220
  318. data/spec/model_no_assoc_spec.rb +0 -1
  319. data/spec/model_spec.rb +0 -1
  320. data/spec/plugin_spec.rb +0 -1
  321. data/spec/sequel_coverage.rb +0 -15
  322. data/spec/sequel_warning.rb +0 -5
  323. data/spec/spec_config.rb +0 -12
@@ -1,405 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Prepared Statements and Bound Arguments" do
4
- before do
5
- @db = DB
6
- @db.create_table!(:items) do
7
- primary_key :id
8
- integer :numb
9
- end
10
- @c = Class.new(Sequel::Model(:items))
11
- @ds = @db[:items]
12
- @ds.insert(:numb=>10)
13
- @pr = @ds.requires_placeholder_type_specifiers? ? proc{|i| :"#{i}__integer"} : proc{|i| i}
14
- end
15
- after do
16
- @db.drop_table?(:items)
17
- end
18
-
19
- it "should support bound variables when selecting" do
20
- @ds.filter(:numb=>:$n).call(:each, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
21
- @ds.filter(:numb=>:$n).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
22
- @ds.filter(:numb=>:$n).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
23
- @ds.filter(:numb=>:$n).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
24
- @ds.select(:numb).filter(:numb=>:$n).call(:single_value, :n=>10).must_equal(10)
25
- @ds.filter(:numb=>:$n).call([:map, :numb], :n=>10).must_equal [10]
26
- @ds.filter(:numb=>:$n).call([:as_hash, :id, :numb], :n=>10).must_equal(1=>10)
27
- @ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).must_equal(1=>10)
28
- @ds.filter(:numb=>:$n).call([:to_hash_groups, :id, :numb], :n=>10).must_equal(1=>[10])
29
- end
30
-
31
- it "should support blocks for each, select, all, and map when using bound variables" do
32
- a = []
33
- @ds.filter(:numb=>:$n).call(:each, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
34
- @ds.filter(:numb=>:$n).call(:select, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
35
- @ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
36
- @ds.filter(:numb=>:$n).call([:map], :n=>10){|r| r[:numb] * 2}.must_equal [20]
37
- end
38
-
39
- it "should support binding variables before the call with #bind" do
40
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
41
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
42
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
43
- @ds.select(:numb).filter(:numb=>:$n).bind(:n=>10).call(:single_value).must_equal(10)
44
-
45
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:select).must_equal [{:id=>1, :numb=>10}]
46
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:all).must_equal [{:id=>1, :numb=>10}]
47
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:first).must_equal(:id=>1, :numb=>10)
48
- @ds.bind(:n=>10).select(:numb).filter(:numb=>:$n).call(:single_value).must_equal(10)
49
- end
50
-
51
- it "should allow overriding variables specified with #bind" do
52
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
53
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
54
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
55
- @ds.select(:numb).filter(:numb=>:$n).bind(:n=>1).call(:single_value, :n=>10).must_equal(10)
56
-
57
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
58
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
59
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
60
- @ds.select(:numb).filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:single_value).must_equal(10)
61
- end
62
-
63
- it "should support placeholder literal strings with call" do
64
- @ds.filter(Sequel.lit("numb = ?", :$n)).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
65
- end
66
-
67
- it "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
68
- @ds.filter(Sequel.lit("numb = :n", :n=>:$n)).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
69
- @ds.insert(:numb=>20)
70
- @ds.insert(:numb=>30)
71
- @ds.filter(Sequel.lit("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).must_equal [{:id=>2, :numb=>20}]
72
- end
73
-
74
- it "should support datasets with static sql and placeholders with call" do
75
- @db["SELECT * FROM items WHERE numb = ?", :$n].call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
76
- end
77
-
78
- it "should support subselects with call" do
79
- @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
80
- end
81
-
82
- it "should support subselects with exists with call" do
83
- @ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
84
- end
85
-
86
- it "should support subselects with literal strings with call" do
87
- @ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter(Sequel.lit("numb = ?", :$n))).call(:select, :n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
88
- end
89
-
90
- it "should support subselects with static sql and placeholders with call" do
91
- @ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).call(:select, :n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
92
- end
93
-
94
- it "should support subselects of subselects with call" do
95
- @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
96
- end
97
-
98
- cspecify "should support using a bound variable for a limit and offset", [:jdbc, :db2] do
99
- @ds.insert(:numb=>20)
100
- ds = @ds.limit(:$n, :$n2).order(:id)
101
- ds.call(:select, :n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
102
- ds.call(:select, :n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
103
- ds.call(:select, :n=>1, :n2=>2).must_equal []
104
- ds.call(:select, :n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
105
- ds.call(:select, :n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
106
- end
107
-
108
- it "should support bound variables with insert" do
109
- @ds.call(:insert, {:n=>20}, :numb=>:$n)
110
- @ds.count.must_equal 2
111
- @ds.order(:id).map(:numb).must_equal [10, 20]
112
- end
113
-
114
- it "should support bound variables with NULL values" do
115
- @ds.delete
116
- @ds.call(:insert, {:n=>nil}, :numb=>@pr[:$n])
117
- @ds.count.must_equal 1
118
- @ds.map(:numb).must_equal [nil]
119
- end
120
-
121
- it "should have insert return primary key value when using bound arguments" do
122
- @ds.call(:insert, {:n=>20}, :numb=>:$n).must_equal 2
123
- @ds.filter(:id=>2).first[:numb].must_equal 20
124
- end
125
-
126
- it "should support bound variables with insert_select" do
127
- @ds.call(:insert_select, {:n=>20}, :numb=>:$n).must_equal(:id=>2, :numb=>20)
128
- @ds.count.must_equal 2
129
- @ds.order(:id).map(:numb).must_equal [10, 20]
130
- end if DB.dataset.supports_insert_select?
131
-
132
- it "should support bound variables with insert returning" do
133
- @ds.returning.call(:insert, {:n=>20}, :numb=>:$n).must_equal([{:id=>2, :numb=>20}])
134
- @ds.count.must_equal 2
135
- @ds.order(:id).map(:numb).must_equal [10, 20]
136
- end if DB.dataset.supports_returning?(:insert)
137
-
138
- it "should support bound variables with update returning" do
139
- @ds.returning.call(:update, {:n=>20}, :numb=>:$n).must_equal([{:id=>1, :numb=>20}])
140
- @ds.count.must_equal 1
141
- @ds.order(:id).map(:numb).must_equal [20]
142
- end if DB.dataset.supports_returning?(:update)
143
-
144
- it "should support bound variables with delete returning" do
145
- @ds.where(:id=>:$id).returning.call(:delete, :id=>1).must_equal([{:id=>1, :numb=>10}])
146
- @ds.count.must_equal 0
147
- end if DB.dataset.supports_returning?(:delete)
148
-
149
- it "should support bound variables with delete" do
150
- @ds.filter(:numb=>:$n).call(:delete, :n=>10).must_equal 1
151
- @ds.count.must_equal 0
152
- end
153
-
154
- it "should support bound variables with update" do
155
- @ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb=>Sequel.+(:numb, :$nn)).must_equal 1
156
- @ds.all.must_equal [{:id=>1, :numb=>30}]
157
- end
158
-
159
- it "should support prepared statements when selecting" do
160
- @ds.filter(:numb=>:$n).prepare(:each, :select_n)
161
- @db.call(:select_n, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
162
- @ds.filter(:numb=>:$n).prepare(:select, :select_n)
163
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
164
- @ds.filter(:numb=>:$n).prepare(:all, :select_n)
165
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
166
- @ds.filter(:numb=>:$n).prepare(:first, :select_n)
167
- @db.call(:select_n, :n=>10).must_equal(:id=>1, :numb=>10)
168
- @ds.select(:numb).filter(:numb=>:$n).prepare(:single_value, :select_n)
169
- @db.call(:select_n, :n=>10).must_equal(10)
170
- @ds.filter(:numb=>:$n).prepare([:map, :numb], :select_n)
171
- @db.call(:select_n, :n=>10).must_equal [10]
172
- @ds.filter(:numb=>:$n).prepare([:as_hash, :id, :numb], :select_n)
173
- @db.call(:select_n, :n=>10).must_equal(1=>10)
174
- @ds.filter(:numb=>:$n).prepare([:to_hash, :id, :numb], :select_n)
175
- @db.call(:select_n, :n=>10).must_equal(1=>10)
176
- end
177
-
178
- it "should support blocks for each, select, all, and map when using prepared statements" do
179
- a = []
180
- @ds.filter(:numb=>:$n).prepare(:each, :select_n).call(:n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
181
- a = []
182
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
183
- @ds.filter(:numb=>:$n).prepare(:select, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
184
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
185
- @ds.filter(:numb=>:$n).prepare(:all, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
186
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
187
- @ds.filter(:numb=>:$n).prepare([:map], :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [20]
188
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [20]
189
- end
190
-
191
- it "should support prepared statements being called multiple times with different arguments" do
192
- @ds.filter(:numb=>:$n).prepare(:select, :select_n)
193
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
194
- @db.call(:select_n, :n=>0).must_equal []
195
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
196
- end
197
-
198
- it "should support placeholder literal strings with prepare" do
199
- @ds.filter(Sequel.lit("numb = ?", :$n)).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
200
- end
201
-
202
- it "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
203
- @ds.filter(Sequel.lit("numb = :n", :n=>:$n)).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
204
- @ds.insert(:numb=>20)
205
- @ds.insert(:numb=>30)
206
- @ds.filter(Sequel.lit("numb > :n1 AND numb < :n2 AND numb = :n3", :n3=>:$n3, :n2=>:$n2, :n1=>:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).must_equal [{:id=>2, :numb=>20}]
207
- end
208
-
209
- it "should support datasets with static sql and placeholders with prepare" do
210
- @db["SELECT * FROM items WHERE numb = ?", :$n].prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
211
- end
212
-
213
- it "should support subselects with prepare" do
214
- @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n)).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
215
- end
216
-
217
- it "should support subselects with exists with prepare" do
218
- @ds.filter(:id=>:$i).filter(@ds.select(:numb).filter(:numb=>:$n).exists).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
219
- end
220
-
221
- it "should support subselects with literal strings with prepare" do
222
- @ds.filter(:id=>:$i, :numb=>@ds.select(:numb).filter(Sequel.lit("numb = ?", :$n))).prepare(:select, :seq_select).call(:n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
223
- end
224
-
225
- it "should support subselects with static sql and placeholders with prepare" do
226
- @ds.filter(:id=>:$i, :numb=>@db["SELECT numb FROM items WHERE numb = ?", :$n]).prepare(:select, :seq_select).call(:n=>10, :i=>1).must_equal [{:id=>1, :numb=>10}]
227
- end
228
-
229
- it "should support subselects of subselects with prepare" do
230
- @ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
231
- end
232
-
233
- cspecify "should support using a prepared_statement for a limit and offset", :db2 do
234
- @ds.insert(:numb=>20)
235
- ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
236
- ps.call(:n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
237
- ps.call(:n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
238
- ps.call(:n=>1, :n2=>2).must_equal []
239
- ps.call(:n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
240
- ps.call(:n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
241
- end
242
-
243
- it "should support prepared statements with insert" do
244
- @ds.prepare(:insert, :insert_n, :numb=>:$n)
245
- @db.call(:insert_n, :n=>20)
246
- @ds.count.must_equal 2
247
- @ds.order(:id).map(:numb).must_equal [10, 20]
248
- end
249
-
250
- it "should support prepared statements with NULL values" do
251
- @ds.delete
252
- @ds.prepare(:insert, :insert_n, :numb=>@pr[:$n])
253
- @db.call(:insert_n, :n=>nil)
254
- @ds.count.must_equal 1
255
- @ds.map(:numb).must_equal [nil]
256
- end
257
-
258
- it "should have insert return primary key value when using prepared statements" do
259
- @ds.prepare(:insert, :insert_n, :numb=>:$n)
260
- @db.call(:insert_n, :n=>20).must_equal 2
261
- @ds.filter(:id=>2).first[:numb].must_equal 20
262
- end
263
-
264
- it "should support prepared_statements with insert_select" do
265
- @ds.prepare(:insert_select, :insert_select_n, :numb=>:$n).call(:n=>20).must_equal(:id=>2, :numb=>20)
266
- @ds.count.must_equal 2
267
- @ds.order(:id).map(:numb).must_equal [10, 20]
268
- end if DB.dataset.supports_insert_select?
269
-
270
- it "should support bound variables with insert returning" do
271
- @ds.returning.prepare(:insert, :insert_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>2, :numb=>20}])
272
- @ds.count.must_equal 2
273
- @ds.order(:id).map(:numb).must_equal [10, 20]
274
- end if DB.dataset.supports_returning?(:insert)
275
-
276
- it "should support bound variables with update returning" do
277
- @ds.returning.prepare(:update, :update_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>1, :numb=>20}])
278
- @ds.count.must_equal 1
279
- @ds.order(:id).map(:numb).must_equal [20]
280
- end if DB.dataset.supports_returning?(:update)
281
-
282
- it "should support bound variables with delete returning" do
283
- @ds.where(:id=>:$id).returning.prepare(:delete, :delete_rn).call(:id=>1).must_equal([{:id=>1, :numb=>10}])
284
- @ds.count.must_equal 0
285
- end if DB.dataset.supports_returning?(:delete)
286
-
287
- it "should support prepared statements with delete" do
288
- @ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
289
- @db.call(:delete_n, :n=>10).must_equal 1
290
- @ds.count.must_equal 0
291
- end
292
-
293
- it "should support prepared statements with update" do
294
- @ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb=>Sequel.+(:numb, :$nn))
295
- @db.call(:update_n, :n=>10, :nn=>20).must_equal 1
296
- @ds.all.must_equal [{:id=>1, :numb=>30}]
297
- end
298
-
299
- it "model datasets should return model instances when using select, all, and first with bound variables" do
300
- @c.filter(:numb=>:$n).call(:select, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
301
- @c.filter(:numb=>:$n).call(:all, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
302
- @c.filter(:numb=>:$n).call(:first, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
303
- end
304
-
305
- it "model datasets should return model instances when using select, all, and first with prepared statements" do
306
- @c.filter(:numb=>:$n).prepare(:select, :select_n1)
307
- @db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
308
- @c.filter(:numb=>:$n).prepare(:all, :select_n1)
309
- @db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
310
- @c.filter(:numb=>:$n).prepare(:first, :select_n1)
311
- @db.call(:select_n1, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
312
- end
313
- end
314
-
315
- describe "Bound Argument Types" do
316
- before(:all) do
317
- @db = DB
318
- @db.create_table!(:items) do
319
- primary_key :id
320
- Date :d
321
- DateTime :dt
322
- File :file
323
- String :s
324
- Time :t
325
- Float :f
326
- TrueClass :b
327
- end
328
- @ds = @db[:items]
329
- @vs = {:d=>Date.civil(2010, 10, 11), :dt=>DateTime.civil(2010, 10, 12, 13, 14, 15), :f=>1.0, :s=>'str', :t=>Time.at(Time.now.to_i), :file=>Sequel::SQL::Blob.new('blob'), :b=>true}
330
- end
331
- before do
332
- @ds.delete
333
- @ds.insert(@vs)
334
- end
335
- after do
336
- Sequel.datetime_class = Time
337
- end
338
- after(:all) do
339
- @db.drop_table?(:items)
340
- end
341
-
342
- cspecify "should handle date type", [:tinytds], [:jdbc, :mssql], [:jdbc, :sqlite], :oracle do
343
- @ds.filter(:d=>:$x).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].must_equal @vs[:d]
344
- end
345
-
346
- cspecify "should handle datetime type", [:mysql2], [:jdbc, :sqlite], [:tinytds], [:oracle] do
347
- Sequel.datetime_class = DateTime
348
- @ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].must_equal @vs[:dt]
349
- end
350
-
351
- cspecify "should handle datetime type with fractional seconds", [:jdbc, :sqlite], [:jdbc, :mysql], [:oracle] do
352
- Sequel.datetime_class = DateTime
353
- fract_time = DateTime.parse('2010-10-12 13:14:15.500000')
354
- @ds.prepare(:update, :ps_datetime_up, :dt=>:$x).call(:x=>fract_time)
355
- @ds.literal(@ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>fract_time)[:dt]).must_equal @ds.literal(fract_time)
356
- end
357
-
358
- cspecify "should handle time type", [:jdbc, :sqlite] do
359
- @ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].must_equal @vs[:t]
360
- end
361
-
362
- cspecify "should handle time type with fractional seconds", [:jdbc, :sqlite], [:jdbc, :mysql] do
363
- fract_time = @vs[:t] + 0.5
364
- @ds.prepare(:update, :ps_time_up, :t=>:$x).call(:x=>fract_time)
365
- @ds.literal(@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>fract_time)[:t]).must_equal @ds.literal(fract_time)
366
- end
367
-
368
- cspecify "should handle blob type", [:odbc] do
369
- @ds.delete
370
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>@vs[:file])
371
- @ds.get(:file).must_equal @vs[:file]
372
- end
373
-
374
- cspecify "should handle blob type with special characters", [:odbc] do
375
- @ds.delete
376
- blob = Sequel.blob("\"'[]`a0 ")
377
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>blob)
378
- @ds.get(:file).must_equal blob
379
- end
380
-
381
- cspecify "should handle blob type with nil values", [:oracle], [:tinytds], [:jdbc, :mssql] do
382
- @ds.delete
383
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>nil)
384
- @ds.get(:file).must_be_nil
385
- end
386
-
387
- cspecify "should handle blob type with embedded zeros", [:odbc] do
388
- zero_blob = Sequel::SQL::Blob.new("a\0"*100)
389
- @ds.delete
390
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>zero_blob)
391
- @ds.get(:file).must_equal zero_blob
392
- end
393
-
394
- it "should handle float type" do
395
- @ds.filter(:f=>:$x).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].must_equal @vs[:f]
396
- end
397
-
398
- it "should handle string type" do
399
- @ds.filter(:s=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].must_equal @vs[:s]
400
- end
401
-
402
- cspecify "should handle boolean type", [:jdbc, :sqlite], [:jdbc, :db2], :oracle do
403
- @ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].must_equal @vs[:b]
404
- end
405
- end
@@ -1,903 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "Database schema parser" do
4
- after do
5
- DB.drop_table?(:items)
6
- end
7
-
8
- describe "with identifier mangling" do
9
- before do
10
- @iom = DB.identifier_output_method
11
- @iim = DB.identifier_input_method
12
- @qi = DB.quote_identifiers?
13
- end
14
- after do
15
- DB.identifier_output_method = @iom
16
- DB.identifier_input_method = @iim
17
- DB.quote_identifiers = @qi
18
- end
19
-
20
- it "should handle a database with a identifier methods" do
21
- DB.identifier_output_method = :reverse
22
- DB.identifier_input_method = :reverse
23
- DB.quote_identifiers = true
24
- DB.create_table!(:items){Integer :number}
25
- begin
26
- DB.schema(:items, :reload=>true).must_be_kind_of(Array)
27
- DB.schema(:items, :reload=>true).first.first.must_equal :number
28
- ensure
29
- end
30
- end
31
-
32
- it "should handle a dataset with identifier methods different than the database's" do
33
- DB.identifier_output_method = :reverse
34
- DB.identifier_input_method = :reverse
35
- DB.quote_identifiers = true
36
- DB.create_table!(:items){Integer :number}
37
- DB.identifier_output_method = @iom
38
- DB.identifier_input_method = @iim
39
- ds = DB[:items].
40
- with_identifier_output_method(:reverse).
41
- with_identifier_input_method(:reverse)
42
- begin
43
- DB.schema(ds, :reload=>true).must_be_kind_of(Array)
44
- DB.schema(ds, :reload=>true).first.first.must_equal :number
45
- ensure
46
- DB.identifier_output_method = :reverse
47
- DB.identifier_input_method = :reverse
48
- DB.drop_table(:items)
49
- end
50
- end
51
- end if IDENTIFIER_MANGLING && !DB.frozen?
52
-
53
- it "should not issue an sql query if the schema has been loaded unless :reload is true" do
54
- DB.create_table!(:items){Integer :number}
55
- DB.schema(:items, :reload=>true)
56
- DB.schema(:items)
57
- DB.schema(:items, :reload=>true)
58
- end
59
-
60
- it "Model schema should include columns in the table, even if they aren't selected" do
61
- DB.create_table!(:items){String :a; Integer :number}
62
- m = Sequel::Model(DB[:items].select(:a))
63
- m.columns.must_equal [:a]
64
- m.db_schema[:number][:type].must_equal :integer
65
- end
66
-
67
- it "should raise an error when the table doesn't exist" do
68
- proc{DB.schema(:no_table)}.must_raise(Sequel::Error, Sequel::DatabaseError)
69
- end
70
-
71
- it "should return the schema correctly" do
72
- DB.create_table!(:items){Integer :number}
73
- schema = DB.schema(:items, :reload=>true)
74
- schema.must_be_kind_of(Array)
75
- schema.length.must_equal 1
76
- col = schema.first
77
- col.must_be_kind_of(Array)
78
- col.length.must_equal 2
79
- col.first.must_equal :number
80
- col_info = col.last
81
- col_info.must_be_kind_of(Hash)
82
- col_info[:type].must_equal :integer
83
- DB.schema(:items)
84
- end
85
-
86
- it "should parse primary keys from the schema properly" do
87
- DB.create_table!(:items){Integer :number}
88
- DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.must_equal []
89
- DB.create_table!(:items){primary_key :number}
90
- DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.must_equal [:number]
91
- DB.create_table!(:items){Integer :number1; Integer :number2; primary_key [:number1, :number2]}
92
- DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.must_equal [:number1, :number2]
93
- end
94
-
95
- cspecify "should parse autoincrementing primary keys from the schema properly", :sqlite, :oracle do
96
- DB.create_table!(:items){Integer :number}
97
- DB.schema(:items).collect{|k,v| k if v[:primary_key] && v[:auto_increment]}.compact.must_equal []
98
- DB.create_table!(:items){primary_key :number}
99
- DB.schema(:items).collect{|k,v| k if v[:primary_key] && v[:auto_increment]}.compact.must_equal [:number]
100
- DB.create_table!(:items){Integer :number, :primary_key=>true}
101
- DB.schema(:items).collect{|k,v| k if v[:primary_key] && v[:auto_increment]}.compact.must_equal []
102
- end
103
-
104
- it "should parse NULL/NOT NULL from the schema properly" do
105
- DB.create_table!(:items){Integer :number, :null=>true}
106
- DB.schema(:items).first.last[:allow_null].must_equal true
107
- DB.create_table!(:items){Integer :number, :null=>false}
108
- DB.schema(:items).first.last[:allow_null].must_equal false
109
- end
110
-
111
- it "should parse defaults from the schema properly" do
112
- DB.create_table!(:items){Integer :number}
113
- DB.schema(:items).first.last[:ruby_default].must_be_nil
114
- DB.create_table!(:items){Integer :number, :default=>0}
115
- DB.schema(:items).first.last[:ruby_default].must_equal 0
116
- DB.create_table!(:items){String :a, :default=>"blah"}
117
- DB.schema(:items).first.last[:ruby_default].must_equal 'blah'
118
- end
119
-
120
- it "should make :default nil for a NULL default" do
121
- DB.create_table!(:items){Integer :number}
122
- DB.schema(:items).first.last[:default].must_be_nil
123
- DB.create_table!(:items){Integer :number, :default=>0}
124
- DB.schema(:items).first.last[:default].wont_equal nil
125
- end
126
-
127
- it "should parse current timestamp defaults from the schema properly" do
128
- DB.create_table!(:items){Time :a, :default=>Sequel::CURRENT_TIMESTAMP}
129
- DB.schema(:items).first.last[:ruby_default].must_equal Sequel::CURRENT_TIMESTAMP
130
- end
131
-
132
- cspecify "should parse current date defaults from the schema properly", [proc{|db| !db.mariadb? || db.server_version <= 100200}, :mysql], :oracle do
133
- DB.create_table!(:items){Date :a, :default=>Sequel::CURRENT_DATE}
134
- DB.schema(:items).first.last[:ruby_default].must_equal Sequel::CURRENT_DATE
135
- end
136
-
137
- cspecify "should parse types from the schema properly", [:jdbc, :db2], :oracle do
138
- DB.create_table!(:items){Integer :number}
139
- DB.schema(:items).first.last[:type].must_equal :integer
140
- DB.create_table!(:items){Fixnum :number}
141
- DB.schema(:items).first.last[:type].must_equal :integer
142
- DB.create_table!(:items){Bignum :number}
143
- DB.schema(:items).first.last[:type].must_equal :integer
144
- DB.create_table!(:items){Float :number}
145
- DB.schema(:items).first.last[:type].must_equal :float
146
- DB.create_table!(:items){BigDecimal :number, :size=>[11, 2]}
147
- DB.schema(:items).first.last[:type].must_equal :decimal
148
- DB.create_table!(:items){Numeric :number, :size=>[12, 0]}
149
- DB.schema(:items).first.last[:type].must_equal :integer
150
- DB.create_table!(:items){String :number}
151
- DB.schema(:items).first.last[:type].must_equal :string
152
- DB.create_table!(:items){Date :number}
153
- DB.schema(:items).first.last[:type].must_equal :date
154
- DB.create_table!(:items){Time :number}
155
- DB.schema(:items).first.last[:type].must_equal :datetime
156
- DB.create_table!(:items){DateTime :number}
157
- DB.schema(:items).first.last[:type].must_equal :datetime
158
- DB.create_table!(:items){File :number}
159
- DB.schema(:items).first.last[:type].must_equal :blob
160
- DB.create_table!(:items){TrueClass :number}
161
- DB.schema(:items).first.last[:type].must_equal :boolean
162
- DB.create_table!(:items){FalseClass :number}
163
- DB.schema(:items).first.last[:type].must_equal :boolean
164
- end
165
-
166
- it "should round trip database types from the schema properly" do
167
- DB.create_table!(:items){String :number, :size=>50}
168
- db_type = DB.schema(:items).first.last[:db_type]
169
- DB.create_table!(:items){column :number, db_type}
170
- DB.schema(:items).first.last[:db_type].must_equal db_type
171
-
172
- DB.create_table!(:items){Numeric :number, :size=>[11,3]}
173
- db_type = DB.schema(:items).first.last[:db_type]
174
- DB.create_table!(:items){column :number, db_type}
175
- DB.schema(:items).first.last[:db_type].must_equal db_type
176
- end
177
-
178
- it "should parse maximum length for string columns" do
179
- DB.create_table!(:items){String :a, :size=>4}
180
- DB.schema(:items).first.last[:max_length].must_equal 4
181
- DB.create_table!(:items){String :a, :fixed=>true, :size=>3}
182
- DB.schema(:items).first.last[:max_length].must_equal 3
183
- end
184
- end if DB.supports_schema_parsing?
185
-
186
- describe "Database index parsing" do
187
- after do
188
- DB.drop_table?(:items)
189
- end
190
-
191
- it "should parse indexes into a hash" do
192
- [:items, Sequel.identifier(:items)].each do |table|
193
- # Delete :deferrable entry, since not all adapters implement it
194
- f = lambda{h = DB.indexes(table); h.values.each{|h2| h2.delete(:deferrable)}; h}
195
-
196
- DB.create_table!(table){Integer :n; Integer :a}
197
- f.call.must_equal({})
198
- DB.add_index(table, :n)
199
- f.call.must_equal(:items_n_index=>{:columns=>[:n], :unique=>false})
200
- DB.drop_index(table, :n)
201
- f.call.must_equal({})
202
- DB.add_index(table, :n, :unique=>true, :name=>:blah_blah_index)
203
- f.call.must_equal(:blah_blah_index=>{:columns=>[:n], :unique=>true})
204
- DB.add_index(table, [:n, :a])
205
- f.call.must_equal(:blah_blah_index=>{:columns=>[:n], :unique=>true}, :items_n_a_index=>{:columns=>[:n, :a], :unique=>false})
206
- DB.drop_index(table, :n, :name=>:blah_blah_index)
207
- f.call.must_equal(:items_n_a_index=>{:columns=>[:n, :a], :unique=>false})
208
- DB.drop_index(table, [:n, :a])
209
- f.call.must_equal({})
210
- end
211
- end
212
-
213
- it "should not include a primary key index" do
214
- DB.create_table!(:items){primary_key :n}
215
- DB.indexes(:items).must_equal({})
216
- DB.create_table!(:items){Integer :n; Integer :a; primary_key [:n, :a]}
217
- DB.indexes(:items).must_equal({})
218
- end
219
-
220
- cspecify "should not include partial indexes", [proc{|db| db.sqlite_version < 30808}, :sqlite] do
221
- DB.create_table!(:items){Integer :n; Integer :a; index :n, :where=>proc{n > 10}}
222
- DB.indexes(:items).must_equal({})
223
- end if DB.supports_partial_indexes?
224
- end if DB.supports_index_parsing?
225
-
226
- describe "Database foreign key parsing" do
227
- before do
228
- @db = DB
229
- @pr = lambda do |table, *expected|
230
- actual = @db.foreign_key_list(table).sort_by{|c| c[:columns].map{|s| s.to_s}.join << (c[:key]||[]).map{|s| s.to_s}.join}.map{|v| v.values_at(:columns, :table, :key)}
231
- actual.zip(expected).each do |a, e|
232
- if e.last.first == :pk
233
- if a.last == nil
234
- a.pop
235
- e.pop
236
- else
237
- e.last.shift
238
- end
239
- end
240
- a.must_equal e
241
- end
242
- actual.length.must_equal expected.length
243
- end
244
- end
245
- after do
246
- @db.drop_table?(:b, :a)
247
- end
248
-
249
- it "should parse foreign key information into an array of hashes" do
250
- @db.create_table!(:a, :engine=>:InnoDB){primary_key :c; Integer :d, :null => false, :unique => true}
251
- @db.create_table!(:b, :engine=>:InnoDB){foreign_key :e, :a}
252
- @pr[:a]
253
- @pr[:b, [[:e], :a, [:pk, :c]]]
254
-
255
- @db.alter_table(:b){add_foreign_key :f, :a, :key=>[:d]}
256
- @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:d]]]
257
-
258
- @db.alter_table(:b){add_foreign_key [:f], :a, :key=>[:c]}
259
- @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:c]], [[:f], :a, [:d]]]
260
-
261
- @db.alter_table(:a){add_unique_constraint [:d, :c]}
262
- @db.alter_table(:b){add_foreign_key [:f, :e], :a, :key=>[:d, :c]}
263
- @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:c]], [[:f], :a, [:d]], [[:f, :e], :a, [:d, :c]]]
264
-
265
- @db.alter_table(:b){drop_foreign_key [:f, :e]}
266
- @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:c]], [[:f], :a, [:d]]]
267
-
268
- @db.alter_table(:b){drop_foreign_key :e}
269
- @pr[:b, [[:f], :a, [:c]], [[:f], :a, [:d]]]
270
-
271
- proc{@db.alter_table(:b){drop_foreign_key :f}}.must_raise(Sequel::Error, Sequel::DatabaseError)
272
- @pr[:b, [[:f], :a, [:c]], [[:f], :a, [:d]]]
273
- end
274
-
275
- it "should handle composite foreign and primary keys" do
276
- @db.create_table!(:a, :engine=>:InnoDB){Integer :b, :null=>false; Integer :c, :null=>false; Integer :d, :null=>false; primary_key [:b, :c]; unique [:d, :c]}
277
- @db.create_table!(:b, :engine=>:InnoDB){Integer :e, :null=>false; Integer :f, :null=>false; Integer :g, :null=>false; foreign_key [:e, :f], :a; foreign_key [:g, :f], :a, :key=>[:d, :c]}
278
- @pr[:b, [[:e, :f], :a, [:pk, :b, :c]], [[:g, :f], :a, [:d, :c]]]
279
- end
280
-
281
- it "should handle self-referential composite foreign and primary keys" do
282
- @db.create_table!(:a, :engine=>:InnoDB){Integer :b, :null=>false; Integer :c, :null=>false; Integer :d, :null=>false; primary_key [:b, :c]; unique [:d, :b]}
283
- @db.alter_table(:a){add_foreign_key [:b, :d], :a; add_foreign_key [:d, :c], :a; add_foreign_key [:c, :b], :a, :key=>[:d, :b]}
284
- @pr[:a, [[:b, :d], :a, [:pk, :b, :c]], [[:c, :b], :a, [:d, :b]], [[:d, :c], :a, [:pk, :b, :c]]]
285
- end
286
- end if DB.supports_foreign_key_parsing?
287
-
288
- describe "Database schema modifiers" do
289
- before do
290
- @db = DB
291
- @ds = @db[:items]
292
- end
293
- after do
294
- # Use instead of drop_table? to work around issues on jdbc/db2
295
- @db.drop_table(:items) rescue nil
296
- @db.drop_table(:items2) rescue nil
297
- end
298
-
299
- it "should create tables correctly" do
300
- @db.create_table!(:items){Integer :number}
301
- @db.table_exists?(:items).must_equal true
302
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
303
- @ds.insert([10])
304
- @ds.columns!.must_equal [:number]
305
- end
306
-
307
- it "should create tables from select statements correctly" do
308
- @db.create_table!(:items){Integer :number}
309
- @ds.insert([10])
310
- @db.create_table(:items2, :as=>@db[:items])
311
- @db.schema(:items2, :reload=>true).map{|x| x.first}.must_equal [:number]
312
- @db[:items2].columns.must_equal [:number]
313
- @db[:items2].all.must_equal [{:number=>10}]
314
- end
315
-
316
- it "should not raise an error if table doesn't exist when using drop_table :if_exists" do
317
- @db.drop_table(:items, :if_exists=>true)
318
- end if DB.supports_drop_table_if_exists?
319
-
320
- describe "views" do
321
- before do
322
- @db.drop_view(:items_view2) rescue nil
323
- @db.drop_view(:items_view) rescue nil
324
- @db.create_table!(:items){Integer :number}
325
- @ds.insert(:number=>1)
326
- @ds.insert(:number=>2)
327
- end
328
- after do
329
- @db.drop_view(:items_view2) rescue nil
330
- @db.drop_view(:items_view) rescue nil
331
- end
332
-
333
- it "should create views correctly" do
334
- @db.create_view(:items_view, @ds.where(:number=>1))
335
- @db[:items_view].map(:number).must_equal [1]
336
- end
337
-
338
- it "should create views with check options correctly" do
339
- @db.create_view(:items_view, @ds.where{number > 2}, :check=>true)
340
- proc{@db[:items_view].insert(1)}.must_raise(Sequel::DatabaseError)
341
- @db[:items_view].insert(3)
342
- @db[:items_view].select_order_map(:number).must_equal [3]
343
- @db.create_view(:items_view2, @db[:items_view].where{number > 1}, :check=>true)
344
- proc{@db[:items_view2].insert(1)}.must_raise(Sequel::DatabaseError)
345
- proc{@db[:items_view2].insert(2)}.must_raise(Sequel::DatabaseError)
346
- @db[:items_view2].insert(4)
347
- @db[:items_view2].select_order_map(:number).must_equal [3, 4]
348
- @ds.select_order_map(:number).must_equal [1, 2, 3, 4]
349
- end if DB.supports_views_with_check_option?
350
-
351
- it "should create views with local check options correctly" do
352
- @db.create_view(:items_view, @ds.where{number > 2})
353
- @db[:items_view].insert(3)
354
- @db[:items_view].select_order_map(:number).must_equal [3]
355
- @db.create_view(:items_view2, @db[:items_view].where{number > 1}, :check=>:local)
356
- proc{@db[:items_view2].insert(1)}.must_raise(Sequel::DatabaseError)
357
- @db[:items_view2].insert(2)
358
- @db[:items_view2].insert(4)
359
- @db[:items_view2].select_order_map(:number).must_equal [3, 4]
360
- @ds.select_order_map(:number).must_equal [1, 2, 2, 3, 4]
361
- end if DB.supports_views_with_local_check_option?
362
-
363
- cspecify "should create views with explicit columns correctly", [proc{|db| db.sqlite_version < 30900}, :sqlite] do
364
- @db.create_view(:items_view, @ds.where(:number=>1), :columns=>[:n])
365
- @db[:items_view].map(:n).must_equal [1]
366
- end
367
-
368
- it "should drop views correctly" do
369
- @db.create_view(:items_view, @ds.where(:number=>1))
370
- @db.drop_view(:items_view)
371
- proc{@db[:items_view].map(:number)}.must_raise(Sequel::DatabaseError)
372
- end
373
-
374
- it "should not raise an error if view doesn't exist when using drop_view :if_exists" do
375
- @db.drop_view(:items_view, :if_exists=>true)
376
- end if DB.supports_drop_table_if_exists?
377
-
378
- it "should create or replace views correctly" do
379
- @db.create_or_replace_view(:items_view, @ds.where(:number=>1))
380
- @db[:items_view].map(:number).must_equal [1]
381
- @db.create_or_replace_view(:items_view, @ds.where(:number=>2))
382
- @db[:items_view].map(:number).must_equal [2]
383
- end
384
- end
385
-
386
- it "should handle create table in a rolled back transaction" do
387
- @db.drop_table?(:items)
388
- @db.transaction(:rollback=>:always){@db.create_table(:items){Integer :number}}
389
- @db.table_exists?(:items).must_equal false
390
- end if DB.supports_transactional_ddl?
391
-
392
- it "should handle errors creating indexes when ignoring index errors" do
393
- @db.drop_table?(:items)
394
- @db.transaction do
395
- @db.create_table(:items, :ignore_index_errors=>true) do
396
- Integer :n1
397
- Integer :n2
398
- index :n1, :name=>'items_n1'
399
- index :foo, :name=>'items_f'
400
- index :n2, :name=>'items_n2'
401
- index :bar, :name=>'items_g'
402
- end
403
- end
404
- @db.table_exists?(:items).must_equal true
405
- indexes = @db.indexes(:items).keys
406
- indexes.must_include :items_n1
407
- indexes.must_include :items_n2
408
- indexes.wont_include :items_f
409
- indexes.wont_include :items_g
410
- end if DB.supports_transactional_ddl? && DB.database_type != :mssql
411
-
412
- describe "join tables" do
413
- after do
414
- @db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
415
- @db.drop_table(:cats, :dogs)
416
- @db.table_exists?(:cats_dogs).must_equal false
417
- end
418
-
419
- it "should create join tables correctly" do
420
- @db.create_table!(:cats){primary_key :id}
421
- @db.create_table!(:dogs){primary_key :id}
422
- @db.create_join_table(:cat_id=>:cats, :dog_id=>:dogs)
423
- @db.table_exists?(:cats_dogs).must_equal true
424
- end
425
- end
426
-
427
- it "should create temporary tables without raising an exception" do
428
- @db.create_table!(:items_temp, :temp=>true){Integer :number}
429
- end
430
-
431
- it "should have create_table? only create the table if it doesn't already exist" do
432
- @db.create_table!(:items){String :a}
433
- @db.create_table?(:items){String :b}
434
- @db[:items].columns.must_equal [:a]
435
- @db.drop_table?(:items)
436
- @db.create_table?(:items){String :b}
437
- @db[:items].columns.must_equal [:b]
438
- end
439
-
440
- it "should have create_table? work correctly with indexes" do
441
- @db.create_table!(:items){String :a, :index=>true}
442
- @db.create_table?(:items){String :b, :index=>true}
443
- @db[:items].columns.must_equal [:a]
444
- @db.drop_table?(:items)
445
- @db.create_table?(:items){String :b, :index=>true}
446
- @db[:items].columns.must_equal [:b]
447
- end
448
-
449
- it "should rename tables correctly" do
450
- @db.drop_table?(:items)
451
- @db.create_table!(:items2){Integer :number}
452
- @db.rename_table(:items2, :items)
453
- @db.table_exists?(:items).must_equal true
454
- @db.table_exists?(:items2).must_equal false
455
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
456
- @ds.insert([10])
457
- @ds.columns!.must_equal [:number]
458
- end
459
-
460
- it "should allow creating indexes with tables" do
461
- @db.create_table!(:items){Integer :number; index :number}
462
- @db.table_exists?(:items).must_equal true
463
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
464
- @ds.insert([10])
465
- @ds.columns!.must_equal [:number]
466
- end
467
-
468
- it "should allow creating partial indexes with tables" do
469
- @db.create_table!(:items){Integer :number; index :number, :where=>proc{number > 10}}
470
- @db.table_exists?(:items).must_equal true
471
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
472
- @ds.insert([10])
473
- @ds.columns!.must_equal [:number]
474
- end if DB.supports_partial_indexes?
475
-
476
- it "should handle combination of default, unique, and not null" do
477
- @db.create_table!(:items){Integer :number, :default=>0, :null=>false, :unique=>true}
478
- @db.table_exists?(:items).must_equal true
479
- @db.schema(:items, :reload=>true).map{|x| x.last}.first.values_at(:ruby_default, :allow_null).must_equal [0, false]
480
- @ds.insert([10])
481
- end
482
-
483
- it "should be able to specify constraint names for column constraints" do
484
- @db.create_table!(:items2){primary_key :id, :primary_key_constraint_name=>:foo_pk}
485
- @db.create_table!(:items){foreign_key :id, :items2, :unique=>true, :foreign_key_constraint_name => :foo_fk, :unique_constraint_name => :foo_uk, :null=>false}
486
- @db.alter_table(:items){drop_constraint :foo_fk, :type=>:foreign_key; drop_constraint :foo_uk, :type=>:unique}
487
- @db.alter_table(:items2){drop_constraint :foo_pk, :type=>:primary_key}
488
- end
489
-
490
- it "should handle foreign keys correctly when creating tables" do
491
- @db.create_table!(:items) do
492
- primary_key :id
493
- foreign_key :item_id, :items
494
- unique [:item_id, :id]
495
- foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
496
- end
497
- @db.table_exists?(:items).must_equal true
498
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
499
- @ds.columns!.must_equal [:id, :item_id]
500
- end
501
-
502
- it "should add columns to tables correctly" do
503
- @db.create_table!(:items){Integer :number}
504
- @ds.insert(:number=>10)
505
- @db.alter_table(:items){add_column :name, String}
506
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number, :name]
507
- @ds.columns!.must_equal [:number, :name]
508
- @ds.all.must_equal [{:number=>10, :name=>nil}]
509
- end
510
-
511
- cspecify "should add primary key columns to tables correctly", :derby do
512
- @db.create_table!(:items){Integer :number}
513
- @ds.insert(:number=>10)
514
- @db.alter_table(:items){add_primary_key :id}
515
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number, :id]
516
- @ds.columns!.must_equal [:number, :id]
517
- @ds.map(:number).must_equal [10]
518
- proc{@ds.insert(:id=>@ds.map(:id).first)}.must_raise Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
519
- end
520
-
521
- it "should drop primary key constraints from tables correctly" do
522
- @db.create_table!(:items){Integer :number; primary_key [:number], :name=>:items_pk}
523
- @ds.insert(:number=>10)
524
- @db.alter_table(:items){drop_constraint :items_pk, :type=>:primary_key}
525
- @ds.map(:number).must_equal [10]
526
- @ds.insert(10)
527
- end
528
-
529
- it "should add foreign key columns to tables correctly" do
530
- @db.create_table!(:items){primary_key :id}
531
- @ds.insert
532
- i = @ds.get(:id)
533
- @db.alter_table(:items){add_foreign_key :item_id, :items}
534
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
535
- @ds.columns!.must_equal [:id, :item_id]
536
- @ds.all.must_equal [{:id=>i, :item_id=>nil}]
537
- end
538
-
539
- it "should not allow NULLs in a primary key" do
540
- @db.create_table!(:items){String :id, :primary_key=>true}
541
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
542
- end
543
-
544
- it "should not allow NULLs when adding a primary key column" do
545
- @db.create_table!(:items){String :foo}
546
- @db.alter_table(:items){add_column :id, String, :primary_key=>true, :default=>'a'}
547
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
548
- end
549
-
550
- it "should not allow NULLs when creating table with primary key constraint" do
551
- @db.create_table!(:items){String :id1; String :id2; primary_key [:id1, :id2]}
552
- proc{@ds.insert(:id1=>nil, :id2=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
553
- proc{@ds.insert(:id1=>nil, :id2=>'1')}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
554
- proc{@ds.insert(:id1=>'1', :id2=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
555
- end
556
-
557
- it "should not allow NULLs when adding a primary key constraint" do
558
- @db.create_table!(:items){String :id1; String :id2}
559
- @db.alter_table(:items){add_primary_key [:id1, :id2]}
560
- proc{@ds.insert(:id1=>nil, :id2=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
561
- proc{@ds.insert(:id1=>nil, :id2=>'1')}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
562
- proc{@ds.insert(:id1=>'1', :id2=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
563
- end
564
-
565
- it "should rename columns correctly" do
566
- @db.create_table!(:items){Integer :id}
567
- @ds.insert(:id=>10)
568
- @db.alter_table(:items){rename_column :id, :id2}
569
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id2]
570
- @ds.columns!.must_equal [:id2]
571
- @ds.all.must_equal [{:id2=>10}]
572
- end
573
-
574
- it "should rename columns with defaults correctly" do
575
- @db.create_table!(:items){String :n, :default=>'blah'}
576
- @ds.insert
577
- @db.alter_table(:items){rename_column :n, :n2}
578
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:n2]
579
- @ds.columns!.must_equal [:n2]
580
- @ds.insert
581
- @ds.all.must_equal [{:n2=>'blah'}, {:n2=>'blah'}]
582
- end
583
-
584
- it "should rename columns with not null constraints" do
585
- @db.create_table!(:items, :engine=>:InnoDB){String :n, :null=>false}
586
- @ds.insert(:n=>'blah')
587
- @db.alter_table(:items){rename_column :n, :n2}
588
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:n2]
589
- @ds.columns!.must_equal [:n2]
590
- @ds.insert(:n2=>'blah')
591
- @ds.all.must_equal [{:n2=>'blah'}, {:n2=>'blah'}]
592
- proc{@ds.insert(:n=>nil)}.must_raise(Sequel::DatabaseError)
593
- end
594
-
595
- it "should rename columns when the table is referenced by a foreign key" do
596
- @db.create_table!(:items2){primary_key :id; Integer :a}
597
- @db.create_table!(:items){Integer :id, :primary_key=>true; foreign_key :items_id, :items2}
598
- @db[:items2].insert(:a=>10)
599
- @ds.insert(:id=>1)
600
- @db.alter_table(:items2){rename_column :a, :b}
601
- @db[:items2].insert(:b=>20)
602
- @ds.insert(:id=>2)
603
- @db[:items2].select_order_map([:id, :b]).must_equal [[1, 10], [2, 20]]
604
- end
605
-
606
- cspecify "should rename primary_key columns correctly", :db2 do
607
- @db.create_table!(:items){Integer :id, :primary_key=>true}
608
- @ds.insert(:id=>10)
609
- @db.alter_table(:items){rename_column :id, :id2}
610
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id2]
611
- @ds.columns!.must_equal [:id2]
612
- @ds.all.must_equal [{:id2=>10}]
613
- end
614
-
615
- cspecify "should set column NULL/NOT NULL correctly", [:jdbc, :db2] do
616
- @db.create_table!(:items, :engine=>:InnoDB){Integer :id}
617
- @ds.insert(:id=>10)
618
- @db.alter_table(:items){set_column_allow_null :id, false}
619
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
620
- @ds.columns!.must_equal [:id]
621
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
622
- @db.alter_table(:items){set_column_allow_null :id, true}
623
- @ds.insert(:id=>nil)
624
- @ds.all.must_equal [{:id=>10}, {:id=>nil}]
625
- end
626
-
627
- it "should set column defaults correctly" do
628
- @db.create_table!(:items){Integer :id}
629
- @ds.insert(:id=>10)
630
- @db.alter_table(:items){set_column_default :id, 20}
631
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
632
- @ds.columns!.must_equal [:id]
633
- @ds.insert
634
- @ds.all.must_equal [{:id=>10}, {:id=>20}]
635
- end
636
-
637
- it "should set column defaults correctly if column has existing default" do
638
- @db.create_table!(:items){Integer :id, :default=>10}
639
- @ds.insert
640
- @ds.all.must_equal [{:id=>10}]
641
- @db.alter_table(:items){set_column_default :id, 20}
642
- @ds.insert
643
- @ds.all.must_equal [{:id=>10}, {:id=>20}]
644
- end
645
-
646
- it "should set column defaults to nil correctly" do
647
- @db.create_table!(:items){Integer :id}
648
- @ds.insert(:id=>10)
649
- @db.alter_table(:items){set_column_default :id, nil}
650
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
651
- @ds.columns!.must_equal [:id]
652
- @ds.insert
653
- @ds.all.must_equal [{:id=>10}, {:id=>nil}]
654
- end
655
-
656
- it "should set column defaults to nil for NOT NULL columns correctly" do
657
- @db.create_table!(:items){Integer :id, :null=>false}
658
- @ds.insert(:id=>10)
659
- @db.alter_table(:items){set_column_default :id, nil}
660
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
661
- @ds.columns!.must_equal [:id]
662
- @ds.insert(20)
663
- @ds.all.must_equal [{:id=>10}, {:id=>20}]
664
- end
665
-
666
- cspecify "should set column types correctly", [:jdbc, :db2], :oracle do
667
- @db.create_table!(:items){Integer :id}
668
- @ds.insert(:id=>10)
669
- @db.alter_table(:items){set_column_type :id, String}
670
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
671
- @ds.columns!.must_equal [:id]
672
- @ds.insert(:id=>'20')
673
- @ds.order(:id).all.must_equal [{:id=>"10"}, {:id=>"20"}]
674
- end
675
-
676
- cspecify "should set column types without modifying NULL/NOT NULL", [:jdbc, :db2], :derby do
677
- @db.create_table!(:items){Integer :id, :null=>false, :default=>2}
678
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
679
- @db.alter_table(:items){set_column_type :id, String}
680
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
681
-
682
- @db.create_table!(:items){Integer :id}
683
- @ds.insert(:id=>nil)
684
- @db.alter_table(:items){set_column_type :id, String}
685
- @ds.insert(:id=>nil)
686
- @ds.map(:id).must_equal [nil, nil]
687
- end
688
-
689
- cspecify "should set column types without modifying defaults", [:jdbc, :db2], :oracle, :derby do
690
- @db.create_table!(:items){Integer :id, :default=>0}
691
- @ds.insert
692
- @ds.map(:id).must_equal [0]
693
- @db.alter_table(:items){set_column_type :id, String}
694
- @ds.insert
695
- @ds.map(:id).must_equal ['0', '0']
696
-
697
- @db.create_table!(:items){String :id, :default=>'a'}
698
- @ds.insert
699
- @ds.map(:id).must_equal %w'a'
700
- @db.alter_table(:items){set_column_type :id, String, :size=>1}
701
- @ds.insert
702
- @ds.map(:id).must_equal %w'a a'
703
- end
704
-
705
- it "should add unnamed unique constraints and foreign key table constraints correctly" do
706
- @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null => false; Integer :item_id, :null => false}
707
- @db.alter_table(:items) do
708
- add_unique_constraint [:item_id, :id]
709
- add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
710
- end
711
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
712
- @ds.columns!.must_equal [:id, :item_id]
713
- @ds.insert(1, 1)
714
- proc{@ds.insert(1, 1)}.must_raise Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
715
- proc{@ds.insert(1, 2)}.must_raise Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
716
- end
717
-
718
- it "should add named unique constraints and foreign key table constraints correctly" do
719
- @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null=>false; Integer :item_id, :null=>false}
720
- @db.alter_table(:items) do
721
- add_unique_constraint [:item_id, :id], :name=>:unique_iii
722
- add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:fk_iii
723
- end
724
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
725
- @ds.columns!.must_equal [:id, :item_id]
726
- @ds.insert(1, 1)
727
- proc{@ds.insert(1, 1)}.must_raise Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
728
- proc{@ds.insert(1, 2)}.must_raise Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
729
- end
730
-
731
- it "should drop unique constraints and foreign key table constraints correctly" do
732
- @db.create_table!(:items) do
733
- Integer :id
734
- Integer :item_id
735
- unique [:item_id, :id], :name=>:items_uk
736
- foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:items_fk
737
- end
738
- @db.alter_table(:items) do
739
- drop_constraint(:items_fk, :type=>:foreign_key)
740
- drop_constraint(:items_uk, :type=>:unique)
741
- end
742
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
743
- @ds.columns!.must_equal [:id, :item_id]
744
- @ds.insert(1, 2)
745
- @ds.insert(1, 2)
746
- end
747
-
748
- it "should remove columns from tables correctly" do
749
- @db.create_table!(:items) do
750
- primary_key :id
751
- Integer :i
752
- end
753
- @ds.insert(:i=>10)
754
- @db.drop_column(:items, :i)
755
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
756
- end
757
-
758
- it "should remove columns with defaults from tables correctly" do
759
- @db.create_table!(:items) do
760
- primary_key :id
761
- Integer :i, :default=>20
762
- Integer :j, :default=>10
763
- String :s, :default=>'a'
764
- end
765
- @ds.insert(:i=>10, :j=>20, :s=>'b')
766
- @db.drop_column(:items, :i)
767
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :j, :s]
768
- @ds.first.must_equal(:id=>1, :j=>20, :s=>'b')
769
- @ds.insert
770
- @ds.first(:id=>2).must_equal(:id=>2, :j=>10, :s=>'a')
771
- end
772
-
773
- it "should remove foreign key columns from tables correctly" do
774
- @db.create_table!(:items, :engine=>:InnoDB) do
775
- primary_key :id
776
- Integer :i
777
- foreign_key :item_id, :items
778
- end
779
- @ds.insert(:i=>10)
780
- @db.alter_table(:items){drop_foreign_key :item_id}
781
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :i]
782
- end if DB.supports_foreign_key_parsing?
783
-
784
- it "should remove multiple columns in a single alter_table block" do
785
- @db.create_table!(:items) do
786
- primary_key :id
787
- String :name
788
- Integer :number
789
- end
790
- @ds.insert(:number=>10)
791
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :name, :number]
792
- @db.alter_table(:items) do
793
- drop_column :name
794
- drop_column :number
795
- end
796
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
797
- end
798
-
799
- cspecify "should work correctly with many operations in a single alter_table call", [:jdbc, :db2] do
800
- @db.create_table!(:items) do
801
- primary_key :id
802
- String :name2
803
- String :number2
804
- constraint :bar, Sequel.~(:number2=>nil, :name2=>nil)
805
- end
806
- @ds.insert(:name2=>'A12')
807
- @db.alter_table(:items) do
808
- add_column :number, Integer
809
- drop_constraint :bar
810
- drop_column :number2
811
- rename_column :name2, :name
812
- set_column_not_null :name
813
- set_column_default :name, 'A13'
814
- add_constraint :foo, Sequel.like(:name, 'A%')
815
- end
816
- @db[:items].first.must_equal(:id=>1, :name=>'A12', :number=>nil)
817
- @db[:items].delete
818
- proc{@db[:items].insert(:name=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
819
- @db[:items].insert(:number=>1)
820
- @db[:items].get(:name).must_equal 'A13'
821
- end
822
-
823
- it "should support deferrable foreign key constraints" do
824
- @db.create_table!(:items2){Integer :id, :primary_key=>true}
825
- @db.create_table!(:items){foreign_key :id, :items2, :deferrable=>true}
826
- proc{@db[:items].insert(1)}.must_raise(Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
827
- @db.transaction{proc{@db[:items].insert(1)}}.must_raise(Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
828
- end if DB.supports_deferrable_foreign_key_constraints?
829
-
830
- it "should support deferrable unique constraints when creating or altering tables" do
831
- @db.create_table!(:items){Integer :t; unique [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
832
- @db[:items].insert(1)
833
- @db[:items].insert(2)
834
- proc{@db[:items].insert(2)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
835
- @db.transaction{proc{@db[:items].insert(2)}}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
836
-
837
- @db.create_table!(:items){Integer :t}
838
- @db.alter_table(:items){add_unique_constraint [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
839
- @db[:items].insert(1)
840
- @db[:items].insert(2)
841
- proc{@db[:items].insert(2)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
842
- @db.transaction{proc{@db[:items].insert(2)}}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
843
- end if DB.supports_deferrable_constraints?
844
- end
845
-
846
- describe "Database#tables and #views" do
847
- before do
848
- class ::String
849
- @@xxxxx = 0
850
- def xxxxx
851
- "xxxxx#{@@xxxxx += 1}"
852
- end
853
- end
854
- @db = DB
855
- @db.drop_view(:sequel_test_view) rescue nil
856
- @db.drop_table?(:sequel_test_table)
857
- @db.create_table(:sequel_test_table){Integer :a}
858
- @db.create_view :sequel_test_view, @db[:sequel_test_table]
859
- end
860
- after do
861
- @db.drop_view :sequel_test_view
862
- @db.drop_table :sequel_test_table
863
- end
864
-
865
- it "#tables should return an array of symbols" do
866
- ts = @db.tables
867
- ts.must_be_kind_of(Array)
868
- ts.each{|t| t.must_be_kind_of(Symbol)}
869
- ts.must_include(:sequel_test_table)
870
- ts.wont_include(:sequel_test_view)
871
- end if DB.supports_table_listing?
872
-
873
- it "#views should return an array of symbols" do
874
- ts = @db.views
875
- ts.must_be_kind_of(Array)
876
- ts.each{|t| t.must_be_kind_of(Symbol)}
877
- ts.wont_include(:sequel_test_table)
878
- ts.must_include(:sequel_test_view)
879
- end if DB.supports_view_listing?
880
-
881
- describe "with identifier mangling" do
882
- before do
883
- @iom = @db.identifier_output_method
884
- @iim = @db.identifier_input_method
885
- end
886
- after do
887
- @db.identifier_output_method = @iom
888
- @db.identifier_input_method = @iim
889
- end
890
-
891
- it "#tables should respect the database's identifier_output_method" do
892
- @db.identifier_output_method = :xxxxx
893
- @db.identifier_input_method = :xxxxx
894
- @db.tables.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
895
- end if DB.supports_table_listing?
896
-
897
- it "#views should respect the database's identifier_output_method" do
898
- @db.identifier_output_method = :xxxxx
899
- @db.identifier_input_method = :xxxxx
900
- @db.views.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
901
- end if DB.supports_view_listing?
902
- end if IDENTIFIER_MANGLING && !DB.frozen?
903
- end