sequel-impala 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +3 -0
  3. data/LICENSE +462 -0
  4. data/README.rdoc +39 -0
  5. data/Rakefile +39 -0
  6. data/lib/driver/commons-logging-1.2.jar +0 -0
  7. data/lib/driver/hadoop-common-2.6.0.jar +0 -0
  8. data/lib/driver/hadoop-core-2.6.0.jar +0 -0
  9. data/lib/driver/hive-exec-1.1.0.jar +0 -0
  10. data/lib/driver/hive-jdbc-1.1.0.jar +0 -0
  11. data/lib/driver/hive-metastore-1.1.0.jar +0 -0
  12. data/lib/driver/hive-service-1.1.0.jar +0 -0
  13. data/lib/driver/httpclient-4.3.jar +0 -0
  14. data/lib/driver/httpcore-4.3.jar +0 -0
  15. data/lib/driver/libfb303-0.9.0.jar +0 -0
  16. data/lib/driver/slf4j-api-1.7.5.jar +0 -0
  17. data/lib/impala.rb +47 -0
  18. data/lib/impala/connection.rb +117 -0
  19. data/lib/impala/cursor.rb +157 -0
  20. data/lib/impala/protocol.rb +8 -0
  21. data/lib/impala/protocol/beeswax_constants.rb +15 -0
  22. data/lib/impala/protocol/beeswax_service.rb +766 -0
  23. data/lib/impala/protocol/beeswax_types.rb +193 -0
  24. data/lib/impala/protocol/cli_service_constants.rb +60 -0
  25. data/lib/impala/protocol/cli_service_types.rb +1452 -0
  26. data/lib/impala/protocol/facebook_service.rb +706 -0
  27. data/lib/impala/protocol/fb303_constants.rb +15 -0
  28. data/lib/impala/protocol/fb303_types.rb +25 -0
  29. data/lib/impala/protocol/hive_metastore_constants.rb +53 -0
  30. data/lib/impala/protocol/hive_metastore_types.rb +698 -0
  31. data/lib/impala/protocol/impala_hive_server2_service.rb +29 -0
  32. data/lib/impala/protocol/impala_service.rb +377 -0
  33. data/lib/impala/protocol/impala_service_constants.rb +13 -0
  34. data/lib/impala/protocol/impala_service_types.rb +90 -0
  35. data/lib/impala/protocol/status_constants.rb +13 -0
  36. data/lib/impala/protocol/status_types.rb +46 -0
  37. data/lib/impala/protocol/t_c_l_i_service.rb +948 -0
  38. data/lib/impala/protocol/thrift_hive_metastore.rb +4707 -0
  39. data/lib/impala/version.rb +3 -0
  40. data/lib/jdbc/hive2.rb +46 -0
  41. data/lib/sequel/adapters/impala.rb +123 -0
  42. data/lib/sequel/adapters/jdbc/hive2.rb +26 -0
  43. data/lib/sequel/adapters/shared/impala.rb +635 -0
  44. data/lib/sequel/extensions/csv_to_parquet.rb +112 -0
  45. data/spec/database_test.rb +56 -0
  46. data/spec/dataset_test.rb +1268 -0
  47. data/spec/files/bad_down_migration/001_create_alt_basic.rb +4 -0
  48. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +4 -0
  49. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  50. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  51. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +3 -0
  52. data/spec/files/bad_up_migration/001_create_alt_basic.rb +4 -0
  53. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +3 -0
  54. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +9 -0
  55. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +9 -0
  56. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +4 -0
  57. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +9 -0
  58. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +9 -0
  59. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  60. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +9 -0
  61. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +4 -0
  62. data/spec/files/integer_migrations/001_create_sessions.rb +9 -0
  63. data/spec/files/integer_migrations/002_create_nodes.rb +9 -0
  64. data/spec/files/integer_migrations/003_3_create_users.rb +4 -0
  65. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  66. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +9 -0
  67. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  68. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +9 -0
  69. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +4 -0
  70. data/spec/files/reversible_migrations/001_reversible.rb +5 -0
  71. data/spec/files/reversible_migrations/002_reversible.rb +5 -0
  72. data/spec/files/reversible_migrations/003_reversible.rb +5 -0
  73. data/spec/files/reversible_migrations/004_reversible.rb +5 -0
  74. data/spec/files/reversible_migrations/005_reversible.rb +10 -0
  75. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +9 -0
  76. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +9 -0
  77. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +4 -0
  78. data/spec/impala_test.rb +285 -0
  79. data/spec/migrator_test.rb +240 -0
  80. data/spec/plugin_test.rb +91 -0
  81. data/spec/prepared_statement_test.rb +327 -0
  82. data/spec/schema_test.rb +356 -0
  83. data/spec/spec_helper.rb +15 -0
  84. data/spec/timezone_test.rb +86 -0
  85. data/spec/type_test.rb +99 -0
  86. metadata +239 -0
