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,398 +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.filter(:numb=>:$n).call([:map, :numb], :n=>10).must_equal [10]
25
- @ds.filter(:numb=>:$n).call([:as_hash, :id, :numb], :n=>10).must_equal(1=>10)
26
- @ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).must_equal(1=>10)
27
- @ds.filter(:numb=>:$n).call([:to_hash_groups, :id, :numb], :n=>10).must_equal(1=>[10])
28
- end
29
-
30
- it "should support blocks for each, select, all, and map when using bound variables" do
31
- a = []
32
- @ds.filter(:numb=>:$n).call(:each, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
33
- @ds.filter(:numb=>:$n).call(:select, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
34
- @ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
35
- @ds.filter(:numb=>:$n).call([:map], :n=>10){|r| r[:numb] * 2}.must_equal [20]
36
- end
37
-
38
- it "should support binding variables before the call with #bind" do
39
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
40
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
41
- @ds.filter(:numb=>:$n).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
42
-
43
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:select).must_equal [{:id=>1, :numb=>10}]
44
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:all).must_equal [{:id=>1, :numb=>10}]
45
- @ds.bind(:n=>10).filter(:numb=>:$n).call(:first).must_equal(:id=>1, :numb=>10)
46
- end
47
-
48
- it "should allow overriding variables specified with #bind" do
49
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
50
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
51
- @ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
52
-
53
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
54
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
55
- @ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
56
- end
57
-
58
- it "should support placeholder literal strings with call" do
59
- @ds.filter(Sequel.lit("numb = ?", :$n)).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
60
- end
61
-
62
- it "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
63
- @ds.filter(Sequel.lit("numb = :n", :n=>:$n)).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
64
- @ds.insert(:numb=>20)
65
- @ds.insert(:numb=>30)
66
- @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}]
67
- end
68
-
69
- it "should support datasets with static sql and placeholders with call" do
70
- @db["SELECT * FROM items WHERE numb = ?", :$n].call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
71
- end
72
-
73
- it "should support subselects with call" do
74
- @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}]
75
- end
76
-
77
- it "should support subselects with exists with call" do
78
- @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}]
79
- end
80
-
81
- it "should support subselects with literal strings with call" do
82
- @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}]
83
- end
84
-
85
- it "should support subselects with static sql and placeholders with call" do
86
- @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}]
87
- end
88
-
89
- it "should support subselects of subselects with call" do
90
- @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}]
91
- end
92
-
93
- cspecify "should support using a bound variable for a limit and offset", [:jdbc, :db2] do
94
- @ds.insert(:numb=>20)
95
- ds = @ds.limit(:$n, :$n2).order(:id)
96
- ds.call(:select, :n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
97
- ds.call(:select, :n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
98
- ds.call(:select, :n=>1, :n2=>2).must_equal []
99
- ds.call(:select, :n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
100
- ds.call(:select, :n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
101
- end
102
-
103
- it "should support bound variables with insert" do
104
- @ds.call(:insert, {:n=>20}, :numb=>:$n)
105
- @ds.count.must_equal 2
106
- @ds.order(:id).map(:numb).must_equal [10, 20]
107
- end
108
-
109
- it "should support bound variables with NULL values" do
110
- @ds.delete
111
- @ds.call(:insert, {:n=>nil}, :numb=>@pr[:$n])
112
- @ds.count.must_equal 1
113
- @ds.map(:numb).must_equal [nil]
114
- end
115
-
116
- it "should have insert return primary key value when using bound arguments" do
117
- @ds.call(:insert, {:n=>20}, :numb=>:$n).must_equal 2
118
- @ds.filter(:id=>2).first[:numb].must_equal 20
119
- end
120
-
121
- it "should support bound variables with insert_select" do
122
- @ds.call(:insert_select, {:n=>20}, :numb=>:$n).must_equal(:id=>2, :numb=>20)
123
- @ds.count.must_equal 2
124
- @ds.order(:id).map(:numb).must_equal [10, 20]
125
- end if DB.dataset.supports_insert_select?
126
-
127
- it "should support bound variables with insert returning" do
128
- @ds.returning.call(:insert, {:n=>20}, :numb=>:$n).must_equal([{:id=>2, :numb=>20}])
129
- @ds.count.must_equal 2
130
- @ds.order(:id).map(:numb).must_equal [10, 20]
131
- end if DB.dataset.supports_returning?(:insert)
132
-
133
- it "should support bound variables with update returning" do
134
- @ds.returning.call(:update, {:n=>20}, :numb=>:$n).must_equal([{:id=>1, :numb=>20}])
135
- @ds.count.must_equal 1
136
- @ds.order(:id).map(:numb).must_equal [20]
137
- end if DB.dataset.supports_returning?(:update)
138
-
139
- it "should support bound variables with delete returning" do
140
- @ds.where(:id=>:$id).returning.call(:delete, :id=>1).must_equal([{:id=>1, :numb=>10}])
141
- @ds.count.must_equal 0
142
- end if DB.dataset.supports_returning?(:delete)
143
-
144
- it "should support bound variables with delete" do
145
- @ds.filter(:numb=>:$n).call(:delete, :n=>10).must_equal 1
146
- @ds.count.must_equal 0
147
- end
148
-
149
- it "should support bound variables with update" do
150
- @ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb=>Sequel.+(:numb, :$nn)).must_equal 1
151
- @ds.all.must_equal [{:id=>1, :numb=>30}]
152
- end
153
-
154
- it "should support prepared statements when selecting" do
155
- @ds.filter(:numb=>:$n).prepare(:each, :select_n)
156
- @db.call(:select_n, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
157
- @ds.filter(:numb=>:$n).prepare(:select, :select_n)
158
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
159
- @ds.filter(:numb=>:$n).prepare(:all, :select_n)
160
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
161
- @ds.filter(:numb=>:$n).prepare(:first, :select_n)
162
- @db.call(:select_n, :n=>10).must_equal(:id=>1, :numb=>10)
163
- @ds.filter(:numb=>:$n).prepare([:map, :numb], :select_n)
164
- @db.call(:select_n, :n=>10).must_equal [10]
165
- @ds.filter(:numb=>:$n).prepare([:as_hash, :id, :numb], :select_n)
166
- @db.call(:select_n, :n=>10).must_equal(1=>10)
167
- @ds.filter(:numb=>:$n).prepare([:to_hash, :id, :numb], :select_n)
168
- @db.call(:select_n, :n=>10).must_equal(1=>10)
169
- end
170
-
171
- it "should support blocks for each, select, all, and map when using prepared statements" do
172
- a = []
173
- @ds.filter(:numb=>:$n).prepare(:each, :select_n).call(:n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
174
- a = []
175
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
176
- @ds.filter(:numb=>:$n).prepare(:select, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
177
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
178
- @ds.filter(:numb=>:$n).prepare(:all, :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
179
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
180
- @ds.filter(:numb=>:$n).prepare([:map], :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [20]
181
- @db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [20]
182
- end
183
-
184
- it "should support prepared statements being called multiple times with different arguments" do
185
- @ds.filter(:numb=>:$n).prepare(:select, :select_n)
186
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
187
- @db.call(:select_n, :n=>0).must_equal []
188
- @db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
189
- end
190
-
191
- it "should support placeholder literal strings with prepare" do
192
- @ds.filter(Sequel.lit("numb = ?", :$n)).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
193
- end
194
-
195
- it "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
196
- @ds.filter(Sequel.lit("numb = :n", :n=>:$n)).prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
197
- @ds.insert(:numb=>20)
198
- @ds.insert(:numb=>30)
199
- @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}]
200
- end
201
-
202
- it "should support datasets with static sql and placeholders with prepare" do
203
- @db["SELECT * FROM items WHERE numb = ?", :$n].prepare(:select, :seq_select).call(:n=>10).must_equal [{:id=>1, :numb=>10}]
204
- end
205
-
206
- it "should support subselects with prepare" do
207
- @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}]
208
- end
209
-
210
- it "should support subselects with exists with prepare" do
211
- @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}]
212
- end
213
-
214
- it "should support subselects with literal strings with prepare" do
215
- @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}]
216
- end
217
-
218
- it "should support subselects with static sql and placeholders with prepare" do
219
- @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}]
220
- end
221
-
222
- it "should support subselects of subselects with prepare" do
223
- @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}]
224
- end
225
-
226
- cspecify "should support using a prepared_statement for a limit and offset", :db2 do
227
- @ds.insert(:numb=>20)
228
- ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
229
- ps.call(:n=>1, :n2=>0).must_equal [{:id=>1, :numb=>10}]
230
- ps.call(:n=>1, :n2=>1).must_equal [{:id=>2, :numb=>20}]
231
- ps.call(:n=>1, :n2=>2).must_equal []
232
- ps.call(:n=>2, :n2=>0).must_equal [{:id=>1, :numb=>10}, {:id=>2, :numb=>20}]
233
- ps.call(:n=>2, :n2=>1).must_equal [{:id=>2, :numb=>20}]
234
- end
235
-
236
- it "should support prepared statements with insert" do
237
- @ds.prepare(:insert, :insert_n, :numb=>:$n)
238
- @db.call(:insert_n, :n=>20)
239
- @ds.count.must_equal 2
240
- @ds.order(:id).map(:numb).must_equal [10, 20]
241
- end
242
-
243
- it "should support prepared statements with NULL values" do
244
- @ds.delete
245
- @ds.prepare(:insert, :insert_n, :numb=>@pr[:$n])
246
- @db.call(:insert_n, :n=>nil)
247
- @ds.count.must_equal 1
248
- @ds.map(:numb).must_equal [nil]
249
- end
250
-
251
- it "should have insert return primary key value when using prepared statements" do
252
- @ds.prepare(:insert, :insert_n, :numb=>:$n)
253
- @db.call(:insert_n, :n=>20).must_equal 2
254
- @ds.filter(:id=>2).first[:numb].must_equal 20
255
- end
256
-
257
- it "should support prepared_statements with insert_select" do
258
- @ds.prepare(:insert_select, :insert_select_n, :numb=>:$n).call(:n=>20).must_equal(:id=>2, :numb=>20)
259
- @ds.count.must_equal 2
260
- @ds.order(:id).map(:numb).must_equal [10, 20]
261
- end if DB.dataset.supports_insert_select?
262
-
263
- it "should support bound variables with insert returning" do
264
- @ds.returning.prepare(:insert, :insert_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>2, :numb=>20}])
265
- @ds.count.must_equal 2
266
- @ds.order(:id).map(:numb).must_equal [10, 20]
267
- end if DB.dataset.supports_returning?(:insert)
268
-
269
- it "should support bound variables with update returning" do
270
- @ds.returning.prepare(:update, :update_rn, :numb=>:$n).call(:n=>20).must_equal([{:id=>1, :numb=>20}])
271
- @ds.count.must_equal 1
272
- @ds.order(:id).map(:numb).must_equal [20]
273
- end if DB.dataset.supports_returning?(:update)
274
-
275
- it "should support bound variables with delete returning" do
276
- @ds.where(:id=>:$id).returning.prepare(:delete, :delete_rn).call(:id=>1).must_equal([{:id=>1, :numb=>10}])
277
- @ds.count.must_equal 0
278
- end if DB.dataset.supports_returning?(:delete)
279
-
280
- it "should support prepared statements with delete" do
281
- @ds.filter(:numb=>:$n).prepare(:delete, :delete_n)
282
- @db.call(:delete_n, :n=>10).must_equal 1
283
- @ds.count.must_equal 0
284
- end
285
-
286
- it "should support prepared statements with update" do
287
- @ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb=>Sequel.+(:numb, :$nn))
288
- @db.call(:update_n, :n=>10, :nn=>20).must_equal 1
289
- @ds.all.must_equal [{:id=>1, :numb=>30}]
290
- end
291
-
292
- it "model datasets should return model instances when using select, all, and first with bound variables" do
293
- @c.filter(:numb=>:$n).call(:select, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
294
- @c.filter(:numb=>:$n).call(:all, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
295
- @c.filter(:numb=>:$n).call(:first, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
296
- end
297
-
298
- it "model datasets should return model instances when using select, all, and first with prepared statements" do
299
- @c.filter(:numb=>:$n).prepare(:select, :select_n1)
300
- @db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
301
- @c.filter(:numb=>:$n).prepare(:all, :select_n1)
302
- @db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
303
- @c.filter(:numb=>:$n).prepare(:first, :select_n1)
304
- @db.call(:select_n1, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
305
- end
306
- end
307
-
308
- describe "Bound Argument Types" do
309
- before(:all) do
310
- @db = DB
311
- @db.create_table!(:items) do
312
- primary_key :id
313
- Date :d
314
- DateTime :dt
315
- File :file
316
- String :s
317
- Time :t
318
- Float :f
319
- TrueClass :b
320
- end
321
- @ds = @db[:items]
322
- @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}
323
- end
324
- before do
325
- @ds.delete
326
- @ds.insert(@vs)
327
- end
328
- after do
329
- Sequel.datetime_class = Time
330
- end
331
- after(:all) do
332
- @db.drop_table?(:items)
333
- end
334
-
335
- cspecify "should handle date type", [:tinytds], [:jdbc, :mssql], [:jdbc, :sqlite], :oracle do
336
- @ds.filter(:d=>:$x).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].must_equal @vs[:d]
337
- end
338
-
339
- cspecify "should handle datetime type", [:mysql2], [:jdbc, :sqlite], [:tinytds], [:oracle] do
340
- Sequel.datetime_class = DateTime
341
- @ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].must_equal @vs[:dt]
342
- end
343
-
344
- cspecify "should handle datetime type with fractional seconds", [:jdbc, :sqlite], [:jdbc, :mysql], [:oracle] do
345
- Sequel.datetime_class = DateTime
346
- fract_time = DateTime.parse('2010-10-12 13:14:15.500000')
347
- @ds.prepare(:update, :ps_datetime_up, :dt=>:$x).call(:x=>fract_time)
348
- @ds.literal(@ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>fract_time)[:dt]).must_equal @ds.literal(fract_time)
349
- end
350
-
351
- cspecify "should handle time type", [:jdbc, :sqlite] do
352
- @ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].must_equal @vs[:t]
353
- end
354
-
355
- cspecify "should handle time type with fractional seconds", [:jdbc, :sqlite], [:jdbc, :mysql] do
356
- fract_time = @vs[:t] + 0.5
357
- @ds.prepare(:update, :ps_time_up, :t=>:$x).call(:x=>fract_time)
358
- @ds.literal(@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>fract_time)[:t]).must_equal @ds.literal(fract_time)
359
- end
360
-
361
- cspecify "should handle blob type", [:odbc] do
362
- @ds.delete
363
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>@vs[:file])
364
- @ds.get(:file).must_equal @vs[:file]
365
- end
366
-
367
- cspecify "should handle blob type with special characters", [:odbc] do
368
- @ds.delete
369
- blob = Sequel.blob("\"'[]`a0 ")
370
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>blob)
371
- @ds.get(:file).must_equal blob
372
- end
373
-
374
- cspecify "should handle blob type with nil values", [:oracle], [:tinytds], [:jdbc, :mssql] do
375
- @ds.delete
376
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>nil)
377
- @ds.get(:file).must_be_nil
378
- end
379
-
380
- cspecify "should handle blob type with embedded zeros", [:odbc] do
381
- zero_blob = Sequel::SQL::Blob.new("a\0"*100)
382
- @ds.delete
383
- @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>zero_blob)
384
- @ds.get(:file).must_equal zero_blob
385
- end
386
-
387
- it "should handle float type" do
388
- @ds.filter(:f=>:$x).prepare(:first, :ps_float).call(:x=>@vs[:f])[:f].must_equal @vs[:f]
389
- end
390
-
391
- it "should handle string type" do
392
- @ds.filter(:s=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:s])[:s].must_equal @vs[:s]
393
- end
394
-
395
- cspecify "should handle boolean type", [:jdbc, :sqlite], [:jdbc, :db2], :oracle do
396
- @ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].must_equal @vs[:b]
397
- end
398
- end
@@ -1,869 +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
- cspecify "should set column types correctly", [:jdbc, :db2], :oracle do
638
- @db.create_table!(:items){Integer :id}
639
- @ds.insert(:id=>10)
640
- @db.alter_table(:items){set_column_type :id, String}
641
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
642
- @ds.columns!.must_equal [:id]
643
- @ds.insert(:id=>'20')
644
- @ds.order(:id).all.must_equal [{:id=>"10"}, {:id=>"20"}]
645
- end
646
-
647
- cspecify "should set column types without modifying NULL/NOT NULL", [:jdbc, :db2], :derby do
648
- @db.create_table!(:items){Integer :id, :null=>false, :default=>2}
649
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
650
- @db.alter_table(:items){set_column_type :id, String}
651
- proc{@ds.insert(:id=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
652
-
653
- @db.create_table!(:items){Integer :id}
654
- @ds.insert(:id=>nil)
655
- @db.alter_table(:items){set_column_type :id, String}
656
- @ds.insert(:id=>nil)
657
- @ds.map(:id).must_equal [nil, nil]
658
- end
659
-
660
- cspecify "should set column types without modifying defaults", [:jdbc, :db2], :oracle, :derby do
661
- @db.create_table!(:items){Integer :id, :default=>0}
662
- @ds.insert
663
- @ds.map(:id).must_equal [0]
664
- @db.alter_table(:items){set_column_type :id, String}
665
- @ds.insert
666
- @ds.map(:id).must_equal ['0', '0']
667
-
668
- @db.create_table!(:items){String :id, :default=>'a'}
669
- @ds.insert
670
- @ds.map(:id).must_equal %w'a'
671
- @db.alter_table(:items){set_column_type :id, String, :size=>1}
672
- @ds.insert
673
- @ds.map(:id).must_equal %w'a a'
674
- end
675
-
676
- it "should add unnamed unique constraints and foreign key table constraints correctly" do
677
- @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null => false; Integer :item_id, :null => false}
678
- @db.alter_table(:items) do
679
- add_unique_constraint [:item_id, :id]
680
- add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
681
- end
682
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
683
- @ds.columns!.must_equal [:id, :item_id]
684
- @ds.insert(1, 1)
685
- proc{@ds.insert(1, 1)}.must_raise Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
686
- proc{@ds.insert(1, 2)}.must_raise Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
687
- end
688
-
689
- it "should add named unique constraints and foreign key table constraints correctly" do
690
- @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null=>false; Integer :item_id, :null=>false}
691
- @db.alter_table(:items) do
692
- add_unique_constraint [:item_id, :id], :name=>:unique_iii
693
- add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:fk_iii
694
- end
695
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
696
- @ds.columns!.must_equal [:id, :item_id]
697
- @ds.insert(1, 1)
698
- proc{@ds.insert(1, 1)}.must_raise Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
699
- proc{@ds.insert(1, 2)}.must_raise Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError
700
- end
701
-
702
- it "should drop unique constraints and foreign key table constraints correctly" do
703
- @db.create_table!(:items) do
704
- Integer :id
705
- Integer :item_id
706
- unique [:item_id, :id], :name=>:items_uk
707
- foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:items_fk
708
- end
709
- @db.alter_table(:items) do
710
- drop_constraint(:items_fk, :type=>:foreign_key)
711
- drop_constraint(:items_uk, :type=>:unique)
712
- end
713
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :item_id]
714
- @ds.columns!.must_equal [:id, :item_id]
715
- @ds.insert(1, 2)
716
- @ds.insert(1, 2)
717
- end
718
-
719
- it "should remove columns from tables correctly" do
720
- @db.create_table!(:items) do
721
- primary_key :id
722
- Integer :i
723
- end
724
- @ds.insert(:i=>10)
725
- @db.drop_column(:items, :i)
726
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
727
- end
728
-
729
- it "should remove columns with defaults from tables correctly" do
730
- @db.create_table!(:items) do
731
- primary_key :id
732
- Integer :i, :default=>20
733
- end
734
- @ds.insert(:i=>10)
735
- @db.drop_column(:items, :i)
736
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
737
- end
738
-
739
- it "should remove foreign key columns from tables correctly" do
740
- @db.create_table!(:items, :engine=>:InnoDB) do
741
- primary_key :id
742
- Integer :i
743
- foreign_key :item_id, :items
744
- end
745
- @ds.insert(:i=>10)
746
- @db.alter_table(:items){drop_foreign_key :item_id}
747
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :i]
748
- end if DB.supports_foreign_key_parsing?
749
-
750
- it "should remove multiple columns in a single alter_table block" do
751
- @db.create_table!(:items) do
752
- primary_key :id
753
- String :name
754
- Integer :number
755
- end
756
- @ds.insert(:number=>10)
757
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :name, :number]
758
- @db.alter_table(:items) do
759
- drop_column :name
760
- drop_column :number
761
- end
762
- @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
763
- end
764
-
765
- cspecify "should work correctly with many operations in a single alter_table call", [:jdbc, :db2] do
766
- @db.create_table!(:items) do
767
- primary_key :id
768
- String :name2
769
- String :number2
770
- constraint :bar, Sequel.~(:number2=>nil, :name2=>nil)
771
- end
772
- @ds.insert(:name2=>'A12')
773
- @db.alter_table(:items) do
774
- add_column :number, Integer
775
- drop_constraint :bar
776
- drop_column :number2
777
- rename_column :name2, :name
778
- set_column_not_null :name
779
- set_column_default :name, 'A13'
780
- add_constraint :foo, Sequel.like(:name, 'A%')
781
- end
782
- @db[:items].first.must_equal(:id=>1, :name=>'A12', :number=>nil)
783
- @db[:items].delete
784
- proc{@db[:items].insert(:name=>nil)}.must_raise(Sequel::NotNullConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
785
- @db[:items].insert(:number=>1)
786
- @db[:items].get(:name).must_equal 'A13'
787
- end
788
-
789
- it "should support deferrable foreign key constraints" do
790
- @db.create_table!(:items2){Integer :id, :primary_key=>true}
791
- @db.create_table!(:items){foreign_key :id, :items2, :deferrable=>true}
792
- proc{@db[:items].insert(1)}.must_raise(Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
793
- @db.transaction{proc{@db[:items].insert(1)}}.must_raise(Sequel::ForeignKeyConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
794
- end if DB.supports_deferrable_foreign_key_constraints?
795
-
796
- it "should support deferrable unique constraints when creating or altering tables" do
797
- @db.create_table!(:items){Integer :t; unique [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
798
- @db[:items].insert(1)
799
- @db[:items].insert(2)
800
- proc{@db[:items].insert(2)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
801
- @db.transaction{proc{@db[:items].insert(2)}}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
802
-
803
- @db.create_table!(:items){Integer :t}
804
- @db.alter_table(:items){add_unique_constraint [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
805
- @db[:items].insert(1)
806
- @db[:items].insert(2)
807
- proc{@db[:items].insert(2)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
808
- @db.transaction{proc{@db[:items].insert(2)}}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation, Sequel::DatabaseError)
809
- end if DB.supports_deferrable_constraints?
810
- end
811
-
812
- describe "Database#tables and #views" do
813
- before do
814
- class ::String
815
- @@xxxxx = 0
816
- def xxxxx
817
- "xxxxx#{@@xxxxx += 1}"
818
- end
819
- end
820
- @db = DB
821
- @db.drop_view(:sequel_test_view) rescue nil
822
- @db.drop_table?(:sequel_test_table)
823
- @db.create_table(:sequel_test_table){Integer :a}
824
- @db.create_view :sequel_test_view, @db[:sequel_test_table]
825
- end
826
- after do
827
- @db.drop_view :sequel_test_view
828
- @db.drop_table :sequel_test_table
829
- end
830
-
831
- it "#tables should return an array of symbols" do
832
- ts = @db.tables
833
- ts.must_be_kind_of(Array)
834
- ts.each{|t| t.must_be_kind_of(Symbol)}
835
- ts.must_include(:sequel_test_table)
836
- ts.wont_include(:sequel_test_view)
837
- end if DB.supports_table_listing?
838
-
839
- it "#views should return an array of symbols" do
840
- ts = @db.views
841
- ts.must_be_kind_of(Array)
842
- ts.each{|t| t.must_be_kind_of(Symbol)}
843
- ts.wont_include(:sequel_test_table)
844
- ts.must_include(:sequel_test_view)
845
- end if DB.supports_view_listing?
846
-
847
- describe "with identifier mangling" do
848
- before do
849
- @iom = @db.identifier_output_method
850
- @iim = @db.identifier_input_method
851
- end
852
- after do
853
- @db.identifier_output_method = @iom
854
- @db.identifier_input_method = @iim
855
- end
856
-
857
- it "#tables should respect the database's identifier_output_method" do
858
- @db.identifier_output_method = :xxxxx
859
- @db.identifier_input_method = :xxxxx
860
- @db.tables.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
861
- end if DB.supports_table_listing?
862
-
863
- it "#views should respect the database's identifier_output_method" do
864
- @db.identifier_output_method = :xxxxx
865
- @db.identifier_input_method = :xxxxx
866
- @db.views.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
867
- end if DB.supports_view_listing?
868
- end if IDENTIFIER_MANGLING && !DB.frozen?
869
- end