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,357 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Sequel::Schema::Generator dump methods" do
4
+ before do
5
+ @d = Sequel::Database.new
6
+ @g = Sequel::Schema::Generator
7
+ end
8
+
9
+ it "should allow the same table information to be converted to a string for evaling inside of another instance with the same result" do
10
+ g = @g.new(@d) do
11
+ Integer :a
12
+ varchar :b
13
+ column :dt, DateTime
14
+ column :vc, :varchar
15
+ primary_key :c
16
+ foreign_key :d, :a
17
+ foreign_key :e
18
+ foreign_key [:d, :e], :name=>:cfk
19
+ constraint :blah, "a=1"
20
+ check :a=>1
21
+ unique [:e]
22
+ index :a
23
+ index [:c, :e]
24
+ index [:b, :c], :type=>:hash
25
+ index [:d], :unique=>true
26
+ spatial_index :a
27
+ full_text_index [:b, :c]
28
+ end
29
+ g2 = @g.new(@d) do
30
+ instance_eval(g.dump_columns, __FILE__, __LINE__)
31
+ instance_eval(g.dump_constraints, __FILE__, __LINE__)
32
+ instance_eval(g.dump_indexes, __FILE__, __LINE__)
33
+ end
34
+ g.columns.should == g2.columns
35
+ g.constraints.should == g2.constraints
36
+ g.indexes.should == g2.indexes
37
+ end
38
+
39
+ it "should allow dumping indexes as separate add_index and drop_index methods" do
40
+ g = @g.new(@d) do
41
+ index :a
42
+ index [:c, :e], :name=>:blah
43
+ index [:b, :c], :unique=>true
44
+ end
45
+
46
+ t = <<END_CODE
47
+ add_index :t, [:a]
48
+ add_index :t, [:c, :e], :name=>:blah
49
+ add_index :t, [:b, :c], :unique=>true
50
+ END_CODE
51
+ g.dump_indexes(:add_index=>:t).should == t.strip
52
+
53
+ t = <<END_CODE
54
+ drop_index :t, [:a]
55
+ drop_index :t, [:c, :e], :name=>:blah
56
+ drop_index :t, [:b, :c], :unique=>true
57
+ END_CODE
58
+ g.dump_indexes(:drop_index=>:t).should == t.strip
59
+ end
60
+
61
+ it "should raise an error if you try to dump a Generator that uses a constraint with a proc" do
62
+ proc{@g.new(@d){check{a>1}}.dump_constraints}.should raise_error(Sequel::Error)
63
+ end
64
+ end
65
+
66
+ describe "Sequel::Database dump methods" do
67
+ before do
68
+ @d = Sequel::Database.new
69
+ @d.meta_def(:tables){|o| [:t1, :t2]}
70
+ @d.meta_def(:schema) do |t, *o|
71
+ case t
72
+ when :t1
73
+ [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
74
+ [:c2, {:db_type=>'varchar(20)', :allow_null=>true}]]
75
+ when :t2
76
+ [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
77
+ [:c2, {:db_type=>'numeric', :primary_key=>true, :allow_null=>false}]]
78
+ when :t3
79
+ [[:c1, {:db_type=>'date', :default=>"'now()'", :allow_null=>true}],
80
+ [:c2, {:db_type=>'datetime', :allow_null=>false}]]
81
+ when :t5
82
+ [[:c1, {:db_type=>'blahblah', :allow_null=>true}]]
83
+ when :t6
84
+ [[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true}]]
85
+ when :t7
86
+ [[:c1, {:db_type=>'somedbspecifictype', :primary_key=>true, :allow_null=>false}]]
87
+ end
88
+ end
89
+ end
90
+
91
+ it "should support dumping table schemas as create_table method calls" do
92
+ @d.dump_table_schema(:t1).should == "create_table(:t1) do\n primary_key :c1\n String :c2, :size=>20\nend"
93
+ end
94
+
95
+ it "should dump non-Integer primary key columns with explicit :type" do
96
+ @d.dump_table_schema(:t6).should == "create_table(:t6) do\n primary_key :c1, :type=>Bignum\nend"
97
+ end
98
+
99
+ it "should dump primary key columns with explicit :type equal to the database type when :same_db option is passed" do
100
+ @d.dump_table_schema(:t7, :same_db => true).should == "create_table(:t7) do\n primary_key :c1, :type=>\"somedbspecifictype\"\nend"
101
+ end
102
+
103
+ it "should use a composite primary_key calls if there is a composite primary key" do
104
+ @d.dump_table_schema(:t2).should == "create_table(:t2) do\n Integer :c1, :null=>false\n BigDecimal :c2, :null=>false\n \n primary_key [:c1, :c2]\nend"
105
+ end
106
+
107
+ it "should include index information if available" do
108
+ @d.meta_def(:indexes) do |t|
109
+ {:i1=>{:columns=>[:c1], :unique=>false},
110
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
111
+ end
112
+ @d.dump_table_schema(:t1).should == "create_table(:t1, :ignore_index_errors=>true) do\n primary_key :c1\n String :c2, :size=>20\n \n index [:c1], :name=>:i1\n index [:c2, :c1], :unique=>true\nend"
113
+ end
114
+
115
+ it "should support dumping the whole database as a migration" do
116
+ @d.dump_schema_migration.should == <<-END_MIG
117
+ Class.new(Sequel::Migration) do
118
+ def up
119
+ create_table(:t1) do
120
+ primary_key :c1
121
+ String :c2, :size=>20
122
+ end
123
+
124
+ create_table(:t2) do
125
+ Integer :c1, :null=>false
126
+ BigDecimal :c2, :null=>false
127
+
128
+ primary_key [:c1, :c2]
129
+ end
130
+ end
131
+
132
+ def down
133
+ drop_table(:t1, :t2)
134
+ end
135
+ end
136
+ END_MIG
137
+ end
138
+
139
+ it "should sort table names when dumping a migration" do
140
+ @d.meta_def(:tables){|o| [:t2, :t1]}
141
+ @d.dump_schema_migration.should == <<-END_MIG
142
+ Class.new(Sequel::Migration) do
143
+ def up
144
+ create_table(:t1) do
145
+ primary_key :c1
146
+ String :c2, :size=>20
147
+ end
148
+
149
+ create_table(:t2) do
150
+ Integer :c1, :null=>false
151
+ BigDecimal :c2, :null=>false
152
+
153
+ primary_key [:c1, :c2]
154
+ end
155
+ end
156
+
157
+ def down
158
+ drop_table(:t1, :t2)
159
+ end
160
+ end
161
+ END_MIG
162
+ end
163
+
164
+ it "should honor the :same_db option to not convert types" do
165
+ @d.dump_table_schema(:t1, :same_db=>true).should == "create_table(:t1) do\n primary_key :c1\n column :c2, \"varchar(20)\"\nend"
166
+ @d.dump_schema_migration(:same_db=>true).should == <<-END_MIG
167
+ Class.new(Sequel::Migration) do
168
+ def up
169
+ create_table(:t1) do
170
+ primary_key :c1
171
+ column :c2, "varchar(20)"
172
+ end
173
+
174
+ create_table(:t2) do
175
+ column :c1, "integer", :null=>false
176
+ column :c2, "numeric", :null=>false
177
+
178
+ primary_key [:c1, :c2]
179
+ end
180
+ end
181
+
182
+ def down
183
+ drop_table(:t1, :t2)
184
+ end
185
+ end
186
+ END_MIG
187
+ end
188
+
189
+ it "should honor the :indexes => false option to not include indexes" do
190
+ @d.meta_def(:indexes) do |t|
191
+ {:i1=>{:columns=>[:c1], :unique=>false},
192
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
193
+ end
194
+ @d.dump_table_schema(:t1, :indexes=>false).should == "create_table(:t1) do\n primary_key :c1\n String :c2, :size=>20\nend"
195
+ @d.dump_schema_migration(:indexes=>false).should == <<-END_MIG
196
+ Class.new(Sequel::Migration) do
197
+ def up
198
+ create_table(:t1) do
199
+ primary_key :c1
200
+ String :c2, :size=>20
201
+ end
202
+
203
+ create_table(:t2) do
204
+ Integer :c1, :null=>false
205
+ BigDecimal :c2, :null=>false
206
+
207
+ primary_key [:c1, :c2]
208
+ end
209
+ end
210
+
211
+ def down
212
+ drop_table(:t1, :t2)
213
+ end
214
+ end
215
+ END_MIG
216
+ end
217
+
218
+ it "should support dumping just indexes as a migration" do
219
+ @d.meta_def(:tables){|o| [:t1]}
220
+ @d.meta_def(:indexes) do |t|
221
+ {:i1=>{:columns=>[:c1], :unique=>false},
222
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
223
+ end
224
+ @d.dump_indexes_migration.should == <<-END_MIG
225
+ Class.new(Sequel::Migration) do
226
+ def up
227
+ add_index :t1, [:c1], :ignore_errors=>true, :name=>:i1
228
+ add_index :t1, [:c2, :c1], :ignore_errors=>true, :unique=>true
229
+ end
230
+
231
+ def down
232
+ drop_index :t1, [:c1], :ignore_errors=>true, :name=>:i1
233
+ drop_index :t1, [:c2, :c1], :ignore_errors=>true, :unique=>true
234
+ end
235
+ end
236
+ END_MIG
237
+ end
238
+
239
+ it "should handle not null values and defaults" do
240
+ @d.dump_table_schema(:t3).should == "create_table(:t3) do\n Date :c1\n DateTime :c2, :null=>false\nend"
241
+ end
242
+
243
+ it "should handle converting common defaults" do
244
+ @d.meta_def(:schema) do |t, *os|
245
+ s = [[:c1, {:db_type=>'boolean', :default=>"false", :type=>:boolean, :allow_null=>true}],
246
+ [:c2, {:db_type=>'varchar', :default=>"'blah'", :type=>:string, :allow_null=>true}],
247
+ [:c3, {:db_type=>'integer', :default=>"-1", :type=>:integer, :allow_null=>true}],
248
+ [:c4, {:db_type=>'float', :default=>"1.0", :type=>:float, :allow_null=>true}],
249
+ [:c5, {:db_type=>'decimal', :default=>"100.50", :type=>:decimal, :allow_null=>true}],
250
+ [:c6, {:db_type=>'blob', :default=>"'blah'", :type=>:blob, :allow_null=>true}],
251
+ [:c7, {:db_type=>'date', :default=>"'2008-10-29'", :type=>:date, :allow_null=>true}],
252
+ [:c8, {:db_type=>'datetime', :default=>"'2008-10-29 10:20:30'", :type=>:datetime, :allow_null=>true}],
253
+ [:c9, {:db_type=>'time', :default=>"'10:20:30'", :type=>:time, :allow_null=>true}],
254
+ [:c10, {:db_type=>'interval', :default=>"'6 weeks'", :type=>:interval, :allow_null=>true}]]
255
+ s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
256
+ s
257
+ end
258
+ @d.dump_table_schema(:t4).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n TrueClass :c1, :default=>false\n String :c2, :default=>\"blah\"\n Integer :c3, :default=>-1\n Float :c4, :default=>1.0\n BigDecimal :c5, :default=>BigDecimal.new(\"0.1005E3\")\n File :c6, :default=>Sequel::SQL::Blob.new(\"blah\")\n Date :c7, :default=>Date.parse(\"2008-10-29\")\n DateTime :c8, :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n Time :c9, :default=>Time.parse(\"10:20:30\"), :only_time=>true\n String :c10\nend"
259
+ @d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n column :c1, \"boolean\", :default=>false\n column :c2, \"varchar\", :default=>\"blah\"\n column :c3, \"integer\", :default=>-1\n column :c4, \"float\", :default=>1.0\n column :c5, \"decimal\", :default=>BigDecimal.new(\"0.1005E3\")\n column :c6, \"blob\", :default=>Sequel::SQL::Blob.new(\"blah\")\n column :c7, \"date\", :default=>Date.parse(\"2008-10-29\")\n column :c8, \"datetime\", :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n column :c9, \"time\", :default=>Time.parse(\"10:20:30\")\n column :c10, \"interval\", :default=>\"'6 weeks'\".lit\nend"
260
+ end
261
+
262
+ it "should not use a '...'.lit as a fallback if using MySQL with the :same_db option" do
263
+ @d.meta_def(:database_type){:mysql}
264
+ @d.meta_def(:schema) do |t, *os|
265
+ s = [[:c10, {:db_type=>'interval', :default=>"'6 weeks'", :type=>:interval, :allow_null=>true}]]
266
+ s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
267
+ s
268
+ end
269
+ @d.dump_table_schema(:t5, :same_db=>true).should == "create_table(:t5) do\n column :c10, \"interval\"\nend"
270
+ end
271
+
272
+ it "should convert unknown database types to strings" do
273
+ @d.dump_table_schema(:t5).should == "create_table(:t5) do\n String :c1\nend"
274
+ end
275
+
276
+ it "should convert many database types to ruby types" do
277
+ types = %w"mediumint smallint int integer mediumint(6) smallint(7) int(8) integer(9)
278
+ tinyint tinyint(2) bigint bigint(20) real float double boolean tinytext mediumtext
279
+ longtext text clob date datetime timestamp time char character
280
+ varchar varchar(255) varchar(30) bpchar string money
281
+ decimal decimal(10,2) numeric numeric(15,3) number bytea tinyblob mediumblob longblob
282
+ blob varbinary varbinary(10) binary binary(20) year" +
283
+ ["double precision", "timestamp with time zone", "timestamp without time zone",
284
+ "time with time zone", "time without time zone", "character varying(20)"] +
285
+ %w"nvarchar ntext smalldatetime smallmoney binary varbinary nchar"
286
+ @d.meta_def(:schema) do |t, *o|
287
+ i = 0
288
+ types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
289
+ end
290
+ table = <<END_MIG
291
+ create_table(:x) do
292
+ Integer :c1
293
+ Integer :c2
294
+ Integer :c3
295
+ Integer :c4
296
+ Integer :c5
297
+ Integer :c6
298
+ Integer :c7
299
+ Integer :c8
300
+ Integer :c9
301
+ Integer :c10
302
+ Bignum :c11
303
+ Bignum :c12
304
+ Float :c13
305
+ Float :c14
306
+ Float :c15
307
+ TrueClass :c16
308
+ String :c17, :text=>true
309
+ String :c18, :text=>true
310
+ String :c19, :text=>true
311
+ String :c20, :text=>true
312
+ String :c21, :text=>true
313
+ Date :c22
314
+ DateTime :c23
315
+ DateTime :c24
316
+ Time :c25, :only_time=>true
317
+ String :c26, :fixed=>true
318
+ String :c27, :fixed=>true
319
+ String :c28
320
+ String :c29, :size=>255
321
+ String :c30, :size=>30
322
+ String :c31
323
+ String :c32
324
+ BigDecimal :c33, :size=>[19, 2]
325
+ BigDecimal :c34
326
+ BigDecimal :c35, :size=>[10, 2]
327
+ BigDecimal :c36
328
+ BigDecimal :c37, :size=>[15, 3]
329
+ BigDecimal :c38
330
+ File :c39
331
+ File :c40
332
+ File :c41
333
+ File :c42
334
+ File :c43
335
+ File :c44
336
+ File :c45, :size=>10
337
+ File :c46
338
+ File :c47, :size=>20
339
+ Integer :c48
340
+ Float :c49
341
+ DateTime :c50
342
+ DateTime :c51
343
+ Time :c52, :only_time=>true
344
+ Time :c53, :only_time=>true
345
+ String :c54, :size=>20
346
+ String :c55
347
+ String :c56, :text=>true
348
+ DateTime :c57
349
+ BigDecimal :c58, :size=>[19, 2]
350
+ File :c59
351
+ File :c60
352
+ String :c61, :fixed=>true
353
+ end
354
+ END_MIG
355
+ @d.dump_table_schema(:x).should == table.chomp
356
+ end
357
+ end
@@ -0,0 +1,127 @@
1
+ require File.join(File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe Sequel::Model, "dataset & schema" do
4
+ before do
5
+ @model = Class.new(Sequel::Model(:items))
6
+ end
7
+
8
+ specify "sets schema with implicit table name" do
9
+ @model.set_schema do
10
+ primary_key :ssn, :string
11
+ end
12
+ @model.primary_key.should == :ssn
13
+ @model.table_name.should == :items
14
+ end
15
+
16
+ specify "sets schema with explicit table name" do
17
+ @model.set_schema :foo do
18
+ primary_key :id
19
+ end
20
+ @model.primary_key.should == :id
21
+ @model.table_name.should == :foo
22
+ end
23
+ end
24
+
25
+ describe Sequel::Model, "table_exists?" do
26
+
27
+ before(:each) do
28
+ MODEL_DB.reset
29
+ @model = Class.new(Sequel::Model(:items))
30
+ end
31
+
32
+ it "should get the table name and question the model's db if table_exists?" do
33
+ @model.should_receive(:table_name).and_return(:items)
34
+ @model.db.should_receive(:table_exists?)
35
+ @model.table_exists?
36
+ end
37
+ end
38
+
39
+ describe Sequel::Model, "create_table and schema" do
40
+
41
+ before(:each) do
42
+ MODEL_DB.reset
43
+ @model = Class.new(Sequel::Model) do
44
+ set_schema(:items) do
45
+ text :name
46
+ float :price, :null => false
47
+ end
48
+ end
49
+ end
50
+
51
+ it "should get the create table SQL list from the db and execute it line by line" do
52
+ @model.create_table
53
+ MODEL_DB.sqls.should == ['CREATE TABLE items (name text, price float NOT NULL)']
54
+ end
55
+
56
+ it "should reload the schema from the database" do
57
+ schem = {:name=>{:type=>:string}, :price=>{:type=>:float}}
58
+ @model.db.should_receive(:schema).with(:items, :reload=>true).and_return(schem.to_a.sort_by{|x| x[0].to_s})
59
+ @model.create_table
60
+ @model.db_schema.should == schem
61
+ @model.instance_variable_get(:@columns).should == [:name, :price]
62
+ end
63
+
64
+ it "should return the schema generator via schema" do
65
+ @model.schema.should be_a_kind_of(Sequel::Schema::Generator)
66
+ end
67
+
68
+ it "should use the superclasses schema if it exists" do
69
+ @submodel = Class.new(@model)
70
+ @submodel.schema.should be_a_kind_of(Sequel::Schema::Generator)
71
+ end
72
+
73
+ it "should return nil if no schema is present" do
74
+ @model = Class.new(Sequel::Model)
75
+ @model.schema.should == nil
76
+ @submodel = Class.new(@model)
77
+ @submodel.schema.should == nil
78
+ end
79
+ end
80
+
81
+ describe Sequel::Model, "drop_table" do
82
+
83
+ before(:each) do
84
+ MODEL_DB.reset
85
+ @model = Class.new(Sequel::Model(:items))
86
+ end
87
+
88
+ it "should get the drop table SQL for the associated table and then execute the SQL." do
89
+ @model.should_receive(:table_name).and_return(:items)
90
+ @model.db.should_receive(:drop_table_sql).with(:items)
91
+ @model.db.should_receive(:execute).and_return(:true)
92
+ @model.drop_table
93
+ end
94
+
95
+ end
96
+
97
+ describe Sequel::Model, "create_table!" do
98
+ before do
99
+ MODEL_DB.reset
100
+ @model = Class.new(Sequel::Model(:items))
101
+ end
102
+
103
+ it "should drop table if it exists and then create the table" do
104
+ @model.should_receive(:drop_table).and_return(true)
105
+ @model.should_receive(:create_table).and_return(true)
106
+ @model.create_table!
107
+ end
108
+ end
109
+
110
+ describe Sequel::Model, "create_table?" do
111
+ before do
112
+ MODEL_DB.reset
113
+ @model = Class.new(Sequel::Model(:items))
114
+ end
115
+
116
+ it "should not create the table if it already exists" do
117
+ @model.should_receive(:table_exists?).and_return(true)
118
+ @model.should_not_receive(:create_table)
119
+ @model.create_table?.should == nil
120
+ end
121
+
122
+ it "should create the table if it doesn't exist" do
123
+ @model.should_receive(:table_exists?).and_return(false)
124
+ @model.should_receive(:create_table).and_return(3)
125
+ @model.create_table?.should == 3
126
+ end
127
+ end