viking-sequel 3.10.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 (237) hide show
  1. data/CHANGELOG +3134 -0
  2. data/COPYING +19 -0
  3. data/README.rdoc +723 -0
  4. data/Rakefile +193 -0
  5. data/bin/sequel +196 -0
  6. data/doc/advanced_associations.rdoc +644 -0
  7. data/doc/cheat_sheet.rdoc +218 -0
  8. data/doc/dataset_basics.rdoc +106 -0
  9. data/doc/dataset_filtering.rdoc +158 -0
  10. data/doc/opening_databases.rdoc +296 -0
  11. data/doc/prepared_statements.rdoc +104 -0
  12. data/doc/reflection.rdoc +84 -0
  13. data/doc/release_notes/1.0.txt +38 -0
  14. data/doc/release_notes/1.1.txt +143 -0
  15. data/doc/release_notes/1.3.txt +101 -0
  16. data/doc/release_notes/1.4.0.txt +53 -0
  17. data/doc/release_notes/1.5.0.txt +155 -0
  18. data/doc/release_notes/2.0.0.txt +298 -0
  19. data/doc/release_notes/2.1.0.txt +271 -0
  20. data/doc/release_notes/2.10.0.txt +328 -0
  21. data/doc/release_notes/2.11.0.txt +215 -0
  22. data/doc/release_notes/2.12.0.txt +534 -0
  23. data/doc/release_notes/2.2.0.txt +253 -0
  24. data/doc/release_notes/2.3.0.txt +88 -0
  25. data/doc/release_notes/2.4.0.txt +106 -0
  26. data/doc/release_notes/2.5.0.txt +137 -0
  27. data/doc/release_notes/2.6.0.txt +157 -0
  28. data/doc/release_notes/2.7.0.txt +166 -0
  29. data/doc/release_notes/2.8.0.txt +171 -0
  30. data/doc/release_notes/2.9.0.txt +97 -0
  31. data/doc/release_notes/3.0.0.txt +221 -0
  32. data/doc/release_notes/3.1.0.txt +406 -0
  33. data/doc/release_notes/3.10.0.txt +286 -0
  34. data/doc/release_notes/3.2.0.txt +268 -0
  35. data/doc/release_notes/3.3.0.txt +192 -0
  36. data/doc/release_notes/3.4.0.txt +325 -0
  37. data/doc/release_notes/3.5.0.txt +510 -0
  38. data/doc/release_notes/3.6.0.txt +366 -0
  39. data/doc/release_notes/3.7.0.txt +179 -0
  40. data/doc/release_notes/3.8.0.txt +151 -0
  41. data/doc/release_notes/3.9.0.txt +233 -0
  42. data/doc/schema.rdoc +36 -0
  43. data/doc/sharding.rdoc +113 -0
  44. data/doc/virtual_rows.rdoc +205 -0
  45. data/lib/sequel.rb +1 -0
  46. data/lib/sequel/adapters/ado.rb +90 -0
  47. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  48. data/lib/sequel/adapters/amalgalite.rb +176 -0
  49. data/lib/sequel/adapters/db2.rb +139 -0
  50. data/lib/sequel/adapters/dbi.rb +113 -0
  51. data/lib/sequel/adapters/do.rb +188 -0
  52. data/lib/sequel/adapters/do/mysql.rb +49 -0
  53. data/lib/sequel/adapters/do/postgres.rb +91 -0
  54. data/lib/sequel/adapters/do/sqlite.rb +40 -0
  55. data/lib/sequel/adapters/firebird.rb +283 -0
  56. data/lib/sequel/adapters/informix.rb +77 -0
  57. data/lib/sequel/adapters/jdbc.rb +587 -0
  58. data/lib/sequel/adapters/jdbc/as400.rb +58 -0
  59. data/lib/sequel/adapters/jdbc/h2.rb +133 -0
  60. data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
  61. data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
  62. data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
  63. data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
  64. data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
  65. data/lib/sequel/adapters/mysql.rb +421 -0
  66. data/lib/sequel/adapters/odbc.rb +143 -0
  67. data/lib/sequel/adapters/odbc/mssql.rb +42 -0
  68. data/lib/sequel/adapters/openbase.rb +64 -0
  69. data/lib/sequel/adapters/oracle.rb +131 -0
  70. data/lib/sequel/adapters/postgres.rb +504 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +490 -0
  72. data/lib/sequel/adapters/shared/mysql.rb +498 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +195 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +830 -0
  75. data/lib/sequel/adapters/shared/progress.rb +44 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +389 -0
  77. data/lib/sequel/adapters/sqlite.rb +224 -0
  78. data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
  79. data/lib/sequel/connection_pool.rb +99 -0
  80. data/lib/sequel/connection_pool/sharded_single.rb +84 -0
  81. data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
  82. data/lib/sequel/connection_pool/single.rb +29 -0
  83. data/lib/sequel/connection_pool/threaded.rb +150 -0
  84. data/lib/sequel/core.rb +293 -0
  85. data/lib/sequel/core_sql.rb +241 -0
  86. data/lib/sequel/database.rb +1079 -0
  87. data/lib/sequel/database/schema_generator.rb +327 -0
  88. data/lib/sequel/database/schema_methods.rb +203 -0
  89. data/lib/sequel/database/schema_sql.rb +320 -0
  90. data/lib/sequel/dataset.rb +32 -0
  91. data/lib/sequel/dataset/actions.rb +441 -0
  92. data/lib/sequel/dataset/features.rb +86 -0
  93. data/lib/sequel/dataset/graph.rb +254 -0
  94. data/lib/sequel/dataset/misc.rb +119 -0
  95. data/lib/sequel/dataset/mutation.rb +64 -0
  96. data/lib/sequel/dataset/prepared_statements.rb +227 -0
  97. data/lib/sequel/dataset/query.rb +709 -0
  98. data/lib/sequel/dataset/sql.rb +996 -0
  99. data/lib/sequel/exceptions.rb +51 -0
  100. data/lib/sequel/extensions/blank.rb +43 -0
  101. data/lib/sequel/extensions/inflector.rb +242 -0
  102. data/lib/sequel/extensions/looser_typecasting.rb +21 -0
  103. data/lib/sequel/extensions/migration.rb +239 -0
  104. data/lib/sequel/extensions/named_timezones.rb +61 -0
  105. data/lib/sequel/extensions/pagination.rb +100 -0
  106. data/lib/sequel/extensions/pretty_table.rb +82 -0
  107. data/lib/sequel/extensions/query.rb +52 -0
  108. data/lib/sequel/extensions/schema_dumper.rb +271 -0
  109. data/lib/sequel/extensions/sql_expr.rb +122 -0
  110. data/lib/sequel/extensions/string_date_time.rb +46 -0
  111. data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
  112. data/lib/sequel/metaprogramming.rb +9 -0
  113. data/lib/sequel/model.rb +120 -0
  114. data/lib/sequel/model/associations.rb +1514 -0
  115. data/lib/sequel/model/base.rb +1069 -0
  116. data/lib/sequel/model/default_inflections.rb +45 -0
  117. data/lib/sequel/model/errors.rb +39 -0
  118. data/lib/sequel/model/exceptions.rb +21 -0
  119. data/lib/sequel/model/inflections.rb +162 -0
  120. data/lib/sequel/model/plugins.rb +70 -0
  121. data/lib/sequel/plugins/active_model.rb +59 -0
  122. data/lib/sequel/plugins/association_dependencies.rb +103 -0
  123. data/lib/sequel/plugins/association_proxies.rb +41 -0
  124. data/lib/sequel/plugins/boolean_readers.rb +53 -0
  125. data/lib/sequel/plugins/caching.rb +141 -0
  126. data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
  127. data/lib/sequel/plugins/composition.rb +138 -0
  128. data/lib/sequel/plugins/force_encoding.rb +72 -0
  129. data/lib/sequel/plugins/hook_class_methods.rb +126 -0
  130. data/lib/sequel/plugins/identity_map.rb +116 -0
  131. data/lib/sequel/plugins/instance_filters.rb +98 -0
  132. data/lib/sequel/plugins/instance_hooks.rb +57 -0
  133. data/lib/sequel/plugins/lazy_attributes.rb +77 -0
  134. data/lib/sequel/plugins/many_through_many.rb +208 -0
  135. data/lib/sequel/plugins/nested_attributes.rb +206 -0
  136. data/lib/sequel/plugins/optimistic_locking.rb +81 -0
  137. data/lib/sequel/plugins/rcte_tree.rb +281 -0
  138. data/lib/sequel/plugins/schema.rb +66 -0
  139. data/lib/sequel/plugins/serialization.rb +166 -0
  140. data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
  141. data/lib/sequel/plugins/subclasses.rb +45 -0
  142. data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
  143. data/lib/sequel/plugins/timestamps.rb +87 -0
  144. data/lib/sequel/plugins/touch.rb +118 -0
  145. data/lib/sequel/plugins/typecast_on_load.rb +72 -0
  146. data/lib/sequel/plugins/validation_class_methods.rb +405 -0
  147. data/lib/sequel/plugins/validation_helpers.rb +223 -0
  148. data/lib/sequel/sql.rb +1020 -0
  149. data/lib/sequel/timezones.rb +161 -0
  150. data/lib/sequel/version.rb +12 -0
  151. data/lib/sequel_core.rb +1 -0
  152. data/lib/sequel_model.rb +1 -0
  153. data/spec/adapters/firebird_spec.rb +407 -0
  154. data/spec/adapters/informix_spec.rb +97 -0
  155. data/spec/adapters/mssql_spec.rb +403 -0
  156. data/spec/adapters/mysql_spec.rb +1019 -0
  157. data/spec/adapters/oracle_spec.rb +286 -0
  158. data/spec/adapters/postgres_spec.rb +969 -0
  159. data/spec/adapters/spec_helper.rb +51 -0
  160. data/spec/adapters/sqlite_spec.rb +432 -0
  161. data/spec/core/connection_pool_spec.rb +808 -0
  162. data/spec/core/core_sql_spec.rb +417 -0
  163. data/spec/core/database_spec.rb +1662 -0
  164. data/spec/core/dataset_spec.rb +3827 -0
  165. data/spec/core/expression_filters_spec.rb +595 -0
  166. data/spec/core/object_graph_spec.rb +296 -0
  167. data/spec/core/schema_generator_spec.rb +159 -0
  168. data/spec/core/schema_spec.rb +830 -0
  169. data/spec/core/spec_helper.rb +56 -0
  170. data/spec/core/version_spec.rb +7 -0
  171. data/spec/extensions/active_model_spec.rb +76 -0
  172. data/spec/extensions/association_dependencies_spec.rb +127 -0
  173. data/spec/extensions/association_proxies_spec.rb +50 -0
  174. data/spec/extensions/blank_spec.rb +67 -0
  175. data/spec/extensions/boolean_readers_spec.rb +92 -0
  176. data/spec/extensions/caching_spec.rb +250 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +252 -0
  178. data/spec/extensions/composition_spec.rb +194 -0
  179. data/spec/extensions/force_encoding_spec.rb +117 -0
  180. data/spec/extensions/hook_class_methods_spec.rb +470 -0
  181. data/spec/extensions/identity_map_spec.rb +202 -0
  182. data/spec/extensions/inflector_spec.rb +181 -0
  183. data/spec/extensions/instance_filters_spec.rb +55 -0
  184. data/spec/extensions/instance_hooks_spec.rb +133 -0
  185. data/spec/extensions/lazy_attributes_spec.rb +153 -0
  186. data/spec/extensions/looser_typecasting_spec.rb +39 -0
  187. data/spec/extensions/many_through_many_spec.rb +884 -0
  188. data/spec/extensions/migration_spec.rb +332 -0
  189. data/spec/extensions/named_timezones_spec.rb +72 -0
  190. data/spec/extensions/nested_attributes_spec.rb +396 -0
  191. data/spec/extensions/optimistic_locking_spec.rb +100 -0
  192. data/spec/extensions/pagination_spec.rb +99 -0
  193. data/spec/extensions/pretty_table_spec.rb +91 -0
  194. data/spec/extensions/query_spec.rb +85 -0
  195. data/spec/extensions/rcte_tree_spec.rb +205 -0
  196. data/spec/extensions/schema_dumper_spec.rb +357 -0
  197. data/spec/extensions/schema_spec.rb +127 -0
  198. data/spec/extensions/serialization_spec.rb +209 -0
  199. data/spec/extensions/single_table_inheritance_spec.rb +96 -0
  200. data/spec/extensions/spec_helper.rb +91 -0
  201. data/spec/extensions/sql_expr_spec.rb +89 -0
  202. data/spec/extensions/string_date_time_spec.rb +93 -0
  203. data/spec/extensions/subclasses_spec.rb +52 -0
  204. data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
  205. data/spec/extensions/thread_local_timezones_spec.rb +45 -0
  206. data/spec/extensions/timestamps_spec.rb +150 -0
  207. data/spec/extensions/touch_spec.rb +155 -0
  208. data/spec/extensions/typecast_on_load_spec.rb +69 -0
  209. data/spec/extensions/validation_class_methods_spec.rb +984 -0
  210. data/spec/extensions/validation_helpers_spec.rb +438 -0
  211. data/spec/integration/associations_test.rb +281 -0
  212. data/spec/integration/database_test.rb +26 -0
  213. data/spec/integration/dataset_test.rb +963 -0
  214. data/spec/integration/eager_loader_test.rb +734 -0
  215. data/spec/integration/model_test.rb +130 -0
  216. data/spec/integration/plugin_test.rb +814 -0
  217. data/spec/integration/prepared_statement_test.rb +213 -0
  218. data/spec/integration/schema_test.rb +361 -0
  219. data/spec/integration/spec_helper.rb +73 -0
  220. data/spec/integration/timezone_test.rb +55 -0
  221. data/spec/integration/transaction_test.rb +122 -0
  222. data/spec/integration/type_test.rb +96 -0
  223. data/spec/model/association_reflection_spec.rb +175 -0
  224. data/spec/model/associations_spec.rb +2633 -0
  225. data/spec/model/base_spec.rb +418 -0
  226. data/spec/model/dataset_methods_spec.rb +78 -0
  227. data/spec/model/eager_loading_spec.rb +1391 -0
  228. data/spec/model/hooks_spec.rb +240 -0
  229. data/spec/model/inflector_spec.rb +26 -0
  230. data/spec/model/model_spec.rb +593 -0
  231. data/spec/model/plugins_spec.rb +236 -0
  232. data/spec/model/record_spec.rb +1500 -0
  233. data/spec/model/spec_helper.rb +97 -0
  234. data/spec/model/validations_spec.rb +153 -0
  235. data/spec/rcov.opts +6 -0
  236. data/spec/spec_config.rb.example +10 -0
  237. metadata +346 -0
