sequel 3.21.0 → 3.41.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 (363) hide show
  1. data/CHANGELOG +1131 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +106 -65
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +68 -52
  7. data/doc/advanced_associations.rdoc +201 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/bin_sequel.rdoc +144 -0
  10. data/doc/cheat_sheet.rdoc +21 -21
  11. data/doc/core_extensions.rdoc +374 -0
  12. data/doc/dataset_basics.rdoc +10 -10
  13. data/doc/dataset_filtering.rdoc +54 -42
  14. data/doc/mass_assignment.rdoc +56 -0
  15. data/doc/migration.rdoc +89 -557
  16. data/doc/model_hooks.rdoc +80 -29
  17. data/doc/object_model.rdoc +576 -0
  18. data/doc/opening_databases.rdoc +121 -53
  19. data/doc/prepared_statements.rdoc +41 -15
  20. data/doc/querying.rdoc +137 -56
  21. data/doc/reflection.rdoc +36 -10
  22. data/doc/release_notes/3.22.0.txt +39 -0
  23. data/doc/release_notes/3.23.0.txt +172 -0
  24. data/doc/release_notes/3.24.0.txt +420 -0
  25. data/doc/release_notes/3.25.0.txt +88 -0
  26. data/doc/release_notes/3.26.0.txt +88 -0
  27. data/doc/release_notes/3.27.0.txt +82 -0
  28. data/doc/release_notes/3.28.0.txt +304 -0
  29. data/doc/release_notes/3.29.0.txt +459 -0
  30. data/doc/release_notes/3.30.0.txt +135 -0
  31. data/doc/release_notes/3.31.0.txt +146 -0
  32. data/doc/release_notes/3.32.0.txt +202 -0
  33. data/doc/release_notes/3.33.0.txt +157 -0
  34. data/doc/release_notes/3.34.0.txt +671 -0
  35. data/doc/release_notes/3.35.0.txt +144 -0
  36. data/doc/release_notes/3.36.0.txt +245 -0
  37. data/doc/release_notes/3.37.0.txt +338 -0
  38. data/doc/release_notes/3.38.0.txt +234 -0
  39. data/doc/release_notes/3.39.0.txt +237 -0
  40. data/doc/release_notes/3.40.0.txt +73 -0
  41. data/doc/release_notes/3.41.0.txt +155 -0
  42. data/doc/schema_modification.rdoc +585 -0
  43. data/doc/sharding.rdoc +99 -8
  44. data/doc/sql.rdoc +154 -112
  45. data/doc/testing.rdoc +169 -0
  46. data/doc/thread_safety.rdoc +17 -0
  47. data/doc/transactions.rdoc +137 -0
  48. data/doc/validations.rdoc +1 -1
  49. data/doc/virtual_rows.rdoc +78 -43
  50. data/lib/sequel/adapters/ado/access.rb +334 -0
  51. data/lib/sequel/adapters/ado/mssql.rb +18 -12
  52. data/lib/sequel/adapters/ado.rb +69 -21
  53. data/lib/sequel/adapters/amalgalite.rb +17 -14
  54. data/lib/sequel/adapters/cubrid.rb +143 -0
  55. data/lib/sequel/adapters/db2.rb +178 -85
  56. data/lib/sequel/adapters/dbi.rb +19 -21
  57. data/lib/sequel/adapters/do/mysql.rb +17 -11
  58. data/lib/sequel/adapters/do/postgres.rb +2 -61
  59. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  60. data/lib/sequel/adapters/do.rb +20 -39
  61. data/lib/sequel/adapters/firebird.rb +33 -210
  62. data/lib/sequel/adapters/ibmdb.rb +452 -0
  63. data/lib/sequel/adapters/informix.rb +6 -29
  64. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  65. data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
  66. data/lib/sequel/adapters/jdbc/db2.rb +78 -0
  67. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  68. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  69. data/lib/sequel/adapters/jdbc/h2.rb +68 -31
  70. data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
  71. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  73. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  74. data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
  75. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  76. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  77. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  78. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  79. data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
  80. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  81. data/lib/sequel/adapters/jdbc.rb +308 -114
  82. data/lib/sequel/adapters/mock.rb +372 -0
  83. data/lib/sequel/adapters/mysql.rb +130 -230
  84. data/lib/sequel/adapters/mysql2.rb +64 -63
  85. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  86. data/lib/sequel/adapters/odbc.rb +29 -10
  87. data/lib/sequel/adapters/openbase.rb +7 -11
  88. data/lib/sequel/adapters/oracle.rb +364 -57
  89. data/lib/sequel/adapters/postgres.rb +379 -145
  90. data/lib/sequel/adapters/shared/access.rb +236 -11
  91. data/lib/sequel/adapters/shared/cubrid.rb +216 -0
  92. data/lib/sequel/adapters/shared/db2.rb +353 -0
  93. data/lib/sequel/adapters/shared/firebird.rb +231 -0
  94. data/lib/sequel/adapters/shared/informix.rb +53 -0
  95. data/lib/sequel/adapters/shared/mssql.rb +412 -116
  96. data/lib/sequel/adapters/shared/mysql.rb +396 -89
  97. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
  98. data/lib/sequel/adapters/shared/oracle.rb +262 -45
  99. data/lib/sequel/adapters/shared/postgres.rb +688 -279
  100. data/lib/sequel/adapters/shared/progress.rb +5 -8
  101. data/lib/sequel/adapters/shared/sqlite.rb +317 -96
  102. data/lib/sequel/adapters/sqlite.rb +109 -46
  103. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  104. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  105. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  106. data/lib/sequel/adapters/swift.rb +31 -27
  107. data/lib/sequel/adapters/tinytds.rb +177 -25
  108. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  109. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  110. data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
  111. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  112. data/lib/sequel/ast_transformer.rb +194 -0
  113. data/lib/sequel/connection_pool/sharded_single.rb +23 -13
  114. data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
  115. data/lib/sequel/connection_pool/single.rb +11 -3
  116. data/lib/sequel/connection_pool/threaded.rb +69 -20
  117. data/lib/sequel/connection_pool.rb +20 -18
  118. data/lib/sequel/core.rb +143 -11
  119. data/lib/sequel/database/connecting.rb +66 -29
  120. data/lib/sequel/database/dataset.rb +4 -4
  121. data/lib/sequel/database/dataset_defaults.rb +63 -2
  122. data/lib/sequel/database/logging.rb +7 -2
  123. data/lib/sequel/database/misc.rb +192 -51
  124. data/lib/sequel/database/query.rb +299 -114
  125. data/lib/sequel/database/schema_generator.rb +103 -36
  126. data/lib/sequel/database/schema_methods.rb +310 -69
  127. data/lib/sequel/dataset/actions.rb +344 -90
  128. data/lib/sequel/dataset/features.rb +101 -8
  129. data/lib/sequel/dataset/graph.rb +42 -15
  130. data/lib/sequel/dataset/misc.rb +52 -25
  131. data/lib/sequel/dataset/mutation.rb +12 -7
  132. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  133. data/lib/sequel/dataset/query.rb +322 -68
  134. data/lib/sequel/dataset/sql.rb +716 -293
  135. data/lib/sequel/dataset.rb +8 -0
  136. data/lib/sequel/exceptions.rb +4 -0
  137. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  138. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  139. data/lib/sequel/extensions/blank.rb +4 -0
  140. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  141. data/lib/sequel/extensions/connection_validator.rb +109 -0
  142. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  143. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  144. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  145. data/lib/sequel/extensions/inflector.rb +4 -0
  146. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  147. data/lib/sequel/extensions/migration.rb +100 -11
  148. data/lib/sequel/extensions/named_timezones.rb +9 -0
  149. data/lib/sequel/extensions/null_dataset.rb +94 -0
  150. data/lib/sequel/extensions/pagination.rb +4 -0
  151. data/lib/sequel/extensions/pg_array.rb +539 -0
  152. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  153. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  154. data/lib/sequel/extensions/pg_hstore.rb +334 -0
  155. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  156. data/lib/sequel/extensions/pg_inet.rb +113 -0
  157. data/lib/sequel/extensions/pg_interval.rb +191 -0
  158. data/lib/sequel/extensions/pg_json.rb +212 -0
  159. data/lib/sequel/extensions/pg_range.rb +513 -0
  160. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  161. data/lib/sequel/extensions/pg_row.rb +576 -0
  162. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  163. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  164. data/lib/sequel/extensions/pretty_table.rb +17 -72
  165. data/lib/sequel/extensions/query.rb +8 -4
  166. data/lib/sequel/extensions/query_literals.rb +79 -0
  167. data/lib/sequel/extensions/schema_caching.rb +76 -0
  168. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  169. data/lib/sequel/extensions/select_remove.rb +39 -0
  170. data/lib/sequel/extensions/server_block.rb +140 -0
  171. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  172. data/lib/sequel/extensions/sql_expr.rb +8 -110
  173. data/lib/sequel/extensions/string_date_time.rb +4 -0
  174. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  175. data/lib/sequel/extensions/to_dot.rb +99 -83
  176. data/lib/sequel/model/associations.rb +1263 -409
  177. data/lib/sequel/model/base.rb +624 -171
  178. data/lib/sequel/model/errors.rb +1 -1
  179. data/lib/sequel/model/exceptions.rb +24 -2
  180. data/lib/sequel/model/inflections.rb +1 -1
  181. data/lib/sequel/model.rb +30 -11
  182. data/lib/sequel/no_core_ext.rb +2 -0
  183. data/lib/sequel/plugins/active_model.rb +13 -1
  184. data/lib/sequel/plugins/association_pks.rb +137 -16
  185. data/lib/sequel/plugins/caching.rb +25 -18
  186. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  187. data/lib/sequel/plugins/composition.rb +44 -12
  188. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  189. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  190. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  191. data/lib/sequel/plugins/dirty.rb +214 -0
  192. data/lib/sequel/plugins/eager_each.rb +59 -0
  193. data/lib/sequel/plugins/force_encoding.rb +6 -6
  194. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  195. data/lib/sequel/plugins/identity_map.rb +134 -15
  196. data/lib/sequel/plugins/instance_filters.rb +10 -0
  197. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  198. data/lib/sequel/plugins/json_serializer.rb +77 -6
  199. data/lib/sequel/plugins/list.rb +13 -2
  200. data/lib/sequel/plugins/many_through_many.rb +103 -51
  201. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  202. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  203. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  204. data/lib/sequel/plugins/pg_row.rb +121 -0
  205. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  206. data/lib/sequel/plugins/prepared_statements.rb +168 -0
  207. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  208. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  209. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  210. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  211. data/lib/sequel/plugins/schema.rb +8 -3
  212. data/lib/sequel/plugins/serialization.rb +98 -49
  213. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  214. data/lib/sequel/plugins/sharding.rb +21 -54
  215. data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
  216. data/lib/sequel/plugins/static_cache.rb +99 -0
  217. data/lib/sequel/plugins/subclasses.rb +29 -3
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  219. data/lib/sequel/plugins/timestamps.rb +1 -1
  220. data/lib/sequel/plugins/touch.rb +18 -6
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  223. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  224. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  225. data/lib/sequel/plugins/validation_helpers.rb +57 -4
  226. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  227. data/lib/sequel/sql.rb +721 -141
  228. data/lib/sequel/timezones.rb +67 -40
  229. data/lib/sequel/version.rb +1 -1
  230. data/spec/adapters/db2_spec.rb +146 -0
  231. data/spec/adapters/firebird_spec.rb +53 -39
  232. data/spec/adapters/mssql_spec.rb +261 -66
  233. data/spec/adapters/mysql_spec.rb +597 -352
  234. data/spec/adapters/oracle_spec.rb +92 -117
  235. data/spec/adapters/postgres_spec.rb +2103 -341
  236. data/spec/adapters/spec_helper.rb +16 -6
  237. data/spec/adapters/sqlite_spec.rb +237 -76
  238. data/spec/core/connection_pool_spec.rb +270 -141
  239. data/spec/core/database_spec.rb +980 -524
  240. data/spec/core/dataset_spec.rb +1658 -1243
  241. data/spec/core/expression_filters_spec.rb +741 -334
  242. data/spec/core/mock_adapter_spec.rb +453 -0
  243. data/spec/core/object_graph_spec.rb +88 -129
  244. data/spec/core/schema_generator_spec.rb +4 -4
  245. data/spec/core/schema_spec.rb +556 -53
  246. data/spec/core/spec_helper.rb +7 -48
  247. data/spec/core_extensions_spec.rb +626 -0
  248. data/spec/extensions/active_model_spec.rb +13 -0
  249. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  250. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  251. data/spec/extensions/association_dependencies_spec.rb +15 -25
  252. data/spec/extensions/association_pks_spec.rb +227 -33
  253. data/spec/extensions/association_proxies_spec.rb +4 -4
  254. data/spec/extensions/boolean_readers_spec.rb +25 -25
  255. data/spec/extensions/caching_spec.rb +47 -51
  256. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  257. data/spec/extensions/columns_introspection_spec.rb +91 -0
  258. data/spec/extensions/composition_spec.rb +18 -13
  259. data/spec/extensions/connection_validator_spec.rb +118 -0
  260. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  261. data/spec/extensions/constraint_validations_spec.rb +316 -0
  262. data/spec/extensions/dataset_associations_spec.rb +199 -0
  263. data/spec/extensions/defaults_setter_spec.rb +88 -0
  264. data/spec/extensions/dirty_spec.rb +155 -0
  265. data/spec/extensions/eager_each_spec.rb +34 -0
  266. data/spec/extensions/eval_inspect_spec.rb +67 -0
  267. data/spec/extensions/force_encoding_spec.rb +4 -2
  268. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  269. data/spec/extensions/identity_map_spec.rb +142 -24
  270. data/spec/extensions/inflector_spec.rb +0 -4
  271. data/spec/extensions/instance_filters_spec.rb +11 -21
  272. data/spec/extensions/instance_hooks_spec.rb +72 -0
  273. data/spec/extensions/json_serializer_spec.rb +49 -12
  274. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  275. data/spec/extensions/list_spec.rb +49 -40
  276. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  277. data/spec/extensions/many_through_many_spec.rb +368 -254
  278. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  279. data/spec/extensions/migration_spec.rb +140 -35
  280. data/spec/extensions/named_timezones_spec.rb +29 -11
  281. data/spec/extensions/nested_attributes_spec.rb +268 -89
  282. data/spec/extensions/null_dataset_spec.rb +85 -0
  283. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  284. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  285. data/spec/extensions/pg_array_spec.rb +324 -0
  286. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  287. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  288. data/spec/extensions/pg_hstore_spec.rb +200 -0
  289. data/spec/extensions/pg_inet_spec.rb +47 -0
  290. data/spec/extensions/pg_interval_spec.rb +72 -0
  291. data/spec/extensions/pg_json_spec.rb +99 -0
  292. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  293. data/spec/extensions/pg_range_spec.rb +395 -0
  294. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  295. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  296. data/spec/extensions/pg_row_spec.rb +340 -0
  297. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  298. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  299. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  300. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  301. data/spec/extensions/prepared_statements_spec.rb +87 -0
  302. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  303. data/spec/extensions/pretty_table_spec.rb +7 -6
  304. data/spec/extensions/query_literals_spec.rb +167 -0
  305. data/spec/extensions/query_spec.rb +9 -3
  306. data/spec/extensions/rcte_tree_spec.rb +50 -43
  307. data/spec/extensions/schema_caching_spec.rb +41 -0
  308. data/spec/extensions/schema_dumper_spec.rb +434 -49
  309. data/spec/extensions/schema_spec.rb +30 -49
  310. data/spec/extensions/select_remove_spec.rb +38 -0
  311. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  312. data/spec/extensions/serialization_spec.rb +86 -48
  313. data/spec/extensions/server_block_spec.rb +90 -0
  314. data/spec/extensions/sharding_spec.rb +69 -143
  315. data/spec/extensions/single_table_inheritance_spec.rb +65 -29
  316. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  317. data/spec/extensions/spec_helper.rb +34 -67
  318. data/spec/extensions/split_array_nil_spec.rb +24 -0
  319. data/spec/extensions/sql_expr_spec.rb +29 -60
  320. data/spec/extensions/static_cache_spec.rb +145 -0
  321. data/spec/extensions/subclasses_spec.rb +14 -0
  322. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  323. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  324. data/spec/extensions/timestamps_spec.rb +6 -6
  325. data/spec/extensions/to_dot_spec.rb +8 -11
  326. data/spec/extensions/touch_spec.rb +53 -14
  327. data/spec/extensions/tree_spec.rb +11 -26
  328. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  329. data/spec/extensions/update_primary_key_spec.rb +30 -24
  330. data/spec/extensions/validation_class_methods_spec.rb +77 -68
  331. data/spec/extensions/validation_helpers_spec.rb +48 -37
  332. data/spec/extensions/xml_serializer_spec.rb +29 -4
  333. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  334. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  335. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  336. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  337. data/spec/integration/associations_test.rb +659 -21
  338. data/spec/integration/database_test.rb +25 -5
  339. data/spec/integration/dataset_test.rb +729 -141
  340. data/spec/integration/eager_loader_test.rb +38 -54
  341. data/spec/integration/migrator_test.rb +2 -3
  342. data/spec/integration/model_test.rb +81 -2
  343. data/spec/integration/plugin_test.rb +871 -160
  344. data/spec/integration/prepared_statement_test.rb +272 -128
  345. data/spec/integration/schema_test.rb +377 -57
  346. data/spec/integration/spec_helper.rb +49 -32
  347. data/spec/integration/timezone_test.rb +38 -12
  348. data/spec/integration/transaction_test.rb +183 -8
  349. data/spec/integration/type_test.rb +40 -8
  350. data/spec/model/association_reflection_spec.rb +207 -8
  351. data/spec/model/associations_spec.rb +1206 -693
  352. data/spec/model/base_spec.rb +334 -100
  353. data/spec/model/dataset_methods_spec.rb +45 -27
  354. data/spec/model/eager_loading_spec.rb +828 -692
  355. data/spec/model/hooks_spec.rb +355 -67
  356. data/spec/model/model_spec.rb +251 -179
  357. data/spec/model/plugins_spec.rb +24 -13
  358. data/spec/model/record_spec.rb +506 -232
  359. data/spec/model/spec_helper.rb +16 -77
  360. data/spec/model/validations_spec.rb +38 -2
  361. data/spec/rcov.opts +2 -0
  362. metadata +223 -81
  363. data/spec/core/core_sql_spec.rb +0 -451
