sequel_impala 1.1.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 (129) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +50 -0
  3. data/LICENSE +463 -0
  4. data/README.md +45 -0
  5. data/Rakefile +39 -0
  6. data/lib/driver/commons-collections-3.2.1.jar +0 -0
  7. data/lib/driver/commons-configuration-1.10.jar +0 -0
  8. data/lib/driver/commons-logging-1.2.jar +0 -0
  9. data/lib/driver/hadoop-auth-2.9.0.jar +0 -0
  10. data/lib/driver/hadoop-common-2.9.0.jar +0 -0
  11. data/lib/driver/hadoop-core-2.6.0.jar +0 -0
  12. data/lib/driver/hive-exec-1.1.0.jar +0 -0
  13. data/lib/driver/hive-jdbc-1.1.0.jar +0 -0
  14. data/lib/driver/hive-metastore-1.1.0.jar +0 -0
  15. data/lib/driver/hive-service-1.1.0.jar +0 -0
  16. data/lib/driver/httpclient-4.3.jar +0 -0
  17. data/lib/driver/httpcore-4.3.jar +0 -0
  18. data/lib/driver/libfb303-0.9.0.jar +0 -0
  19. data/lib/driver/log4j-1.2.17.jar +0 -0
  20. data/lib/driver/slf4j-api-1.7.5.jar +0 -0
  21. data/lib/driver/stax2-api-3.1.4.jar +0 -0
  22. data/lib/driver/woodstox-core-asl-4.4.1.jar +0 -0
  23. data/lib/impala.rb +55 -0
  24. data/lib/impala/connection.rb +180 -0
  25. data/lib/impala/cursor.rb +200 -0
  26. data/lib/impala/progress_reporter.rb +40 -0
  27. data/lib/impala/protocol.rb +8 -0
  28. data/lib/impala/protocol/beeswax_constants.rb +15 -0
  29. data/lib/impala/protocol/beeswax_service.rb +747 -0
  30. data/lib/impala/protocol/beeswax_types.rb +193 -0
  31. data/lib/impala/protocol/exec_stats_constants.rb +13 -0
  32. data/lib/impala/protocol/exec_stats_types.rb +133 -0
  33. data/lib/impala/protocol/facebook_service.rb +706 -0
  34. data/lib/impala/protocol/fb303_constants.rb +15 -0
  35. data/lib/impala/protocol/fb303_types.rb +25 -0
  36. data/lib/impala/protocol/hive_metastore_constants.rb +53 -0
  37. data/lib/impala/protocol/hive_metastore_types.rb +698 -0
  38. data/lib/impala/protocol/impala_hive_server2_service.rb +137 -0
  39. data/lib/impala/protocol/impala_service.rb +443 -0
  40. data/lib/impala/protocol/impala_service_constants.rb +13 -0
  41. data/lib/impala/protocol/impala_service_types.rb +192 -0
  42. data/lib/impala/protocol/status_constants.rb +13 -0
  43. data/lib/impala/protocol/status_types.rb +46 -0
  44. data/lib/impala/protocol/t_c_l_i_service.rb +1108 -0
  45. data/lib/impala/protocol/t_c_l_i_service_constants.rb +72 -0
  46. data/lib/impala/protocol/t_c_l_i_service_types.rb +1802 -0
  47. data/lib/impala/protocol/thrift_hive_metastore.rb +4707 -0
  48. data/lib/impala/protocol/types_constants.rb +13 -0
  49. data/lib/impala/protocol/types_types.rb +332 -0
  50. data/lib/impala/sasl_transport.rb +117 -0
  51. data/lib/impala/thrift_patch.rb +31 -0
  52. data/lib/impala/version.rb +3 -0
  53. data/lib/jdbc/hive2.rb +52 -0
  54. data/lib/jdbc/impala.rb +50 -0
  55. data/lib/rbhive.rb +8 -0
  56. data/lib/rbhive/connection.rb +150 -0
  57. data/lib/rbhive/explain_result.rb +46 -0
  58. data/lib/rbhive/result_set.rb +37 -0
  59. data/lib/rbhive/schema_definition.rb +86 -0
  60. data/lib/rbhive/t_c_l_i_connection.rb +466 -0
  61. data/lib/rbhive/t_c_l_i_result_set.rb +3 -0
  62. data/lib/rbhive/t_c_l_i_schema_definition.rb +87 -0
  63. data/lib/rbhive/table_schema.rb +122 -0
  64. data/lib/rbhive/version.rb +3 -0
  65. data/lib/sequel/adapters/impala.rb +220 -0
  66. data/lib/sequel/adapters/jdbc/hive2.rb +36 -0
  67. data/lib/sequel/adapters/jdbc/impala.rb +38 -0
  68. data/lib/sequel/adapters/rbhive.rb +177 -0
  69. data/lib/sequel/adapters/shared/impala.rb +808 -0
  70. data/lib/sequel/extensions/csv_to_parquet.rb +166 -0
  71. data/lib/thrift/facebook_service.rb +700 -0
  72. data/lib/thrift/fb303_constants.rb +9 -0
  73. data/lib/thrift/fb303_types.rb +19 -0
  74. data/lib/thrift/hive_metastore_constants.rb +41 -0
  75. data/lib/thrift/hive_metastore_types.rb +630 -0
  76. data/lib/thrift/hive_service_constants.rb +13 -0
  77. data/lib/thrift/hive_service_types.rb +72 -0
  78. data/lib/thrift/queryplan_constants.rb +13 -0
  79. data/lib/thrift/queryplan_types.rb +261 -0
  80. data/lib/thrift/sasl_client_transport.rb +161 -0
  81. data/lib/thrift/serde_constants.rb +92 -0
  82. data/lib/thrift/serde_types.rb +7 -0
  83. data/lib/thrift/t_c_l_i_service.rb +1054 -0
  84. data/lib/thrift/t_c_l_i_service_constants.rb +72 -0
  85. data/lib/thrift/t_c_l_i_service_types.rb +1768 -0
  86. data/lib/thrift/thrift_hive.rb +508 -0
  87. data/lib/thrift/thrift_hive_metastore.rb +3856 -0
  88. data/spec/database_test.rb +56 -0
  89. data/spec/dataset_test.rb +1268 -0
  90. data/spec/files/bad_down_migration/001_create_alt_basic.rb +4 -0
  91. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +4 -0
  92. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  93. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  94. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +3 -0
  95. data/spec/files/bad_up_migration/001_create_alt_basic.rb +4 -0
  96. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +3 -0
  97. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +9 -0
  98. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +9 -0
  99. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +4 -0
  100. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +9 -0
  101. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +9 -0
  102. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  103. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +9 -0
  104. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +4 -0
  105. data/spec/files/integer_migrations/001_create_sessions.rb +9 -0
  106. data/spec/files/integer_migrations/002_create_nodes.rb +9 -0
  107. data/spec/files/integer_migrations/003_3_create_users.rb +4 -0
  108. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +9 -0
  109. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +9 -0
  110. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +9 -0
  111. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +9 -0
  112. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +4 -0
  113. data/spec/files/reversible_migrations/001_reversible.rb +5 -0
  114. data/spec/files/reversible_migrations/002_reversible.rb +5 -0
  115. data/spec/files/reversible_migrations/003_reversible.rb +5 -0
  116. data/spec/files/reversible_migrations/004_reversible.rb +5 -0
  117. data/spec/files/reversible_migrations/005_reversible.rb +10 -0
  118. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +9 -0
  119. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +9 -0
  120. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +4 -0
  121. data/spec/impala_test.rb +290 -0
  122. data/spec/migrator_test.rb +240 -0
  123. data/spec/plugin_test.rb +91 -0
  124. data/spec/prepared_statement_test.rb +327 -0
  125. data/spec/schema_test.rb +356 -0
  126. data/spec/spec_helper.rb +19 -0
  127. data/spec/timezone_test.rb +86 -0
  128. data/spec/type_test.rb +99 -0
  129. metadata +294 -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
+ assert_nil(DB.schema(:items).first.last[:default])
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,19 @@
1
+ require 'rubygems'
2
+ require 'logger'
3
+ require 'sequel'
4
+
5
+ module Minitest
6
+ @@installed_at_exit = true
7
+ end if defined?(M)
8
+
9
+ gem 'minitest'
10
+ require 'minitest/autorun'
11
+ require 'minitest/hooks/default'
12
+ require 'minitest/shared_description'
13
+
14
+ Sequel::Model.cache_associations = false if ENV['SEQUEL_NO_CACHE_ASSOCIATIONS']
15
+ Sequel.cache_anonymous_models = false
16
+
17
+ unless defined?(DB)
18
+ DB = Sequel.connect(ENV['IMPALA_URL'] || 'jdbc:hive2://localhost:21050/;auth=noSasl')
19
+ 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