sequel 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/CHANGELOG +1551 -4
  2. data/README +306 -19
  3. data/Rakefile +84 -56
  4. data/bin/sequel +106 -0
  5. data/doc/cheat_sheet.rdoc +225 -0
  6. data/doc/dataset_filtering.rdoc +182 -0
  7. data/lib/sequel_core.rb +136 -0
  8. data/lib/sequel_core/adapters/adapter_skeleton.rb +54 -0
  9. data/lib/sequel_core/adapters/ado.rb +80 -0
  10. data/lib/sequel_core/adapters/db2.rb +148 -0
  11. data/lib/sequel_core/adapters/dbi.rb +117 -0
  12. data/lib/sequel_core/adapters/informix.rb +78 -0
  13. data/lib/sequel_core/adapters/jdbc.rb +186 -0
  14. data/lib/sequel_core/adapters/jdbc/mysql.rb +55 -0
  15. data/lib/sequel_core/adapters/jdbc/postgresql.rb +66 -0
  16. data/lib/sequel_core/adapters/jdbc/sqlite.rb +47 -0
  17. data/lib/sequel_core/adapters/mysql.rb +231 -0
  18. data/lib/sequel_core/adapters/odbc.rb +155 -0
  19. data/lib/sequel_core/adapters/odbc_mssql.rb +106 -0
  20. data/lib/sequel_core/adapters/openbase.rb +64 -0
  21. data/lib/sequel_core/adapters/oracle.rb +170 -0
  22. data/lib/sequel_core/adapters/postgres.rb +199 -0
  23. data/lib/sequel_core/adapters/shared/mysql.rb +275 -0
  24. data/lib/sequel_core/adapters/shared/postgres.rb +351 -0
  25. data/lib/sequel_core/adapters/shared/sqlite.rb +146 -0
  26. data/lib/sequel_core/adapters/sqlite.rb +138 -0
  27. data/lib/sequel_core/connection_pool.rb +194 -0
  28. data/lib/sequel_core/core_ext.rb +203 -0
  29. data/lib/sequel_core/core_sql.rb +184 -0
  30. data/lib/sequel_core/database.rb +471 -0
  31. data/lib/sequel_core/database/schema.rb +156 -0
  32. data/lib/sequel_core/dataset.rb +457 -0
  33. data/lib/sequel_core/dataset/callback.rb +13 -0
  34. data/lib/sequel_core/dataset/convenience.rb +245 -0
  35. data/lib/sequel_core/dataset/pagination.rb +96 -0
  36. data/lib/sequel_core/dataset/query.rb +41 -0
  37. data/lib/sequel_core/dataset/schema.rb +15 -0
  38. data/lib/sequel_core/dataset/sql.rb +889 -0
  39. data/lib/sequel_core/deprecated.rb +26 -0
  40. data/lib/sequel_core/exceptions.rb +42 -0
  41. data/lib/sequel_core/migration.rb +187 -0
  42. data/lib/sequel_core/object_graph.rb +216 -0
  43. data/lib/sequel_core/pretty_table.rb +71 -0
  44. data/lib/sequel_core/schema.rb +2 -0
  45. data/lib/sequel_core/schema/generator.rb +239 -0
  46. data/lib/sequel_core/schema/sql.rb +325 -0
  47. data/lib/sequel_core/sql.rb +812 -0
  48. data/lib/sequel_model.rb +5 -1
  49. data/lib/sequel_model/association_reflection.rb +3 -8
  50. data/lib/sequel_model/base.rb +15 -10
  51. data/lib/sequel_model/inflector.rb +3 -5
  52. data/lib/sequel_model/plugins.rb +1 -1
  53. data/lib/sequel_model/record.rb +11 -3
  54. data/lib/sequel_model/schema.rb +4 -4
  55. data/lib/sequel_model/validations.rb +6 -1
  56. data/spec/adapters/ado_spec.rb +17 -0
  57. data/spec/adapters/informix_spec.rb +96 -0
  58. data/spec/adapters/mysql_spec.rb +764 -0
  59. data/spec/adapters/oracle_spec.rb +222 -0
  60. data/spec/adapters/postgres_spec.rb +441 -0
  61. data/spec/adapters/spec_helper.rb +7 -0
  62. data/spec/adapters/sqlite_spec.rb +400 -0
  63. data/spec/integration/dataset_test.rb +51 -0
  64. data/spec/integration/eager_loader_test.rb +702 -0
  65. data/spec/integration/schema_test.rb +102 -0
  66. data/spec/integration/spec_helper.rb +44 -0
  67. data/spec/integration/type_test.rb +43 -0
  68. data/spec/rcov.opts +2 -0
  69. data/spec/sequel_core/connection_pool_spec.rb +363 -0
  70. data/spec/sequel_core/core_ext_spec.rb +156 -0
  71. data/spec/sequel_core/core_sql_spec.rb +427 -0
  72. data/spec/sequel_core/database_spec.rb +964 -0
  73. data/spec/sequel_core/dataset_spec.rb +2977 -0
  74. data/spec/sequel_core/expression_filters_spec.rb +346 -0
  75. data/spec/sequel_core/migration_spec.rb +261 -0
  76. data/spec/sequel_core/object_graph_spec.rb +234 -0
  77. data/spec/sequel_core/pretty_table_spec.rb +58 -0
  78. data/spec/sequel_core/schema_generator_spec.rb +122 -0
  79. data/spec/sequel_core/schema_spec.rb +497 -0
  80. data/spec/sequel_core/spec_helper.rb +51 -0
  81. data/spec/{association_reflection_spec.rb → sequel_model/association_reflection_spec.rb} +6 -6
  82. data/spec/{associations_spec.rb → sequel_model/associations_spec.rb} +47 -18
  83. data/spec/{base_spec.rb → sequel_model/base_spec.rb} +2 -1
  84. data/spec/{caching_spec.rb → sequel_model/caching_spec.rb} +0 -0
  85. data/spec/{dataset_methods_spec.rb → sequel_model/dataset_methods_spec.rb} +13 -1
  86. data/spec/{eager_loading_spec.rb → sequel_model/eager_loading_spec.rb} +75 -14
  87. data/spec/{hooks_spec.rb → sequel_model/hooks_spec.rb} +4 -4
  88. data/spec/sequel_model/inflector_spec.rb +119 -0
  89. data/spec/{model_spec.rb → sequel_model/model_spec.rb} +30 -11
  90. data/spec/{plugins_spec.rb → sequel_model/plugins_spec.rb} +0 -0
  91. data/spec/{record_spec.rb → sequel_model/record_spec.rb} +47 -6
  92. data/spec/{schema_spec.rb → sequel_model/schema_spec.rb} +18 -4
  93. data/spec/{spec_helper.rb → sequel_model/spec_helper.rb} +3 -2
  94. data/spec/{validations_spec.rb → sequel_model/validations_spec.rb} +37 -17
  95. data/spec/spec_config.rb +9 -0
  96. data/spec/spec_config.rb.example +10 -0
  97. metadata +110 -37
  98. data/spec/inflector_spec.rb +0 -34
