sequel 3.21.0 → 3.39.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 (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
3
 
3
4
  require ENV['SEQUEL_MSSQL_SPEC_REQUIRE'] if ENV['SEQUEL_MSSQL_SPEC_REQUIRE']
@@ -17,23 +18,6 @@ def logger.method_missing(m, msg)
17
18
  end
18
19
  MSSQL_DB.loggers = [logger]
19
20
 
20
- MSSQL_DB.create_table! :test do
21
- text :name
22
- integer :value, :index => true
23
- end
24
- MSSQL_DB.create_table! :test2 do
25
- text :name
26
- integer :value
27
- end
28
- MSSQL_DB.create_table! :test3 do
29
- integer :value
30
- timestamp :time
31
- end
32
- MSSQL_DB.create_table! :test4 do
33
- varchar :name, :size => 20
34
- varbinary :value
35
- end
36
-
37
21
  describe "A MSSQL database" do
38
22
  before do
39
23
  @db = MSSQL_DB
@@ -53,21 +37,63 @@ describe "A MSSQL database" do
53
37
  proc{@db.server_version}.should_not raise_error
54
38
  proc{@db.dataset.server_version}.should_not raise_error
55
39
  end
40
+ end
56
41
 
42
+ describe "A MSSQL database" do
43
+ before do
44
+ @db = MSSQL_DB
45
+ @db.create_table! :test3 do
46
+ Integer :value
47
+ Time :time
48
+ end
49
+ end
50
+ after do
51
+ @db.drop_table?(:test3)
52
+ end
53
+
57
54
  specify "should work with NOLOCK" do
58
55
  @db.transaction{@db[:test3].nolock.all.should == []}
59
56
  end
60
57
  end
61
58
 
59
+ # This spec is currently disabled as the SQL Server 2008 R2 Express doesn't support
60
+ # full text searching. Even if full text searching is supported,
61
+ # you may need to create a full text catalog on the database first via:
62
+ # CREATE FULLTEXT CATALOG ftscd AS DEFAULT
63
+ describe "MSSQL full_text_search" do
64
+ before do
65
+ @db = MSSQL_DB
66
+ @db.drop_table?(:posts)
67
+ end
68
+ after do
69
+ @db.drop_table?(:posts)
70
+ end
71
+
72
+ specify "should support fulltext indexes and full_text_search" do
73
+ log do
74
+ @db.create_table(:posts){Integer :id, :null=>false; String :title; String :body; index :id, :name=>:fts_id_idx, :unique=>true; full_text_index :title, :key_index=>:fts_id_idx; full_text_index [:title, :body], :key_index=>:fts_id_idx}
75
+ @db[:posts].insert(:title=>'ruby rails', :body=>'y')
76
+ @db[:posts].insert(:title=>'sequel', :body=>'ruby')
77
+ @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
78
+
79
+ @db[:posts].full_text_search(:title, 'rails').all.should == [{:title=>'ruby rails', :body=>'y'}]
80
+ @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
81
+
82
+ @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
83
+ @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
84
+ end
85
+ end
86
+ end if false
87
+
62
88
  describe "MSSQL Dataset#join_table" do
63
89
  specify "should emulate the USING clause with ON" do
64
90
  MSSQL_DB[:items].join(:categories, [:id]).sql.should ==
65
- 'SELECT * FROM ITEMS INNER JOIN CATEGORIES ON (CATEGORIES.ID = ITEMS.ID)'
66
- ['SELECT * FROM ITEMS INNER JOIN CATEGORIES ON ((CATEGORIES.ID1 = ITEMS.ID1) AND (CATEGORIES.ID2 = ITEMS.ID2))',
67
- 'SELECT * FROM ITEMS INNER JOIN CATEGORIES ON ((CATEGORIES.ID2 = ITEMS.ID2) AND (CATEGORIES.ID1 = ITEMS.ID1))'].
68
- should include(MSSQL_DB[:items].join(:categories, [:id1, :id2]).sql)
91
+ 'SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON ([CATEGORIES].[ID] = [ITEMS].[ID])'
92
+ ['SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON (([CATEGORIES].[ID1] = [ITEMS].[ID1]) AND ([CATEGORIES].[ID2] = [ITEMS].[ID2]))',
93
+ 'SELECT * FROM [ITEMS] INNER JOIN [CATEGORIES] ON (([CATEGORIES].[ID2] = [ITEMS].[ID2]) AND ([CATEGORIES].[ID1] = [ITEMS].[ID1]))'].
94
+ should include(MSSQL_DB[:items].join(:categories, [:id1, :id2]).sql)
69
95
  MSSQL_DB[:items___i].join(:categories___c, [:id]).sql.should ==
70
- 'SELECT * FROM ITEMS AS I INNER JOIN CATEGORIES AS C ON (C.ID = I.ID)'
96
+ 'SELECT * FROM [ITEMS] AS [I] INNER JOIN [CATEGORIES] AS [C] ON ([C].[ID] = [I].[ID])'
71
97
  end
72
98
  end
73
99
 
@@ -79,50 +105,49 @@ describe "MSSQL Dataset#output" do
79
105
  @ds = @db[:items]
80
106
  end
81
107
  after do
82
- @db.drop_table(:items)
83
- @db.drop_table(:out)
108
+ @db.drop_table?(:items, :out)
84
109
  end
85
110
 
86
111
  specify "should format OUTPUT clauses without INTO for DELETE statements" do
87
112
  @ds.output(nil, [:deleted__name, :deleted__value]).delete_sql.should =~
88
- /DELETE FROM ITEMS OUTPUT DELETED.(NAME|VALUE), DELETED.(NAME|VALUE)/
89
- @ds.output(nil, [:deleted.*]).delete_sql.should =~
90
- /DELETE FROM ITEMS OUTPUT DELETED.*/
113
+ /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\]/
114
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:deleted)]).delete_sql.should =~
115
+ /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].*/
91
116
  end