@@ -0,0 +1,356 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
+
3
+ describe "Database schema parser" do
4
+ after do
5
+ DB.identifier_output_method = nil
6
+ DB.identifier_input_method = nil
7
+ DB.drop_table?(:items)
8
+ end
9
+
10
+ it "should handle a database with a identifier methods" do
11
+ DB.identifier_output_method = :reverse
12
+ DB.identifier_input_method = :reverse
13
+ DB.create_table!(:items){Integer :number}
14
+ begin
15
+ DB.schema(:items, :reload=>true).must_be_kind_of(Array)
16
+ DB.schema(:items, :reload=>true).first.first.must_equal :number
17
+ ensure
18
+ DB.drop_table(:items)
19
+ end
20
+ end
21
+
22
+ it "should handle a dataset with identifier methods different than the database's" do
23
+ DB.identifier_output_method = :reverse
24
+ DB.identifier_input_method = :reverse
25
+ DB.create_table!(:items){Integer :number}
26
+ DB.identifier_output_method = nil
27
+ DB.identifier_input_method = nil
28
+ ds = DB[:items]
29
+ ds.identifier_output_method = :reverse
30
+ ds.identifier_input_method = :reverse
31
+ begin
32
+ DB.schema(ds, :reload=>true).must_be_kind_of(Array)
33
+ DB.schema(ds, :reload=>true).first.first.must_equal :number
34
+ ensure
35
+ DB.identifier_output_method = :reverse
36
+ DB.identifier_input_method = :reverse
37
+ DB.drop_table(:items)
38
+ end
39
+ end
40
+
41
+ it "should not issue an sql query if the schema has been loaded unless :reload is true" do
42
+ DB.create_table!(:items){Integer :number}
43
+ DB.schema(:items, :reload=>true)
44
+ DB.schema(:items)
45
+ DB.schema(:items, :reload=>true)
46
+ end
47
+
48
+ it "Model schema should include columns in the table, even if they aren't selected" do
49
+ DB.create_table!(:items){String :a; Integer :number}
50
+ m = Sequel::Model(DB[:items].select(:a))
51
+ m.columns.must_equal [:a]
52
+ m.db_schema[:number][:type].must_equal :integer
53
+ end
54
+
55
+ it "should raise an error when the table doesn't exist" do
56
+ proc{DB.schema(:no_table)}.must_raise(Sequel::Error, Sequel::DatabaseError)
57
+ end
58
+
59
+ it "should return the schema correctly" do
60
+ DB.create_table!(:items){Integer :number}
61
+ schema = DB.schema(:items, :reload=>true)
62
+ schema.must_be_kind_of(Array)
63
+ schema.length.must_equal 1
64
+ col = schema.first
65
+ col.must_be_kind_of(Array)
66
+ col.length.must_equal 2
67
+ col.first.must_equal :number
68
+ col_info = col.last
69
+ col_info.must_be_kind_of(Hash)
70
+ col_info[:type].must_equal :integer
71
+ DB.schema(:items)
72
+ end
73
+
74
+ it "should make :default nil for a NULL default" do
75
+ DB.create_table!(:items){Integer :number}
76
+ DB.schema(:items).first.last[:default].must_equal nil
77
+ end
78
+
79
+ it "should parse types from the schema properly" do
80
+ DB.create_table!(:items){Integer :number}
81
+ DB.schema(:items).first.last[:type].must_equal :integer
82
+ DB.create_table!(:items){Fixnum :number}
83
+ DB.schema(:items).first.last[:type].must_equal :integer
84
+ DB.create_table!(:items){Bignum :number}
85
+ DB.schema(:items).first.last[:type].must_equal :integer
86
+ DB.create_table!(:items){Float :number}
87
+ DB.schema(:items).first.last[:type].must_equal :float
88
+ DB.create_table!(:items){BigDecimal :number, :size=>[11, 2]}
89
+ DB.schema(:items).first.last[:type].must_equal :decimal
90
+ DB.create_table!(:items){Numeric :number, :size=>[12, 0]}
91
+ DB.schema(:items).first.last[:type].must_equal :integer
92
+ DB.create_table!(:items){String :number}
93
+ DB.schema(:items).first.last[:type].must_equal :string
94
+ DB.create_table!(:items){Time :number}
95
+ DB.schema(:items).first.last[:type].must_equal :datetime
96
+ DB.create_table!(:items){DateTime :number}
97
+ DB.schema(:items).first.last[:type].must_equal :datetime
98
+ DB.create_table!(:items){Date :number}
99
+ DB.schema(:items).first.last[:type].must_equal :datetime
100
+ DB.create_table!(:items){TrueClass :number}
101
+ DB.schema(:items).first.last[:type].must_equal :boolean
102
+ DB.create_table!(:items){FalseClass :number}
103
+ DB.schema(:items).first.last[:type].must_equal :boolean
104
+ end
105
+
106
+ it "should parse maximum length for string columns" do
107
+ DB.create_table!(:items){String :a, :size=>4}
108
+ DB.schema(:items).first.last[:max_length].must_equal 4
109
+ DB.create_table!(:items){String :a, :fixed=>true, :size=>3}
110
+ DB.schema(:items).first.last[:max_length].must_equal 3
111
+ end
112
+ end
113
+
114
+ describe "Database schema modifiers" do
115
+ before do
116
+ @db = DB
117
+ @ds = @db[:items]
118
+ end
119
+ after do
120
+ @db.drop_table?(:items)
121
+ @db.drop_table?(:items2)
122
+ end
123
+
124
+ it "should create tables correctly" do
125
+ @db.create_table!(:items){Integer :number}
126
+ @db.table_exists?(:items).must_equal true
127
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
128
+ @ds.insert([10])
129
+ @ds.columns!.must_equal [:number]
130
+ end
131
+
132
+ it "should create tables from select statements correctly" do
133
+ @db.create_table!(:items){Integer :number}
134
+ @ds.insert([10])
135
+ @db.create_table(:items2, :as=>@db[:items])
136
+ @db.schema(:items2, :reload=>true).map{|x| x.first}.must_equal [:number]
137
+ @db[:items2].columns.must_equal [:number]
138
+ @db[:items2].all.must_equal [{:number=>10}]
139
+ end
140
+
141
+ it "should not raise an error if table doesn't exist when using drop_table :if_exists" do
142
+ @db.drop_table(:items, :if_exists=>true)
143
+ end
144
+
145
+ describe "views" do
146
+ before do
147
+ @db.drop_view(:items_view2) rescue nil
148
+ @db.drop_view(:items_view) rescue nil
149
+ @db.create_table!(:items){Integer :number}
150
+ @ds.insert(:number=>1)
151
+ @ds.insert(:number=>2)
152
+ end
153
+ after do
154
+ @db.drop_view(:items_view2) rescue nil
155
+ @db.drop_view(:items_view) rescue nil
156
+ end
157
+
158
+ it "should create views correctly" do
159
+ @db.create_view(:items_view, @ds.where(:number=>1))
160
+ @db[:items_view].map(:number).must_equal [1]
161
+ end
162
+
163
+ it "should create views with explicit columns correctly" do
164
+ @db.create_view(:items_view, @ds.where(:number=>1), :columns=>[:n])
165
+ @db[:items_view].map(:n).must_equal [1]
166
+ end
167
+
168
+ it "should drop views correctly" do
169
+ @db.create_view(:items_view, @ds.where(:number=>1))
170
+ @db.drop_view(:items_view)
171
+ proc{@db[:items_view].map(:number)}.must_raise(Sequel::DatabaseError)
172
+ end
173
+
174
+ it "should not raise an error if view doesn't exist when using drop_view :if_exists" do
175
+ @db.drop_view(:items_view, :if_exists=>true)
176
+ end
177
+
178
+ it "should create or replace views correctly" do
179
+ @db.create_or_replace_view(:items_view, @ds.where(:number=>1))
180
+ @db[:items_view].map(:number).must_equal [1]
181
+ @db.create_or_replace_view(:items_view, @ds.where(:number=>2))
182
+ @db[:items_view].map(:number).must_equal [2]
183
+ end
184
+ end
185
+
186
+ describe "join tables" do
187
+ after do
188
+ @db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
189
+ @db.drop_table(:cats, :dogs)
190
+ @db.table_exists?(:cats_dogs).must_equal false
191
+ end
192
+
193
+ it "should create join tables correctly" do
194
+ @db.create_table!(:cats){primary_key :id}
195
+ @db.create_table!(:dogs){primary_key :id}
196
+ @db.create_join_table(:cat_id=>:cats, :dog_id=>:dogs)
197
+ @db.table_exists?(:cats_dogs).must_equal true
198
+ end
199
+ end
200
+
201
+ it "should have create_table? only create the table if it doesn't already exist" do
202
+ @db.create_table!(:items){String :a}
203
+ @db.create_table?(:items){String :b}
204
+ @db[:items].columns.must_equal [:a]
205
+ @db.drop_table?(:items)
206
+ @db.create_table?(:items){String :b}
207
+ @db[:items].columns.must_equal [:b]
208
+ end
209
+
210
+ it "should rename tables correctly" do
211
+ @db.drop_table?(:items)
212
+ @db.create_table!(:items2){Integer :number}
213
+ @db.rename_table(:items2, :items)
214
+ @db.table_exists?(:items).must_equal true
215
+ @db.table_exists?(:items2).must_equal false
216
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number]
217
+ @ds.insert([10])
218
+ @ds.columns!.must_equal [:number]
219
+ end
220
+
221
+ it "should add columns to tables correctly" do
222
+ @db.create_table!(:items){Integer :number}
223
+ @ds.insert(:number=>10)
224
+ @db.alter_table(:items){add_column :name, String}
225
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:number, :name]
226
+ @ds.columns!.must_equal [:number, :name]
227
+ @ds.all.must_equal [{:number=>10, :name=>nil}]
228
+ end
229
+
230
+ it "should rename columns correctly" do
231
+ @db.create_table!(:items){Integer :id}
232
+ @ds.insert(:id=>10)
233
+ @db.alter_table(:items){rename_column :id, :id2}
234
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id2]
235
+ @ds.columns!.must_equal [:id2]
236
+ @ds.all.must_equal [{:id2=>10}]
237
+ end
238
+
239
+ it "should set column types correctly" do
240
+ @db.create_table!(:items){Integer :id}
241
+ @ds.insert(:id=>10)
242
+ @db.alter_table(:items){set_column_type :id, String}
243
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
244
+ @ds.columns!.must_equal [:id]
245
+ @ds.insert(:id=>'20')
246
+ @ds.order(:id).all.must_equal [{:id=>"10"}, {:id=>"20"}]
247
+ end
248
+
249
+ it "should remove columns from tables correctly" do
250
+ @db.create_table!(:items) do
251
+ primary_key :id
252
+ Integer :i
253
+ end
254
+ @ds.insert(:id=>1, :i=>10)
255
+ @db.drop_column(:items, :i)
256
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
257
+ end
258
+
259
+ it "should remove multiple columns in a single alter_table block" do
260
+ @db.create_table!(:items) do
261
+ primary_key :id
262
+ String :name
263
+ Integer :number
264
+ end
265
+ @ds.insert(:id=>1, :number=>10)
266
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id, :name, :number]
267
+ @db.alter_table(:items) do
268
+ drop_column :name
269
+ drop_column :number
270
+ end
271
+ @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
272
+ end
273
+
274
+ it "should work correctly with many operations in a single alter_table call" do
275
+ @db.create_table!(:items) do
276
+ primary_key :id
277
+ String :name2
278
+ String :number2
279
+ end
280
+ @ds.insert(:id=>1, :name2=>'A12')
281
+ @db.alter_table(:items) do
282
+ add_column :number, Integer
283
+ drop_column :number2
284
+ rename_column :name2, :name
285
+ end
286
+ @db[:items].first.must_equal(:id=>1, :name=>'A12', :number=>nil)
287
+ end
288
+ end
289
+
290
+ describe "Database#tables" do
291
+ before do
292
+ class ::String
293
+ @@xxxxx = 0
294
+ def xxxxx
295
+ "xxxxx#{@@xxxxx += 1}"
296
+ end
297
+ end
298
+ @db = DB
299
+ @db.create_table!(:sequel_test_table){Integer :a}
300
+ @db.create_view :sequel_test_view, @db[:sequel_test_table]
301
+ end
302
+ after do
303
+ @db.identifier_output_method = nil
304
+ @db.identifier_input_method = nil
305
+ @db.drop_view :sequel_test_view
306
+ @db.drop_table :sequel_test_table
307
+ end
308
+
309
+ it "should return an array of symbols" do
310
+ ts = @db.tables
311
+ ts.must_be_kind_of(Array)
312
+ ts.each{|t| t.must_be_kind_of(Symbol)}
313
+ ts.must_include(:sequel_test_table)
314
+ ts.wont_include(:sequel_test_view)
315
+ end
316
+
317
+ it "should respect the database's identifier_output_method" do
318
+ @db.identifier_output_method = :xxxxx
319
+ @db.identifier_input_method = :xxxxx
320
+ @db.tables.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
321
+ end
322
+ end
323
+
324
+ describe "Database#views" do
325
+ before do
326
+ class ::String
327
+ @@xxxxx = 0
328
+ def xxxxx
329
+ "xxxxx#{@@xxxxx += 1}"
330
+ end
331
+ end
332
+ @db = DB
333
+ @db.create_table!(:sequel_test_table){Integer :a}
334
+ @db.create_view :sequel_test_view, @db[:sequel_test_table]
335
+ end
336
+ after do
337
+ @db.identifier_output_method = nil
338
+ @db.identifier_input_method = nil
339
+ @db.drop_view :sequel_test_view
340
+ @db.drop_table :sequel_test_table
341
+ end
342
+
343
+ it "should return an array of symbols" do
344
+ ts = @db.views
345
+ ts.must_be_kind_of(Array)
346
+ ts.each{|t| t.must_be_kind_of(Symbol)}
347
+ ts.must_include(:sequel_test_view)
348
+ ts.wont_include(:sequel_test_table)
349
+ end
350
+
351
+ it "should respect the database's identifier_output_method" do
352
+ @db.identifier_output_method = :xxxxx
353
+ @db.identifier_input_method = :xxxxx
354
+ @db.views.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
355
+ end
356
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'logger'
3
+ require 'sequel'
4
+
5
+ gem 'minitest'
6
+ require 'minitest/autorun'
7
+ require 'minitest/hooks/default'
8
+ require 'minitest/shared_description'
9
+
10
+ Sequel::Model.cache_associations = false if ENV['SEQUEL_NO_CACHE_ASSOCIATIONS']
11
+ Sequel.cache_anonymous_models = false
12
+
13
+ unless defined?(DB)
14
+ DB = Sequel.connect(ENV['IMPALA_URL'] || 'jdbc:hive2://localhost:21050/;auth=noSasl')
15
+ end
@@ -0,0 +1,86 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
+
3
+ describe "Sequel timezone support" do
4
+ def _test_timezone(timezone=Sequel.application_timezone)
5
+ Sequel.datetime_class = Time
6
+ # Tests should cover both DST and non-DST times.
7
+ [Time.now, Time.local(2010,1,1,12), Time.local(2010,6,1,12)].each do |t|
8
+ @db[:t].insert(t)
9
+ t2 = @db[:t].single_value
10
+ t2 = @db.to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
11
+ (t2 - t).must_be_close_to 0, 2
12
+ t2.utc_offset.must_equal 0 if timezone == :utc
13
+ t2.utc_offset.must_equal t.getlocal.utc_offset if timezone == :local
14
+ @db[:t].delete
15
+ end
16
+
17
+ Sequel.datetime_class = DateTime
18
+ local_dst_offset = Time.local(2010, 6).utc_offset/86400.0
19
+ local_std_offset = Time.local(2010, 1).utc_offset/86400.0
20
+ [DateTime.now, DateTime.civil(2010,1,1,12,0,0,local_std_offset), DateTime.civil(2010,6,1,12,0,0,local_dst_offset)].each do |dt|
21
+ @db[:t].insert(dt)
22
+ dt2 = @db[:t].single_value
23
+ dt2 = @db.to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
24
+ (dt2 - dt).must_be_close_to 0, 0.00002
25
+ dt2.offset.must_equal 0 if timezone == :utc
26
+ dt2.offset.must_equal dt.offset if timezone == :local
27
+ @db[:t].delete
28
+ end
29
+ end
30
+
31
+ before do
32
+ @db = DB
33
+ @db.create_table!(:t){DateTime :t}
34
+ end
35
+ after do
36
+ @db.timezone = nil
37
+ Sequel.default_timezone = nil
38
+ Sequel.datetime_class = Time
39
+ @db.drop_table(:t)
40
+ end
41
+
42
+ it "should support using UTC for database storage and local time for the application" do
43
+ Sequel.database_timezone = :utc
44
+ Sequel.application_timezone = :local
45
+ _test_timezone
46
+ Sequel.database_timezone = nil
47
+ @db.timezone = :utc
48
+ _test_timezone
49
+ end
50
+
51
+ it "should support using local time for database storage and UTC for the application" do
52
+ Sequel.database_timezone = :local
53
+ Sequel.application_timezone = :utc
54
+ _test_timezone
55
+ Sequel.database_timezone = nil
56
+ @db.timezone = :local
57
+ _test_timezone
58
+ end
59
+
60
+ it "should support using UTC for both database storage and for application" do
61
+ Sequel.default_timezone = :utc
62
+ _test_timezone
63
+ Sequel.database_timezone = :local
64
+ @db.timezone = :utc
65
+ _test_timezone
66
+ end
67
+
68
+ it "should support using local time for both database storage and for application" do
69
+ Sequel.default_timezone = :local
70
+ _test_timezone
71
+ Sequel.database_timezone = :utc
72
+ @db.timezone = :local
73
+ _test_timezone
74
+ end
75
+
76
+ it "should allow overriding the database_timezone on a per-database basis" do
77
+ Sequel.database_timezone = :utc
78
+ @db.timezone = :local
79
+ t = Time.now
80
+ @db[:t].insert(t)
81
+ s = @db[:t].get(Sequel.cast(:t, String))
82
+ if o = Date._parse(s)[:offset]
83
+ o.must_equal t.utc_offset
84
+ end
85
+ end
86
+ end