blob: 9b8e2bc90d987cfcd62c87e1f84f998c4356d0d1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# frozen_string_literal: true
# rubocop:disable CodeReuse/ActiveRecord
module ClickHouse
module Redactor
# Redacts the SQL query represented by the query builder.
#
# @param query_builder [::ClickHouse::Querybuilder] The query builder object to be redacted.
# @return [String] The redacted SQL query as a string.
# @raise [ArgumentError] when the condition in the query is of an unsupported type.
#
# Example:
# query_builder = ClickHouse::QueryBuilder.new('users').where(name: 'John Doe')
# redacted_query = ClickHouse::Redactor.redact(query_builder)
# # The redacted_query will contain the SQL query with values replaced by placeholders.
# output: "SELECT * FROM \"users\" WHERE \"users\".\"name\" = $1"
def self.redact(query_builder)
cloned_query_builder = query_builder.clone
bind_manager = ::ClickHouse::BindIndexManager.new
cloned_query_builder.conditions = cloned_query_builder.conditions.map do |condition|
redact_condition(condition, bind_manager)
end
cloned_query_builder.manager.constraints.clear
cloned_query_builder.conditions.each do |condition|
cloned_query_builder.manager.where(condition)
end
cloned_query_builder.manager.to_sql
end
def self.redact_condition(condition, bind_manager)
case condition
when Arel::Nodes::In
condition.left.in(Array.new(condition.right.size) { Arel.sql(bind_manager.next_bind_str) })
when Arel::Nodes::Equality
condition.left.eq(Arel.sql(bind_manager.next_bind_str))
when Arel::Nodes::LessThan
condition.left.lt(Arel.sql(bind_manager.next_bind_str))
when Arel::Nodes::LessThanOrEqual
condition.left.lteq(Arel.sql(bind_manager.next_bind_str))
when Arel::Nodes::GreaterThan
condition.left.gt(Arel.sql(bind_manager.next_bind_str))
when Arel::Nodes::GreaterThanOrEqual
condition.left.gteq(Arel.sql(bind_manager.next_bind_str))
else
raise ArgumentError, "Unsupported Arel node type for Redactor: #{condition.class}"
end
end
end
end
# rubocop:enable CodeReuse/ActiveRecord
|