@@ -1,35 +1,59 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
- if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
4
3
  describe "Database schema parser" do
5
4
  before do
6
5
  @iom = INTEGRATION_DB.identifier_output_method
7
6
  @iim = INTEGRATION_DB.identifier_input_method
8
7
  @defsch = INTEGRATION_DB.default_schema
9
- clear_sqls
8
+ @qi = INTEGRATION_DB.quote_identifiers?
10
9
  end
11
10
  after do
12
11
  INTEGRATION_DB.identifier_output_method = @iom
13
12
  INTEGRATION_DB.identifier_input_method = @iim
14
13
  INTEGRATION_DB.default_schema = @defsch
15
- INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
14
+ INTEGRATION_DB.quote_identifiers = @qi
15
+ INTEGRATION_DB.drop_table?(:items)
16
16
  end
17
17
 
18
- specify "should handle a database with a identifier_output_method" do
18
+ specify "should handle a database with a identifier methods" do
19
19
  INTEGRATION_DB.identifier_output_method = :reverse
20
20
  INTEGRATION_DB.identifier_input_method = :reverse
21
+ INTEGRATION_DB.quote_identifiers = true
21
22
  INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
22
23
  INTEGRATION_DB.create_table!(:items){Integer :number}
23
- INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
24
- INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
24
+ begin
25
+ INTEGRATION_DB.schema(:items, :reload=>true).should be_a_kind_of(Array)
26
+ INTEGRATION_DB.schema(:items, :reload=>true).first.first.should == :number
27
+ ensure
28
+ INTEGRATION_DB.drop_table(:items)
29
+ end
30
+ end
31
+
32
+ specify "should handle a dataset with identifier methods different than the database's" do
33
+ INTEGRATION_DB.identifier_output_method = :reverse
34
+ INTEGRATION_DB.identifier_input_method = :reverse
35
+ INTEGRATION_DB.quote_identifiers = true
36
+ INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
37
+ INTEGRATION_DB.create_table!(:items){Integer :number}
38
+ INTEGRATION_DB.identifier_output_method = @iom
39
+ INTEGRATION_DB.identifier_input_method = @iim
40
+ ds = INTEGRATION_DB[:items]
41
+ ds.identifier_output_method = :reverse
42
+ ds.identifier_input_method = :reverse
43
+ begin
44
+ INTEGRATION_DB.schema(ds, :reload=>true).should be_a_kind_of(Array)
45
+ INTEGRATION_DB.schema(ds, :reload=>true).first.first.should == :number
46
+ ensure
47
+ INTEGRATION_DB.identifier_output_method = :reverse
48
+ INTEGRATION_DB.identifier_input_method = :reverse
49
+ INTEGRATION_DB.drop_table(:items)
50
+ end
25
51
  end