92
117
 
93
118
  specify "should format OUTPUT clauses with INTO for DELETE statements" do
94
119
  @ds.output(:out, [:deleted__name, :deleted__value]).delete_sql.should =~
95
- /DELETE FROM ITEMS OUTPUT DELETED.(NAME|VALUE), DELETED.(NAME|VALUE) INTO OUT/
120
+ /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\] INTO \[OUT\]/
96
121
  @ds.output(:out, {:name => :deleted__name, :value => :deleted__value}).delete_sql.should =~
97
- /DELETE FROM ITEMS OUTPUT DELETED.(NAME|VALUE), DELETED.(NAME|VALUE) INTO OUT \((NAME|VALUE), (NAME|VALUE)\)/
122
+ /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/
98
123
  end
99
124
 
100
125
  specify "should format OUTPUT clauses without INTO for INSERT statements" do
101
126
  @ds.output(nil, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).should =~
102
- /INSERT INTO ITEMS \((NAME|VALUE), (NAME|VALUE)\) OUTPUT INSERTED.(NAME|VALUE), INSERTED.(NAME|VALUE) VALUES \((N'name'|1), (N'name'|1)\)/
103
- @ds.output(nil, [:inserted.*]).insert_sql(:name => "name", :value => 1).should =~
104
- /INSERT INTO ITEMS \((NAME|VALUE), (NAME|VALUE)\) OUTPUT INSERTED.* VALUES \((N'name'|1), (N'name'|1)\)/
127
+ /INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] VALUES \((N'name'|1), (N'name'|1)\)/
128
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).insert_sql(:name => "name", :value => 1).should =~
129
+ /INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].* VALUES \((N'name'|1), (N'name'|1)\)/
105
130
  end
106
131
 
107
132
  specify "should format OUTPUT clauses with INTO for INSERT statements" do
108
133
  @ds.output(:out, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).should =~
109
- /INSERT INTO ITEMS \((NAME|VALUE), (NAME|VALUE)\) OUTPUT INSERTED.(NAME|VALUE), INSERTED.(NAME|VALUE) INTO OUT VALUES \((N'name'|1), (N'name'|1)\)/
134
+ /INSERT INTO \[ITEMS\] \((\[NAME\]|\[VALUE\]), (\[NAME\]|\[VALUE\])\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] INTO \[OUT\] VALUES \((N'name'|1), (N'name'|1)\)/
110
135
  @ds.output(:out, {:name => :inserted__name, :value => :inserted__value}).insert_sql(:name => "name", :value => 1).should =~
111
- /INSERT INTO ITEMS \((NAME|VALUE), (NAME|VALUE)\) OUTPUT INSERTED.(NAME|VALUE), INSERTED.(NAME|VALUE) INTO OUT \((NAME|VALUE), (NAME|VALUE)\) VALUES \((N'name'|1), (N'name'|1)\)/
136
+ /INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) VALUES \((N'name'|1), (N'name'|1)\)/
112
137
  end
