click_house 1.4.0 → 1.5.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/.github/workflows/main.yml +1 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +11 -3
- data/CHANGELOG.md +6 -1
- data/Gemfile.lock +11 -7
- data/docker-compose.yml +1 -1
- data/lib/click_house/config.rb +5 -1
- data/lib/click_house/connection.rb +19 -2
- data/lib/click_house/extend/connection_explaining.rb +4 -2
- data/lib/click_house/extend/connection_healthy.rb +1 -2
- data/lib/click_house/extend/connection_selective.rb +3 -3
- data/lib/click_house/middleware/logging.rb +24 -5
- data/lib/click_house/response/factory.rb +6 -1
- data/lib/click_house/response/result_set.rb +6 -2
- data/lib/click_house/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dbe7ae01f5130dc0d18d9f9456ad75c2fdcc04bfe815debac344c93ce9bd00e
|
4
|
+
data.tar.gz: 4f7c8ab45593d9d37744ea9125c202052a99f582cd0887e251af790973c8a22a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f865c9753769cfa587ce59e428d45a664d1b976b535418e86bba7688ab3b0255177d9de7201479a683635c7376ae0958ad7803490328f55f003ba10ec098c2fc
|
7
|
+
data.tar.gz: ae3cf74cc163b842f9e27d49c84165b94858fe9b91461aa6a0bfde7404d9c9175a663a099c75e9eaf4e05ec8a1bc2dbf1840e0ed1f26f48590dc217dd6a8b4e1
|
data/.github/workflows/main.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -13,9 +13,9 @@ AllCops:
|
|
13
13
|
Bundler/OrderedGems:
|
14
14
|
Enabled: false
|
15
15
|
|
16
|
-
# ==============================
|
17
|
-
|
18
|
-
Enabled:
|
16
|
+
# ============================== Gemspec ======================
|
17
|
+
Gemspec/DateAssignment:
|
18
|
+
Enabled: true
|
19
19
|
|
20
20
|
# =============================== Performance =======================
|
21
21
|
Performance/AncestorsInclude:
|
@@ -46,6 +46,10 @@ Performance/ConstantRegexp:
|
|
46
46
|
Enabled: true
|
47
47
|
Performance/MethodObjectAsBlock:
|
48
48
|
Enabled: false
|
49
|
+
Performance/RedundantEqualityComparisonBlock:
|
50
|
+
Enabled: true
|
51
|
+
Performance/RedundantSplitRegexpArgument:
|
52
|
+
Enabled: true
|
49
53
|
|
50
54
|
# ============================== Metrics ============================
|
51
55
|
Metrics/ClassLength:
|
@@ -227,6 +231,10 @@ Style/EndlessMethod:
|
|
227
231
|
Enabled: true
|
228
232
|
Style/IfWithBooleanLiteralBranches:
|
229
233
|
Enabled: true
|
234
|
+
Style/HashConversion:
|
235
|
+
Enabled: true
|
236
|
+
Style/Documentation:
|
237
|
+
Enabled: false
|
230
238
|
|
231
239
|
# ============================== Lint ==============================
|
232
240
|
Lint/DuplicateMethods:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
# 1.5.0
|
2
|
+
* add support for 'WITH TOTALS' modifier in response
|
3
|
+
* send SQL in GET request's body [#12](https://github.com/shlima/click_house/pull/12)
|
4
|
+
* add support of 'WITH TOTALS' on a resulting set
|
5
|
+
|
1
6
|
# 1.4.0
|
2
|
-
*
|
7
|
+
* fix decimal type casting [#11](https://github.com/shlima/click_house/issues/11)
|
3
8
|
|
4
9
|
# 1.3.9
|
5
10
|
* add `ClickHouse.connection.add_index`, `ClickHouse.connection.drop_index`
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
click_house (1.
|
4
|
+
click_house (1.5.0)
|
5
5
|
faraday
|
6
6
|
faraday_middleware
|
7
7
|
|
@@ -11,11 +11,15 @@ GEM
|
|
11
11
|
ast (2.4.2)
|
12
12
|
coderay (1.1.3)
|
13
13
|
diff-lcs (1.4.4)
|
14
|
-
faraday (1.
|
14
|
+
faraday (1.4.1)
|
15
|
+
faraday-excon (~> 1.1)
|
15
16
|
faraday-net_http (~> 1.0)
|
17
|
+
faraday-net_http_persistent (~> 1.1)
|
16
18
|
multipart-post (>= 1.2, < 3)
|
17
|
-
ruby2_keywords
|
19
|
+
ruby2_keywords (>= 0.0.4)
|
20
|
+
faraday-excon (1.1.0)
|
18
21
|
faraday-net_http (1.0.1)
|
22
|
+
faraday-net_http_persistent (1.1.0)
|
19
23
|
faraday_middleware (1.0.0)
|
20
24
|
faraday (~> 1.0)
|
21
25
|
method_source (1.0.0)
|
@@ -28,7 +32,7 @@ GEM
|
|
28
32
|
method_source (~> 1.0)
|
29
33
|
rainbow (3.0.0)
|
30
34
|
rake (13.0.3)
|
31
|
-
regexp_parser (2.
|
35
|
+
regexp_parser (2.1.1)
|
32
36
|
rexml (3.2.4)
|
33
37
|
rspec (3.10.0)
|
34
38
|
rspec-core (~> 3.10.0)
|
@@ -43,7 +47,7 @@ GEM
|
|
43
47
|
diff-lcs (>= 1.2.0, < 2.0)
|
44
48
|
rspec-support (~> 3.10.0)
|
45
49
|
rspec-support (3.10.2)
|
46
|
-
rubocop (1.
|
50
|
+
rubocop (1.11.0)
|
47
51
|
parallel (~> 1.10)
|
48
52
|
parser (>= 3.0.0.0)
|
49
53
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -54,7 +58,7 @@ GEM
|
|
54
58
|
unicode-display_width (>= 1.4.0, < 3.0)
|
55
59
|
rubocop-ast (1.4.1)
|
56
60
|
parser (>= 2.7.1.5)
|
57
|
-
rubocop-performance (1.
|
61
|
+
rubocop-performance (1.10.1)
|
58
62
|
rubocop (>= 0.90.0, < 2.0)
|
59
63
|
rubocop-ast (>= 0.4.0)
|
60
64
|
ruby-progressbar (1.11.0)
|
@@ -74,4 +78,4 @@ DEPENDENCIES
|
|
74
78
|
rubocop-performance
|
75
79
|
|
76
80
|
BUNDLED WITH
|
77
|
-
2.2.
|
81
|
+
2.2.14
|
data/docker-compose.yml
CHANGED
data/lib/click_house/config.rb
CHANGED
@@ -49,11 +49,15 @@ module ClickHouse
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def logger!
|
52
|
-
@logger ||
|
52
|
+
@logger || null_logger
|
53
53
|
end
|
54
54
|
|
55
55
|
def url!
|
56
56
|
@url || "#{scheme}://#{host}:#{port}"
|
57
57
|
end
|
58
|
+
|
59
|
+
def null_logger
|
60
|
+
@null_logger ||= Logger.new(IO::NULL)
|
61
|
+
end
|
58
62
|
end
|
59
63
|
end
|
@@ -21,8 +21,25 @@ module ClickHouse
|
|
21
21
|
post(body, query: { query: query }, database: database)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
# @param path [String] Clickhouse HTTP endpoint, e.g. /ping, /replica_status
|
25
|
+
# @param body [String] SQL to run
|
26
|
+
# @param database [String|NilClass] database to use, nil to skip
|
27
|
+
# @param query [Hash] other CH settings to send through params, e.g. max_rows_to_read=1
|
28
|
+
# @example get(body: 'select number from system.numbers limit 100', query: { max_rows_to_read: 10 })
|
29
|
+
# @return [Faraday::Response]
|
30
|
+
def get(path = '/', body: '', query: {}, database: config.database)
|
31
|
+
# backward compatibility since
|
32
|
+
# https://github.com/shlima/click_house/pull/12/files#diff-9c6f3f06d3b575731eae4b6b95ddbcdcc20452c432b8f6e87a3a8e8645818107R24
|
33
|
+
if query.is_a?(String)
|
34
|
+
query = { query: query }
|
35
|
+
config.logger!.warn('since v1.4.0 use connection.get(body: "SELECT 1") instead of connection.get(query: "SELECT 1")')
|
36
|
+
end
|
37
|
+
|
38
|
+
transport.get(path) do |conn|
|
39
|
+
conn.params = query.merge(database: database).compact
|
40
|
+
conn.params[:send_progress_in_http_headers] = 1 unless body.empty?
|
41
|
+
conn.body = body
|
42
|
+
end
|
26
43
|
end
|
27
44
|
|
28
45
|
def post(body = nil, query: {}, database: config.database)
|
@@ -6,9 +6,11 @@ module ClickHouse
|
|
6
6
|
EXPLAIN = 'EXPLAIN'
|
7
7
|
EXPLAIN_RE = /\A(\s*#{EXPLAIN})/io.freeze
|
8
8
|
|
9
|
-
|
9
|
+
# @return String
|
10
|
+
def explain(sql, io: StringIO.new)
|
10
11
|
res = execute("#{EXPLAIN} #{sql.gsub(EXPLAIN_RE, '')}")
|
11
|
-
io
|
12
|
+
io.puts(res.body)
|
13
|
+
io.string
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -4,8 +4,7 @@ module ClickHouse
|
|
4
4
|
module Extend
|
5
5
|
module ConnectionHealthy
|
6
6
|
def ping
|
7
|
-
|
8
|
-
get(database: nil, query: { send_progress_in_http_headers: nil }).success?
|
7
|
+
get('/ping', database: nil).success?
|
9
8
|
end
|
10
9
|
|
11
10
|
def replicas_status
|
@@ -5,17 +5,17 @@ module ClickHouse
|
|
5
5
|
module ConnectionSelective
|
6
6
|
# @return [ResultSet]
|
7
7
|
def select_all(sql)
|
8
|
-
response =
|
8
|
+
response = get(body: Util::Statement.format(sql, 'JSON'))
|
9
9
|
Response::Factory[response]
|
10
10
|
end
|
11
11
|
|
12
12
|
def select_value(sql)
|
13
|
-
response =
|
13
|
+
response = get(body: Util::Statement.format(sql, 'JSON'))
|
14
14
|
Array(Response::Factory[response].first).dig(0, -1)
|
15
15
|
end
|
16
16
|
|
17
17
|
def select_one(sql)
|
18
|
-
response =
|
18
|
+
response = get(body: Util::Statement.format(sql, 'JSON'))
|
19
19
|
Response::Factory[response].first
|
20
20
|
end
|
21
21
|
end
|
@@ -29,11 +29,8 @@ module ClickHouse
|
|
29
29
|
# rubocop:disable Layout/LineLength
|
30
30
|
def on_complete(env)
|
31
31
|
summary = extract_summary(env.response_headers)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
logger.info("\e[1m[35mSQL (#{Util::Pretty.measure(elapsed)})\e[0m #{query};")
|
36
|
-
logger.debug(body) if body
|
32
|
+
logger.info("\e[1m[35mSQL (#{duration_stats_log(env.body)})\e[0m #{query(env)};")
|
33
|
+
logger.debug(body) if body && !query_in_body?(env)
|
37
34
|
logger.info("\e[1m[36mRead: #{summary.fetch(:read_rows)} rows, #{summary.fetch(:read_bytes)}. Written: #{summary.fetch(:written_rows)} rows, #{summary.fetch(:written_bytes)}\e[0m")
|
38
35
|
end
|
39
36
|
# rubocop:enable Layout/LineLength
|
@@ -46,6 +43,28 @@ module ClickHouse
|
|
46
43
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
47
44
|
end
|
48
45
|
|
46
|
+
def query_in_body?(env)
|
47
|
+
env.method == :get
|
48
|
+
end
|
49
|
+
|
50
|
+
def query(env)
|
51
|
+
if query_in_body?(env)
|
52
|
+
body
|
53
|
+
else
|
54
|
+
CGI.parse(env.url.query.to_s).dig('query', 0) || '[NO QUERY]'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def duration_stats_log(body)
|
59
|
+
elapsed = duration
|
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
|
+
|
49
68
|
def extract_summary(headers)
|
50
69
|
JSON.parse(headers.fetch('x-clickhouse-summary', '{}')).tap do |summary|
|
51
70
|
summary[:read_rows] = summary['read_rows']
|
@@ -10,7 +10,12 @@ module ClickHouse
|
|
10
10
|
|
11
11
|
return body if !body.is_a?(Hash) || !(body.key?('meta') && body.key?('data'))
|
12
12
|
|
13
|
-
ResultSet.new(
|
13
|
+
ResultSet.new(
|
14
|
+
meta: body.fetch('meta'),
|
15
|
+
data: body.fetch('data'),
|
16
|
+
totals: body['totals'],
|
17
|
+
statistics: body['statistics']
|
18
|
+
)
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -14,7 +14,7 @@ module ClickHouse
|
|
14
14
|
:inspect, :each, :fetch, :length, :count, :size,
|
15
15
|
:first, :last, :[], :to_h
|
16
16
|
|
17
|
-
attr_reader :meta, :data, :statistics
|
17
|
+
attr_reader :meta, :data, :totals, :statistics
|
18
18
|
|
19
19
|
class << self
|
20
20
|
# @return [Array<String, Array>]
|
@@ -48,9 +48,13 @@ module ClickHouse
|
|
48
48
|
|
49
49
|
# @param meta [Array]
|
50
50
|
# @param data [Array]
|
51
|
-
|
51
|
+
# @param totals [Array|Hash|NilClass] Support for 'GROUP BY WITH TOTALS' modifier
|
52
|
+
# https://clickhouse.tech/docs/en/sql-reference/statements/select/group-by/#with-totals-modifier
|
53
|
+
# Hash in JSON format and Array in JSONCompact
|
54
|
+
def initialize(meta:, data:, totals: nil, statistics: nil)
|
52
55
|
@meta = meta
|
53
56
|
@data = data
|
57
|
+
@totals = totals
|
54
58
|
@statistics = Hash(statistics)
|
55
59
|
end
|
56
60
|
|
data/lib/click_house/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: click_house
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aliaksandr Shylau
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -210,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
210
|
- !ruby/object:Gem::Version
|
211
211
|
version: '0'
|
212
212
|
requirements: []
|
213
|
-
rubygems_version: 3.2.
|
213
|
+
rubygems_version: 3.2.15
|
214
214
|
signing_key:
|
215
215
|
specification_version: 4
|
216
216
|
summary: Modern Ruby database driver for ClickHouse
|