26
52
 
27
53
  specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
28
54
  INTEGRATION_DB.create_table!(:items){Integer :number}
29
55
  INTEGRATION_DB.schema(:items, :reload=>true)
30
- clear_sqls
31
56
  INTEGRATION_DB.schema(:items)
32
- clear_sqls
33
57
  INTEGRATION_DB.schema(:items, :reload=>true)
34
58
  end
35
59
 
@@ -56,11 +80,10 @@ describe "Database schema parser" do
56
80
  col_info = col.last
57
81
  col_info.should be_a_kind_of(Hash)
58
82
  col_info[:type].should == :integer
59
- clear_sqls
60
83
  INTEGRATION_DB.schema(:items)
61
84
  end
62
85
 
63
- cspecify "should parse primary keys from the schema properly", [proc{|db| db.adapter_scheme != :jdbc}, :mssql] do
86
+ specify "should parse primary keys from the schema properly" do
64
87
  INTEGRATION_DB.create_table!(:items){Integer :number}
65
88
  INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
66
89
  INTEGRATION_DB.create_table!(:items){primary_key :number}
@@ -85,7 +108,17 @@ describe "Database schema parser" do
85
108
  INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
86
109
  end
87
110
 
88
- specify "should parse types from the schema properly" do
111
+ specify "should parse current timestamp defaults from the schema properly" do
112
+ INTEGRATION_DB.create_table!(:items){Time :a, :default=>Sequel::CURRENT_TIMESTAMP}
113
+ INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == Sequel::CURRENT_TIMESTAMP
114
+ end
115
+
116
+ cspecify "should parse current date defaults from the schema properly", :mysql, :oracle do
117
+ INTEGRATION_DB.create_table!(:items){Date :a, :default=>Sequel::CURRENT_DATE}
118
+ INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == Sequel::CURRENT_DATE
119
+ end
120
+
121
+ cspecify "should parse types from the schema properly", [:jdbc, :db2], :oracle do
89
122
  INTEGRATION_DB.create_table!(:items){Integer :number}
