click_house-client 0.8.1 → 0.8.3
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/Gemfile.lock +2 -2
- data/lib/click_house/client/arel_visitor.rb +2 -0
- data/lib/click_house/client/query_builder.rb +10 -3
- data/lib/click_house/client/to_redacted_sql_visitor.rb +118 -0
- data/lib/click_house/client/version.rb +1 -1
- data/lib/click_house/client.rb +2 -2
- metadata +3 -3
- data/lib/click_house/client/redactor.rb +0 -91
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f12c7192094a0cec94c354381b9be928dff901c03a9e8522dde43a695ce99b62
|
|
4
|
+
data.tar.gz: bedf93d6760663e747598c2cf9f60b90106b5d6979a7fe11dd00749cb03e4326
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5fe06dbc303e5b94e72e84b0da50c96defa1be6445a77236ad29f49ed4283cb0e0d5ce147e5bafba671ac01d7064be5c3f0e4f80ff83ffe74eae7207f1b6a56e
|
|
7
|
+
data.tar.gz: a183e8f5081a5f1c4463e0b35c5fde96968023555c6b65ef4e5495a52650f747a224dfb468145cb3c5d5a55333e859398db6284952fec9c323f0bec3a4b6247e
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
click_house-client (0.8.
|
|
4
|
+
click_house-client (0.8.3)
|
|
5
5
|
activerecord (>= 7.0, < 9.0)
|
|
6
6
|
activesupport (>= 7.0, < 9.0)
|
|
7
7
|
addressable (~> 2.8)
|
|
@@ -136,7 +136,7 @@ CHECKSUMS
|
|
|
136
136
|
benchmark (0.4.1) sha256=d4ef40037bba27f03b28013e219b950b82bace296549ec15a78016552f8d2cce
|
|
137
137
|
bigdecimal (3.2.2) sha256=39085f76b495eb39a79ce07af716f3a6829bc35eb44f2195e2753749f2fa5adc
|
|
138
138
|
byebug (12.0.0) sha256=d4a150d291cca40b66ec9ca31f754e93fed8aa266a17335f71bb0afa7fca1a1e
|
|
139
|
-
click_house-client (0.8.
|
|
139
|
+
click_house-client (0.8.3)
|
|
140
140
|
concurrent-ruby (1.3.5) sha256=813b3e37aca6df2a21a3b9f1d497f8cbab24a2b94cab325bffe65ee0f6cbebc6
|
|
141
141
|
connection_pool (2.5.3) sha256=cfd74a82b9b094d1ce30c4f1a346da23ee19dc8a062a16a85f58eab1ced4305b
|
|
142
142
|
diff-lcs (1.5.0) sha256=49b934001c8c6aedb37ba19daec5c634da27b318a7a3c654ae979d6ba1929b67
|
|
@@ -29,8 +29,13 @@ module ClickHouse
|
|
|
29
29
|
Arel::Nodes::As
|
|
30
30
|
].freeze
|
|
31
31
|
|
|
32
|
-
def initialize(
|
|
33
|
-
@table =
|
|
32
|
+
def initialize(table, alias_name = nil)
|
|
33
|
+
@table = if table.is_a?(self.class) # subquery
|
|
34
|
+
Arel::Nodes::TableAlias.new(table.to_arel, alias_name)
|
|
35
|
+
else
|
|
36
|
+
Arel::Table.new(table)
|
|
37
|
+
end
|
|
38
|
+
|
|
34
39
|
@manager = Arel::SelectManager.new(Arel::Table.engine).from(@table).project(Arel.star)
|
|
35
40
|
end
|
|
36
41
|
|
|
@@ -315,7 +320,9 @@ module ClickHouse
|
|
|
315
320
|
end
|
|
316
321
|
|
|
317
322
|
def to_redacted_sql(bind_index_manager = ClickHouse::Client::BindIndexManager.new)
|
|
318
|
-
ClickHouse::Client::
|
|
323
|
+
visitor = ClickHouse::Client::ToRedactedSqlVisitor.new(ClickHouse::Client::ArelEngine.new,
|
|
324
|
+
bind_manager: bind_index_manager)
|
|
325
|
+
visitor.accept(manager.ast, Arel::Collectors::SQLString.new).value
|
|
319
326
|
end
|
|
320
327
|
|
|
321
328
|
def to_arel
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ClickHouse
|
|
4
|
+
module Client
|
|
5
|
+
# Redacts the SQL query represented by the query builder.
|
|
6
|
+
#
|
|
7
|
+
# Example:
|
|
8
|
+
# query_builder = ClickHouse::QueryBuilder.new('users').where(name: 'John Doe')
|
|
9
|
+
# redacted_query = query_builder.to_redacted_sql
|
|
10
|
+
# # The redacted_query will contain the SQL query with values replaced by placeholders.
|
|
11
|
+
# output: "SELECT * FROM \"users\" WHERE \"users\".\"name\" = $1"
|
|
12
|
+
class ToRedactedSqlVisitor < ArelVisitor
|
|
13
|
+
attr_reader :bind_manager
|
|
14
|
+
|
|
15
|
+
def initialize(*args, bind_manager: ClickHouse::Client::BindIndexManager.new)
|
|
16
|
+
@bind_manager = bind_manager
|
|
17
|
+
super(*args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def redaction_enabled?
|
|
23
|
+
!!@redaction_enabled
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def collect_nodes_for(nodes, collector, spacer, *args)
|
|
27
|
+
return super unless spacer.strip.in?(%w[WHERE HAVING])
|
|
28
|
+
|
|
29
|
+
redaction_was = @redaction_enabled
|
|
30
|
+
@redaction_enabled = true
|
|
31
|
+
super
|
|
32
|
+
@redaction_enabled = redaction_was
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# rubocop:disable Naming/MethodName -- following Arel::Visitors::Visitor pattern
|
|
36
|
+
# rubocop:disable Naming/MethodParameterName -- following Arel::Visitors::Visitor pattern
|
|
37
|
+
|
|
38
|
+
def visit_Arel_Nodes_In(o, collector)
|
|
39
|
+
return super unless redaction_enabled?
|
|
40
|
+
|
|
41
|
+
return super if o.right.is_a? Arel::Nodes::SelectStatement
|
|
42
|
+
|
|
43
|
+
super(redact_right(o), collector)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def visit_Arel_Nodes_Equality(o, collector)
|
|
47
|
+
return super unless redaction_enabled?
|
|
48
|
+
|
|
49
|
+
super(redact_right(o), collector)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def visit_Arel_Nodes_LessThan(o, collector)
|
|
53
|
+
return super unless redaction_enabled?
|
|
54
|
+
|
|
55
|
+
super(redact_right(o), collector)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def visit_Arel_Nodes_LessThanOrEqual(o, collector)
|
|
59
|
+
return super unless redaction_enabled?
|
|
60
|
+
|
|
61
|
+
super(redact_right(o), collector)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def visit_Arel_Nodes_GreaterThan(o, collector)
|
|
65
|
+
return super unless redaction_enabled?
|
|
66
|
+
|
|
67
|
+
super(redact_right(o), collector)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def visit_Arel_Nodes_GreaterThanOrEqual(o, collector)
|
|
71
|
+
return super unless redaction_enabled?
|
|
72
|
+
|
|
73
|
+
super(redact_right(o), collector)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def visit_Arel_Nodes_NamedFunction(o, collector)
|
|
77
|
+
return super unless redaction_enabled?
|
|
78
|
+
|
|
79
|
+
redacted_o = Arel::Nodes::NamedFunction.new(o.name, o.expressions.dup)
|
|
80
|
+
|
|
81
|
+
case redacted_o.name
|
|
82
|
+
when 'startsWith'
|
|
83
|
+
redacted_o.expressions[1] = Arel.sql(bind_manager.next_bind_str)
|
|
84
|
+
else
|
|
85
|
+
redacted_o.expressions = redacted_o.expressions.map do
|
|
86
|
+
Arel.sql(bind_manager.next_bind_str)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
super(redacted_o, collector)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def visit_Arel_Nodes_Matches(o, collector)
|
|
94
|
+
return super unless redaction_enabled?
|
|
95
|
+
|
|
96
|
+
super(redact_right(o), collector)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def redact_right(o)
|
|
100
|
+
cloned_o = o.clone
|
|
101
|
+
|
|
102
|
+
redacted_right = if o.right.is_a?(Array)
|
|
103
|
+
Array.new(o.right.size) do
|
|
104
|
+
Arel.sql(bind_manager.next_bind_str)
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
Arel.sql(bind_manager.next_bind_str)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
cloned_o.right = redacted_right
|
|
111
|
+
cloned_o
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# rubocop:enable Naming/MethodName
|
|
115
|
+
# rubocop:enable Naming/MethodParameterName
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
data/lib/click_house/client.rb
CHANGED
|
@@ -15,11 +15,11 @@ require_relative "client/quoting"
|
|
|
15
15
|
require_relative "client/arel_engine"
|
|
16
16
|
require_relative "client/query_like"
|
|
17
17
|
require_relative "client/query"
|
|
18
|
-
require_relative "client/
|
|
18
|
+
require_relative "client/arel_visitor"
|
|
19
|
+
require_relative "client/to_redacted_sql_visitor"
|
|
19
20
|
require_relative "client/query_builder"
|
|
20
21
|
require_relative "client/formatter"
|
|
21
22
|
require_relative "client/response"
|
|
22
|
-
require_relative "client/arel_visitor"
|
|
23
23
|
|
|
24
24
|
module ClickHouse
|
|
25
25
|
module Client
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: click_house-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- group::optimize
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -193,8 +193,8 @@ files:
|
|
|
193
193
|
- lib/click_house/client/query_builder.rb
|
|
194
194
|
- lib/click_house/client/query_like.rb
|
|
195
195
|
- lib/click_house/client/quoting.rb
|
|
196
|
-
- lib/click_house/client/redactor.rb
|
|
197
196
|
- lib/click_house/client/response.rb
|
|
197
|
+
- lib/click_house/client/to_redacted_sql_visitor.rb
|
|
198
198
|
- lib/click_house/client/version.rb
|
|
199
199
|
homepage: https://gitlab.com/gitlab-org/ruby/gems/clickhouse-client
|
|
200
200
|
licenses:
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module ClickHouse
|
|
4
|
-
module Client
|
|
5
|
-
module Redactor
|
|
6
|
-
class << self
|
|
7
|
-
# Redacts the SQL query represented by the query builder.
|
|
8
|
-
#
|
|
9
|
-
# @param query_builder [::ClickHouse::Querybuilder] The query builder object to be redacted.
|
|
10
|
-
# @return [String] The redacted SQL query as a string.
|
|
11
|
-
# @raise [ArgumentError] when the condition in the query is of an unsupported type.
|
|
12
|
-
#
|
|
13
|
-
# Example:
|
|
14
|
-
# query_builder = ClickHouse::QueryBuilder.new('users').where(name: 'John Doe')
|
|
15
|
-
# redacted_query = ClickHouse::Redactor.redact(query_builder)
|
|
16
|
-
# # The redacted_query will contain the SQL query with values replaced by placeholders.
|
|
17
|
-
# output: "SELECT * FROM \"users\" WHERE \"users\".\"name\" = $1"
|
|
18
|
-
def redact(query_builder, bind_manager = ClickHouse::Client::BindIndexManager.new)
|
|
19
|
-
redacted_constraints = query_builder.manager.constraints.map do |constraint|
|
|
20
|
-
redact_constraint(constraint, bind_manager)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
cloned_query_builder = query_builder.clone
|
|
24
|
-
|
|
25
|
-
cloned_query_builder.manager.constraints.clear
|
|
26
|
-
redacted_constraints.each do |constraint|
|
|
27
|
-
cloned_query_builder.manager.where(constraint)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
cloned_query_builder.to_sql
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def redact_constraint(constraint, bind_manager)
|
|
36
|
-
case constraint
|
|
37
|
-
when Arel::Nodes::In
|
|
38
|
-
if constraint.right.is_a? Arel::Nodes::SelectStatement
|
|
39
|
-
constraint.left.in(redact_select_statement(constraint.right, bind_manager))
|
|
40
|
-
else
|
|
41
|
-
constraint.left.in(Array.new(constraint.right.size) { Arel.sql(bind_manager.next_bind_str) })
|
|
42
|
-
end
|
|
43
|
-
when Arel::Nodes::Equality
|
|
44
|
-
constraint.left.eq(Arel.sql(bind_manager.next_bind_str))
|
|
45
|
-
when Arel::Nodes::LessThan
|
|
46
|
-
constraint.left.lt(Arel.sql(bind_manager.next_bind_str))
|
|
47
|
-
when Arel::Nodes::LessThanOrEqual
|
|
48
|
-
constraint.left.lteq(Arel.sql(bind_manager.next_bind_str))
|
|
49
|
-
when Arel::Nodes::GreaterThan
|
|
50
|
-
constraint.left.gt(Arel.sql(bind_manager.next_bind_str))
|
|
51
|
-
when Arel::Nodes::GreaterThanOrEqual
|
|
52
|
-
constraint.left.gteq(Arel.sql(bind_manager.next_bind_str))
|
|
53
|
-
when Arel::Nodes::NamedFunction
|
|
54
|
-
redact_named_function(constraint, bind_manager)
|
|
55
|
-
else
|
|
56
|
-
raise ArgumentError, "Unsupported Arel node type for Redactor: #{constraint.class}"
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def redact_named_function(constraint, bind_manager)
|
|
61
|
-
redacted_constraint =
|
|
62
|
-
Arel::Nodes::NamedFunction.new(constraint.name, constraint.expressions.dup)
|
|
63
|
-
|
|
64
|
-
case redacted_constraint.name
|
|
65
|
-
when 'startsWith'
|
|
66
|
-
redacted_constraint.expressions[1] = Arel.sql(bind_manager.next_bind_str)
|
|
67
|
-
else
|
|
68
|
-
redacted_constraint.expressions = redacted_constraint.expressions.map do
|
|
69
|
-
Arel.sql(bind_manager.next_bind_str)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
redacted_constraint
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def redact_select_statement(select_statement, bind_manager)
|
|
77
|
-
cloned_statement = select_statement.clone
|
|
78
|
-
cloned_statement.cores.map! do |select_core|
|
|
79
|
-
select_core.wheres = select_core.wheres.map do |where|
|
|
80
|
-
redact_constraint(where, bind_manager)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
select_core
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
cloned_statement
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|