@@ -0,0 +1,234 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Sequel::Dataset, " graphing" do
4
+ before do
5
+ dbc = Class.new
6
+ @db = dbc.new
7
+ @ds1 = Sequel::Dataset.new(@db).from(:points)
8
+ @ds2 = Sequel::Dataset.new(@db).from(:lines)
9
+ @ds3 = Sequel::Dataset.new(@db).from(:graphs)
10
+ dss = {:points=>@ds1, :lines=>@ds2, :graphs=>@ds3}
11
+ dbc.send(:define_method, :[]){|ds| dss[ds]}
12
+ def @ds1.columns; [:id, :x, :y] end
13
+ def @ds2.columns; [:id, :x, :y, :graph_id] end
14
+ def @ds3.columns; [:id, :name, :x, :y, :lines_x] end
15
+ end
16
+
17
+ it "#graph should not modify the current dataset's opts" do
18
+ o1 = @ds1.opts
19
+ o2 = o1.dup
20
+ ds1 = @ds1.graph(@ds2, :x=>:id)
21
+ @ds1.opts.should == o1
22
+ @ds1.opts.should == o2
23
+ ds1.opts.should_not == o1
24
+ end
25
+
26
+ it "#graph should accept a dataset as the dataset" do
27
+ ds = @ds1.graph(@ds2, :x=>:id)
28
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
29
+ end
30
+
31
+ it "#graph should accept a symbol table name as the dataset" do
32
+ ds = @ds1.graph(:lines, :x=>:id)
33
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
34
+ end
35
+
36
+ it "#graph should accept an object that responds to dataset as the dataset" do
37
+ oc = Class.new
38
+ o = oc.new
39
+ ds = @ds2
40
+ oc.send(:define_method, :dataset){ds}
41
+ ds = @ds1.graph(o, :x=>:id)
42
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
43
+ ds = :lines
44
+ oc.send(:define_method, :dataset){ds}
45
+ ds = @ds1.graph(o, :x=>:id)
46
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
47
+ end
48
+
49
+ it "#graph should raise an error if a symbol, dataset, or model is not used" do
50
+ proc{@ds1.graph(Object.new, :x=>:id)}.should raise_error(Sequel::Error)
51
+ end
52
+
53
+ it "#graph should accept a :table_alias option" do
54
+ ds = @ds1.graph(:lines, {:x=>:id}, :table_alias=>:planes)
55
+ ds.sql.should == 'SELECT points.id, points.x, points.y, planes.id AS planes_id, planes.x AS planes_x, planes.y AS planes_y, planes.graph_id FROM points LEFT OUTER JOIN lines AS planes ON (planes.x = points.id)'
56
+ end
57
+
58
+ it "#graph should accept a :join_type option" do
59
+ ds = @ds1.graph(:lines, {:x=>:id}, :join_type=>:inner)
60
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points INNER JOIN lines ON (lines.x = points.id)'
61
+ end
62
+
63
+ it "#graph should not select any columns from the graphed table if :select option is false" do
64
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
65
+ ds.sql.should == 'SELECT points.id, points.x, points.y, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
66
+ end
67
+
68
+ it "#graph should use the given columns if :select option is used" do
69
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>[:x, :graph_id]).graph(:graphs, :id=>:graph_id)
70
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.x AS lines_x, lines.graph_id, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x AS graphs_lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
71
+ end
72
+
73
+ it "#graph should pass all join_conditions to join_table" do
74
+ ds = @ds1.graph(@ds2, [[:x, :id], [:y, :id]])
75
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
76
+ end
77
+
78
+ it "#graph should accept a block instead of conditions and pass it to join_table" do
79
+ ds = @ds1.graph(@ds2){|ja, lja, js| [[:x.qualify(ja), :id.qualify(lja)], [:y.qualify(ja), :id.qualify(lja)]]}
80
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON ((lines.x = points.id) AND (lines.y = points.id))'
81
+ end
82
+
83
+ it "#graph should not add columns if graph is called after set_graph_aliases" do
84
+ ds = @ds1.set_graph_aliases([[:x,[:points, :x]], [:y,[:lines, :y]]])
85
+ ds.sql.should == 'SELECT points.x, lines.y FROM points'
86
+ ds = ds.graph(:lines, :x=>:id)
87
+ ds.sql.should == 'SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
88
+ end
89
+
90
+ it "#graph should allow graphing of multiple datasets" do
91
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
92
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graphs.id AS graphs_id, graphs.name, graphs.x AS graphs_x, graphs.y AS graphs_y, graphs.lines_x AS graphs_lines_x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN graphs ON (graphs.id = lines.graph_id)'
93
+ end
94
+
95
+ it "#graph should allow graphing of the same dataset multiple times" do
96
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
97
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id, graph.id AS graph_id_0, graph.x AS graph_x, graph.y AS graph_y, graph.graph_id AS graph_graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id) LEFT OUTER JOIN lines AS graph ON (graph.y = points.id)'
98
+ end
99
+
100
+ it "#graph should raise an error if the table/table alias has already been used" do
101
+ proc{@ds1.graph(@ds1, :x=>:id)}.should raise_error(Sequel::Error)
102
+ proc{@ds1.graph(@ds2, :x=>:id)}.should_not raise_error
103
+ proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, :x=>:id)}.should raise_error(Sequel::Error)
104
+ proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:x=>:id}, :table_alias=>:blah)}.should_not raise_error
105
+ end
106
+
107
+ it "#set_graph_aliases should not modify the current dataset's opts" do
108
+ o1 = @ds1.opts
109
+ o2 = o1.dup
110
+ ds1 = @ds1.set_graph_aliases(:x=>[:graphs,:id])
111
+ @ds1.opts.should == o1
112
+ @ds1.opts.should == o2
113
+ ds1.opts.should_not == o1
114
+ end
115
+
116
+ it "#set_graph_aliases should specify the graph mapping" do
117
+ ds = @ds1.graph(:lines, :x=>:id)
118
+ ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
119
+ ds = ds.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
120
+ ['SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
121
+ 'SELECT lines.y, points.x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
122
+ ].should(include(ds.sql))
123
+ end
124
+
125
+ it "#set_graph_aliases should only alias columns if necessary" do
126
+ ds = @ds1.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
127
+ ['SELECT points.x, lines.y FROM points',
128
+ 'SELECT lines.y, points.x FROM points'
129
+ ].should(include(ds.sql))
130
+
131
+ ds = @ds1.set_graph_aliases(:x1=>[:points, :x], :y=>[:lines, :y])
132
+ ['SELECT points.x AS x1, lines.y FROM points',
133
+ 'SELECT lines.y, points.x AS x1 FROM points'
134
+ ].should(include(ds.sql))
135
+ end
136
+
137
+ it "#graph_each should split the result set into component tables" do
138
+ ds = @ds1.graph(@ds2, :x=>:id)
139
+ def ds.fetch_rows(sql, &block)
140
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
141
+ end
142
+ results = ds.all
143
+ results.length.should == 1
144
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}}
145
+
146
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
147
+ def ds.fetch_rows(sql, &block)
148
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :graphs_lines_x=>12})
149
+ end
150
+ results = ds.all
151
+ results.length.should == 1
152
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
153
+
154
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
155
+ def ds.fetch_rows(sql, &block)
156
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graph_id_0=>8, :graph_x=>9, :graph_y=>10, :graph_graph_id=>11})
157
+ end
158
+ results = ds.all
159
+ results.length.should == 1
160
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graph=>{:id=>8, :x=>9, :y=>10, :graph_id=>11}}
161
+ end
162
+
163
+ it "#graph_each should give a nil value instead of a hash when all values for a table are nil" do
164
+ ds = @ds1.graph(@ds2, :x=>:id)
165
+ def ds.fetch_rows(sql, &block)
166
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>nil,:lines_x=>nil,:lines_y=>nil,:graph_id=>nil})
167
+ end
168
+ results = ds.all
169
+ results.length.should == 1
170
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>nil}
171
+
172
+ ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
173
+ def ds.fetch_rows(sql, &block)
174
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>nil, :name=>nil, :graphs_x=>nil, :graphs_y=>nil, :graphs_lines_x=>nil})
175
+ yield({:id=>2,:x=>4,:y=>5,:lines_id=>nil,:lines_x=>nil,:lines_y=>nil,:graph_id=>nil, :graphs_id=>nil, :name=>nil, :graphs_x=>nil, :graphs_y=>nil, :graphs_lines_x=>nil})
176
+ yield({:id=>3,:x=>5,:y=>6,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7, :graphs_id=>7, :name=>8, :graphs_x=>9, :graphs_y=>10, :graphs_lines_x=>11})
177
+ yield({:id=>3,:x=>5,:y=>6,:lines_id=>7,:lines_x=>5,:lines_y=>8,:graph_id=>9, :graphs_id=>9, :name=>10, :graphs_x=>10, :graphs_y=>11, :graphs_lines_x=>12})
178
+ end
179
+ results = ds.all
180
+ results.length.should == 4
181
+ results[0].should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>nil}
182
+ results[1].should == {:points=>{:id=>2, :x=>4, :y=>5}, :lines=>nil, :graphs=>nil}
183
+ results[2].should == {:points=>{:id=>3, :x=>5, :y=>6}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>{:id=>7, :name=>8, :x=>9, :y=>10, :lines_x=>11}}
184
+ results[3].should == {:points=>{:id=>3, :x=>5, :y=>6}, :lines=>{:id=>7, :x=>5, :y=>8, :graph_id=>9}, :graphs=>{:id=>9, :name=>10, :x=>10, :y=>11, :lines_x=>12}}
185
+ end
186
+
187
+ it "#graph_each should not included tables graphed with the :select => false option in the result set" do
188
+ ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
189
+ def ds.fetch_rows(sql, &block)
190
+ yield({:id=>1,:x=>2,:y=>3,:graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :lines_x=>12})
191
+ end
192
+ results = ds.all
193
+ results.length.should == 1
194
+ results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
195
+ end
196
+
197
+ it "#graph_each should only include the columns selected with #set_graph_aliases, if called" do
198
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
199
+ def ds.fetch_rows(sql, &block)
200
+ yield({:x=>2,:y=>3})
201
+ end
202
+ results = ds.all
203
+ results.length.should == 1
204
+ results.first.should == {:points=>{:x=>2}, :lines=>{:y=>3}}
205
+
206
+ ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x])
207
+ def ds.fetch_rows(sql, &block)
208
+ yield({:x=>2})
209
+ end
210
+ results = ds.all
211
+ results.length.should == 1
212
+ results.first.should == {:points=>{:x=>2}, :lines=>nil}
213
+ end
214
+
215
+ it "#graph_each should run the row_proc and transform for graphed datasets" do
216
+ @ds1.row_proc = proc{|h| h.keys.each{|k| h[k] *= 2}; h}
217
+ @ds2.row_proc = proc{|h| h.keys.each{|k| h[k] *= 3}; h}
218
+ @ds1.transform(:x=>[
219
+ proc{|v| 123},
220
+ proc{|v| 123}
221
+ ])
222
+ @ds2.transform(:x=>[
223
+ proc{|v| 321},
224
+ proc{|v| 321}
225
+ ])
226
+ ds = @ds1.graph(@ds2, :x=>:id)
227
+ def ds.fetch_rows(sql, &block)
228
+ yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
229
+ end
230
+ results = ds.all
231
+ results.length.should == 1
232
+ results.first.should == {:points=>{:id=>2, :x=>246, :y=>6}, :lines=>{:id=>12, :x=>963, :y=>18, :graph_id=>21}}
233
+ end
234
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ require 'stringio'
4
+
5
+ context "PrettyTable" do
6
+ setup do
7
+ @data1 = [
8
+ {:x => 3, :y => 4}
9
+ ]
10
+
11
+ @data2 = [
12
+ {:a => 23, :b => 45},
13
+ {:a => 45, :b => 2377}
14
+ ]
15
+
16
+ @data3 = [
17
+ {:aaa => 1},
18
+ {:bb => 2},
19
+ {:c => 3}
20
+ ]
21
+
22
+ @output = StringIO.new
23
+ @orig_stdout = $stdout
24
+ $stdout = @output
25
+ end
26
+
27
+ teardown do
28
+ $stdout = @orig_stdout
29
+ end
30
+
31
+ specify "should infer the columns if not given" do
32
+ Sequel::PrettyTable.print(@data1)
33
+ @output.rewind
34
+ @output.read.should =~ \
35
+ /\n(\|x\|y\|)|(\|y\|x\|)\n/
36
+ end
37
+
38
+ specify "should calculate the maximum width of each column correctly" do
39
+ Sequel::PrettyTable.print(@data2, [:a, :b])
40
+ @output.rewind
41
+ @output.read.should == \
42
+ "+--+----+\n|a |b |\n+--+----+\n|23| 45|\n|45|2377|\n+--+----+\n"
43
+ end
44
+
45
+ specify "should also take header width into account" do
46
+ Sequel::PrettyTable.print(@data3, [:aaa, :bb, :c])
47
+ @output.rewind
48
+ @output.read.should == \
49
+ "+---+--+-+\n|aaa|bb|c|\n+---+--+-+\n| 1| | |\n| | 2| |\n| | |3|\n+---+--+-+\n"
50
+ end
51
+
52
+ specify "should print only the specified columns" do
53
+ Sequel::PrettyTable.print(@data2, [:a])
54
+ @output.rewind
55
+ @output.read.should == \
56
+ "+--+\n|a |\n+--+\n|23|\n|45|\n+--+\n"
57
+ end
58
+ end
@@ -0,0 +1,122 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Sequel::Schema::Generator do
4
+ before do
5
+ @generator = Sequel::Schema::Generator.new(SchemaDummyDatabase.new) do
6
+ string :title
7
+ column :body, :text
8
+ foreign_key :parent_id
9
+ primary_key :id
10
+ check 'price > 100'
11
+ constraint(:xxx) {:yyy == :zzz}
12
+ index :title
13
+ index [:title, :body]
14
+ foreign_key :node_id, :nodes
15
+ end
16
+ @columns, @indexes = @generator.create_info
17
+ end
18
+
19
+ {:name => :id, :primary_key => true}.each do |column, expected|
20
+ it "uses default primary key #{column}" do
21
+ @columns.first[column].should == expected
22
+ end
23
+ end
24
+
25
+ it "counts primary key, column and constraint definitions as columns" do
26
+ @columns.size.should == 7
27
+ end
28
+
29
+ it "places primary key first" do
30
+ @columns[0][:primary_key].should be_true
31
+ @columns[1][:primary_key].should_not be_true
32
+ @columns[2][:primary_key].should_not be_true
33
+ end
34
+
35
+ it "retrieves primary key name" do
36
+ @generator.primary_key_name.should == :id
37
+ end
38
+
39
+ it "keeps columns in order" do
40
+ @columns[1][:name].should == :title
41
+ @columns[1][:type].should == :string
42
+ @columns[2][:name].should == :body
43
+ @columns[2][:type].should == :text
44
+ end
45
+
46
+ it "creates foreign key column" do
47
+ @columns[3][:name].should == :parent_id
48
+ @columns[3][:type].should == :integer
49
+ @columns[6][:name].should == :node_id
50
+ @columns[6][:type].should == :integer
51
+ end
52
+
53
+ it "uses table for foreign key columns, if specified" do
54
+ @columns[6][:table].should == :nodes
55
+ @columns[3][:table].should == nil
56
+ end
57
+
58
+ it "finds columns" do
59
+ [:title, :body, :parent_id, :id].each do |col|
60
+ @generator.has_column?(col).should be_true
61
+ end
62
+ @generator.has_column?(:foo).should_not be_true
63
+ end
64
+
65
+ it "creates constraints" do
66
+ @columns[4][:name].should == nil
67
+ @columns[4][:type].should == :check
68
+ @columns[4][:check].should == ['price > 100']
69
+
70
+ @columns[5][:name].should == :xxx
71
+ @columns[5][:type].should == :check
72
+ @columns[5][:check].should be_a_kind_of(Proc)
73
+ end
74
+
75
+ it "creates indexes" do
76
+ @indexes[0][:columns].should include(:title)
77
+ @indexes[1][:columns].should include(:title)
78
+ @indexes[1][:columns].should include(:body)
79
+ end
80
+ end
81
+
82
+ describe Sequel::Schema::AlterTableGenerator do
83
+ before do
84
+ @generator = Sequel::Schema::AlterTableGenerator.new(SchemaDummyDatabase.new) do
85
+ add_column :aaa, :text
86
+ drop_column :bbb
87
+ rename_column :ccc, :ho
88
+ set_column_type :ddd, :float
89
+ set_column_default :eee, 1
90
+ add_index [:fff, :ggg]
91
+ drop_index :hhh
92
+ add_full_text_index :blah
93
+ add_spatial_index :geom
94
+ add_index :blah, :type => :hash
95
+ add_index :blah, :where => {:something => true}
96
+ add_constraint :con1, ':fred > 100'
97
+ drop_constraint :con2
98
+ add_primary_key :id
99
+ add_foreign_key :node_id, :nodes
100
+ end
101
+ end
102
+
103
+ specify "should generate operation records" do
104
+ @generator.operations.should == [
105
+ {:op => :add_column, :name => :aaa, :type => :text},
106
+ {:op => :drop_column, :name => :bbb},
107
+ {:op => :rename_column, :name => :ccc, :new_name => :ho},
108
+ {:op => :set_column_type, :name => :ddd, :type => :float},
109
+ {:op => :set_column_default, :name => :eee, :default => 1},
110
+ {:op => :add_index, :columns => [:fff, :ggg]},
111
+ {:op => :drop_index, :columns => [:hhh]},
112
+ {:op => :add_index, :columns => [:blah], :type => :full_text},
113
+ {:op => :add_index, :columns => [:geom], :type => :spatial},
114
+ {:op => :add_index, :columns => [:blah], :type => :hash},
115
+ {:op => :add_index, :columns => [:blah], :where => {:something => true}},
116
+ {:op => :add_constraint, :type => :check, :name => :con1, :check => [':fred > 100']},
117
+ {:op => :drop_constraint, :name => :con2},
118
+ {:op => :add_column, :name => :id, :type => :integer, :primary_key=>true, :auto_increment=>true},
119
+ {:op => :add_column, :name => :node_id, :type => :integer, :table=>:nodes}
120
+ ]
121
+ end
122
+ end
@@ -0,0 +1,497 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "DB#create_table" do
4
+ setup do
5
+ @db = SchemaDummyDatabase.new
6
+ end
7
+
8
+ specify "should accept the table name" do
9
+ @db.create_table(:cats) {}
10
+ @db.sqls.should == ['CREATE TABLE cats ()']
11
+ end
12
+
13
+ specify "should accept multiple columns" do
14
+ @db.create_table(:cats) do
15
+ column :id, :integer
16
+ column :name, :text
17
+ end
18
+ @db.sqls.should == ['CREATE TABLE cats (id integer, name text)']
19
+ end
20
+
21
+ specify "should accept method calls as data types" do
22
+ @db.create_table(:cats) do
23
+ integer :id
24
+ text :name
25
+ end
26
+ @db.sqls.should == ['CREATE TABLE cats (id integer, name text)']
27
+ end
28
+
29
+ specify "should accept primary key definition" do
30
+ @db.create_table(:cats) do
31
+ primary_key :id
32
+ end
33
+ @db.sqls.should == ['CREATE TABLE cats (id integer PRIMARY KEY AUTOINCREMENT)']
34
+
35
+ @db.sqls.clear
36
+ @db.create_table(:cats) do
37
+ primary_key :id, :serial, :auto_increment => false
38
+ end
39
+ @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
40
+
41
+ @db.sqls.clear
42
+ @db.create_table(:cats) do
43
+ primary_key :id, :type => :serial, :auto_increment => false
44
+ end
45
+ @db.sqls.should == ['CREATE TABLE cats (id serial PRIMARY KEY)']
46
+ end
47
+
48
+ specify "should accept and literalize default values" do
49
+ @db.create_table(:cats) do
50
+ integer :id, :default => 123
51
+ text :name, :default => "abc'def"
52
+ end
53
+ @db.sqls.should == ["CREATE TABLE cats (id integer DEFAULT 123, name text DEFAULT 'abc''def')"]
54
+ end
55
+
56
+ specify "should accept not null definition" do
57
+ @db.create_table(:cats) do
58
+ integer :id
59
+ text :name, :null => false
60
+ end
61
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL)"]
62
+ end
63
+
64
+ specify "should accept null definition" do
65
+ @db.create_table(:cats) do
66
+ integer :id
67
+ text :name, :null => true
68
+ end
69
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL)"]
70
+ end
71
+
72
+ specify "should accept unique definition" do
73
+ @db.create_table(:cats) do
74
+ integer :id
75
+ text :name, :unique => true
76
+ end
77
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text UNIQUE)"]
78
+ end
79
+
80
+ specify "should accept unsigned definition" do
81
+ @db.create_table(:cats) do
82
+ integer :value, :unsigned => true
83
+ end
84
+ @db.sqls.should == ["CREATE TABLE cats (value integer UNSIGNED)"]
85
+ end
86
+
87
+ specify "should accept [SET|ENUM](...) types" do
88
+ @db.create_table(:cats) do
89
+ set :color, :elements => ['black', 'tricolor', 'grey']
90
+ end
91
+ @db.sqls.should == ["CREATE TABLE cats (color set('black', 'tricolor', 'grey'))"]
92
+ end
93
+
94
+ specify "should accept varchar size" do
95
+ @db.create_table(:cats) do
96
+ varchar :name
97
+ end
98
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(255))"]
99
+ @db.sqls.clear
100
+ @db.create_table(:cats) do
101
+ varchar :name, :size => 51
102
+ end
103
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(51))"]
104
+ end
105
+
106
+ specify "should accept varchar size as sql function" do
107
+ @db.create_table(:cats) do
108
+ column :name, :varchar[102]
109
+ end
110
+ @db.sqls.should == ["CREATE TABLE cats (name varchar(102))"]
111
+ end
112
+
113
+ specify "should accept foreign keys without options" do
114
+ @db.create_table(:cats) do
115
+ foreign_key :project_id
116
+ end
117
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer)"]
118
+ end
119
+
120
+ specify "should accept foreign keys with options" do
121
+ @db.create_table(:cats) do
122
+ foreign_key :project_id, :table => :projects
123
+ end
124
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects)"]
125
+ end
126
+
127
+ specify "should accept foreign keys with separate table argument" do
128
+ @db.create_table(:cats) do
129
+ foreign_key :project_id, :projects, :default=>3
130
+ end
131
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer DEFAULT 3 REFERENCES projects)"]
132
+ end
133
+
134
+ specify "should raise an error if the table argument to foreign_key isn't a hash, symbol, or nil" do
135
+ proc{@db.create_table(:cats){foreign_key :project_id, Object.new, :default=>3}}.should raise_error(Sequel::Error)
136
+ end
137
+
138
+ specify "should accept foreign keys with arbitrary keys" do
139
+ @db.create_table(:cats) do
140
+ foreign_key :project_id, :table => :projects, :key => :id
141
+ end
142
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects(id))"]
143
+
144
+ @db.sqls.clear
145
+ @db.create_table(:cats) do
146
+ foreign_key :project_id, :table => :projects, :key => :zzz
147
+ end
148
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects(zzz))"]
149
+ end
150
+
151
+ specify "should accept foreign keys with ON DELETE clause" do
152
+ @db.create_table(:cats) do
153
+ foreign_key :project_id, :table => :projects, :on_delete => :restrict
154
+ end
155
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE RESTRICT)"]
156
+
157
+ @db.sqls.clear
158
+ @db.create_table(:cats) do
159
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade
160
+ end
161
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)"]
162
+
163
+ @db.sqls.clear
164
+ @db.create_table(:cats) do
165
+ foreign_key :project_id, :table => :projects, :on_delete => :no_action
166
+ end
167
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE NO ACTION)"]
168
+ @db.sqls.clear
169
+
170
+ @db.sqls.clear
171
+ @db.create_table(:cats) do
172
+ foreign_key :project_id, :table => :projects, :on_delete => :set_null
173
+ end
174
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET NULL)"]
175
+ @db.sqls.clear
176
+
177
+ @db.sqls.clear
178
+ @db.create_table(:cats) do
179
+ foreign_key :project_id, :table => :projects, :on_delete => :set_default
180
+ end
181
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET DEFAULT)"]
182
+ @db.sqls.clear
183
+ end
184
+
185
+ specify "should accept inline index definition" do
186
+ @db.create_table(:cats) do
187
+ integer :id, :index => true
188
+ end
189
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
190
+ end
191
+
192
+ specify "should accept inline index definition for foreign keys" do
193
+ @db.create_table(:cats) do
194
+ foreign_key :project_id, :table => :projects, :on_delete => :cascade, :index => true
195
+ end
196
+ @db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE CASCADE)",
197
+ "CREATE INDEX cats_project_id_index ON cats (project_id)"]
198
+ end
199
+
200
+ specify "should accept index definitions" do
201
+ @db.create_table(:cats) do
202
+ integer :id
203
+ index :id
204
+ end
205
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)"]
206
+ end
207
+
208
+ specify "should accept unique index definitions" do
209
+ @db.create_table(:cats) do
210
+ text :name
211
+ unique :name
212
+ end
213
+ @db.sqls.should == ["CREATE TABLE cats (name text)", "CREATE UNIQUE INDEX cats_name_index ON cats (name)"]
214
+ end
215
+
216
+ specify "should raise on full-text index definitions" do
217
+ proc {
218
+ @db.create_table(:cats) do
219
+ text :name
220
+ full_text_index :name
221
+ end
222
+ }.should raise_error(Sequel::Error)
223
+ end
224
+
225
+ specify "should raise on spatial index definitions" do
226
+ proc {
227
+ @db.create_table(:cats) do
228
+ point :geom
229
+ spatial_index :geom
230
+ end
231
+ }.should raise_error(Sequel::Error)
232
+ end
233
+
234
+ specify "should raise on partial index definitions" do
235
+ proc {
236
+ @db.create_table(:cats) do
237
+ text :name
238
+ index :name, :where => {:something => true}
239
+ end
240
+ }.should raise_error(Sequel::Error)
241
+ end
242
+
243
+ specify "should raise index definitions with type" do
244
+ proc {
245
+ @db.create_table(:cats) do
246
+ text :name
247
+ index :name, :type => :hash
248
+ end
249
+ }.should raise_error(Sequel::Error)
250
+ end
251
+
252
+ specify "should accept multiple index definitions" do
253
+ @db.create_table(:cats) do
254
+ integer :id
255
+ index :id
256
+ index :name
257
+ end
258
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX cats_id_index ON cats (id)", "CREATE INDEX cats_name_index ON cats (name)"]
259
+ end
260
+
261
+ specify "should accept custom index names" do
262
+ @db.create_table(:cats) do
263
+ integer :id
264
+ index :id, :name => 'abc'
265
+ end
266
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE INDEX abc ON cats (id)"]
267
+ end
268
+
269
+ specify "should accept unique index definitions" do
270
+ @db.create_table(:cats) do
271
+ integer :id
272
+ index :id, :unique => true
273
+ end
274
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_index ON cats (id)"]
275
+ end
276
+
277
+ specify "should accept composite index definitions" do
278
+ @db.create_table(:cats) do
279
+ integer :id
280
+ index [:id, :name], :unique => true
281
+ end
282
+ @db.sqls.should == ["CREATE TABLE cats (id integer)", "CREATE UNIQUE INDEX cats_id_name_index ON cats (id, name)"]
283
+ end
284
+
285
+ specify "should accept unnamed constraint definitions with blocks" do
286
+ @db.create_table(:cats) do
287
+ integer :score
288
+ check {(:x > 0) & (:y < 1)}
289
+ end
290
+ @db.sqls.should == ["CREATE TABLE cats (score integer, CHECK ((x > 0) AND (y < 1)))"]
291
+ end
292
+
293
+ specify "should accept unnamed constraint definitions" do
294
+ @db.create_table(:cats) do
295
+ check 'price < ?', 100
296
+ end
297
+ @db.sqls.should == ["CREATE TABLE cats (CHECK (price < 100))"]
298
+ end
299
+
300
+ specify "should accept named constraint definitions" do
301
+ @db.create_table(:cats) do
302
+ integer :score
303
+ constraint :valid_score, 'score <= 100'
304
+ end
305
+ @db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100))"]
306
+ end
307
+
308
+ specify "should accept named constraint definitions with block" do
309
+ @db.create_table(:cats) do
310
+ constraint(:blah_blah) {(:x > 0) & (:y < 1)}
311
+ end
312
+ @db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
313
+ end
314
+ end
315
+
316
+ context "DB#create_table!" do
317
+ setup do
318
+ @db = SchemaDummyDatabase.new
319
+ end
320
+
321
+ specify "should drop the table and then create it" do
322
+ @db.create_table!(:cats) {}
323
+ @db.sqls.should == ['DROP TABLE cats', 'CREATE TABLE cats ()']
324
+ end
325
+ end
326
+
327
+ context "DB#drop_table" do
328
+ setup do
329
+ @db = SchemaDummyDatabase.new
330
+ end
331
+
332
+ specify "should generate a DROP TABLE statement" do
333
+ @db.drop_table :cats
334
+ @db.sqls.should == ['DROP TABLE cats']
335
+ end
336
+ end
337
+
338
+ context "DB#alter_table" do
339
+ setup do
340
+ @db = SchemaDummyDatabase.new
341
+ end
342
+
343
+ specify "should support add_column" do
344
+ @db.alter_table(:cats) do
345
+ add_column :score, :integer
346
+ end
347
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN score integer"]
348
+ end
349
+
350
+ specify "should support add_constraint" do
351
+ @db.alter_table(:cats) do
352
+ add_constraint :valid_score, 'score <= 100'
353
+ end
354
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100)"]
355
+ end
356
+
357
+ specify "should support add_constraint with block" do
358
+ @db.alter_table(:cats) do
359
+ add_constraint(:blah_blah) {(:x > 0) & (:y < 1)}
360
+ end
361
+ @db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1))"]
362
+ end
363
+
364
+ specify "should support add_foreign_key" do
365
+ @db.alter_table(:cats) do
366
+ add_foreign_key :node_id, :nodes
367
+ end
368
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN node_id integer REFERENCES nodes"]
369
+ end
370
+
371
+ specify "should support add_index" do
372
+ @db.alter_table(:cats) do
373
+ add_index :name
374
+ end
375
+ @db.sqls.should == ["CREATE INDEX cats_name_index ON cats (name)"]
376
+ end
377
+
378
+ specify "should support add_primary_key" do
379
+ @db.alter_table(:cats) do
380
+ add_primary_key :id
381
+ end
382
+ @db.sqls.should == ["ALTER TABLE cats ADD COLUMN id integer PRIMARY KEY AUTOINCREMENT"]
383
+ end
384
+
385
+ specify "should support drop_column" do
386
+ @db.alter_table(:cats) do
387
+ drop_column :score
388
+ end
389
+ @db.sqls.should == ["ALTER TABLE cats DROP COLUMN score"]
390
+ end
391
+
392
+ specify "should support drop_constraint" do
393
+ @db.alter_table(:cats) do
394
+ drop_constraint :valid_score
395
+ end
396
+ @db.sqls.should == ["ALTER TABLE cats DROP CONSTRAINT valid_score"]
397
+ end
398
+
399
+ specify "should support drop_index" do
400
+ @db.alter_table(:cats) do
401
+ drop_index :name
402
+ end
403
+ @db.sqls.should == ["DROP INDEX cats_name_index"]
404
+ end
405
+
406
+ specify "should support rename_column" do
407
+ @db.alter_table(:cats) do
408
+ rename_column :name, :old_name
409
+ end
410
+ @db.sqls.should == ["ALTER TABLE cats RENAME COLUMN name TO old_name"]
411
+ end
412
+
413
+ specify "should support set_column_default" do
414
+ @db.alter_table(:cats) do
415
+ set_column_default :score, 3
416
+ end
417
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score SET DEFAULT 3"]
418
+ end
419
+
420
+ specify "should support set_column_type" do
421
+ @db.alter_table(:cats) do
422
+ set_column_type :score, :real
423
+ end
424
+ @db.sqls.should == ["ALTER TABLE cats ALTER COLUMN score TYPE real"]
425
+ end
426
+ end
427
+
428
+ context "Schema Parser" do
429
+ setup do
430
+ sqls = @sqls = []
431
+ @db = Sequel::Database.new
432
+ @db.meta_def(:dataset) do
433
+ ds = super()
434
+ ds.instance_variable_set(:@sqls, sqls)
435
+ def ds.fetch_rows(sql)
436
+ @sqls << sql
437
+ table = /'(.*)'/.match(sql)[1]
438
+ h = {:column=>"a", :db_type=>table, :max_chars=>nil, :numeric_precision=>nil, :default=>'', :allow_null=>'YES'}
439
+ (h[:column] = h[:table_name] = :x) if sql =~ /BASE TABLE/
440
+ yield h
441
+ end
442
+ ds
443
+ end
444
+ end
445
+ after do
446
+ Sequel.convert_tinyint_to_bool = true
447
+ end
448
+
449
+ specify "should parse the schema correctly for a single table" do
450
+ @db.schema(:x).should == [[:a, {:type=>nil, :db_type=>"x", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]
451
+ @sqls.should == ["SELECT column_name AS column, data_type AS db_type, character_maximum_length AS max_chars, numeric_precision, column_default AS default, is_nullable AS allow_null FROM information_schema.tables AS t INNER JOIN information_schema.columns AS c USING (table_catalog, table_schema, table_name) WHERE (c.table_name = 'x')"]
452
+ @db.schema(:x).should == [[:a, {:type=>nil, :db_type=>"x", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]
453
+ @sqls.length.should == 1
454
+ @db.schema(:x, :reload=>true).should == [[:a, {:type=>nil, :db_type=>"x", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]
455
+ @sqls.length.should == 2
456
+ end
457
+
458
+ specify "should parse the schema correctly for all tables" do
459
+ @db.schema.should == {:x=>[[:x, {:type=>nil, :db_type=>"BASE TABLE", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]}
460
+ @sqls.should == ["SELECT column_name AS column, data_type AS db_type, character_maximum_length AS max_chars, numeric_precision, column_default AS default, is_nullable AS allow_null, c.table_name FROM information_schema.tables AS t INNER JOIN information_schema.columns AS c USING (table_catalog, table_schema, table_name) WHERE (t.table_type = 'BASE TABLE')"]
461
+ @db.schema.should == {:x=>[[:x, {:type=>nil, :db_type=>"BASE TABLE", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]}
462
+ @sqls.length.should == 1
463
+ @db.schema(nil, :reload=>true).should == {:x=>[[:x, {:type=>nil, :db_type=>"BASE TABLE", :max_chars=>nil, :numeric_precision=>nil, :default=>nil, :allow_null=>true}]]}
464
+ @sqls.length.should == 2
465
+ end
466
+
467
+ specify "should correctly parse all supported data types" do
468
+ @db.schema(:tinyint).first.last[:type].should == :boolean
469
+ Sequel.convert_tinyint_to_bool = false
470
+ @db.schema(:tinyint, :reload=>true).first.last[:type].should == :integer
471
+ @db.schema(:int).first.last[:type].should == :integer
472
+ @db.schema(:integer).first.last[:type].should == :integer
473
+ @db.schema(:bigint).first.last[:type].should == :integer
474
+ @db.schema(:smallint).first.last[:type].should == :integer
475
+ @db.schema(:character).first.last[:type].should == :string
476
+ @db.schema(:"character varying").first.last[:type].should == :string
477
+ @db.schema(:varchar).first.last[:type].should == :string
478
+ @db.schema(:text).first.last[:type].should == :string
479
+ @db.schema(:date).first.last[:type].should == :date
480
+ @db.schema(:datetime).first.last[:type].should == :datetime
481
+ @db.schema(:timestamp).first.last[:type].should == :datetime
482
+ @db.schema(:"timestamp with time zone").first.last[:type].should == :datetime
483
+ @db.schema(:"timestamp without time zone").first.last[:type].should == :datetime
484
+ @db.schema(:time).first.last[:type].should == :time
485
+ @db.schema(:"time with time zone").first.last[:type].should == :time
486
+ @db.schema(:"time without time zone").first.last[:type].should == :time
487
+ @db.schema(:boolean).first.last[:type].should == :boolean
488
+ @db.schema(:real).first.last[:type].should == :float
489
+ @db.schema(:float).first.last[:type].should == :float
490
+ @db.schema(:double).first.last[:type].should == :float
491
+ @db.schema(:"double precision").first.last[:type].should == :float
492
+ @db.schema(:numeric).first.last[:type].should == :decimal
493
+ @db.schema(:decimal).first.last[:type].should == :decimal
494
+ @db.schema(:money).first.last[:type].should == :decimal
495
+ @db.schema(:bytea).first.last[:type].should == :blob
496
+ end
497
+ end