90
123
  INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
91
124
  INTEGRATION_DB.create_table!(:items){Fixnum :number}
@@ -113,17 +146,20 @@ describe "Database schema parser" do
113
146
  INTEGRATION_DB.create_table!(:items){FalseClass :number}
114
147
  INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
115
148
  end
116
- end
117
- end
149
+ end if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
118
150
 
119
- begin
120
- INTEGRATION_DB.drop_table(:blah) rescue nil
151
+ test_indexes = begin
152
+ INTEGRATION_DB.drop_table?(:blah)
121
153
  INTEGRATION_DB.indexes(:blah)
154
+ true
122
155
  rescue Sequel::NotImplemented
156
+ false
123
157
  rescue
158
+ true
159
+ end
124
160
  describe "Database index parsing" do
125
161
  after do
126
- INTEGRATION_DB.drop_table(:items)
162
+ INTEGRATION_DB.drop_table?(:items)
127
163
  end
128
164
 
129
165
  specify "should parse indexes into a hash" do
@@ -149,17 +185,73 @@ describe "Database index parsing" do
149
185
  INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a; primary_key [:n, :a]}
150
186
  INTEGRATION_DB.indexes(:items).should == {}
151
187
  end
188
+ end if test_indexes
189
+
190
+ test_foreign_key_list = begin
191
+ INTEGRATION_DB.drop_table?(:blah)
192
+ INTEGRATION_DB.foreign_key_list(:blah)
193
+ true
194
+ rescue Sequel::NotImplemented
195
+ false
196
+ rescue
197
+ true
152
198
  end
