click_house-client 0.5.1 → 0.7.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/Gemfile.lock +2 -2
- data/lib/click_house/client/arel_visitor.rb +34 -0
- data/lib/click_house/client/query_builder.rb +47 -14
- data/lib/click_house/client/version.rb +1 -1
- data/lib/click_house/client.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9934204626e5719062113ca9663b762a387b91112a39bfe78aa6ac92f5741d6
|
4
|
+
data.tar.gz: 574ea9046e7cd316802871c6dc86152022092b4d0bea14c1d10943dec3cf6748
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ace70ea9c9575040206ac917acb386b95bb206d79a4e270f558b2b189ed5a11add58fd79e8b821538d6042ebd9d189a7552472b1036bd4191705a5d8504788e
|
7
|
+
data.tar.gz: 2b962b32106e75a1ed3384703907558de78d97356a88d9903cc3b427a43c4158415a28810fd10d7d28ad0fa9c2999421c7a7b7d925e7b3cb5cc1a50e3ad418b9
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
click_house-client (0.
|
4
|
+
click_house-client (0.7.0)
|
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.
|
139
|
+
click_house-client (0.7.0)
|
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
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ClickHouse
|
4
|
+
module Client
|
5
|
+
class ArelVisitor < Arel::Visitors::ToSql
|
6
|
+
private
|
7
|
+
|
8
|
+
# rubocop:disable Naming/MethodName -- parent method calls in this format
|
9
|
+
def visit_Arel_Nodes_Matches(object, collector)
|
10
|
+
op = object.case_sensitive ? " LIKE " : " ILIKE "
|
11
|
+
collector = infix_value object, collector, op
|
12
|
+
if object.escape
|
13
|
+
collector << " ESCAPE "
|
14
|
+
visit object.escape, collector
|
15
|
+
else
|
16
|
+
collector
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def visit_Arel_Nodes_DoesNotMatch(object, collector)
|
21
|
+
op = object.case_sensitive ? " NOT LIKE " : " NOT ILIKE "
|
22
|
+
collector = infix_value object, collector, op
|
23
|
+
if object.escape
|
24
|
+
collector << " ESCAPE "
|
25
|
+
visit object.escape, collector
|
26
|
+
else
|
27
|
+
collector
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:enable Naming/MethodName
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -21,7 +21,9 @@ module ClickHouse
|
|
21
21
|
Arel::Nodes::Between,
|
22
22
|
Arel::Nodes::And,
|
23
23
|
Arel::Nodes::Or,
|
24
|
-
Arel::Nodes::Grouping
|
24
|
+
Arel::Nodes::Grouping,
|
25
|
+
Arel::Nodes::Matches,
|
26
|
+
Arel::Nodes::DoesNotMatch
|
25
27
|
].freeze
|
26
28
|
|
27
29
|
def initialize(table_name)
|
@@ -54,7 +56,25 @@ module ClickHouse
|
|
54
56
|
validate_constraint_type!(constraints)
|
55
57
|
|
56
58
|
clone.tap do |new_instance|
|
57
|
-
|
59
|
+
apply_constraints(new_instance, constraints, :where)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# The `having` method applies constraints to the HAVING clause, similar to how
|
64
|
+
# `where` applies constraints to the WHERE clause. It supports the same constraint types.
|
65
|
+
# Correct usage:
|
66
|
+
# query.group(:name).having(count: 5).to_sql
|
67
|
+
# "SELECT * FROM \"table\" GROUP BY \"table\".\"name\" HAVING \"table\".\"count\" = 5"
|
68
|
+
#
|
69
|
+
# query.group(:name).having(query.table[:count].gt(10)).to_sql
|
70
|
+
# "SELECT * FROM \"table\" GROUP BY \"table\".\"name\" HAVING \"table\".\"count\" > 10"
|
71
|
+
#
|
72
|
+
# @return [ClickHouse::QueryBuilder] New instance of query builder.
|
73
|
+
def having(constraints)
|
74
|
+
validate_constraint_type!(constraints)
|
75
|
+
|
76
|
+
clone.tap do |new_instance|
|
77
|
+
apply_constraints(new_instance, constraints, :having)
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|
@@ -159,7 +179,7 @@ module ClickHouse
|
|
159
179
|
end
|
160
180
|
|
161
181
|
def to_sql
|
162
|
-
visitor =
|
182
|
+
visitor = ClickHouse::Client::ArelVisitor.new(ClickHouse::Client::ArelEngine.new)
|
163
183
|
visitor.accept(manager.ast, Arel::Collectors::SQLString.new).value
|
164
184
|
end
|
165
185
|
|
@@ -179,32 +199,45 @@ module ClickHouse
|
|
179
199
|
raise ArgumentError, "Unsupported Arel node type for QueryBuilder: #{constraint.class.name}"
|
180
200
|
end
|
181
201
|
|
182
|
-
def
|
202
|
+
def apply_constraints(instance, constraints, clause_type)
|
183
203
|
if constraints.is_a?(Arel::Nodes::Node)
|
184
|
-
instance
|
204
|
+
apply_constraint_node(instance, constraints, clause_type)
|
185
205
|
else
|
186
206
|
constraints.each do |key, value|
|
187
207
|
if value.is_a?(Hash)
|
188
208
|
# Handle nested hash for joined tables
|
189
209
|
join_table = Arel::Table.new(key)
|
190
210
|
value.each do |nested_key, nested_value|
|
191
|
-
|
211
|
+
constraint = build_constraint(join_table, nested_key, nested_value)
|
212
|
+
apply_constraint_node(instance, constraint, clause_type)
|
192
213
|
end
|
193
214
|
else
|
194
|
-
|
215
|
+
constraint = build_constraint(instance.table, key, value)
|
216
|
+
apply_constraint_node(instance, constraint, clause_type)
|
195
217
|
end
|
196
218
|
end
|
197
219
|
end
|
198
220
|
end
|
199
221
|
|
200
|
-
def
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
222
|
+
def apply_constraint_node(instance, constraint, clause_type)
|
223
|
+
case clause_type
|
224
|
+
when :where
|
225
|
+
instance.manager.where(constraint)
|
226
|
+
when :having
|
227
|
+
instance.manager.having(constraint)
|
228
|
+
else
|
229
|
+
raise ArgumentError, "Unsupported clause type: #{clause_type}"
|
230
|
+
end
|
231
|
+
end
|
206
232
|
|
207
|
-
|
233
|
+
def build_constraint(table, key, value)
|
234
|
+
if value.is_a?(Array)
|
235
|
+
table[key].in(value)
|
236
|
+
elsif value.is_a?(ClickHouse::Client::QueryBuilder)
|
237
|
+
table[key].in(value.to_arel)
|
238
|
+
else
|
239
|
+
table[key].eq(value)
|
240
|
+
end
|
208
241
|
end
|
209
242
|
|
210
243
|
def validate_order_direction!(direction)
|
data/lib/click_house/client.rb
CHANGED
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.
|
4
|
+
version: 0.7.0
|
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-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- gemfiles/Gemfile-rails-8.0
|
185
185
|
- lib/click_house/client.rb
|
186
186
|
- lib/click_house/client/arel_engine.rb
|
187
|
+
- lib/click_house/client/arel_visitor.rb
|
187
188
|
- lib/click_house/client/bind_index_manager.rb
|
188
189
|
- lib/click_house/client/configuration.rb
|
189
190
|
- lib/click_house/client/database.rb
|