@@ -0,0 +1,213 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+
3
+ describe "Prepared Statements and Bound Arguments" do
4
+ before do
5
+ INTEGRATION_DB.create_table!(:items) do
6
+ primary_key :id
7
+ integer :number
8
+ end
9
+ @c = Class.new(Sequel::Model(:items))
10
+ @ds = INTEGRATION_DB[:items]
11
+ @ds.insert(:number=>10)
12
+ @ds.meta_def(:ba) do |sym|
13
+ prepared_arg_placeholder == '$' ? :"#{sym}__int" : sym
14
+ end
15
+ clear_sqls
16
+ end
17
+ after do
18
+ INTEGRATION_DB.drop_table(:items)
19
+ end
20
+
21
+ specify "should support bound variables with select, all, and first" do
22
+ @ds.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
23
+ @ds.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
24
+ @ds.filter(:number=>@ds.ba(:$n)).call(:first, :n=>10).should == {:id=>1, :number=>10}
25
+ end
26
+
27
+ specify "should support blocks for select and all" do
28
+ @ds.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
29
+ @ds.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10){|r| r[:number] *= 2}.should == [{:id=>1, :number=>20}]
30
+ end
31
+
32
+ specify "should support binding variables before the call with #bind" do
33
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
34
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
35
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
36
+
37
+ @ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:select).should == [{:id=>1, :number=>10}]
38
+ @ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:all).should == [{:id=>1, :number=>10}]
39
+ @ds.bind(:n=>10).filter(:number=>@ds.ba(:$n)).call(:first).should == {:id=>1, :number=>10}
40
+ end
41
+
42
+ specify "should allow overriding variables specified with #bind" do
43
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
44
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:all, :n=>10).should == [{:id=>1, :number=>10}]
45
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).call(:first, :n=>10).should == {:id=>1, :number=>10}
46
+
47
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:select).should == [{:id=>1, :number=>10}]
48
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:all).should == [{:id=>1, :number=>10}]
49
+ @ds.filter(:number=>@ds.ba(:$n)).bind(:n=>1).bind(:n=>10).call(:first).should == {:id=>1, :number=>10}
50
+ end
51
+
52
+ specify "should support placeholder literal strings with call" do
53
+ @ds.filter("number = ?", @ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
54
+ end
55
+
56
+ specify "should support named placeholder literal strings and handle multiple named placeholders correctly with call" do
57
+ @ds.filter("number = :n", :n=>@ds.ba(:$n)).call(:select, :n=>10).should == [{:id=>1, :number=>10}]
58
+ @ds.insert(:number=>20)
59
+ @ds.insert(:number=>30)
60
+ @ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>@ds.ba(:$n3), :n2=>@ds.ba(:$n2), :n1=>@ds.ba(:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
61
+ end
62
+
63
+ specify "should support datasets with static sql and placeholders with call" do
64
+ INTEGRATION_DB["SELECT * FROM items WHERE number = ?", @ds.ba(:$n)].call(:select, :n=>10).should == [{:id=>1, :number=>10}]
65
+ end
66
+
67
+ specify "should support subselects with call" do
68
+ @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
69
+ end
70
+
71
+ specify "should support subselects with literal strings with call" do
72
+ @ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", @ds.ba(:$n))).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
73
+ end
74
+
75
+ specify "should support subselects with static sql and placeholders with call" do
76
+ @ds.filter(:id=>:$i, :number=>INTEGRATION_DB["SELECT number FROM items WHERE number = ?", @ds.ba(:$n)]).call(:select, :n=>10, :i=>1).should == [{:id=>1, :number=>10}]
77
+ end
78
+
79
+ specify "should support subselects of subselects with call" do
80
+ @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n)))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
81
+ end
82
+
83
+ specify "should support using a bound variable for a limit and offset" do
84
+ @ds.insert(:number=>20)
85
+ ds = @ds.limit(@ds.ba(:$n), @ds.ba(:$n2)).order(:id)
86
+ ds.call(:select, :n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
87
+ ds.call(:select, :n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
88
+ ds.call(:select, :n=>1, :n2=>2).should == []
89
+ ds.call(:select, :n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
90
+ ds.call(:select, :n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
91
+ end
92
+
93
+ specify "should support bound variables with insert" do
94
+ @ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n))
95
+ @ds.count.should == 2
96
+ @ds.order(:id).map(:number).should == [10, 20]
97
+ end
98
+
99
+ specify "should have insert return primary key value when using bound arguments" do
100
+ @ds.call(:insert, {:n=>20}, :number=>@ds.ba(:$n)).should == 2
101
+ @ds.filter(:id=>2).first[:number].should == 20
102
+ end
103
+
104
+ specify "should support bound variables with delete" do
105
+ @ds.filter(:number=>@ds.ba(:$n)).call(:delete, :n=>10).should == 1
106
+ @ds.count.should == 0
107
+ end
108
+
109
+ specify "should support bound variables with update" do
110
+ @ds.filter(:number=>@ds.ba(:$n)).call(:update, {:n=>10, :nn=>20}, :number=>:number+@ds.ba(:$nn)).should == 1
111
+ @ds.all.should == [{:id=>1, :number=>30}]
112
+ end
113
+
114
+ specify "should support prepared statements with select, first, and all" do
115
+ @ds.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
116
+ INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
117
+ @ds.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
118
+ INTEGRATION_DB.call(:select_n, :n=>10).should == [{:id=>1, :number=>10}]
119
+ @ds.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
120
+ INTEGRATION_DB.call(:select_n, :n=>10).should == {:id=>1, :number=>10}
121
+ if INTEGRATION_DB.class.adapter_scheme == :jdbc and INTEGRATION_DB.database_type == :sqlite
122
+ # Work around for open prepared statements on a table not allowing the
123
+ # dropping of a table when using SQLite over JDBC
124
+ INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
125
+ end
126
+ end
127
+
128
+ specify "should support placeholder literal strings with prepare" do
129
+ @ds.filter("number = ?", @ds.ba(:$n)).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
130
+ end
131
+
132
+ specify "should support named placeholder literal strings and handle multiple named placeholders correctly with prepare" do
133
+ @ds.filter("number = :n", :n=>@ds.ba(:$n)).prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
134
+ @ds.insert(:number=>20)
135
+ @ds.insert(:number=>30)
136
+ @ds.filter("number > :n1 AND number < :n2 AND number = :n3", :n3=>@ds.ba(:$n3), :n2=>@ds.ba(:$n2), :n1=>@ds.ba(:$n1)).call(:select, :n3=>20, :n2=>30, :n1=>10).should == [{:id=>2, :number=>20}]
137
+ end
138
+
139
+ specify "should support datasets with static sql and placeholders with prepare" do
140
+ INTEGRATION_DB["SELECT * FROM items WHERE number = ?", @ds.ba(:$n)].prepare(:select, :seq_select).call(:n=>10).should == [{:id=>1, :number=>10}]
141
+ end
142
+
143
+ specify "should support subselects with prepare" do
144
+ @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
145
+ end
146
+
147
+ specify "should support subselects with literal strings with prepare" do
148
+ @ds.filter(:id=>:$i, :number=>@ds.select(:number).filter("number = ?", @ds.ba(:$n))).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
149
+ end
150
+
151
+ specify "should support subselects with static sql and placeholders with prepare" do
152
+ @ds.filter(:id=>:$i, :number=>INTEGRATION_DB["SELECT number FROM items WHERE number = ?", @ds.ba(:$n)]).prepare(:select, :seq_select).call(:n=>10, :i=>1).should == [{:id=>1, :number=>10}]
153
+ end
154
+
155
+ specify "should support subselects of subselects with prepare" do
156
+ @ds.filter(:id=>:$i).filter(:number=>@ds.select(:number).filter(:number=>@ds.select(:number).filter(:number=>@ds.ba(:$n)))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).should == [{:id=>1, :number=>10}]
157
+ end
158
+
159
+ specify "should support using a prepared_statement for a limit and offset" do
160
+ @ds.insert(:number=>20)
161
+ ps = @ds.limit(@ds.ba(:$n), @ds.ba(:$n2)).order(:id).prepare(:select, :seq_select)
162
+ ps.call(:n=>1, :n2=>0).should == [{:id=>1, :number=>10}]
163
+ ps.call(:n=>1, :n2=>1).should == [{:id=>2, :number=>20}]
164
+ ps.call(:n=>1, :n2=>2).should == []
165
+ ps.call(:n=>2, :n2=>0).should == [{:id=>1, :number=>10}, {:id=>2, :number=>20}]
166
+ ps.call(:n=>2, :n2=>1).should == [{:id=>2, :number=>20}]
167
+ end
168
+
169
+ specify "should support prepared statements with insert" do
170
+ @ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
171
+ INTEGRATION_DB.call(:insert_n, :n=>20)
172
+ @ds.count.should == 2
173
+ @ds.order(:id).map(:number).should == [10, 20]
174
+ end
175
+
176
+ specify "should have insert return primary key value when using prepared statements" do
177
+ @ds.prepare(:insert, :insert_n, :number=>@ds.ba(:$n))
178
+ INTEGRATION_DB.call(:insert_n, :n=>20).should == 2
179
+ @ds.filter(:id=>2).first[:number].should == 20
180
+ end
181
+
182
+ specify "should support prepared statements with delete" do
183
+ @ds.filter(:number=>@ds.ba(:$n)).prepare(:delete, :delete_n)
184
+ INTEGRATION_DB.call(:delete_n, :n=>10).should == 1
185
+ @ds.count.should == 0
186
+ end
187
+
188
+ specify "should support prepared statements with update" do
189
+ @ds.filter(:number=>@ds.ba(:$n)).prepare(:update, :update_n, :number=>:number+@ds.ba(:$nn))
190
+ INTEGRATION_DB.call(:update_n, :n=>10, :nn=>20).should == 1
191
+ @ds.all.should == [{:id=>1, :number=>30}]
192
+ end
193
+
194
+ specify "model datasets should return model instances when using select, all, and first with bound variables" do
195
+ @c.filter(:number=>@ds.ba(:$n)).call(:select, :n=>10).should == [@c.load(:id=>1, :number=>10)]
196
+ @c.filter(:number=>@ds.ba(:$n)).call(:all, :n=>10).should == [@c.load(:id=>1, :number=>10)]
197
+ @c.filter(:number=>@ds.ba(:$n)).call(:first, :n=>10).should == @c.load(:id=>1, :number=>10)
198
+ end
199
+
200
+ specify "model datasets should return model instances when using select, all, and first with prepared statements" do
201
+ @c.filter(:number=>@ds.ba(:$n)).prepare(:select, :select_n)
202
+ INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
203
+ @c.filter(:number=>@ds.ba(:$n)).prepare(:all, :select_n)
204
+ INTEGRATION_DB.call(:select_n, :n=>10).should == [@c.load(:id=>1, :number=>10)]
205
+ @c.filter(:number=>@ds.ba(:$n)).prepare(:first, :select_n)
206
+ INTEGRATION_DB.call(:select_n, :n=>10).should == @c.load(:id=>1, :number=>10)
207
+ if INTEGRATION_DB.class.adapter_scheme == :jdbc and INTEGRATION_DB.database_type == :sqlite
208
+ # Work around for open prepared statements on a table not allowing the
209
+ # dropping of a table when using SQLite over JDBC
210
+ INTEGRATION_DB.synchronize{|c| c.prepared_statements[:select_n][1].close}
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,361 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+
3
+ if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
4
+ describe "Database schema parser" do
5
+ before do
6
+ @iom = INTEGRATION_DB.identifier_output_method
7
+ @iim = INTEGRATION_DB.identifier_input_method
8
+ @defsch = INTEGRATION_DB.default_schema
9
+ clear_sqls
10
+ end
11
+ after do
12
+ INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
13
+ INTEGRATION_DB.identifier_output_method = @iom
14
+ INTEGRATION_DB.identifier_input_method = @iim
15
+ INTEGRATION_DB.default_schema = @defsch
16
+ end
17
+
18
+ specify "should handle a database with a identifier_output_method" do
19
+ INTEGRATION_DB.identifier_output_method = :reverse
20
+ INTEGRATION_DB.identifier_input_method = :reverse
21
+ INTEGRATION_DB.default_schema = nil if INTEGRATION_DB.default_schema
22
+ 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
25
+ end
26
+
27
+ specify "should not issue an sql query if the schema has been loaded unless :reload is true" do
28
+ INTEGRATION_DB.create_table!(:items){Integer :number}
29
+ INTEGRATION_DB.schema(:items, :reload=>true)
30
+ clear_sqls
31
+ INTEGRATION_DB.schema(:items)
32
+ clear_sqls
33
+ INTEGRATION_DB.schema(:items, :reload=>true)
34
+ end
35
+
36
+ specify "should raise an error when the table doesn't exist" do
37
+ proc{INTEGRATION_DB.schema(:no_table)}.should raise_error(Sequel::Error)
38
+ end
39
+
40
+ specify "should return the schema correctly" do
41
+ INTEGRATION_DB.create_table!(:items){Integer :number}
42
+ schema = INTEGRATION_DB.schema(:items, :reload=>true)
43
+ schema.should be_a_kind_of(Array)
44
+ schema.length.should == 1
45
+ col = schema.first
46
+ col.should be_a_kind_of(Array)
47
+ col.length.should == 2
48
+ col.first.should == :number
49
+ col_info = col.last
50
+ col_info.should be_a_kind_of(Hash)
51
+ col_info[:type].should == :integer
52
+ clear_sqls
53
+ INTEGRATION_DB.schema(:items)
54
+ end
55
+
56
+ cspecify "should parse primary keys from the schema properly", [proc{|db| db.class.adapter_scheme != :jdbc}, :mssql] do
57
+ INTEGRATION_DB.create_table!(:items){Integer :number}
58
+ INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == []
59
+ INTEGRATION_DB.create_table!(:items){primary_key :number}
60
+ INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number]
61
+ INTEGRATION_DB.create_table!(:items){Integer :number1; Integer :number2; primary_key [:number1, :number2]}
62
+ INTEGRATION_DB.schema(:items).collect{|k,v| k if v[:primary_key]}.compact.should == [:number1, :number2]
63
+ end
64
+
65
+ specify "should parse NULL/NOT NULL from the schema properly" do
66
+ INTEGRATION_DB.create_table!(:items){Integer :number, :null=>true}
67
+ INTEGRATION_DB.schema(:items).first.last[:allow_null].should == true
68
+ INTEGRATION_DB.create_table!(:items){Integer :number, :null=>false}
69
+ INTEGRATION_DB.schema(:items).first.last[:allow_null].should == false
70
+ end
71
+
72
+ specify "should parse defaults from the schema properly" do
73
+ INTEGRATION_DB.create_table!(:items){Integer :number}
74
+ INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == nil
75
+ INTEGRATION_DB.create_table!(:items){Integer :number, :default=>0}
76
+ INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 0
77
+ INTEGRATION_DB.create_table!(:items){String :a, :default=>"blah"}
78
+ INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
79
+ end
80
+
81
+ cspecify "should parse types from the schema properly", [:jdbc, :mysql] do
82
+ INTEGRATION_DB.create_table!(:items){Integer :number}
83
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
84
+ INTEGRATION_DB.create_table!(:items){Fixnum :number}
85
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
86
+ INTEGRATION_DB.create_table!(:items){Bignum :number}
87
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
88
+ INTEGRATION_DB.create_table!(:items){Float :number}
89
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :float
90
+ INTEGRATION_DB.create_table!(:items){BigDecimal :number}
91
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
92
+ INTEGRATION_DB.create_table!(:items){Numeric :number}
93
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
94
+ INTEGRATION_DB.create_table!(:items){String :number}
95
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :string
96
+ INTEGRATION_DB.create_table!(:items){Date :number}
97
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :date
98
+ INTEGRATION_DB.create_table!(:items){Time :number}
99
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :datetime
100
+ INTEGRATION_DB.create_table!(:items){DateTime :number}
101
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :datetime
102
+ INTEGRATION_DB.create_table!(:items){File :number}
103
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :blob
104
+ INTEGRATION_DB.create_table!(:items){TrueClass :number}
105
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
106
+ INTEGRATION_DB.create_table!(:items){FalseClass :number}
107
+ INTEGRATION_DB.schema(:items).first.last[:type].should == :boolean
108
+ end
109
+ end
110
+ end
111
+
112
+ if INTEGRATION_DB.respond_to?(:indexes)
113
+ describe "Database index parsing" do
114
+ after do
115
+ INTEGRATION_DB.drop_table(:items)
116
+ end
117
+
118
+ specify "should parse indexes into a hash" do
119
+ INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a}
120
+ INTEGRATION_DB.indexes(:items).should == {}
121
+ INTEGRATION_DB.add_index(:items, :n)
122
+ INTEGRATION_DB.indexes(:items).should == {:items_n_index=>{:columns=>[:n], :unique=>false}}
123
+ INTEGRATION_DB.drop_index(:items, :n)
124
+ INTEGRATION_DB.indexes(:items).should == {}
125
+ INTEGRATION_DB.add_index(:items, :n, :unique=>true, :name=>:blah_blah_index)
126
+ INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}}
127
+ INTEGRATION_DB.add_index(:items, [:n, :a])
128
+ INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}, :items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
129
+ INTEGRATION_DB.drop_index(:items, :n, :name=>:blah_blah_index)
130
+ INTEGRATION_DB.indexes(:items).should == {:items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
131
+ INTEGRATION_DB.drop_index(:items, [:n, :a])
132
+ INTEGRATION_DB.indexes(:items).should == {}
133
+ end
134
+
135
+ specify "should not include a primary key index" do
136
+ INTEGRATION_DB.create_table!(:items){primary_key :n}
137
+ INTEGRATION_DB.indexes(:items).should == {}
138
+ INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a; primary_key [:n, :a]}
139
+ INTEGRATION_DB.indexes(:items).should == {}
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "Database schema modifiers" do
145
+ before do
146
+ @db = INTEGRATION_DB
147
+ @ds = @db[:items]
148
+ clear_sqls
149
+ end
150
+ after do
151
+ @db.drop_table(:items) if @db.table_exists?(:items)
152
+ end
153
+
154
+ specify "should create tables correctly" do
155
+ @db.create_table!(:items){Integer :number}
156
+ @db.table_exists?(:items).should == true
157
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
158
+ @ds.insert([10])
159
+ @ds.columns!.should == [:number]
160
+ end
161
+
162
+ specify "should rename tables correctly" do
163
+ @db.drop_table(:items) rescue nil
164
+ @db.create_table!(:items2){Integer :number}
165
+ @db.rename_table(:items2, :items)
166
+ @db.table_exists?(:items).should == true
167
+ @db.table_exists?(:items2).should == false
168
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
169
+ @ds.insert([10])
170
+ @ds.columns!.should == [:number]
171
+ end
172
+
173
+ specify "should allow creating indexes with tables" do
174
+ @db.create_table!(:items){Integer :number; index :number}
175
+ @db.table_exists?(:items).should == true
176
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
177
+ @ds.insert([10])
178
+ @ds.columns!.should == [:number]
179
+ end
180
+
181
+ specify "should handle foreign keys correctly when creating tables" do
182
+ @db.create_table!(:items) do
183
+ primary_key :id
184
+ foreign_key :item_id, :items
185
+ unique [:item_id, :id]
186
+ foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
187
+ end
188
+ @db.table_exists?(:items).should == true
189
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
190
+ @ds.columns!.should == [:id, :item_id]
191
+ end
192
+
193
+ specify "should add columns to tables correctly" do
194
+ @db.create_table!(:items){Integer :number}
195
+ @ds.insert(:number=>10)
196
+ @db.alter_table(:items){add_column :name, :text}
197
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name]
198
+ @ds.columns!.should == [:number, :name]
199
+ @ds.all.should == [{:number=>10, :name=>nil}]
200
+ end
201
+
202
+ cspecify "should add primary key columns to tables correctly", :h2 do
203
+ @db.create_table!(:items){Integer :number}
204
+ @ds.insert(:number=>10)
205
+ @db.alter_table(:items){add_primary_key :id}
206
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :id]
207
+ @ds.columns!.should == [:number, :id]
208
+ @ds.map(:number).should == [10]
209
+ end
210
+
211
+ specify "should add foreign key columns to tables correctly" do
212
+ @db.create_table!(:items){primary_key :id}
213
+ i = @ds.insert
214
+ @db.alter_table(:items){add_foreign_key :item_id, :items}
215
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
216
+ @ds.columns!.should == [:id, :item_id]
217
+ @ds.all.should == [{:id=>i, :item_id=>nil}]
218
+ end
219
+
220
+ specify "should rename columns correctly" do
221
+ @db.create_table!(:items){Integer :id}
222
+ @ds.insert(:id=>10)
223
+ @db.alter_table(:items){rename_column :id, :id2}
224
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id2]
225
+ @ds.columns!.should == [:id2]
226
+ @ds.all.should == [{:id2=>10}]
227
+ end
228
+
229
+ specify "should rename columns with defaults correctly" do
230
+ @db.create_table!(:items){String :n, :default=>'blah'}
231
+ @ds.insert
232
+ @db.alter_table(:items){rename_column :n, :n2}
233
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
234
+ @ds.columns!.should == [:n2]
235
+ @ds.insert
236
+ @ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
237
+ end
238
+
239
+ cspecify "should rename columns with not null constraints", [:mysql, :mysql] do
240
+ @db.create_table!(:items){String :n, :null=>false}
241
+ @ds.insert(:n=>'blah')
242
+ @db.alter_table(:items){rename_column :n, :n2}
243
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
244
+ @ds.columns!.should == [:n2]
245
+ @ds.insert(:n2=>'blah')
246
+ @ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
247
+ proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
248
+ end
249
+
250
+ cspecify "should set column NULL/NOT NULL correctly", [:mysql, :mysql] do
251
+ @db.create_table!(:items){Integer :id}
252
+ @ds.insert(:id=>10)
253
+ @db.alter_table(:items){set_column_allow_null :id, false}
254
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
255
+ @ds.columns!.should == [:id]
256
+ proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
257
+ @db.alter_table(:items){set_column_allow_null :id, true}
258
+ @ds.insert
259
+ @ds.all.should == [{:id=>10}, {:id=>nil}]
260
+ end
261
+
262
+ specify "should set column defaults correctly" do
263
+ @db.create_table!(:items){Integer :id}
264
+ @ds.insert(:id=>10)
265
+ @db.alter_table(:items){set_column_default :id, 20}
266
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
267
+ @ds.columns!.should == [:id]
268
+ @ds.insert
269
+ @ds.all.should == [{:id=>10}, {:id=>20}]
270
+ end
271
+
272
+ specify "should set column types correctly" do
273
+ @db.create_table!(:items){Integer :id}
274
+ @ds.insert(:id=>10)
275
+ @db.alter_table(:items){set_column_type :id, String}
276
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
277
+ @ds.columns!.should == [:id]
278
+ @ds.insert(:id=>20)
279
+ @ds.all.should == [{:id=>"10"}, {:id=>"20"}]
280
+ end
281
+
282
+ cspecify "should add unique constraints and foreign key table constraints correctly", :sqlite do
283
+ @db.create_table!(:items){Integer :id; Integer :item_id}
284
+ @db.alter_table(:items) do
285
+ add_unique_constraint [:item_id, :id]
286
+ add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
287
+ end
288
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
289
+ @ds.columns!.should == [:id, :item_id]
290
+ end
291
+
292
+ cspecify "should remove columns from tables correctly", :h2, :mssql do
293
+ @db.create_table!(:items) do
294
+ primary_key :id
295
+ String :name
296
+ Integer :number
297
+ foreign_key :item_id, :items
298
+ end
299
+ @ds.insert(:number=>10)
300
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
301
+ @ds.columns!.should == [:id, :name, :number, :item_id]
302
+ @db.drop_column(:items, :number)
303
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
304
+ @ds.columns!.should == [:id, :name, :item_id]
305
+ @db.drop_column(:items, :name)
306
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
307
+ @ds.columns!.should == [:id, :item_id]
308
+ @db.drop_column(:items, :item_id)
309
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
310
+ @ds.columns!.should == [:id]
311
+ end
312
+
313
+ specify "should remove multiple columns in a single alter_table block" do
314
+ @db.create_table!(:items) do
315
+ primary_key :id
316
+ String :name
317
+ Integer :number
318
+ end
319
+ @ds.insert(:number=>10)
320
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number]
321
+ @ds.columns!.should == [:id, :name, :number]
322
+ @db.alter_table(:items) do
323
+ drop_column :name
324
+ drop_column :number
325
+ end
326
+ @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
327
+ @ds.columns!.should == [:id]
328
+ end
329
+ end
330
+
331
+ if INTEGRATION_DB.respond_to?(:tables)
332
+ describe "Database#tables" do
333
+ before do
334
+ class ::String
335
+ @@xxxxx = 0
336
+ def xxxxx
337
+ "xxxxx#{@@xxxxx += 1}"
338
+ end
339
+ end
340
+ @iom = INTEGRATION_DB.identifier_output_method
341
+ @iim = INTEGRATION_DB.identifier_input_method
342
+ clear_sqls
343
+ end
344
+ after do
345
+ INTEGRATION_DB.identifier_output_method = @iom
346
+ INTEGRATION_DB.identifier_input_method = @iim
347
+ end
348
+
349
+ specify "should return an array of symbols" do
350
+ ts = INTEGRATION_DB.tables
351
+ ts.should be_a_kind_of(Array)
352
+ ts.each{|t| t.should be_a_kind_of(Symbol)}
353
+ end
354
+
355
+ specify "should respect the database's identifier_output_method" do
356
+ INTEGRATION_DB.identifier_output_method = :xxxxx
357
+ INTEGRATION_DB.identifier_input_method = :xxxxx
358
+ INTEGRATION_DB.tables.each{|t| t.to_s.should =~ /\Ax{5}\d+\z/}
359
+ end
360
+ end
361
+ end