153
- end
199
+ describe "Database foreign key parsing" do
200
+ before do
201
+ @db = INTEGRATION_DB
202
+ @pr = lambda do |table, *expected|
203
+ 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)}
204
+ actual.zip(expected).each do |a, e|
205
+ if e.last.first == :pk
206
+ if a.last == nil
207
+ a.pop
208
+ e.pop
209
+ else
210
+ e.last.shift
211
+ end
212
+ end
213
+ a.should == e
214
+ end
215
+ actual.length.should == expected.length
216
+ end
217
+ end
218
+ after do
219
+ @db.drop_table?(:b, :a)
220
+ end
221
+
222
+ specify "should parse foreign key information into an array of hashes" do
223
+ @db.create_table!(:a, :engine=>:InnoDB){primary_key :c; Integer :d; index :d, :unique=>true}
224
+ @db.create_table!(:b, :engine=>:InnoDB){foreign_key :e, :a}
225
+ @pr[:a]
226
+ @pr[:b, [[:e], :a, [:pk, :c]]]
227
+
228
+ @db.alter_table(:b){add_foreign_key :f, :a, :key=>[:d]}
229
+ @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:d]]]
230
+
231
+ @db.alter_table(:b){add_foreign_key [:f], :a, :key=>[:c]}
232
+ @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:c]], [[:f], :a, [:d]]]
233
+
234
+ @db.alter_table(:a){add_index [:d, :c], :unique=>true}
235
+ @db.alter_table(:b){add_foreign_key [:f, :e], :a, :key=>[:d, :c]}
236
+ @pr[:b, [[:e], :a, [:pk, :c]], [[:f], :a, [:c]], [[:f], :a, [:d]], [[:f, :e], :a, [:d, :c]]]
237
+ end
238
+
239
+ specify "should handle composite foreign and primary keys" do
240
+ @db.create_table!(:a, :engine=>:InnoDB){Integer :b; Integer :c; primary_key [:b, :c]; index [:c, :b], :unique=>true}
241
+ @db.create_table!(:b, :engine=>:InnoDB){Integer :e; Integer :f; foreign_key [:e, :f], :a; foreign_key [:f, :e], :a, :key=>[:c, :b]}
242
+ @pr[:b, [[:e, :f], :a, [:pk, :b, :c]], [[:f, :e], :a, [:c, :b]]]
243
+ end
244
+ end if test_foreign_key_list
154
245
 
155
246
  describe "Database schema modifiers" do
156
247
  before do
157
248
  @db = INTEGRATION_DB
158
249
  @ds = @db[:items]
159
- clear_sqls
160
250
  end
161
251
  after do
162
- @db.drop_table(:items) if @db.table_exists?(:items)
252
+ # Use instead of drop_table? to work around issues on jdbc/db2
253
+ @db.drop_table(:items) rescue nil
254
+ @db.drop_table(:items2) rescue nil
163
255
  end
164
256
 
165
257
  specify "should create tables correctly" do
@@ -170,12 +262,60 @@ describe "Database schema modifiers" do
170
262
  @ds.columns!.should == [:number]
171
263
  end
172
264
 
265
+ specify "should create tables from select statements correctly" do
266
+ @db.create_table!(:items){Integer :number}
267
+ @ds.insert([10])
268
+ @db.create_table(:items2, :as=>@db[:items])
269
+ @db.schema(:items2, :reload=>true).map{|x| x.first}.should == [:number]
270
+ @db[:items2].columns.should == [:number]
271
+ @db[:items2].all.should == [{:number=>10}]
272
+ end
273
+
274
+ specify "should handle create table in a rolled back transaction" do
275
+ @db.drop_table?(:items)
276
+ @db.transaction(:rollback=>:always){@db.create_table(:items){Integer :number}}
277
+ @db.table_exists?(:items).should be_false
278
+ end if INTEGRATION_DB.supports_transactional_ddl?
279
+
280
+ describe "join tables" do
281
+ after do
282
+ @db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
283
+ @db.drop_table(:cats, :dogs)
284
+ @db.table_exists?(:cats_dogs).should == false
285
+ end
286
+
287
+ specify "should create join tables correctly" do
288
+ @db.create_table!(:cats){primary_key :id}
289
+ @db.create_table!(:dogs){primary_key :id}
290
+ @db.create_join_table(:cat_id=>:cats, :dog_id=>:dogs)
291
+ @db.table_exists?(:cats_dogs).should == true
292
+ end
293
+ end
294
+
173
295
  specify "should create temporary tables without raising an exception" do