113
138
 
114
139
  specify "should format OUTPUT clauses without INTO for UPDATE statements" do
115
140
  @ds.output(nil, [:inserted__name, :deleted__value]).update_sql(:value => 2).should =~
116
- /UPDATE ITEMS SET VALUE = 2 OUTPUT (INSERTED.NAME|DELETED.VALUE), (INSERTED.NAME|DELETED.VALUE)/
117
- @ds.output(nil, [:inserted.*]).update_sql(:value => 2).should =~
118
- /UPDATE ITEMS SET VALUE = 2 OUTPUT INSERTED.*/
141
+ /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\]/
142
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).update_sql(:value => 2).should =~
143
+ /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[INSERTED\].*/
119
144
  end
120
145
 
121
146
  specify "should format OUTPUT clauses with INTO for UPDATE statements" do
122
147
  @ds.output(:out, [:inserted__name, :deleted__value]).update_sql(:value => 2).should =~
123
- /UPDATE ITEMS SET VALUE = 2 OUTPUT (INSERTED.NAME|DELETED.VALUE), (INSERTED.NAME|DELETED.VALUE) INTO OUT/
148
+ /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\] INTO \[OUT\]/
124
149
  @ds.output(:out, {:name => :inserted__name, :value => :deleted__value}).update_sql(:value => 2).should =~
125
- /UPDATE ITEMS SET VALUE = 2 OUTPUT (INSERTED.NAME|DELETED.VALUE), (INSERTED.NAME|DELETED.VALUE) INTO OUT \((NAME|VALUE), (NAME|VALUE)\)/
150
+ /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\] INTO \[OUT\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\)/
126
151
  end
127
152
 
128
153
  specify "should execute OUTPUT clauses in DELETE statements" do
@@ -163,23 +188,23 @@ describe "MSSQL dataset" do
163
188
  end
164
189
 
165
190
  specify "should prepend UPDATE statements with WITH clause" do
166
- @ds1.update_sql(:x => :y).should == 'WITH T AS (SELECT * FROM X) UPDATE T SET X = Y'
167
- @ds2.update_sql(:x => :y).should == 'WITH T AS (SELECT * FROM X UNION ALL SELECT * FROM T) UPDATE T SET X = Y'
191
+ @ds1.update_sql(:x => :y).should == 'WITH [T] AS (SELECT * FROM [X]) UPDATE [T] SET [X] = [Y]'
192
+ @ds2.update_sql(:x => :y).should == 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) UPDATE [T] SET [X] = [Y]'
168
193
  end
169
194
 
170
195
  specify "should prepend DELETE statements with WITH clause" do
171
- @ds1.filter(:y => 1).delete_sql.should == 'WITH T AS (SELECT * FROM X) DELETE FROM T WHERE (Y = 1)'
172
- @ds2.filter(:y => 1).delete_sql.should == 'WITH T AS (SELECT * FROM X UNION ALL SELECT * FROM T) DELETE FROM T WHERE (Y = 1)'
196
+ @ds1.filter(:y => 1).delete_sql.should == 'WITH [T] AS (SELECT * FROM [X]) DELETE FROM [T] WHERE ([Y] = 1)'
197
+ @ds2.filter(:y => 1).delete_sql.should == 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) DELETE FROM [T] WHERE ([Y] = 1)'
173
198
  end
174
199
 
175
200
  specify "should prepend INSERT statements with WITH clause" do
176
- @ds1.insert_sql(@db[:t]).should == 'WITH T AS (SELECT * FROM X) INSERT INTO T SELECT * FROM T'
177
- @ds2.insert_sql(@db[:t]).should == 'WITH T AS (SELECT * FROM X UNION ALL SELECT * FROM T) INSERT INTO T SELECT * FROM T'
201
+ @ds1.insert_sql(@db[:t]).should == 'WITH [T] AS (SELECT * FROM [X]) INSERT INTO [T] SELECT * FROM [T]'
202
+ @ds2.insert_sql(@db[:t]).should == 'WITH [T] AS (SELECT * FROM [X] UNION ALL SELECT * FROM [T]) INSERT INTO [T] SELECT * FROM [T]'
178
203
  end
179
204
 
180
205
  specify "should move WITH clause on joined dataset to top level" do
