ch-client 0.0.1
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 +7 -0
- data/.codeclimate.yml +22 -0
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +58 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +262 -0
- data/Rakefile +15 -0
- data/VERSION +1 -0
- data/bin/clickhouse +9 -0
- data/clickhouse.gemspec +36 -0
- data/lib/clickhouse.rb +60 -0
- data/lib/clickhouse/cli.rb +46 -0
- data/lib/clickhouse/cli/client.rb +149 -0
- data/lib/clickhouse/cli/console.rb +73 -0
- data/lib/clickhouse/cli/server.rb +37 -0
- data/lib/clickhouse/cli/server/assets/css/clickhouse.css +177 -0
- data/lib/clickhouse/cli/server/assets/css/codemirror.css +341 -0
- data/lib/clickhouse/cli/server/assets/css/datatables.css +1 -0
- data/lib/clickhouse/cli/server/assets/css/normalize.css +427 -0
- data/lib/clickhouse/cli/server/assets/css/skeleton.css +418 -0
- data/lib/clickhouse/cli/server/assets/js/clickhouse.js +188 -0
- data/lib/clickhouse/cli/server/assets/js/codemirror.js +9096 -0
- data/lib/clickhouse/cli/server/assets/js/datatables.js +166 -0
- data/lib/clickhouse/cli/server/assets/js/disableswipeback.js +97 -0
- data/lib/clickhouse/cli/server/assets/js/jquery.js +11015 -0
- data/lib/clickhouse/cli/server/assets/js/sql.js +232 -0
- data/lib/clickhouse/cli/server/views/index.erb +46 -0
- data/lib/clickhouse/cluster.rb +43 -0
- data/lib/clickhouse/connection.rb +42 -0
- data/lib/clickhouse/connection/client.rb +135 -0
- data/lib/clickhouse/connection/logger.rb +12 -0
- data/lib/clickhouse/connection/query.rb +160 -0
- data/lib/clickhouse/connection/query/result_row.rb +36 -0
- data/lib/clickhouse/connection/query/result_set.rb +103 -0
- data/lib/clickhouse/connection/query/table.rb +50 -0
- data/lib/clickhouse/error.rb +18 -0
- data/lib/clickhouse/utils.rb +23 -0
- data/lib/clickhouse/version.rb +7 -0
- data/script/console +58 -0
- data/test/test_helper.rb +15 -0
- data/test/test_helper/coverage.rb +16 -0
- data/test/test_helper/minitest.rb +13 -0
- data/test/test_helper/simple_connection.rb +12 -0
- data/test/unit/connection/query/test_result_row.rb +36 -0
- data/test/unit/connection/query/test_result_set.rb +196 -0
- data/test/unit/connection/query/test_table.rb +39 -0
- data/test/unit/connection/test_client.rb +206 -0
- data/test/unit/connection/test_cluster.rb +81 -0
- data/test/unit/connection/test_logger.rb +35 -0
- data/test/unit/connection/test_query.rb +410 -0
- data/test/unit/test_clickhouse.rb +99 -0
- data/test/unit/test_connection.rb +55 -0
- data/test/unit/test_utils.rb +39 -0
- metadata +326 -0
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative "test_helper/coverage"
|
2
|
+
|
3
|
+
require "minitest"
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "mocha/setup"
|
6
|
+
|
7
|
+
def path(path)
|
8
|
+
File.expand_path "../../#{path}", __FILE__
|
9
|
+
end
|
10
|
+
|
11
|
+
require "bundler"
|
12
|
+
Bundler.require :default, :development, :test
|
13
|
+
|
14
|
+
require_relative "test_helper/minitest"
|
15
|
+
require_relative "test_helper/simple_connection"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
if Dir.pwd == File.expand_path("../../..", __FILE__)
|
2
|
+
if ENV["REPORT"].to_i == 1
|
3
|
+
require "dotenv"
|
4
|
+
Dotenv.load
|
5
|
+
|
6
|
+
require "codeclimate-test-reporter"
|
7
|
+
CodeClimate::TestReporter.start
|
8
|
+
end
|
9
|
+
|
10
|
+
require "simplecov"
|
11
|
+
SimpleCov.coverage_dir "test/coverage"
|
12
|
+
SimpleCov.start do
|
13
|
+
add_group "Clickhouse", "lib"
|
14
|
+
add_group "Test suite", "test"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class MiniTest::Test
|
2
|
+
def teardown
|
3
|
+
Clickhouse.instance_variables.each do |name|
|
4
|
+
Clickhouse.instance_variable_set name, nil
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class MiniTest::Spec
|
10
|
+
def assert_query(expected, actual)
|
11
|
+
assert_equal(expected.strip.gsub(/^\s+/, ""), actual)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative "../../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
module Query
|
6
|
+
class TestResultRow < MiniTest::Test
|
7
|
+
|
8
|
+
describe Clickhouse::Connection::Query::ResultRow do
|
9
|
+
describe "#to_hash" do
|
10
|
+
describe "when passing names" do
|
11
|
+
it "uses the names as hash keys" do
|
12
|
+
result_row = Clickhouse::Connection::Query::ResultRow.new([1, 2, 3], [:a, :b, :c])
|
13
|
+
assert_equal({:a => 1, :b => 2, :c => 3}, result_row.to_hash)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when not passing names" do
|
18
|
+
it "uses 'column<i>' as hash keys" do
|
19
|
+
result_row = Clickhouse::Connection::Query::ResultRow.new([1, 2, 3])
|
20
|
+
assert_equal({"column0" => 1, "column1" => 2, "column2" => 3}, result_row.to_hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "memoization" do
|
25
|
+
it "memoizes the resulting hash" do
|
26
|
+
result_row = Clickhouse::Connection::Query::ResultRow.new([1, 2, 3])
|
27
|
+
assert_equal result_row.to_hash.object_id, result_row.to_hash.object_id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require_relative "../../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
module Query
|
6
|
+
class TestResultSet < MiniTest::Test
|
7
|
+
|
8
|
+
describe Clickhouse::Connection::Query::ResultSet do
|
9
|
+
before do
|
10
|
+
@empty_set = Clickhouse::Connection::Query::ResultSet.new
|
11
|
+
@result_set = Clickhouse::Connection::Query::ResultSet.new(
|
12
|
+
[
|
13
|
+
[
|
14
|
+
"1072649",
|
15
|
+
"142.94",
|
16
|
+
"badrequest.io",
|
17
|
+
"d91d1c90\u0000\u0000\u0000",
|
18
|
+
"2016-03-20",
|
19
|
+
"2016-03-20 23:49:11",
|
20
|
+
[4, 2, 5, 7]
|
21
|
+
], [
|
22
|
+
"12948140",
|
23
|
+
"9320.11",
|
24
|
+
"engel.pm",
|
25
|
+
"d91d217c\u0000\u0000",
|
26
|
+
"2016-03-20",
|
27
|
+
"2016-03-20 23:58:34",
|
28
|
+
[6, 2, 9, 8, 1]
|
29
|
+
], [
|
30
|
+
"319384",
|
31
|
+
"101.02",
|
32
|
+
"archan937.com",
|
33
|
+
"d91d2294\u0000\u0000\u0000",
|
34
|
+
"2016-03-20",
|
35
|
+
"2016-03-20 22:55:39",
|
36
|
+
[3, 1, 2]
|
37
|
+
]
|
38
|
+
],
|
39
|
+
%w(
|
40
|
+
SUM(clicks)
|
41
|
+
AVG(price)
|
42
|
+
domain
|
43
|
+
id
|
44
|
+
date
|
45
|
+
MAX(time)
|
46
|
+
groupUniqArray(code)
|
47
|
+
),
|
48
|
+
%w(
|
49
|
+
UInt32
|
50
|
+
Float32
|
51
|
+
String
|
52
|
+
FixedString(16)
|
53
|
+
Date
|
54
|
+
DateTime
|
55
|
+
Array(8)
|
56
|
+
)
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#size" do
|
61
|
+
it "returns the size of the result set" do
|
62
|
+
assert_equal 3, @result_set.size
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#empty?" do
|
67
|
+
it "returns whether the result set is empty or not" do
|
68
|
+
assert_equal true, @empty_set.empty?
|
69
|
+
assert_equal false, @result_set.empty?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#present?" do
|
74
|
+
it "returns whether the result set contains rows or not" do
|
75
|
+
assert_equal false, @empty_set.present?
|
76
|
+
assert_equal true, @result_set.present?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#first" do
|
81
|
+
it "returns the first row of the result set" do
|
82
|
+
assert_equal [
|
83
|
+
1072649,
|
84
|
+
142.94,
|
85
|
+
"badrequest.io",
|
86
|
+
"d91d1c90",
|
87
|
+
Date.new(2016, 3, 20),
|
88
|
+
Time.new(2016, 3, 20, 23, 49, 11),
|
89
|
+
[4, 2, 5, 7]
|
90
|
+
], @result_set.first
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#last" do
|
95
|
+
it "returns the size of the result set" do
|
96
|
+
assert_equal [
|
97
|
+
319384,
|
98
|
+
101.02,
|
99
|
+
"archan937.com",
|
100
|
+
"d91d2294",
|
101
|
+
Date.new(2016, 3, 20),
|
102
|
+
Time.new(2016, 3, 20, 22, 55, 39),
|
103
|
+
[3, 1, 2]
|
104
|
+
], @result_set.last
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#flatten" do
|
109
|
+
it "returns the size of the result set" do
|
110
|
+
assert_equal [
|
111
|
+
1072649,
|
112
|
+
142.94,
|
113
|
+
"badrequest.io",
|
114
|
+
"d91d1c90",
|
115
|
+
Date.new(2016, 3, 20),
|
116
|
+
Time.new(2016, 3, 20, 23, 49, 11),
|
117
|
+
4,
|
118
|
+
2,
|
119
|
+
5,
|
120
|
+
7,
|
121
|
+
12948140,
|
122
|
+
9320.11,
|
123
|
+
"engel.pm",
|
124
|
+
"d91d217c",
|
125
|
+
Date.new(2016, 3, 20),
|
126
|
+
Time.new(2016, 3, 20, 23, 58, 34),
|
127
|
+
6,
|
128
|
+
2,
|
129
|
+
9,
|
130
|
+
8,
|
131
|
+
1,
|
132
|
+
319384,
|
133
|
+
101.02,
|
134
|
+
"archan937.com",
|
135
|
+
"d91d2294",
|
136
|
+
Date.new(2016, 3, 20),
|
137
|
+
Time.new(2016, 3, 20, 22, 55, 39),
|
138
|
+
3,
|
139
|
+
1,
|
140
|
+
2
|
141
|
+
], @result_set.flatten
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#to_hashes" do
|
146
|
+
it "returns an array containing the rows as hashes" do
|
147
|
+
assert_equal [
|
148
|
+
{
|
149
|
+
"SUM(clicks)" => 1072649,
|
150
|
+
"AVG(price)" => 142.94,
|
151
|
+
"domain" => "badrequest.io",
|
152
|
+
"id" => "d91d1c90",
|
153
|
+
"date" => Date.new(2016, 3, 20),
|
154
|
+
"MAX(time)" => Time.new(2016, 3, 20, 23, 49, 11),
|
155
|
+
"groupUniqArray(code)" => [4, 2, 5, 7]
|
156
|
+
}, {
|
157
|
+
"SUM(clicks)" => 12948140,
|
158
|
+
"AVG(price)" => 9320.11,
|
159
|
+
"domain" => "engel.pm",
|
160
|
+
"id" => "d91d217c",
|
161
|
+
"date" => Date.new(2016, 3, 20),
|
162
|
+
"MAX(time)" => Time.new(2016, 3, 20, 23, 58, 34),
|
163
|
+
"groupUniqArray(code)" => [6, 2, 9, 8, 1]
|
164
|
+
}, {
|
165
|
+
"SUM(clicks)" => 319384,
|
166
|
+
"AVG(price)" => 101.02,
|
167
|
+
"domain" => "archan937.com",
|
168
|
+
"id" => "d91d2294",
|
169
|
+
"date" => Date.new(2016, 3, 20),
|
170
|
+
"MAX(time)" => Time.new(2016, 3, 20, 22, 55, 39),
|
171
|
+
"groupUniqArray(code)" => [3, 1, 2]
|
172
|
+
}
|
173
|
+
], @result_set.to_hashes
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "memoization" do
|
178
|
+
it "memoizes the parsed rows" do
|
179
|
+
assert_equal @result_set.to_a[-1].object_id, @result_set.each{}[-1].object_id
|
180
|
+
assert_equal @result_set.first.object_id, @result_set[0].object_id
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "non-supported data types" do
|
185
|
+
it "raises a NotImplementedError error" do
|
186
|
+
assert_raises NotImplementedError do
|
187
|
+
Clickhouse::Connection::Query::ResultSet.new([[1]], ["Foo"], ["Bar"])[0]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative "../../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
module Query
|
6
|
+
class TestTable < MiniTest::Test
|
7
|
+
|
8
|
+
describe Clickhouse::Connection::Query::Table do
|
9
|
+
it "generates a 'CREATE TABLE' statement" do
|
10
|
+
table = Clickhouse::Connection::Query::Table.new("logs_test") do |t|
|
11
|
+
t.uint8 :id
|
12
|
+
t.float32 :price
|
13
|
+
t.string :name
|
14
|
+
t.date :date
|
15
|
+
t.date_time :time
|
16
|
+
t.fixed_string :hex_id, 8
|
17
|
+
t.engine "MergeTree(date, 8192)"
|
18
|
+
end
|
19
|
+
|
20
|
+
sql = <<-SQL
|
21
|
+
CREATE TABLE logs_test (
|
22
|
+
id UInt8,
|
23
|
+
price Float32,
|
24
|
+
name String,
|
25
|
+
date Date,
|
26
|
+
time DateTime,
|
27
|
+
hex_id FixedString(8)
|
28
|
+
)
|
29
|
+
ENGINE = MergeTree(date, 8192)
|
30
|
+
SQL
|
31
|
+
|
32
|
+
assert_equal sql.strip, table.to_sql.strip
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require_relative "../../test_helper"
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
module Connection
|
5
|
+
class TestClient < MiniTest::Test
|
6
|
+
|
7
|
+
class Connection < SimpleConnection
|
8
|
+
include Clickhouse::Connection::Client
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Clickhouse::Connection::Client do
|
12
|
+
before do
|
13
|
+
@connection = Connection.new
|
14
|
+
@connection.stubs(:parse_stats)
|
15
|
+
@connection.stubs(:write_log)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#connect!" do
|
19
|
+
describe "when failed to connect" do
|
20
|
+
it "returns true" do
|
21
|
+
Faraday::Connection.any_instance.expects(:get).raises(Faraday::ConnectionFailed.new("Failed to connect"))
|
22
|
+
assert_raises Clickhouse::ConnectionError do
|
23
|
+
@connection.connect!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "when receiving 200" do
|
29
|
+
it "returns true" do
|
30
|
+
Faraday::Connection.any_instance.expects(:get).returns(stub(:status => 200))
|
31
|
+
assert_equal true, @connection.connect!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "when receiving 500" do
|
36
|
+
it "raises a Clickhouse::ConnectionError" do
|
37
|
+
Faraday::Connection.any_instance.expects(:get).returns(stub(:status => 500))
|
38
|
+
assert_raises Clickhouse::ConnectionError do
|
39
|
+
@connection.connect!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when already connected" do
|
45
|
+
it "returns nil" do
|
46
|
+
@connection.instance_variable_set :@client, mock
|
47
|
+
assert_nil @connection.connect!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#connected?" do
|
53
|
+
it "returns whether it has an connected socket" do
|
54
|
+
assert_equal false, @connection.connected?
|
55
|
+
@connection.instance_variable_set :@client, mock
|
56
|
+
assert_equal true, @connection.connected?
|
57
|
+
@connection.instance_variable_set :@client, nil
|
58
|
+
assert_equal false, @connection.connected?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#get" do
|
63
|
+
it "sends a GET request the server" do
|
64
|
+
@connection.instance_variable_set :@client, (client = mock)
|
65
|
+
client.expects(:get).with("/?query=foo&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => ""))
|
66
|
+
@connection.stubs(:log)
|
67
|
+
@connection.get("foo")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#post" do
|
72
|
+
it "sends a POST request the server" do
|
73
|
+
@connection.instance_variable_set :@client, (client = mock)
|
74
|
+
client.expects(:post).with("/?query=foo&output_format_write_statistics=1", "body").returns(stub(:status => 200, :body => ""))
|
75
|
+
@connection.stubs(:log)
|
76
|
+
@connection.post("foo", "body")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#request" do
|
81
|
+
before do
|
82
|
+
@connection.stubs(:log)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "connects to the server first" do
|
86
|
+
@connection.instance_variable_set :@client, (client = mock)
|
87
|
+
@connection.expects(:connect!)
|
88
|
+
client.stubs(:get).returns(stub(:status => 200, :body => ""))
|
89
|
+
@connection.send :request, :get, "/", "query"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "queries the server returning the response" do
|
93
|
+
@connection.instance_variable_set :@client, (client = mock)
|
94
|
+
client.expects(:get).with("/?query=SELECT+1&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => ""))
|
95
|
+
@connection.expects(:parse_body).returns(data = mock)
|
96
|
+
assert_equal data, @connection.send(:request, :get, "SELECT 1")
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "when not receiving status 200" do
|
100
|
+
it "raises a Clickhouse::QueryError" do
|
101
|
+
@connection.instance_variable_set :@client, (client = mock)
|
102
|
+
client.expects(:get).with("/?query=SELECT+1&output_format_write_statistics=1", nil).returns(stub(:status => 500, :body => ""))
|
103
|
+
assert_raises Clickhouse::QueryError do
|
104
|
+
@connection.send(:request, :get, "SELECT 1")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "when getting Faraday::Error" do
|
110
|
+
it "raises a Clickhouse::ConnectionError" do
|
111
|
+
@connection.instance_variable_set :@client, (client = mock)
|
112
|
+
client.expects(:get).raises(Faraday::ConnectionFailed.new("Failed to connect"))
|
113
|
+
assert_raises Clickhouse::ConnectionError do
|
114
|
+
@connection.send(:request, :get, "SELECT 1")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it "parses the body" do
|
120
|
+
json = <<-JSON
|
121
|
+
{"meta": []}
|
122
|
+
JSON
|
123
|
+
@connection.instance_variable_set :@client, (client = mock)
|
124
|
+
client.expects(:get).with("/?query=SELECT+1+FORMAT+JSONCompact&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => json))
|
125
|
+
assert_equal({"meta" => []}, @connection.send(:request, :get, "SELECT 1 FORMAT JSONCompact"))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "configuration" do
|
130
|
+
describe "database" do
|
131
|
+
it "includes the database in the querystring" do
|
132
|
+
@connection.instance_variable_get(:@config)[:database] = "system"
|
133
|
+
@connection.instance_variable_set(:@client, (client = mock))
|
134
|
+
client.expects(:get).with("/?database=system&query=SELECT+1&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => ""))
|
135
|
+
@connection.expects(:parse_body).returns(data = mock)
|
136
|
+
assert_equal data, @connection.send(:request, :get, "SELECT 1")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "authentication" do
|
141
|
+
it "includes the credentials in the request headers" do
|
142
|
+
Faraday::Connection.any_instance.expects(:get).returns(stub(status: 200))
|
143
|
+
connection = Clickhouse::Connection.new :password => "awesomepassword"
|
144
|
+
connection.connect!
|
145
|
+
assert_equal "Basic ZGVmYXVsdDphd2Vzb21lcGFzc3dvcmQ=", connection.send(:client).headers["Authorization"].force_encoding("UTF-8")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "statistics" do
|
151
|
+
before do
|
152
|
+
@connection = Connection.new
|
153
|
+
@json = <<-JSON
|
154
|
+
{
|
155
|
+
"rows": 1947,
|
156
|
+
"statistics": {
|
157
|
+
"elapsed": 0.1882,
|
158
|
+
"rows_read": 1982,
|
159
|
+
"bytes_read": 2003
|
160
|
+
}
|
161
|
+
}
|
162
|
+
JSON
|
163
|
+
end
|
164
|
+
|
165
|
+
it "parses the statistics" do
|
166
|
+
@connection.stubs(:log)
|
167
|
+
@connection.instance_variable_set :@client, (client = mock)
|
168
|
+
Time.expects(:now).returns(1882).twice
|
169
|
+
|
170
|
+
client.expects(:get).with("/?query=SELECT+1+FORMAT+JSONCompact&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => @json))
|
171
|
+
@connection.expects(:write_log).with(
|
172
|
+
0, "SELECT 1", {
|
173
|
+
"elapsed" => "188.2ms",
|
174
|
+
"rows_read" => "1.98 thousand",
|
175
|
+
"bytes_read" => 2003,
|
176
|
+
"rows" => 1947,
|
177
|
+
"rows_per_second" => "10.53 thousand",
|
178
|
+
"data_per_second" => "10.39 KB",
|
179
|
+
"data_read" => "1.96 KB"
|
180
|
+
}
|
181
|
+
)
|
182
|
+
@connection.send(:request, :get, "SELECT 1 FORMAT JSONCompact")
|
183
|
+
end
|
184
|
+
|
185
|
+
it "write the expected logs" do
|
186
|
+
@connection.instance_variable_set :@client, (client = mock)
|
187
|
+
Time.expects(:now).returns(1882).twice
|
188
|
+
|
189
|
+
client.expects(:get).with("/?query=SELECT+1+FORMAT+JSONCompact&output_format_write_statistics=1", nil).returns(stub(:status => 200, :body => @json))
|
190
|
+
log = "\n \e[1m\e[35mSQL (0.0ms)\e\e[0m SELECT 1;\e\n \e[1m\e[36m1947 rows in set. Elapsed: 188.2ms. Processed: 1.98 thousand rows, 1.96 KB (10.53 thousand rows/s, 10.39 KB/s)\e[0m "
|
191
|
+
|
192
|
+
@connection.expects(:log).with(:debug, log)
|
193
|
+
@connection.send(:request, :get, "SELECT 1 FORMAT JSONCompact")
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#number_to_human_duration" do
|
197
|
+
it "returns in seconds when more than 1 seconds" do
|
198
|
+
assert_equal "2.0s", @connection.send(:number_to_human_duration, 2)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|