174
296
  @db.create_table!(:items, :temp=>true){Integer :number}
175
297
  end
176
298
 
299
+ specify "should have create_table? only create the table if it doesn't already exist" do
300
+ @db.create_table!(:items){String :a}
301
+ @db.create_table?(:items){String :b}
302
+ @db[:items].columns.should == [:a]
303
+ @db.drop_table?(:items)
304
+ @db.create_table?(:items){String :b}
305
+ @db[:items].columns.should == [:b]
306
+ end
307
+
308
+ specify "should have create_table? work correctly with indexes" do
309
+ @db.create_table!(:items){String :a, :index=>true}
310
+ @db.create_table?(:items){String :b, :index=>true}
311
+ @db[:items].columns.should == [:a]
312
+ @db.drop_table?(:items)
313
+ @db.create_table?(:items){String :b, :index=>true}
314
+ @db[:items].columns.should == [:b]
315
+ end
316
+
177
317
  specify "should rename tables correctly" do
178
- @db.drop_table(:items) rescue nil
318
+ @db.drop_table?(:items)
179
319
  @db.create_table!(:items2){Integer :number}
180
320
  @db.rename_table(:items2, :items)
181
321
  @db.table_exists?(:items).should == true
@@ -215,30 +355,45 @@ describe "Database schema modifiers" do
215
355
  specify "should add columns to tables correctly" do
216
356
  @db.create_table!(:items){Integer :number}
217
357
  @ds.insert(:number=>10)
218
- @db.alter_table(:items){add_column :name, :text}
358
+ @db.alter_table(:items){add_column :name, String}
219
359
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
220
360
  @ds.columns!.should == [:number, :name]
221
361
  @ds.all.should == [{:number=>10, :name=>nil}]
222
362
  end
223
363
 
224
- cspecify "should add primary key columns to tables correctly", :h2 do
364
+ cspecify "should add primary key columns to tables correctly", :h2, :derby do
225
365
  @db.create_table!(:items){Integer :number}
226
366
  @ds.insert(:number=>10)
227
367
  @db.alter_table(:items){add_primary_key :id}
228
368
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :id]
229
369
  @ds.columns!.should == [:number, :id]
230
370
  @ds.map(:number).should == [10]
371
+ proc{@ds.insert(:id=>@ds.map(:id).first)}.should raise_error
372
+ end
373
+
374
+ specify "should drop primary key constraints from tables correctly" do
375
+ @db.create_table!(:items){Integer :number; primary_key [:number], :name=>:items_pk}
376
+ @ds.insert(:number=>10)
377
+ @db.alter_table(:items){drop_constraint :items_pk, :type=>:primary_key}
378
+ @ds.map(:number).should == [10]
379
+ proc{@ds.insert(10)}.should_not raise_error
231
380
  end
232
381
 
233
382
  specify "should add foreign key columns to tables correctly" do
234
383
  @db.create_table!(:items){primary_key :id}
235
- i = @ds.insert
384
+ @ds.insert
385
+ i = @ds.get(:id)
236
386
  @db.alter_table(:items){add_foreign_key :item_id, :items}
237
387
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
238
388
  @ds.columns!.should == [:id, :item_id]
239
389
  @ds.all.should == [{:id=>i, :item_id=>nil}]
240
390
  end
241
391
 
392
+ specify "should not allow NULLs in a primary key" do
393
+ @db.create_table!(:items){String :id, :primary_key=>true}
394
+ proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
395
+ end
396
+
242
397
  specify "should rename columns correctly" do
243
398
  @db.create_table!(:items){Integer :id}
244
399
  @ds.insert(:id=>10)
@@ -269,7 +424,27 @@ describe "Database schema modifiers" do
269
424
  proc{@ds.insert(:n=>nil)}.should raise_error(Sequel::DatabaseError)
270
425
  end
271
426
 
272
- specify "should set column NULL/NOT NULL correctly" do
427
+ specify "should rename columns when the table is referenced by a foreign key" do
428
+ @db.create_table!(:items2){primary_key :id; Integer :a}
429
+ @db.create_table!(:items){Integer :id, :primary_key=>true; foreign_key :items_id, :items2}
430
+ @db[:items2].insert(:a=>10)
431
+ @ds.insert(:id=>1)
432
+ @db.alter_table(:items2){rename_column :a, :b}
433
+ @db[:items2].insert(:b=>20)
434
+ @ds.insert(:id=>2)
435
+ @db[:items2].select_order_map([:id, :b]).should == [[1, 10], [2, 20]]
436
+ end
437
+
438
+ cspecify "should rename primary_key columns correctly", :db2 do
439
+ @db.create_table!(:items){Integer :id, :primary_key=>true}
440
+ @ds.insert(:id=>10)
441
+ @db.alter_table(:items){rename_column :id, :id2}
442
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id2]
443
+ @ds.columns!.should == [:id2]
444
+ @ds.all.should == [{:id2=>10}]
445
+ end
446
+
447
+ cspecify "should set column NULL/NOT NULL correctly", [:jdbc, :db2], [:db2] do
273
448
  @db.create_table!(:items, :engine=>:InnoDB){Integer :id}
274
449
  @ds.insert(:id=>10)
275
450
  @db.alter_table(:items){set_column_allow_null :id, false}
@@ -277,7 +452,7 @@ describe "Database schema modifiers" do
277
452
  @ds.columns!.should == [:id]
278
453
  proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
