click_house 2.1.0 → 2.1.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 +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile.lock +1 -1
- data/Gemfile_faraday1.lock +1 -1
- data/Gemfile_faraday2.lock +1 -1
- data/README.md +4 -0
- data/lib/click_house/connection.rb +3 -2
- data/lib/click_house/extend/connection_inserting.rb +1 -1
- data/lib/click_house/extend/connection_selective.rb +10 -1
- data/lib/click_house/middleware/logging.rb +23 -39
- data/lib/click_house/middleware/response_base.rb +4 -4
- data/lib/click_house/middleware/summary_middleware.rb +26 -0
- data/lib/click_house/middleware.rb +1 -0
- data/lib/click_house/response/factory.rb +22 -14
- data/lib/click_house/response/result_set.rb +17 -10
- data/lib/click_house/response/summary.rb +109 -0
- data/lib/click_house/response.rb +1 -1
- data/lib/click_house/util.rb +7 -0
- data/lib/click_house/version.rb +1 -1
- metadata +3 -2
- data/lib/click_house/response/execution.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 364117bb31fd3478fcf00d981b61205aa9fb864abbfeb9f9bdf253e53a0917fa
|
4
|
+
data.tar.gz: d0b0d7a21175a9c2e044a88351ddd6d107b1875769ae737d3e547e41e01d93d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 481ba8166f2300302c1a0836e336097e97a25015fbe5a5cf8e8fb5912b2170d50a2a1bc25178deb8b4a4b17d63e5638d0200bbca5a84c6a237de694ecf5f4d76
|
7
|
+
data.tar.gz: ba051b743929517452507d54f98de6d57de724b4400d1cf9db02666a48c5b00d4dbd00a3ffab6b5f2f9c3a7db78c15f84ae36523e2ee76946526fe131722ee05
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
# 2.1.1
|
2
|
+
* Fix logging with symbolized keys JSON
|
3
|
+
* Unknown formats return raw `Response::ResultSelt` like regular JSON query
|
4
|
+
|
1
5
|
# 2.1.0
|
2
|
-
* `ClickHouse.connection.insert` now returns `ClickHouse::Response::
|
6
|
+
* `ClickHouse.connection.insert` now returns `ClickHouse::Response::Summary` object
|
3
7
|
with methods `headers`, `summary`, `written_rows`, `written_bytes`, etc...
|
4
8
|
* `ClickHouse.connection.insert(columns: ["id"], values: [1])` now uses `JSONCompactEachRow` by default
|
5
9
|
(to increase JSON serialization speed)
|
data/Gemfile.lock
CHANGED
data/Gemfile_faraday1.lock
CHANGED
data/Gemfile_faraday2.lock
CHANGED
data/README.md
CHANGED
@@ -138,12 +138,16 @@ Select all type-casted result set
|
|
138
138
|
@result = ClickHouse.connection.select_all('SELECT * FROM visits')
|
139
139
|
|
140
140
|
# all enumerable methods are delegated like #each, #map, #select etc
|
141
|
+
# results of #to_a is type casted
|
141
142
|
@result.to_a #=> [{"date"=>#<Date: 2000-01-01>, "id"=>1}]
|
142
143
|
|
143
144
|
# you can access raw data
|
144
145
|
@result.meta #=> [{"name"=>"date", "type"=>"Date"}, {"name"=>"id", "type"=>"UInt32"}]
|
145
146
|
@result.data #=> [{"date"=>"2000-01-01", "id"=>1}, {"date"=>"2000-01-02", "id"=>2}]
|
146
147
|
@result.statistics #=> {"elapsed"=>0.0002271, "rows_read"=>2, "bytes_read"=>12}
|
148
|
+
@result.summary #=> ClickHouse::Response::Summary
|
149
|
+
@result.headers #=> {"x-clickhouse-query-id"=>"9bf5f604-31fc-4eff-a4b5-277f2c71d199"}
|
150
|
+
@result.types #=> [Hash<String|Symbol, ClickHouse::Ast::Statement>]
|
147
151
|
```
|
148
152
|
|
149
153
|
### Select Value
|
@@ -65,8 +65,9 @@ module ClickHouse
|
|
65
65
|
|
66
66
|
conn.response Middleware::RaiseError
|
67
67
|
conn.response Middleware::Logging, logger: config.logger!
|
68
|
-
conn.response
|
69
|
-
conn.response
|
68
|
+
conn.response Middleware::SummaryMiddleware, options: { config: config } # should be after logger
|
69
|
+
conn.response config.json_parser, content_type: %r{application/json}, options: { config: config }
|
70
|
+
conn.response Middleware::ParseCsv, content_type: %r{text/csv}, options: { config: config }
|
70
71
|
conn.adapter config.adapter
|
71
72
|
end
|
72
73
|
end
|
@@ -46,7 +46,7 @@ module ClickHouse
|
|
46
46
|
return insert_compact(table, columns: columns, values: values, format: format)
|
47
47
|
end
|
48
48
|
|
49
|
-
Response::Factory.empty_exec
|
49
|
+
Response::Factory.empty_exec(config)
|
50
50
|
end
|
51
51
|
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
52
52
|
|
@@ -11,7 +11,16 @@ module ClickHouse
|
|
11
11
|
|
12
12
|
def select_value(sql)
|
13
13
|
response = get(body: sql, query: { default_format: 'JSON' })
|
14
|
-
|
14
|
+
got = Response::Factory.response(response, config).first
|
15
|
+
|
16
|
+
case got
|
17
|
+
when Hash
|
18
|
+
Array(got).dig(0, -1) # get a value of a first key for JSON format
|
19
|
+
when Array
|
20
|
+
got[0] # for CSV format
|
21
|
+
else
|
22
|
+
got # for RowBinary format
|
23
|
+
end
|
15
24
|
end
|
16
25
|
|
17
26
|
def select_one(sql)
|
@@ -5,36 +5,32 @@ module ClickHouse
|
|
5
5
|
class Logging < Faraday::Middleware
|
6
6
|
Faraday::Response.register_middleware self => self
|
7
7
|
|
8
|
-
|
8
|
+
EMPTY = ''
|
9
|
+
GET = :get
|
9
10
|
|
10
|
-
attr_reader :logger, :starting
|
11
|
+
attr_reader :logger, :starting
|
11
12
|
|
12
13
|
def initialize(app = nil, logger:)
|
13
14
|
@logger = logger
|
14
15
|
super(app)
|
15
16
|
end
|
16
17
|
|
17
|
-
def call(
|
18
|
+
def call(env)
|
18
19
|
@starting = timestamp
|
19
|
-
|
20
|
-
@app.call(environment).on_complete(&method(:on_complete))
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def log_body?
|
26
|
-
logger.level == Logger::DEBUG
|
20
|
+
super
|
27
21
|
end
|
28
22
|
|
29
23
|
# rubocop:disable Layout/LineLength
|
30
24
|
def on_complete(env)
|
31
|
-
summary =
|
32
|
-
logger.info("\e[1m[35mSQL (#{duration_stats_log(
|
33
|
-
logger.debug(
|
34
|
-
logger.info("\e[1m[36mRead: #{summary.
|
25
|
+
summary = SummaryMiddleware.extract(env)
|
26
|
+
logger.info("\e[1m[35mSQL (#{duration_stats_log(summary)})\e[0m #{query(env)};")
|
27
|
+
logger.debug(env.request_body) if log_body?(env)
|
28
|
+
logger.info("\e[1m[36mRead: #{summary.read_rows} rows, #{summary.read_bytes_pretty}. Written: #{summary.written_rows} rows, #{summary.written_bytes_pretty}\e[0m")
|
35
29
|
end
|
36
30
|
# rubocop:enable Layout/LineLength
|
37
31
|
|
32
|
+
private
|
33
|
+
|
38
34
|
def duration
|
39
35
|
timestamp - starting
|
40
36
|
end
|
@@ -43,37 +39,25 @@ module ClickHouse
|
|
43
39
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
44
40
|
end
|
45
41
|
|
46
|
-
|
47
|
-
|
42
|
+
# @return [Boolean]
|
43
|
+
def log_body?(env)
|
44
|
+
return unless logger.debug?
|
45
|
+
return if env.method == GET # GET queries logs body as a statement
|
46
|
+
return if env.request_body.nil? || env.request_body == EMPTY
|
47
|
+
|
48
|
+
true
|
48
49
|
end
|
49
50
|
|
50
51
|
def query(env)
|
51
|
-
if
|
52
|
-
|
52
|
+
if env.method == GET
|
53
|
+
env.request_body
|
53
54
|
else
|
54
|
-
CGI.parse(env.url.query.to_s).dig('query', 0) || '[NO QUERY]'
|
55
|
+
String(CGI.parse(env.url.query.to_s).dig('query', 0) || '[NO QUERY]').chomp
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
def duration_stats_log(
|
59
|
-
|
60
|
-
clickhouse_elapsed = body['statistics'].fetch('elapsed') if body.is_a?(Hash) && body.key?('statistics')
|
61
|
-
|
62
|
-
[
|
63
|
-
"Total: #{Util::Pretty.measure(elapsed * 1000)}",
|
64
|
-
("CH: #{Util::Pretty.measure(clickhouse_elapsed * 1000)}" if clickhouse_elapsed)
|
65
|
-
].compact.join(', ')
|
66
|
-
end
|
67
|
-
|
68
|
-
def extract_summary(headers)
|
69
|
-
JSON.parse(headers.fetch('x-clickhouse-summary', '{}')).tap do |summary|
|
70
|
-
summary[:read_rows] = summary['read_rows']
|
71
|
-
summary[:read_bytes] = Util::Pretty.size(summary['read_bytes'].to_i)
|
72
|
-
summary[:written_rows] = summary['written_rows']
|
73
|
-
summary[:written_bytes] = Util::Pretty.size(summary['written_bytes'].to_i)
|
74
|
-
end
|
75
|
-
rescue JSON::ParserError
|
76
|
-
{}
|
59
|
+
def duration_stats_log(summary)
|
60
|
+
"Total: #{Util::Pretty.measure(duration * 1000)}, CH: #{summary.elapsed_pretty}"
|
77
61
|
end
|
78
62
|
end
|
79
63
|
end
|
@@ -5,12 +5,12 @@ module ClickHouse
|
|
5
5
|
class ResponseBase < Faraday::Middleware
|
6
6
|
CONTENT_TYPE_HEADER = 'content-type'
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :options
|
9
9
|
attr_reader :content_type
|
10
10
|
|
11
|
-
def initialize(app = nil,
|
11
|
+
def initialize(app = nil, options: {}, content_type: nil, preserve_raw: false)
|
12
12
|
super(app)
|
13
|
-
@
|
13
|
+
@options = options
|
14
14
|
@content_type = content_type
|
15
15
|
@preserve_raw = preserve_raw
|
16
16
|
on_setup
|
@@ -32,7 +32,7 @@ module ClickHouse
|
|
32
32
|
|
33
33
|
# @return [Config]
|
34
34
|
def config
|
35
|
-
|
35
|
+
options.fetch(:config)
|
36
36
|
end
|
37
37
|
|
38
38
|
private
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickHouse
|
4
|
+
module Middleware
|
5
|
+
class SummaryMiddleware < ResponseBase
|
6
|
+
Faraday::Response.register_middleware self => self
|
7
|
+
|
8
|
+
KEY = :summary
|
9
|
+
|
10
|
+
# @param env [Faraday::Env]
|
11
|
+
# @return [Response::Summary]
|
12
|
+
def self.extract(env)
|
13
|
+
env.custom_members.fetch(KEY)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param env [Faraday::Env]
|
17
|
+
def on_complete(env)
|
18
|
+
env.custom_members[KEY] = Response::Summary.new(
|
19
|
+
config,
|
20
|
+
headers: env.response_headers,
|
21
|
+
body: env.body.is_a?(Hash) ? env.body : {}
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module ClickHouse
|
4
4
|
module Middleware
|
5
5
|
autoload :ResponseBase, 'click_house/middleware/response_base'
|
6
|
+
autoload :SummaryMiddleware, 'click_house/middleware/summary_middleware'
|
6
7
|
autoload :Logging, 'click_house/middleware/logging'
|
7
8
|
autoload :ParseCsv, 'click_house/middleware/parse_csv'
|
8
9
|
autoload :ParseJsonOj, 'click_house/middleware/parse_json_oj'
|
@@ -5,38 +5,46 @@ module ClickHouse
|
|
5
5
|
class Factory
|
6
6
|
KEY_META = 'meta'
|
7
7
|
KEY_DATA = 'data'
|
8
|
-
KEY_TOTALS = 'totals'
|
9
|
-
KEY_STATISTICS = 'statistics'
|
10
|
-
KEY_ROWS_BEFORE_LIMIT_AT_LEAST = 'rows_before_limit_at_least'
|
11
8
|
|
12
|
-
# @return [
|
9
|
+
# @return [ResultSet]
|
13
10
|
# @params faraday [Faraday::Response]
|
14
11
|
# @params config [Config]
|
15
12
|
def self.response(faraday, config)
|
16
13
|
body = faraday.body
|
17
14
|
|
18
|
-
|
19
|
-
|
15
|
+
# wrap to be able to use connection#select_one, connection#select_value
|
16
|
+
# with other formats like binary
|
17
|
+
return raw(faraday, config) unless body.is_a?(Hash)
|
18
|
+
return raw(faraday, config) unless body.key?(config.key(KEY_META)) && body.key?(config.key(KEY_DATA))
|
20
19
|
|
21
20
|
ResultSet.new(
|
22
21
|
config: config,
|
23
22
|
meta: body.fetch(config.key(KEY_META)),
|
24
23
|
data: body.fetch(config.key(KEY_DATA)),
|
25
|
-
|
26
|
-
statistics: body[config.key(KEY_STATISTICS)],
|
27
|
-
rows_before_limit_at_least: body[config.key(KEY_ROWS_BEFORE_LIMIT_AT_LEAST)]
|
24
|
+
summary: Middleware::SummaryMiddleware.extract(faraday.env)
|
28
25
|
)
|
29
26
|
end
|
30
27
|
|
31
|
-
# @return [
|
28
|
+
# @return [ResultSet]
|
29
|
+
# Rae ResultSet (without type casting)
|
30
|
+
def self.raw(faraday, config)
|
31
|
+
ResultSet.raw(
|
32
|
+
config: config,
|
33
|
+
data: Util.array(faraday.body),
|
34
|
+
summary: Middleware::SummaryMiddleware.extract(faraday.env)
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Result of execution
|
39
|
+
# @return [Response::Summary]
|
32
40
|
# @params faraday [Faraday::Response]
|
33
41
|
def self.exec(faraday)
|
34
|
-
|
42
|
+
Middleware::SummaryMiddleware.extract(faraday.env)
|
35
43
|
end
|
36
44
|
|
37
|
-
# @return [Response::
|
38
|
-
def self.empty_exec
|
39
|
-
|
45
|
+
# @return [Response::Summary]
|
46
|
+
def self.empty_exec(config)
|
47
|
+
Summary.new(config)
|
40
48
|
end
|
41
49
|
end
|
42
50
|
end
|
@@ -13,24 +13,31 @@ module ClickHouse
|
|
13
13
|
:inspect, :each, :fetch, :length, :count, :size,
|
14
14
|
:first, :last, :[], :to_h
|
15
15
|
|
16
|
-
|
16
|
+
def_delegators :summary,
|
17
|
+
:statistics, :headers,
|
18
|
+
:totals, :rows_before_limit_at_least
|
19
|
+
|
20
|
+
attr_reader :config, :meta, :data, :summary
|
21
|
+
|
22
|
+
class << self
|
23
|
+
# @param config [Config]
|
24
|
+
# @return [ResultSet]
|
25
|
+
def raw(config:, data:, summary:)
|
26
|
+
new(config: config, data: data, to_a: data, meta: [], summary: summary)
|
27
|
+
end
|
28
|
+
end
|
17
29
|
|
18
30
|
# @param config [Config]
|
19
31
|
# @param meta [Array]
|
20
32
|
# @param data [Array]
|
21
|
-
# @param
|
22
|
-
|
23
|
-
# Hash in JSON format and Array in JSONCompact
|
24
|
-
# rubocop:disable Metrics/ParameterLists
|
25
|
-
def initialize(config:, meta:, data:, totals: nil, statistics: nil, rows_before_limit_at_least: nil)
|
33
|
+
# @param summary [Response::Summary]
|
34
|
+
def initialize(config:, meta:, data:, summary:, to_a: nil)
|
26
35
|
@config = config
|
27
36
|
@meta = meta
|
28
37
|
@data = data
|
29
|
-
@
|
30
|
-
@
|
31
|
-
@statistics = Hash(statistics)
|
38
|
+
@summary = summary
|
39
|
+
@to_a = to_a
|
32
40
|
end
|
33
|
-
# rubocop:enable Metrics/ParameterLists
|
34
41
|
|
35
42
|
# @return [Array, Hash]
|
36
43
|
# @param data [Array, Hash]
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickHouse
|
4
|
+
module Response
|
5
|
+
class Summary
|
6
|
+
SUMMARY_HEADER = 'x-clickhouse-summary'
|
7
|
+
KEY_TOTALS = 'totals'
|
8
|
+
KEY_STATISTICS = 'statistics'
|
9
|
+
KEY_ROWS_BEFORE_LIMIT_AT_LEAST = 'rows_before_limit_at_least'
|
10
|
+
KEY_STAT_ELAPSED = 'elapsed'
|
11
|
+
|
12
|
+
attr_reader :config,
|
13
|
+
:headers,
|
14
|
+
:summary,
|
15
|
+
# {:elapsed=>0.387287e-3, :rows_read=>0, :bytes_read=>0}}
|
16
|
+
:statistics,
|
17
|
+
:totals,
|
18
|
+
:rows_before_limit_at_least
|
19
|
+
|
20
|
+
# @param config [Config]
|
21
|
+
# @param headers [Faraday::Utils::Headers]
|
22
|
+
# @param body [Hash]
|
23
|
+
# TOTALS [Array|Hash|NilClass] Support for 'GROUP BY WITH TOTALS' modifier
|
24
|
+
# https://clickhouse.tech/docs/en/sql-reference/statements/select/group-by/#with-totals-modifier
|
25
|
+
# Hash in JSON format and Array in JSONCompact
|
26
|
+
def initialize(config, headers: Faraday::Utils::Headers.new, body: {})
|
27
|
+
@headers = headers
|
28
|
+
@config = config
|
29
|
+
@statistics = body.fetch(config.key(KEY_STATISTICS), {})
|
30
|
+
@totals = body[config.key(KEY_TOTALS)]
|
31
|
+
@rows_before_limit_at_least = body[config.key(KEY_ROWS_BEFORE_LIMIT_AT_LEAST)]
|
32
|
+
@summary = parse_summary(headers[SUMMARY_HEADER])
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Integer]
|
36
|
+
def read_rows
|
37
|
+
summary[config.key('read_rows')].to_i
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Integer]
|
41
|
+
def read_bytes
|
42
|
+
summary[config.key('read_bytes')].to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String]
|
46
|
+
def read_bytes_pretty
|
47
|
+
Util::Pretty.size(read_bytes)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Integer]
|
51
|
+
def written_rows
|
52
|
+
summary[config.key('written_rows')].to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Integer]
|
56
|
+
def written_bytes
|
57
|
+
summary[config.key('written_bytes')].to_i
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [String]
|
61
|
+
def written_bytes_pretty
|
62
|
+
Util::Pretty.size(written_bytes)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Integer]
|
66
|
+
def total_rows_to_read
|
67
|
+
summary[config.key('total_rows_to_read')].to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Integer]
|
71
|
+
def result_rows
|
72
|
+
summary[config.key('result_rows')].to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Integer]
|
76
|
+
def result_bytes
|
77
|
+
summary[config.key('result_bytes')].to_i
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Float]
|
81
|
+
def elapsed
|
82
|
+
statistics[config.key(KEY_STAT_ELAPSED)].to_f
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [String]
|
86
|
+
def elapsed_pretty
|
87
|
+
Util::Pretty.measure(elapsed * 1000)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# @return [Hash]
|
93
|
+
# {
|
94
|
+
# "read_rows" => "1",
|
95
|
+
# "read_bytes" => "23",
|
96
|
+
# "written_rows" => "1",
|
97
|
+
# "written_bytes" => "23",
|
98
|
+
# "total_rows_to_read" => "0",
|
99
|
+
# "result_rows" => "1",
|
100
|
+
# "result_bytes" => "23",
|
101
|
+
# }
|
102
|
+
def parse_summary(value)
|
103
|
+
return {} if value.nil? || value.empty?
|
104
|
+
|
105
|
+
JSON.parse(value)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/click_house/response.rb
CHANGED
data/lib/click_house/util.rb
CHANGED
data/lib/click_house/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: click_house
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aliaksandr Shylau
|
@@ -200,10 +200,11 @@ files:
|
|
200
200
|
- lib/click_house/middleware/parse_json_oj.rb
|
201
201
|
- lib/click_house/middleware/raise_error.rb
|
202
202
|
- lib/click_house/middleware/response_base.rb
|
203
|
+
- lib/click_house/middleware/summary_middleware.rb
|
203
204
|
- lib/click_house/response.rb
|
204
|
-
- lib/click_house/response/execution.rb
|
205
205
|
- lib/click_house/response/factory.rb
|
206
206
|
- lib/click_house/response/result_set.rb
|
207
|
+
- lib/click_house/response/summary.rb
|
207
208
|
- lib/click_house/serializer.rb
|
208
209
|
- lib/click_house/serializer/base.rb
|
209
210
|
- lib/click_house/serializer/json_oj_serializer.rb
|
@@ -1,70 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ClickHouse
|
4
|
-
module Response
|
5
|
-
class Execution
|
6
|
-
SUMMARY_HEADER = 'x-clickhouse-summary'
|
7
|
-
|
8
|
-
attr_reader :headers, :summary
|
9
|
-
|
10
|
-
# @param headers [Faraday::Utils::Headers]
|
11
|
-
def initialize(headers: Faraday::Utils::Headers.new)
|
12
|
-
@headers = headers
|
13
|
-
@summary = parse_summary(headers[SUMMARY_HEADER])
|
14
|
-
end
|
15
|
-
|
16
|
-
# @return [Integer]
|
17
|
-
def read_rows
|
18
|
-
summary['read_rows'].to_i
|
19
|
-
end
|
20
|
-
|
21
|
-
# @return [Integer]
|
22
|
-
def read_bytes
|
23
|
-
summary['read_bytes'].to_i
|
24
|
-
end
|
25
|
-
|
26
|
-
# @return [Integer]
|
27
|
-
def written_rows
|
28
|
-
summary['written_rows'].to_i
|
29
|
-
end
|
30
|
-
|
31
|
-
# @return [Integer]
|
32
|
-
def written_bytes
|
33
|
-
summary['written_bytes'].to_i
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Integer]
|
37
|
-
def total_rows_to_read
|
38
|
-
summary['total_rows_to_read'].to_i
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [Integer]
|
42
|
-
def result_rows
|
43
|
-
summary['result_rows'].to_i
|
44
|
-
end
|
45
|
-
|
46
|
-
# @return [Integer]
|
47
|
-
def result_bytes
|
48
|
-
summary['result_bytes'].to_i
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
# @return [Hash]
|
54
|
-
# {
|
55
|
-
# "read_rows" => "1",
|
56
|
-
# "read_bytes" => "23",
|
57
|
-
# "written_rows" => "1",
|
58
|
-
# "written_bytes" => "23",
|
59
|
-
# "total_rows_to_read" => "0",
|
60
|
-
# "result_rows" => "1",
|
61
|
-
# "result_bytes" => "23",
|
62
|
-
# }
|
63
|
-
def parse_summary(value)
|
64
|
-
return {} if value.nil? || value.empty?
|
65
|
-
|
66
|
-
JSON.parse(value)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|