181
- @db[:s].inner_join(@ds1).sql.should == "WITH T AS (SELECT * FROM X) SELECT * FROM S INNER JOIN (SELECT * FROM T) AS T1"
182
- @ds1.inner_join(@db[:s].with(:s, @db[:y])).sql.should == "WITH T AS (SELECT * FROM X), S AS (SELECT * FROM Y) SELECT * FROM T INNER JOIN (SELECT * FROM S) AS T1"
206
+ @db[:s].inner_join(@ds1).sql.should == "WITH [T] AS (SELECT * FROM [X]) SELECT * FROM [S] INNER JOIN (SELECT * FROM [T]) AS [T1]"
207
+ @ds1.inner_join(@db[:s].with(:s, @db[:y])).sql.should == "WITH [T] AS (SELECT * FROM [X]), [S] AS (SELECT * FROM [Y]) SELECT * FROM [T] INNER JOIN (SELECT * FROM [S]) AS [T1]"
183
208
  end
184
209
 
185
210
  describe "on #import" do
@@ -207,10 +232,10 @@ describe "MSSQL dataset" do
207
232
  @db[:items].with(:items, @db[:inventory].group(:type)).import([:x, :y], [[1, 2], [3, 4], [5, 6]], :slice => 2)
208
233
  @db.import_sqls.should == [
209
234
  'BEGIN',
210
- "WITH ITEMS AS (SELECT * FROM INVENTORY GROUP BY TYPE) INSERT INTO ITEMS (X, Y) SELECT 1, 2 UNION ALL SELECT 3, 4",
235
+ "WITH [ITEMS] AS (SELECT * FROM [INVENTORY] GROUP BY [TYPE]) INSERT INTO [ITEMS] ([X], [Y]) SELECT 1, 2 UNION ALL SELECT 3, 4",
211
236
  'COMMIT',
212
237
  'BEGIN',
213
- "WITH ITEMS AS (SELECT * FROM INVENTORY GROUP BY TYPE) INSERT INTO ITEMS (X, Y) SELECT 5, 6",
238
+ "WITH [ITEMS] AS (SELECT * FROM [INVENTORY] GROUP BY [TYPE]) INSERT INTO [ITEMS] ([X], [Y]) SELECT 5, 6",
214
239
  'COMMIT'
215
240
  ]
216
241
  end
@@ -218,6 +243,23 @@ describe "MSSQL dataset" do
218
243
  end
219
244
  end
220
245
 
246
+ describe "MSSQL::Dataset#import" do
247
+ before do
248
+ @db = MSSQL_DB
249
+ @db.create_table!(:test){primary_key :x; Integer :y}
250
+ @db.sqls.clear
251
+ @ds = @db[:test]
252
+ end
253
+ after do
254
+ @db.drop_table?(:test)
255
+ end
256
+
257
+ specify "#import should work correctly with an arbitrary output value" do
258
+ @ds.output(nil, [:inserted__y, :inserted__x]).import([:y], [[3], [4]]).should == [{:y=>3, :x=>1}, {:y=>4, :x=>2}]
259
+ @ds.all.should == [{:x=>1, :y=>3}, {:x=>2, :y=>4}]
260
+ end
261
+ end
262
+
221
263
  describe "MSSQL joined datasets" do
222
264
  before do
223
265
  @db = MSSQL_DB
@@ -225,12 +267,12 @@ describe "MSSQL joined datasets" do
225
267
 
226
268
  specify "should format DELETE statements" do
227
269
  @db[:t1].inner_join(:t2, :t1__pk => :t2__pk).delete_sql.should ==
228
- "DELETE FROM T1 FROM T1 INNER JOIN T2 ON (T1.PK = T2.PK)"
270
+ "DELETE FROM [T1] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
229
271
  end
230
272
 
231
273
  specify "should format UPDATE statements" do
232
274
  @db[:t1].inner_join(:t2, :t1__pk => :t2__pk).update_sql(:pk => :t2__pk).should ==
233
- "UPDATE T1 SET PK = T2.PK FROM T1 INNER JOIN T2 ON (T1.PK = T2.PK)"
275
+ "UPDATE [T1] SET [PK] = [T2].[PK] FROM [T1] INNER JOIN [T2] ON ([T1].[PK] = [T2].[PK])"
234
276
  end
235
277
  end
236
278
 
@@ -244,7 +286,7 @@ describe "Offset support" do
244
286
  @ds.import [:id, :parent_id], [[1,nil],[2,nil],[3,1],[4,1],[5,3],[6,5]]