279
454
  @db.alter_table(:items){set_column_allow_null :id, true}
280
- @ds.insert
455
+ @ds.insert(:id=>nil)
281
456
  @ds.all.should == [{:id=>10}, {:id=>nil}]
282
457
  end
283
458
 
@@ -291,45 +466,119 @@ describe "Database schema modifiers" do
291
466
  @ds.all.should == [{:id=>10}, {:id=>20}]
292
467
  end
293
468
 
294
- specify "should set column types correctly" do
469
+ cspecify "should set column types correctly", [:jdbc, :db2], [:db2], :oracle do
295
470
  @db.create_table!(:items){Integer :id}
296
471
  @ds.insert(:id=>10)
297
472
  @db.alter_table(:items){set_column_type :id, String}
298
473
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
299
474
  @ds.columns!.should == [:id]
300
- @ds.insert(:id=>20)
475
+ @ds.insert(:id=>'20')
301
476
  @ds.all.should == [{:id=>"10"}, {:id=>"20"}]
302
477
  end
303
478
 
304
- cspecify "should add unique constraints and foreign key table constraints correctly", :sqlite do
305
- @db.create_table!(:items){Integer :id; Integer :item_id}
479
+ cspecify "should set column types without modifying NULL/NOT NULL", [:jdbc, :db2], [:db2], :oracle, :derby do
480
+ @db.create_table!(:items){Integer :id, :null=>false, :default=>2}
481
+ proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
482
+ @db.alter_table(:items){set_column_type :id, String}
483
+ proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
484
+
485
+ @db.create_table!(:items){Integer :id}
486
+ @ds.insert(:id=>nil)
487
+ @db.alter_table(:items){set_column_type :id, String}
488
+ @ds.insert(:id=>nil)
489
+ @ds.map(:id).should == [nil, nil]
490
+ end
491
+
492
+ cspecify "should set column types without modifying defaults", [:jdbc, :db2], [:db2], :oracle, :derby do
493
+ @db.create_table!(:items){Integer :id, :default=>0}
494
+ @ds.insert
495
+ @ds.map(:id).should == [0]
496
+ @db.alter_table(:items){set_column_type :id, String}
497
+ @ds.insert
498
+ @ds.map(:id).should == ['0', '0']
499
+
500
+ @db.create_table!(:items){String :id, :default=>'a'}
501
+ @ds.insert
502
+ @ds.map(:id).should == %w'a'
503
+ @db.alter_table(:items){set_column_type :id, String, :size=>1}
504
+ @ds.insert
505
+ @ds.map(:id).should == %w'a a'
506
+ end
507
+
508
+ specify "should add unnamed unique constraints and foreign key table constraints correctly" do
509
+ @db.create_table!(:items, :engine=>:InnoDB){Integer :id; Integer :item_id}
306
510
  @db.alter_table(:items) do
307
511
  add_unique_constraint [:item_id, :id]
308
512
  add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
309
513
  end
310
514
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
311
515
  @ds.columns!.should == [:id, :item_id]
516
+ proc{@ds.insert(1, 1)}.should_not raise_error
517
+ proc{@ds.insert(1, 1)}.should raise_error
518
+ proc{@ds.insert(1, 2)}.should raise_error
519
+ end
520
+
521
+ specify "should add named unique constraints and foreign key table constraints correctly" do
522
+ @db.create_table!(:items, :engine=>:InnoDB){Integer :id, :null=>false; Integer :item_id, :null=>false}
523
+ @db.alter_table(:items) do
524
+ add_unique_constraint [:item_id, :id], :name=>:unique_iii
525
+ add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:fk_iii
526
+ end
527
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
528
+ @ds.columns!.should == [:id, :item_id]
529
+ proc{@ds.insert(1, 1)}.should_not raise_error
530
+ proc{@ds.insert(1, 1)}.should raise_error
531
+ proc{@ds.insert(1, 2)}.should raise_error
312
532
  end
313
533
 
314
- cspecify "should remove columns from tables correctly", :h2, :mssql do
534
+ specify "should drop unique constraints and foreign key table constraints correctly" do
315
535
  @db.create_table!(:items) do
316
- primary_key :id
317
- String :name
318
- Integer :number
319
- foreign_key :item_id, :items
536
+ Integer :id
537
+ Integer :item_id
538
+ unique [:item_id, :id], :name=>:items_uk
539
+ foreign_key [:id, :item_id], :items, :key=>[:item_id, :id], :name=>:items_fk
540
+ end
541
+ @db.alter_table(:items) do
542
+ drop_constraint(:items_fk, :type=>:foreign_key)
543
+ drop_constraint(:items_uk, :type=>:unique)
320
544
  end
321
- @ds.insert(:number=>10)
322
- @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
323
- @ds.columns!.should == [:id, :name, :number, :item_id]
324
- @db.drop_column(:items, :number)
325
- @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
326
- @ds.columns!.should == [:id, :name, :item_id]
327
- @db.drop_column(:items, :name)
328
545
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
329
546
  @ds.columns!.should == [:id, :item_id]
330
- @db.drop_column(:items, :item_id)
547
+ proc{@ds.insert(1, 2)}.should_not raise_error
548
+ proc{@ds.insert(1, 2)}.should_not raise_error
549
+ end
550
+
551
+ specify "should remove columns from tables correctly" do
552
+ @db.create_table!(:items) do
553
+ primary_key :id
554
+ Integer :i
555
+ end
556
+ @ds.insert(:i=>10)
557
+ @db.drop_column(:items, :i)
331
558
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
332
- @ds.columns!.should == [:id]
559
+ end
560
+
561
+ specify "should remove columns with defaults from tables correctly" do
562
+ @db.create_table!(:items) do
563
+ primary_key :id
564
+ Integer :i, :default=>20
565
+ end
566
+ @ds.insert(:i=>10)
567
+ @db.drop_column(:items, :i)
568
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
569
+ end
570
+
571
+ cspecify "should remove foreign key columns from tables correctly", :h2, :mssql, :hsqldb do
572
+ # MySQL with InnoDB cannot drop foreign key columns unless you know the
573
+ # name of the constraint, see Bug #14347
574
+ @db.create_table!(:items, :engine=>:MyISAM) do
575
+ primary_key :id
576
+ Integer :i
577
+ foreign_key :item_id, :items
578
+ end
579
+ @ds.insert(:i=>10)
580
+ @db.drop_column(:items, :item_id)
581
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :i]
333
582
  end
