|
1 | 1 | require 'securerandom' |
2 | 2 |
|
3 | 3 | describe Sequel::Snowflake::Dataset do |
4 | | - let(:db) { Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) } |
| 4 | + let(:db) { @db ||= Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) } |
| 5 | + |
| 6 | + before(:all) do |
| 7 | + @db = Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) |
| 8 | + end |
| 9 | + |
| 10 | + after(:all) do |
| 11 | + @db.disconnect if @db |
| 12 | + end |
5 | 13 |
|
6 | 14 | describe 'Converting Snowflake data types' do |
7 | 15 | # Create a test table with a reasonably-random suffix |
|
70 | 78 | end |
71 | 79 | end |
72 | 80 |
|
| 81 | + describe 'GROUP BY features' do |
| 82 | + before(:all) do |
| 83 | + @products = "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym |
| 84 | + @sales = "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym |
| 85 | + |
| 86 | + @db.create_table(@products, :temp => true) do |
| 87 | + Integer :product_id |
| 88 | + Float :wholesale_price |
| 89 | + end |
| 90 | + |
| 91 | + @db.create_table(@sales, :temp => true) do |
| 92 | + Integer :product_id |
| 93 | + Float :retail_price |
| 94 | + Integer :quantity |
| 95 | + String :city |
| 96 | + String :state |
| 97 | + end |
| 98 | + |
| 99 | + @db[@products].insert({ product_id: 1, wholesale_price: 1.00 }) |
| 100 | + @db[@products].insert({ product_id: 2, wholesale_price: 2.00 }) |
| 101 | + @db[@sales].insert({ product_id: 1, retail_price: 2.00, quantity: 1, city: 'SF', state: 'CA' }) |
| 102 | + @db[@sales].insert({ product_id: 1, retail_price: 2.00, quantity: 2, city: 'SJ', state: 'CA' }) |
| 103 | + @db[@sales].insert({ product_id: 2, retail_price: 5.00, quantity: 4, city: 'SF', state: 'CA' }) |
| 104 | + @db[@sales].insert({ product_id: 2, retail_price: 5.00, quantity: 8, city: 'SJ', state: 'CA' }) |
| 105 | + @db[@sales].insert({ product_id: 2, retail_price: 5.00, quantity: 16, city: 'Miami', state: 'FL' }) |
| 106 | + @db[@sales].insert({ product_id: 2, retail_price: 5.00, quantity: 32, city: 'Orlando', state: 'FL' }) |
| 107 | + @db[@sales].insert({ product_id: 2, retail_price: 5.00, quantity: 64, city: 'SJ', state: 'CA' }) |
| 108 | + end |
| 109 | + |
| 110 | + after(:all) do |
| 111 | + @db.drop_table(@products) if @products |
| 112 | + @db.drop_table(@sales) if @sales |
| 113 | + end |
| 114 | + |
| 115 | + let(:products) { @products } |
| 116 | + let(:sales) { @sales } |
| 117 | + |
| 118 | + it 'can use GROUP CUBE' do |
| 119 | + res = db.from(Sequel[products].as(:p)). |
| 120 | + join(Sequel[sales].as(:s), Sequel[:p][:product_id] => Sequel[:s][:product_id]). |
| 121 | + select( |
| 122 | + Sequel[:s][:state], |
| 123 | + Sequel[:s][:city], |
| 124 | + Sequel.function(:sum, Sequel.*(Sequel.-(Sequel[:s][:retail_price], Sequel[:p][:wholesale_price]), Sequel[:s][:quantity])).as(:profit) |
| 125 | + ). |
| 126 | + group(Sequel[:s][:state], Sequel[:s][:city]). |
| 127 | + group_cube. |
| 128 | + order(Sequel.asc(Sequel[:s][:state], nulls: :last)). |
| 129 | + order_append(Sequel[:s][:city]). |
| 130 | + all |
| 131 | + |
| 132 | + expect(res).to match_array([ |
| 133 | + { state: 'CA', city: 'SF', profit: 13 }, |
| 134 | + { state: 'CA', city: 'SJ', profit: 218 }, |
| 135 | + { state: 'CA', city: nil, profit: 231 }, |
| 136 | + { state: 'FL', city: 'Miami', profit: 48 }, |
| 137 | + { state: 'FL', city: 'Orlando', profit: 96 }, |
| 138 | + { state: 'FL', city: nil, profit: 144 }, |
| 139 | + { state: nil, city: 'Miami', profit: 48 }, |
| 140 | + { state: nil, city: 'Orlando', profit: 96 }, |
| 141 | + { state: nil, city: 'SF', profit: 13 }, |
| 142 | + { state: nil, city: 'SJ', profit: 218 }, |
| 143 | + { state: nil, city: nil, profit: 375 }, |
| 144 | + ]) |
| 145 | + end |
| 146 | + |
| 147 | + it 'can use GROUP ROLLUP' do |
| 148 | + res = db.from(Sequel[products].as(:p)). |
| 149 | + join(Sequel[sales].as(:s), Sequel[:p][:product_id] => Sequel[:s][:product_id]). |
| 150 | + select( |
| 151 | + Sequel[:s][:state], |
| 152 | + Sequel[:s][:city], |
| 153 | + Sequel.function(:sum, Sequel.*(Sequel.-(Sequel[:s][:retail_price], Sequel[:p][:wholesale_price]), Sequel[:s][:quantity])).as(:profit) |
| 154 | + ). |
| 155 | + group(Sequel[:s][:state], Sequel[:s][:city]). |
| 156 | + group_rollup. |
| 157 | + order(Sequel.asc(Sequel[:s][:state], nulls: :last)). |
| 158 | + order_append(Sequel[:s][:city]). |
| 159 | + all |
| 160 | + |
| 161 | + expect(res).to match_array([ |
| 162 | + { state: 'CA', city: 'SF', profit: 13 }, |
| 163 | + { state: 'CA', city: 'SJ', profit: 218 }, |
| 164 | + { state: 'CA', city: nil, profit: 231 }, |
| 165 | + { state: 'FL', city: 'Miami', profit: 48 }, |
| 166 | + { state: 'FL', city: 'Orlando', profit: 96 }, |
| 167 | + { state: 'FL', city: nil, profit: 144 }, |
| 168 | + { state: nil, city: nil, profit: 375 }, |
| 169 | + ]) |
| 170 | + end |
| 171 | + |
| 172 | + it 'can use GROUPING SETS' do |
| 173 | + res = db.from(Sequel[products].as(:p)). |
| 174 | + join(Sequel[sales].as(:s), Sequel[:p][:product_id] => Sequel[:s][:product_id]). |
| 175 | + select( |
| 176 | + Sequel[:s][:state], |
| 177 | + Sequel[:s][:city], |
| 178 | + Sequel.function(:sum, Sequel.*(Sequel.-(Sequel[:s][:retail_price], Sequel[:p][:wholesale_price]), Sequel[:s][:quantity])).as(:profit) |
| 179 | + ). |
| 180 | + group([Sequel[:s][:state]], [Sequel[:s][:city]]). |
| 181 | + grouping_sets. |
| 182 | + order(Sequel.asc(Sequel[:s][:state], nulls: :last)). |
| 183 | + order_append(Sequel[:s][:city]). |
| 184 | + all |
| 185 | + |
| 186 | + expect(res).to match_array([ |
| 187 | + { state: 'CA', city: nil, profit: 231 }, |
| 188 | + { state: 'FL', city: nil, profit: 144 }, |
| 189 | + { state: nil, city: 'Miami', profit: 48 }, |
| 190 | + { state: nil, city: 'Orlando', profit: 96 }, |
| 191 | + { state: nil, city: 'SF', profit: 13 }, |
| 192 | + { state: nil, city: 'SJ', profit: 218 }, |
| 193 | + ]) |
| 194 | + end |
| 195 | + end |
| 196 | + |
73 | 197 | describe 'MERGE feature' do |
74 | | - let(:target_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym } |
75 | | - let(:source_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym } |
| 198 | + before(:all) do |
| 199 | + @target_table = "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym |
| 200 | + @source_table = "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym |
76 | 201 |
|
77 | | - before(:each) do |
78 | | - db.create_table(target_table, :temp => true) do |
| 202 | + @db.create_table(@target_table, :temp => true) do |
79 | 203 | String :str |
80 | 204 | String :str2 |
81 | 205 | String :str3 |
82 | 206 | end |
83 | 207 |
|
84 | | - db.create_table(source_table, :temp => true) do |
| 208 | + @db.create_table(@source_table, :temp => true) do |
85 | 209 | String :from |
86 | 210 | String :to |
87 | 211 | String :whomst |
88 | 212 | end |
| 213 | + end |
89 | 214 |
|
90 | | - db[target_table].insert({ str: 'foo', str2: 'foo', str3: 'phoo' }) |
91 | | - db[target_table].insert({ str: 'baz', str2: 'foo', str3: 'buzz' }) |
92 | | - db[source_table].insert({ from: 'foo', to: 'bar', whomst: 'me' }) |
| 215 | + after(:all) do |
| 216 | + @db.drop_table(@target_table) if @target_table |
| 217 | + @db.drop_table(@source_table) if @source_table |
93 | 218 | end |
94 | 219 |
|
95 | | - after(:each) do |
96 | | - db.drop_table(target_table) |
97 | | - db.drop_table(source_table) |
| 220 | + before(:each) do |
| 221 | + # Clear and repopulate data for each test since MERGE modifies data |
| 222 | + db[@target_table].delete |
| 223 | + db[@source_table].delete |
| 224 | + db[@target_table].insert({ str: 'foo', str2: 'foo', str3: 'phoo' }) |
| 225 | + db[@target_table].insert({ str: 'baz', str2: 'foo', str3: 'buzz' }) |
| 226 | + db[@source_table].insert({ from: 'foo', to: 'bar', whomst: 'me' }) |
98 | 227 | end |
99 | 228 |
|
| 229 | + let(:target_table) { @target_table } |
| 230 | + let(:source_table) { @source_table } |
| 231 | + |
100 | 232 | it 'can use MERGE' do |
101 | 233 | db[target_table].merge_using(source_table, str: :from).merge_update(str2: :to).merge |
102 | 234 |
|
|
108 | 240 | end |
109 | 241 |
|
110 | 242 | describe '#explain' do |
111 | | - # Create a test table with a reasonably-random suffix |
112 | | - let(:test_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym } |
| 243 | + before(:all) do |
| 244 | + @test_table = "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym |
113 | 245 |
|
114 | | - before(:each) do |
115 | | - db.create_table(test_table, :temp => true) do |
| 246 | + @db.create_table(@test_table, :temp => true) do |
116 | 247 | Numeric :id |
117 | 248 | String :name |
118 | 249 | String :email |
119 | 250 | String :title |
120 | 251 | end |
121 | 252 |
|
122 | | - db[test_table].insert( |
| 253 | + @db[@test_table].insert( |
123 | 254 | { id: 1, name: 'John Null', email: '[email protected]', title: 'Software Tester' } |
124 | 255 | ) |
125 | 256 | end |
126 | 257 |
|
127 | | - after(:each) do |
128 | | - db.drop_table(test_table) |
| 258 | + after(:all) do |
| 259 | + @db.drop_table(@test_table) if @test_table |
129 | 260 | end |
130 | 261 |
|
| 262 | + let(:test_table) { @test_table } |
| 263 | + |
131 | 264 | it "should have explain output" do |
132 | 265 | query = db.fetch("SELECT * FROM #{test_table} WHERE ID=1;") |
133 | 266 |
|
|
0 commit comments