sequel-impala 1.0.1 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/lib/impala.rb +14 -6
- data/lib/impala/connection.rb +46 -23
- data/lib/impala/cursor.rb +48 -4
- data/lib/impala/progress_reporter.rb +40 -0
- data/lib/impala/protocol/beeswax_constants.rb +1 -1
- data/lib/impala/protocol/beeswax_service.rb +1 -20
- data/lib/impala/protocol/beeswax_types.rb +1 -1
- data/lib/impala/protocol/exec_stats_constants.rb +13 -0
- data/lib/impala/protocol/exec_stats_types.rb +133 -0
- data/lib/impala/protocol/facebook_service.rb +3 -3
- data/lib/impala/protocol/fb303_constants.rb +1 -1
- data/lib/impala/protocol/fb303_types.rb +1 -1
- data/lib/impala/protocol/hive_metastore_constants.rb +1 -1
- data/lib/impala/protocol/hive_metastore_types.rb +1 -1
- data/lib/impala/protocol/impala_hive_server2_service.rb +111 -3
- data/lib/impala/protocol/impala_service.rb +67 -1
- data/lib/impala/protocol/impala_service_constants.rb +1 -1
- data/lib/impala/protocol/impala_service_types.rb +109 -7
- data/lib/impala/protocol/status_constants.rb +1 -1
- data/lib/impala/protocol/status_types.rb +1 -1
- data/lib/impala/protocol/t_c_l_i_service.rb +884 -724
- data/lib/impala/protocol/t_c_l_i_service_constants.rb +72 -0
- data/lib/impala/protocol/t_c_l_i_service_types.rb +1799 -0
- data/lib/impala/protocol/thrift_hive_metastore.rb +1 -1
- data/lib/impala/protocol/types_constants.rb +13 -0
- data/lib/impala/protocol/types_types.rb +332 -0
- data/lib/impala/sasl_transport.rb +117 -0
- data/lib/impala/thrift_patch.rb +42 -0
- data/lib/rbhive/connection.rb +25 -25
- data/lib/rbhive/explain_result.rb +9 -9
- data/lib/rbhive/schema_definition.rb +12 -12
- data/lib/rbhive/t_c_l_i_connection.rb +28 -26
- data/lib/rbhive/t_c_l_i_schema_definition.rb +1 -1
- data/lib/rbhive/table_schema.rb +1 -1
- data/lib/sequel/adapters/impala.rb +63 -6
- data/lib/sequel/adapters/jdbc/hive2.rb +1 -1
- data/lib/sequel/adapters/rbhive.rb +3 -2
- data/lib/sequel/adapters/shared/impala.rb +133 -25
- data/lib/thrift/sasl_client_transport.rb +2 -2
- data/lib/thrift/thrift_hive.rb +2 -2
- data/lib/thrift/thrift_hive_metastore.rb +2 -2
- data/spec/dataset_test.rb +85 -85
- data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +1 -1
- data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +1 -1
- data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +1 -1
- data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +1 -1
- data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +1 -1
- data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +1 -1
- data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +1 -1
- data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +1 -1
- data/spec/files/integer_migrations/001_create_sessions.rb +1 -1
- data/spec/files/integer_migrations/002_create_nodes.rb +1 -1
- data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +1 -1
- data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +1 -1
- data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +1 -1
- data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +1 -1
- data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +1 -1
- data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +1 -1
- data/spec/migrator_test.rb +2 -2
- data/spec/prepared_statement_test.rb +12 -12
- data/spec/schema_test.rb +6 -6
- data/spec/type_test.rb +8 -8
- metadata +30 -11
- data/CHANGELOG +0 -19
- data/lib/impala/protocol/cli_service_constants.rb +0 -60
- data/lib/impala/protocol/cli_service_types.rb +0 -1452
data/spec/migrator_test.rb
CHANGED
@@ -9,7 +9,7 @@ describe Sequel::Migrator do
|
|
9
9
|
after do
|
10
10
|
@db.drop_table?(:schema_info, :schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333, :sm11111, :sm22222)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "should be able to migrate up and down all the way successfully" do
|
14
14
|
@dir = 'spec/files/integer_migrations'
|
15
15
|
@m.apply(@db, @dir)
|
@@ -19,7 +19,7 @@ describe Sequel::Migrator do
|
|
19
19
|
[:sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).must_equal false}
|
20
20
|
@db[:schema_info].get(:version).must_equal 0
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it "should be able to migrate up and down to specific versions successfully" do
|
24
24
|
@dir = 'spec/files/integer_migrations'
|
25
25
|
@m.apply(@db, @dir, 2)
|
@@ -15,7 +15,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
15
15
|
after do
|
16
16
|
@db.drop_table?(:items)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "should support bound variables when selecting" do
|
20
20
|
@ds.filter(:numb=>:$n).call(:each, :n=>10){|h| h.must_equal(:id=>1, :numb=>10)}
|
21
21
|
@ds.filter(:numb=>:$n).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
@@ -25,7 +25,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
25
25
|
@ds.filter(:numb=>:$n).call([:to_hash, :id, :numb], :n=>10).must_equal(1=>10)
|
26
26
|
@ds.filter(:numb=>:$n).call([:to_hash_groups, :id, :numb], :n=>10).must_equal(1=>[10])
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it "should support blocks for each, select, all, and map when using bound variables" do
|
30
30
|
a = []
|
31
31
|
@ds.filter(:numb=>:$n).call(:each, :n=>10){|r| r[:numb] *= 2; a << r}; a.must_equal [{:id=>1, :numb=>20}]
|
@@ -33,22 +33,22 @@ describe "Prepared Statements and Bound Arguments" do
|
|
33
33
|
@ds.filter(:numb=>:$n).call(:all, :n=>10){|r| r[:numb] *= 2}.must_equal [{:id=>1, :numb=>20}]
|
34
34
|
@ds.filter(:numb=>:$n).call([:map], :n=>10){|r| r[:numb] * 2}.must_equal [20]
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
it "should support binding variables before the call with #bind" do
|
38
38
|
@ds.filter(:numb=>:$n).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
|
39
39
|
@ds.filter(:numb=>:$n).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
|
40
40
|
@ds.filter(:numb=>:$n).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
|
41
|
-
|
41
|
+
|
42
42
|
@ds.bind(:n=>10).filter(:numb=>:$n).call(:select).must_equal [{:id=>1, :numb=>10}]
|
43
43
|
@ds.bind(:n=>10).filter(:numb=>:$n).call(:all).must_equal [{:id=>1, :numb=>10}]
|
44
44
|
@ds.bind(:n=>10).filter(:numb=>:$n).call(:first).must_equal(:id=>1, :numb=>10)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "should allow overriding variables specified with #bind" do
|
48
48
|
@ds.filter(:numb=>:$n).bind(:n=>1).call(:select, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
49
49
|
@ds.filter(:numb=>:$n).bind(:n=>1).call(:all, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
50
50
|
@ds.filter(:numb=>:$n).bind(:n=>1).call(:first, :n=>10).must_equal(:id=>1, :numb=>10)
|
51
|
-
|
51
|
+
|
52
52
|
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:select).must_equal [{:id=>1, :numb=>10}]
|
53
53
|
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:all).must_equal [{:id=>1, :numb=>10}]
|
54
54
|
@ds.filter(:numb=>:$n).bind(:n=>1).bind(:n=>10).call(:first).must_equal(:id=>1, :numb=>10)
|
@@ -88,7 +88,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
88
88
|
it "should support subselects of subselects with call" do
|
89
89
|
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).call(:select, :n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
it "should support using a bound variable for a limit and offset" do
|
93
93
|
@ds.insert(:id=>2, :numb=>20)
|
94
94
|
ds = @ds.limit(:$n, :$n2).order(:id)
|
@@ -142,7 +142,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
142
142
|
@ds.filter(:numb=>:$n).prepare([:map], :select_n).call(:n=>10){|r| r[:numb] *= 2}.must_equal [20]
|
143
143
|
@db.call(:select_n, :n=>10){|r| r[:numb] *= 2}.must_equal [20]
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
it "should support prepared statements being called multiple times with different arguments" do
|
147
147
|
@ds.filter(:numb=>:$n).prepare(:select, :select_n)
|
148
148
|
@db.call(:select_n, :n=>10).must_equal [{:id=>1, :numb=>10}]
|
@@ -184,7 +184,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
184
184
|
it "should support subselects of subselects with prepare" do
|
185
185
|
@ds.filter(:id=>:$i).filter(:numb=>@ds.select(:numb).filter(:numb=>@ds.select(:numb).filter(:numb=>:$n))).filter(:id=>:$j).prepare(:select, :seq_select).call(:n=>10, :i=>1, :j=>1).must_equal [{:id=>1, :numb=>10}]
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
188
|
it "should support using a prepared_statement for a limit and offset" do
|
189
189
|
@ds.insert(:id=>2, :numb=>20)
|
190
190
|
ps = @ds.limit(:$n, :$n2).order(:id).prepare(:select, :seq_select)
|
@@ -219,7 +219,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
219
219
|
@c.filter(:numb=>:$n).call(:all, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
220
220
|
@c.filter(:numb=>:$n).call(:first, :n=>10).must_equal @c.load(:id=>1, :numb=>10)
|
221
221
|
end
|
222
|
-
|
222
|
+
|
223
223
|
it "model datasets should return model instances when using select, all, and first with prepared statements" do
|
224
224
|
@c.filter(:numb=>:$n).prepare(:select, :select_n1)
|
225
225
|
@db.call(:select_n1, :n=>10).must_equal [@c.load(:id=>1, :numb=>10)]
|
@@ -276,7 +276,7 @@ describe "Dataset#unbind" do
|
|
276
276
|
after do
|
277
277
|
DB.drop_table?(:items)
|
278
278
|
end
|
279
|
-
|
279
|
+
|
280
280
|
it "should unbind values assigned to equality and inequality statements" do
|
281
281
|
@ct[Integer, 10]
|
282
282
|
@u[@ds.filter(:c=>10)].must_equal(:c=>10)
|
@@ -324,4 +324,4 @@ describe "Dataset#unbind" do
|
|
324
324
|
@u[@ds.filter{c > 1}.or{c < 1}.invert].must_equal(:c=>1)
|
325
325
|
@u[@ds.filter{c > 1}.or{c < 1}].must_equal nil
|
326
326
|
end
|
327
|
-
end
|
327
|
+
end
|
data/spec/schema_test.rb
CHANGED
@@ -14,7 +14,7 @@ describe "Database schema parser" do
|
|
14
14
|
begin
|
15
15
|
DB.schema(:items, :reload=>true).must_be_kind_of(Array)
|
16
16
|
DB.schema(:items, :reload=>true).first.first.must_equal :number
|
17
|
-
ensure
|
17
|
+
ensure
|
18
18
|
DB.drop_table(:items)
|
19
19
|
end
|
20
20
|
end
|
@@ -31,7 +31,7 @@ describe "Database schema parser" do
|
|
31
31
|
begin
|
32
32
|
DB.schema(ds, :reload=>true).must_be_kind_of(Array)
|
33
33
|
DB.schema(ds, :reload=>true).first.first.must_equal :number
|
34
|
-
ensure
|
34
|
+
ensure
|
35
35
|
DB.identifier_output_method = :reverse
|
36
36
|
DB.identifier_input_method = :reverse
|
37
37
|
DB.drop_table(:items)
|
@@ -128,7 +128,7 @@ describe "Database schema modifiers" do
|
|
128
128
|
@ds.insert([10])
|
129
129
|
@ds.columns!.must_equal [:number]
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
it "should create tables from select statements correctly" do
|
133
133
|
@db.create_table!(:items){Integer :number}
|
134
134
|
@ds.insert([10])
|
@@ -137,7 +137,7 @@ describe "Database schema modifiers" do
|
|
137
137
|
@db[:items2].columns.must_equal [:number]
|
138
138
|
@db[:items2].all.must_equal [{:number=>10}]
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
it "should not raise an error if table doesn't exist when using drop_table :if_exists" do
|
142
142
|
@db.drop_table(:items, :if_exists=>true)
|
143
143
|
end
|
@@ -182,7 +182,7 @@ describe "Database schema modifiers" do
|
|
182
182
|
@db[:items_view].map(:number).must_equal [2]
|
183
183
|
end
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
describe "join tables" do
|
187
187
|
after do
|
188
188
|
@db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
|
@@ -217,7 +217,7 @@ describe "Database schema modifiers" do
|
|
217
217
|
@ds.insert([10])
|
218
218
|
@ds.columns!.must_equal [:number]
|
219
219
|
end
|
220
|
-
|
220
|
+
|
221
221
|
it "should add columns to tables correctly" do
|
222
222
|
@db.create_table!(:items){Integer :number}
|
223
223
|
@ds.insert(:number=>10)
|
data/spec/type_test.rb
CHANGED
@@ -30,25 +30,25 @@ describe "Supported types" do
|
|
30
30
|
ds.insert(:number => 2)
|
31
31
|
ds.all.must_equal [{:number=>2}]
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
it "should support generic fixnum type" do
|
35
35
|
ds = create_items_table_with_column(:number, Fixnum)
|
36
36
|
ds.insert(:number => 2)
|
37
37
|
ds.all.must_equal [{:number=>2}]
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "should support generic bignum type" do
|
41
41
|
ds = create_items_table_with_column(:number, Bignum)
|
42
42
|
ds.insert(:number => 2**34)
|
43
43
|
ds.all.must_equal [{:number=>2**34}]
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it "should support generic float type" do
|
47
47
|
ds = create_items_table_with_column(:number, Float)
|
48
48
|
ds.insert(:number => 2.1)
|
49
49
|
ds.all.must_equal [{:number=>2.1}]
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it "should support generic numeric type" do
|
53
53
|
ds = create_items_table_with_column(:number, Numeric, :size=>[15, 10])
|
54
54
|
ds.insert(:number => BigDecimal.new('2.123456789'))
|
@@ -63,13 +63,13 @@ describe "Supported types" do
|
|
63
63
|
ds.insert(:name => 'Test User')
|
64
64
|
ds.all.must_equal [{:name=>'Test User'}]
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should support generic string type with size" do
|
68
68
|
ds = create_items_table_with_column(:name, String, :size=>100)
|
69
69
|
ds.insert(:name => Sequel.cast('Test User', 'varchar(100)'))
|
70
70
|
ds.all.must_equal [{:name=>'Test User'}]
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should support generic datetime type" do
|
74
74
|
ds = create_items_table_with_column(:tim, DateTime)
|
75
75
|
t = DateTime.now
|
@@ -80,14 +80,14 @@ describe "Supported types" do
|
|
80
80
|
ds.insert(:tim => t)
|
81
81
|
ds.first[:tim].strftime('%Y%m%d%H%M%S').must_equal t.strftime('%Y%m%d%H%M%S')
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
it "should support generic date type" do
|
85
85
|
ds = create_items_table_with_column(:d, Date)
|
86
86
|
t = Date.today
|
87
87
|
ds.insert(:d => t)
|
88
88
|
ds.first[:d].strftime('%Y%m%d').must_equal t.strftime('%Y%m%d')
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
it "should support generic boolean type" do
|
92
92
|
ds = create_items_table_with_column(:number, TrueClass)
|
93
93
|
ds.insert(:number => true)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-impala
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Duryea
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09
|
11
|
+
date: 2016-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -16,28 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '4'
|
19
|
+
version: '4.39'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '4'
|
26
|
+
version: '4.39'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thrift
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.9
|
33
|
+
version: '0.9'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.9
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: gssapi
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.2'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,11 +131,9 @@ email: aguynamedryan@gmail.com
|
|
117
131
|
executables: []
|
118
132
|
extensions: []
|
119
133
|
extra_rdoc_files:
|
120
|
-
- README.md
|
121
|
-
- CHANGELOG
|
122
134
|
- LICENSE
|
123
135
|
files:
|
124
|
-
- CHANGELOG
|
136
|
+
- CHANGELOG.md
|
125
137
|
- LICENSE
|
126
138
|
- README.md
|
127
139
|
- Rakefile
|
@@ -139,12 +151,13 @@ files:
|
|
139
151
|
- lib/impala.rb
|
140
152
|
- lib/impala/connection.rb
|
141
153
|
- lib/impala/cursor.rb
|
154
|
+
- lib/impala/progress_reporter.rb
|
142
155
|
- lib/impala/protocol.rb
|
143
156
|
- lib/impala/protocol/beeswax_constants.rb
|
144
157
|
- lib/impala/protocol/beeswax_service.rb
|
145
158
|
- lib/impala/protocol/beeswax_types.rb
|
146
|
-
- lib/impala/protocol/
|
147
|
-
- lib/impala/protocol/
|
159
|
+
- lib/impala/protocol/exec_stats_constants.rb
|
160
|
+
- lib/impala/protocol/exec_stats_types.rb
|
148
161
|
- lib/impala/protocol/facebook_service.rb
|
149
162
|
- lib/impala/protocol/fb303_constants.rb
|
150
163
|
- lib/impala/protocol/fb303_types.rb
|
@@ -157,7 +170,13 @@ files:
|
|
157
170
|
- lib/impala/protocol/status_constants.rb
|
158
171
|
- lib/impala/protocol/status_types.rb
|
159
172
|
- lib/impala/protocol/t_c_l_i_service.rb
|
173
|
+
- lib/impala/protocol/t_c_l_i_service_constants.rb
|
174
|
+
- lib/impala/protocol/t_c_l_i_service_types.rb
|
160
175
|
- lib/impala/protocol/thrift_hive_metastore.rb
|
176
|
+
- lib/impala/protocol/types_constants.rb
|
177
|
+
- lib/impala/protocol/types_types.rb
|
178
|
+
- lib/impala/sasl_transport.rb
|
179
|
+
- lib/impala/thrift_patch.rb
|
161
180
|
- lib/impala/version.rb
|
162
181
|
- lib/jdbc/hive2.rb
|
163
182
|
- lib/rbhive.rb
|