334
583
 
335
584
  specify "should remove multiple columns in a single alter_table block" do
@@ -340,20 +589,44 @@ describe "Database schema modifiers" do
340
589
  end
341
590
  @ds.insert(:number=>10)
342
591
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number]
343
- @ds.columns!.should == [:id, :name, :number]
344
592
  @db.alter_table(:items) do
345
593
  drop_column :name
346
594
  drop_column :number
347
595
  end
348
596
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
349
- @ds.columns!.should == [:id]
597
+ end
598
+
599
+ cspecify "should work correctly with many operations in a single alter_table call", [:jdbc, :db2], [:db2] do
600
+ @db.create_table!(:items) do
601
+ primary_key :id
602
+ String :name2
603
+ String :number2
604
+ constraint :bar, Sequel.~(:id=>nil)
605
+ end
606
+ @ds.insert(:name2=>'A12')
607
+ @db.alter_table(:items) do
608
+ add_column :number, Integer
609
+ drop_column :number2
610
+ rename_column :name2, :name
611
+ drop_constraint :bar
612
+ set_column_not_null :name
613
+ set_column_default :name, 'A13'
614
+ add_constraint :foo, Sequel.like(:name, 'A%')
615
+ end
616
+ @db[:items].first.should == {:id=>1, :name=>'A12', :number=>nil}
617
+ @db[:items].delete
618
+ proc{@db[:items].insert(:name=>nil)}.should raise_error(Sequel::DatabaseError)
619
+ @db[:items].insert(:number=>1)
620
+ @db[:items].get(:name).should == 'A13'
350
621
  end
351
622
  end
352
623
 
353
- begin
624
+ test_tables = begin
354
625
  INTEGRATION_DB.tables
626
+ true
355
627
  rescue Sequel::NotImplemented
356
- rescue
628
+ false
629
+ end
357
630
  describe "Database#tables" do
358
631
  before do
359
632
  class ::String
@@ -362,25 +635,72 @@ describe "Database#tables" do
362
635
  "xxxxx#{@@xxxxx += 1}"
363
636
  end
364
637
  end
365
- @iom = INTEGRATION_DB.identifier_output_method
366
- @iim = INTEGRATION_DB.identifier_input_method
367
- clear_sqls
638
+ @db = INTEGRATION_DB
639
+ @db.create_table(:sequel_test_table){Integer :a}
640
+ @db.create_view :sequel_test_view, @db[:sequel_test_table]
641
+ @iom = @db.identifier_output_method
642
+ @iim = @db.identifier_input_method
368
643
  end
369
644
  after do
370
- INTEGRATION_DB.identifier_output_method = @iom
371
- INTEGRATION_DB.identifier_input_method = @iim
645
+ @db.identifier_output_method = @iom
646
+ @db.identifier_input_method = @iim
647
+ @db.drop_view :sequel_test_view
648
+ @db.drop_table :sequel_test_table
372
649
  end
373
650
 
374
651
  specify "should return an array of symbols" do
375
- ts = INTEGRATION_DB.tables
652
+ ts = @db.tables
376
653
  ts.should be_a_kind_of(Array)
377
654
  ts.each{|t| t.should be_a_kind_of(Symbol)}
655
+ ts.should include(:sequel_test_table)
656
+ ts.should_not include(:sequel_test_view)
378
657
  end
379
658
 
380
659
  specify "should respect the database's identifier_output_method" do
381
- INTEGRATION_DB.identifier_output_method = :xxxxx
382
- INTEGRATION_DB.identifier_input_method = :xxxxx
383
- INTEGRATION_DB.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
660
+ @db.identifier_output_method = :xxxxx
661
+ @db.identifier_input_method = :xxxxx
662
+ @db.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
384
663
  end
664
+ end if test_tables
665
+
666
+ test_views = begin
667
+ INTEGRATION_DB.views
668
+ true
669
+ rescue Sequel::NotImplemented
670
+ false
385
671
  end
386
- end
672
+ describe "Database#views" do
673
+ before do
674
+ class ::String
675
+ @@xxxxx = 0
676
+ def xxxxx
677
+ "xxxxx#{@@xxxxx += 1}"
678
+ end
679
+ end
680
+ @db = INTEGRATION_DB
681
+ @db.create_table(:sequel_test_table){Integer :a}
682
+ @db.create_view :sequel_test_view, @db[:sequel_test_table]
683
+ @iom = @db.identifier_output_method
684
+ @iim = @db.identifier_input_method
685
+ end
686
+ after do
687
+ @db.identifier_output_method = @iom
688
+ @db.identifier_input_method = @iim
689
+ @db.drop_view :sequel_test_view
690
+ @db.drop_table :sequel_test_table
691
+ end
692
+
693
+ specify "should return an array of symbols" do
694
+ ts = @db.views
695
+ ts.should be_a_kind_of(Array)
696
+ ts.each{|t| t.should be_a_kind_of(Symbol)}
697
+ ts.should_not include(:sequel_test_table)
698
+ ts.should include(:sequel_test_view)
699
+ end
700
+
701
+ specify "should respect the database's identifier_output_method" do
702
+ @db.identifier_output_method = :xxxxx
703
+ @db.identifier_input_method = :xxxxx
704
+ @db.views.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
705
+ end
706
+ end if test_views