1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
|
require File.join(File.dirname(__FILE__), 'spec_helper')
describe Sequel::Dataset, " graphing" do
before do
dbc = Class.new
@db = dbc.new
@ds1 = Sequel::Dataset.new(@db).from(:points)
@ds2 = Sequel::Dataset.new(@db).from(:lines)
@ds3 = Sequel::Dataset.new(@db).from(:graphs)
dss = {:points=>@ds1, :lines=>@ds2, :graphs=>@ds3}
dbc.send(:define_method, :[]){|ds| dss[ds]}
def @ds1.columns; [:id, :x, :y] end
def @ds2.columns; [:id, :x, :y, :graph_id] end
def @ds3.columns; [:id, :name, :x, :y, :lines_x] end
end
it "#graph should not modify the current dataset's opts" do
o1 = @ds1.opts
o2 = o1.dup
ds1 = @ds1.graph(@ds2, :x=>:id)
@ds1.opts.should == o1
@ds1.opts.should == o2
ds1.opts.should_not == o1
end
it "#graph should accept a dataset as the dataset" do
ds = @ds1.graph(@ds2, :x=>:id)
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)'
end
it "#graph should accept a symbol table name as the dataset" do
ds = @ds1.graph(:lines, :x=>:id)
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)'
end
it "#graph should accept an object that responds to dataset as the dataset" do
oc = Class.new
o = oc.new
ds = @ds2
oc.send(:define_method, :dataset){ds}
ds = @ds1.graph(o, :x=>:id)
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)'
ds = :lines
oc.send(:define_method, :dataset){ds}
ds = @ds1.graph(o, :x=>:id)
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)'
end
it "#graph should accept a :table_alias option" do
ds = @ds1.graph(:lines, {:x=>:id}, :table_alias=>:planes)
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 planes ON (planes.x = points.id)'
end
it "#graph should accept a :join_type option" do
ds = @ds1.graph(:lines, {:x=>:id}, :join_type=>:inner)
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)'
end
it "#graph should accept a :select_option" do
ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
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)'
end
it "#graph should pass all join_conditions to join_table" do
ds = @ds1.graph(@ds2, :x=>:id, :y=>:id)
['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)',
'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.y = points.id) AND (lines.x = points.id)'
].should(include(ds.sql))
end
it "#graph should not add columns if graph is called after set_graph_aliases" do
ds = @ds1.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
['SELECT points.x, lines.y FROM points',
'SELECT lines.y, points.x FROM points'
].should(include(ds.sql))
ds = ds.graph(:lines, :x=>:id)
['SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
'SELECT lines.y, points.x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
].should(include(ds.sql))
end
it "#graph should allow graphing of multiple datasets" do
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
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)'
end
it "#graph should allow graphing of the same dataset multiple times" do
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
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 graph ON (graph.y = points.id)'
end
it "#graph should raise an error if the table/table alias has already been used" do
proc{@ds1.graph(@ds1, :x=>:id)}.should raise_error(Sequel::Error)
proc{@ds1.graph(@ds2, :x=>:id)}.should_not raise_error
proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, :x=>:id)}.should raise_error(Sequel::Error)
proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:x=>:id}, :table_alias=>:blah)}.should_not raise_error
end
it "#set_graph_aliases should not modify the current dataset's opts" do
o1 = @ds1.opts
o2 = o1.dup
ds1 = @ds1.set_graph_aliases(:x=>[:graphs,:id])
@ds1.opts.should == o1
@ds1.opts.should == o2
ds1.opts.should_not == o1
end
it "#set_graph_aliases should specify the graph mapping" do
ds = @ds1.graph(:lines, :x=>:id)
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)'
ds = ds.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
['SELECT points.x, lines.y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
'SELECT lines.y, points.x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
].should(include(ds.sql))
end
it "#set_graph_aliases should only alias columns if necessary" do
ds = @ds1.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
['SELECT points.x, lines.y FROM points',
'SELECT lines.y, points.x FROM points'
].should(include(ds.sql))
ds = @ds1.set_graph_aliases(:x1=>[:points, :x], :y=>[:lines, :y])
['SELECT points.x AS x1, lines.y FROM points',
'SELECT lines.y, points.x AS x1 FROM points'
].should(include(ds.sql))
end
it "#graph_each should split the result set into component tables" do
ds = @ds1.graph(@ds2, :x=>:id)
def ds.fetch_rows(sql, &block)
yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}}
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
def ds.fetch_rows(sql, &block)
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})
end
results = ds.all
results.length.should == 1
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}}
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds2, {:y=>:points__id}, :table_alias=>:graph)
def ds.fetch_rows(sql, &block)
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})
end
results = ds.all
results.length.should == 1
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}}
end
it "#graph_each should give a nil value instead of a hash when all values for a table are nil" do
ds = @ds1.graph(@ds2, :x=>:id)
def ds.fetch_rows(sql, &block)
yield({:id=>1,:x=>2,:y=>3,:lines_id=>nil,:lines_x=>nil,:lines_y=>nil,:graph_id=>nil})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>nil}
ds = @ds1.graph(@ds2, :x=>:id).graph(@ds3, :id=>:graph_id)
def ds.fetch_rows(sql, &block)
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})
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})
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})
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})
end
results = ds.all
results.length.should == 4
results[0].should == {:points=>{:id=>1, :x=>2, :y=>3}, :lines=>{:id=>4, :x=>5, :y=>6, :graph_id=>7}, :graphs=>nil}
results[1].should == {:points=>{:id=>2, :x=>4, :y=>5}, :lines=>nil, :graphs=>nil}
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}}
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}}
end
it "#graph_each should not included tables graphed with the :select option in the result set" do
ds = @ds1.graph(:lines, {:x=>:id}, :select=>false).graph(:graphs, :id=>:graph_id)
def ds.fetch_rows(sql, &block)
yield({:id=>1,:x=>2,:y=>3,:graphs_id=>8, :name=>9, :graphs_x=>10, :graphs_y=>11, :lines_x=>12})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
end
it "#graph_each should only include the columns selected with #set_graph_aliases, if called" do
ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
def ds.fetch_rows(sql, &block)
yield({:x=>2,:y=>3})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:x=>2}, :lines=>{:y=>3}}
ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x])
def ds.fetch_rows(sql, &block)
yield({:x=>2})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:x=>2}, :lines=>nil}
end
it "#graph_each should run the row_proc and transform for graphed datasets" do
@ds1.row_proc = proc{|h| h.keys.each{|k| h[k] *= 2}; h}
@ds2.row_proc = proc{|h| h.keys.each{|k| h[k] *= 3}; h}
@ds1.transform(:x=>[
proc{|v| 123},
proc{|v| 123}
])
@ds2.transform(:x=>[
proc{|v| 321},
proc{|v| 321}
])
ds = @ds1.graph(@ds2, :x=>:id)
def ds.fetch_rows(sql, &block)
yield({:id=>1,:x=>2,:y=>3,:lines_id=>4,:lines_x=>5,:lines_y=>6,:graph_id=>7})
end
results = ds.all
results.length.should == 1
results.first.should == {:points=>{:id=>2, :x=>246, :y=>6}, :lines=>{:id=>12, :x=>963, :y=>18, :graph_id=>21}}
end
end
|