245
287
  end
246
288
  after do
247
- @db.drop_table(:i)
289
+ @db.drop_table?(:i)
248
290
  end
249
291
 
250
292
  specify "should return correct rows" do
@@ -267,8 +309,7 @@ describe "Common Table Expressions" do
267
309
  @ds.import [:id, :parent_id], [[1,nil],[2,nil],[3,1],[4,1],[5,3],[6,5]]
268
310
  end
269
311
  after do
270
- @db.drop_table(:i1)
271
- @db.drop_table(:i2)
312
+ @db.drop_table?(:i1, :i2)
272
313
  end
273
314
 
274
315
  specify "using #with should be able to update" do
@@ -284,7 +325,7 @@ describe "Common Table Expressions" do
284
325
 
285
326
  specify "using #with_recursive should be able to update" do
286
327
  ds = @ds.with_recursive(:t, @ds.filter(:parent_id=>1).or(:id => 1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
287
- ds.filter(~{:id => @db[:t].select(:i)}).update(:parent_id => 1)
328
+ ds.exclude(:id => @db[:t].select(:i)).update(:parent_id => 1)
288
329
  @ds[:id => 1].should == {:id => 1, :parent_id => nil}
289
330
  @ds[:id => 2].should == {:id => 2, :parent_id => 1}
290
331
  @ds[:id => 5].should == {:id => 5, :parent_id => 3}
@@ -334,11 +375,15 @@ describe "MSSSQL::Dataset#insert" do
334
375
  before do
335
376
  @db = MSSQL_DB
336
377
  @db.create_table!(:test5){primary_key :xid; Integer :value}
378
+ @db.create_table! :test4 do
379
+ String :name, :size => 20
380
+ column :value, 'varbinary(max)'
381
+ end
337
382
  @db.sqls.clear
338
383
  @ds = @db[:test5]
339
384
  end
340
385
  after do
341
- @db.drop_table(:test5) rescue nil
386
+ @db.drop_table?(:test5, :test4)
342
387
  end
343
388
 
344
389
  specify "should have insert_select return nil if disable_insert_output is used" do
@@ -355,11 +400,17 @@ describe "MSSSQL::Dataset#insert" do
355
400
  h[:value].should == 10
356
401
  @ds.first(:xid=>h[:xid])[:value].should == 10
357
402
  end
358
- end
359
403
 
360
- describe "MSSSQL::Dataset#disable_insert_output" do
404
+ cspecify "should allow large text and binary values", :odbc do
405
+ blob = Sequel::SQL::Blob.new("0" * (65*1024))
406
+ @db[:test4].insert(:name => 'max varbinary test', :value => blob)
407
+ b = @db[:test4].where(:name => 'max varbinary test').get(:value)
408
+ b.length.should == blob.length
409
+ b.should == blob
410
+ end
411
+
361
412
  specify "should play nicely with simple_select_all?" do
362
- MSSQL_DB[:test].disable_insert_output.send(:simple_select_all?).should == true
413
+ MSSQL_DB[:test4].disable_insert_output.send(:simple_select_all?).should == true
363
414
  end
364
415
  end
365
416
 
@@ -369,7 +420,7 @@ describe "MSSSQL::Dataset#into" do
369
420
  end
370
421
 
371
422
  specify "should format SELECT statement" do
372
- @db[:t].into(:new).select_sql.should == "SELECT * INTO NEW FROM T"
423
+ @db[:t].into(:new).select_sql.should == "SELECT * INTO [NEW] FROM [T]"
373
424
  end
374
425
 
375
426
  specify "should select rows into a new table" do
@@ -377,8 +428,7 @@ describe "MSSSQL::Dataset#into" do
377
428
  @db[:t].insert(:id => 1, :value => "test")
378
429
  @db << @db[:t].into(:new).select_sql
379
430
  @db[:new].all.should == [{:id => 1, :value => "test"}]
380
- @db.drop_table(:t)
381
- @db.drop_table(:new)
431
+ @db.drop_table?(:t, :new)
382
432
  end
383
433
  end
384
434
 
@@ -387,7 +437,7 @@ describe "A MSSQL database" do
387
437
  @db = MSSQL_DB
388
438
  end
389
439
  after do
390
- @db.drop_table(:a)
440
+ @db.drop_table?(:a)
391
441
  end
392
442
 
393
443
  specify "should handle many existing types for set_column_allow_null" do
@@ -409,16 +459,20 @@ describe "A MSSQL database" do
409
459
  end
410
460
 
411
461
  describe "MSSQL::Database#rename_table" do
462
+ after do
463
+ MSSQL_DB.drop_table?(:foo)
464
+ end
465
+
412
466
  specify "should work on non-schema bound tables which need escaping" do
413
467
  MSSQL_DB.quote_identifiers = true
414
468
  MSSQL_DB.create_table! :'foo bar' do
415
469
  text :name
416
470
  end
417
- MSSQL_DB.drop_table :baz rescue nil
418
- proc { MSSQL_DB.rename_table 'foo bar', 'baz' }.should_not raise_error
471
+ MSSQL_DB.drop_table? :foo
472
+ proc { MSSQL_DB.rename_table 'foo bar', 'foo' }.should_not raise_error
419
473
  end
420
474
 
421
- specify "should workd on schema bound tables" do
475
+ specify "should work on schema bound tables" do
422
476
  MSSQL_DB.execute(<<-SQL)
423
477
  IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'MY')
424
478
  EXECUTE sp_executesql N'create schema MY'
@@ -440,3 +494,77 @@ describe "MSSQL::Dataset#count" do
440
494
  MSSQL_DB[:items].select(:name, :value).group(:name, :value).order(:name).count.should == 1
441
495
  end
442
496
  end
497
+
498
+ describe "MSSQL::Database#create_table" do
499
+ specify "should support collate with various other column options" do
500
+ MSSQL_DB.create_table!(:items){ String :name, :size => 128, :collate => :sql_latin1_general_cp1_ci_as, :default => 'foo', :null => false, :unique => true}
501
+ MSSQL_DB[:items].insert
502
+ MSSQL_DB[:items].select_map(:name).should == ["foo"]
503
+ end
504
+ end
505
+
506
+ describe "MSSQL::Database#mssql_unicode_strings = false" do
507
+ before do
508
+ MSSQL_DB.mssql_unicode_strings = false
509
+ end
510
+ after do
511
+ MSSQL_DB.drop_table?(:items)
512
+ MSSQL_DB.mssql_unicode_strings = true
513
+ end
514
+
515
+ specify "should work correctly" do
516
+ MSSQL_DB.create_table!(:items){String :name}
517
+ MSSQL_DB[:items].mssql_unicode_strings.should == false
518
+ MSSQL_DB[:items].insert(:name=>'foo')
519
+ MSSQL_DB[:items].select_map(:name).should == ['foo']
520
+ end
521
+
522
+ specify "should be overridable at the dataset level" do
523
+ MSSQL_DB.create_table!(:items){String :name}
524
+ ds = MSSQL_DB[:items]
525
+ ds.mssql_unicode_strings.should == false
526
+ ds.mssql_unicode_strings = true
527
+ ds.mssql_unicode_strings.should == true
528
+ ds.insert(:name=>'foo')
529
+ ds.select_map(:name).should == ['foo']
530
+ end
531
+ end
532
+
533
+ describe "A MSSQL database adds index with include" do
534
+ before :all do
535
+ @table_name = :test_index_include
536
+ @db = MSSQL_DB
537
+ @db.create_table! @table_name do
538
+ integer :col1
539
+ integer :col2
540
+ integer :col3
541
+ end
542
+ end
543
+
544
+ after :all do
545
+ @db.drop_table? @table_name
546
+ end
547
+
548
+ cspecify "should be able add index with include" do
549
+ @db.alter_table @table_name do
550
+ add_index [:col1], :include => [:col2,:col3]
551
+ end
552
+ @db.indexes(@table_name).should have_key("#{@table_name}_col1_index".to_sym)
553
+ end
554
+ end
555
+
556
+ describe "MSSQL::Database#drop_column with a schema" do
557
+ before do
558
+ MSSQL_DB.run "create schema test" rescue nil
559
+ end
560
+ after do
561
+ MSSQL_DB.drop_table(:test__items)
562
+ MSSQL_DB.run "drop schema test" rescue nil
563
+ end
564
+
565
+ specify "drops columns with a default value" do
566
+ MSSQL_DB.create_table!(:test__items){ Integer :id; String :name, :default => 'widget' }
567
+ MSSQL_DB.drop_column(:test__items, :name)
568
+ MSSQL_DB[:test__items].columns.should == [:id]
569
+ end
570
+ end