clickhouse-activerecord 1.6.1 → 1.6.2
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 +4 -0
- data/README.md +8 -0
- data/lib/active_record/connection_adapters/clickhouse/schema_statements.rb +20 -7
- data/lib/active_record/connection_adapters/clickhouse/statement/response_processor.rb +21 -1
- data/lib/active_record/connection_adapters/clickhouse/statement.rb +11 -3
- data/lib/clickhouse-activerecord/minitest.rb +3 -0
- data/lib/clickhouse-activerecord/rspec.rb +4 -2
- data/lib/clickhouse-activerecord/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c1e3e82dce96b76db15803ccee1b33d8808d0c4eb542115a080d8aa3854859a
|
|
4
|
+
data.tar.gz: 1ed698d16beeb439179b7d57139328ab47ffd25598ad5a98b314e0612166b1c2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc3f56f9f381a583a66ed57db6a8a1457868ce29db354302991920721118415b9850ac02ae4fe7f86dccb618971b87a310c50befb8ba84ca0528b463f9e2d736
|
|
7
|
+
data.tar.gz: c1427aa749177c0f6f97ad34db9508dadbef1f22448d83d1466e61428f8f438aab2fe90851d7f95874399d9019f19ed1dfb74bb05a4a86e183f2ad1467b32763
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -235,6 +235,14 @@ Action.with(ActionView.select(Arel.sql('min(date)')) => :min_date).where(Arel.sq
|
|
|
235
235
|
#=> #<ActiveRecord::Relation [#<Action *** >]>
|
|
236
236
|
```
|
|
237
237
|
|
|
238
|
+
### Streaming request
|
|
239
|
+
|
|
240
|
+
```ruby
|
|
241
|
+
path = Action.connection.execute_streaming(Action.where(date: Date.current), format: 'CSVWithNames')
|
|
242
|
+
# Clickhouse Stream (10.3ms) SELECT actions.* FROM actions WHERE actions.date = '2017-11-29'
|
|
243
|
+
file = File.open(path)
|
|
244
|
+
```
|
|
245
|
+
|
|
238
246
|
|
|
239
247
|
### Migration Data Types
|
|
240
248
|
|
|
@@ -53,6 +53,18 @@ module ActiveRecord
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# @return [ClickhouseActiverecord::StreamResponse]
|
|
57
|
+
def execute_streaming(sql, name = nil, format: @response_format, settings: {})
|
|
58
|
+
with_response_format(format) do
|
|
59
|
+
log(sql, [adapter_name, 'Stream', name].compact.join(' ')) do
|
|
60
|
+
statement = Statement.new(sql, format: @response_format)
|
|
61
|
+
request(statement, settings: settings) do |response|
|
|
62
|
+
return statement.streaming_response(response)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
56
68
|
def exec_insert(sql, name = nil, _binds = [], _pk = nil, _sequence_name = nil, returning: nil)
|
|
57
69
|
new_sql = sql.sub(/ (DEFAULT )?VALUES/, " VALUES")
|
|
58
70
|
with_response_format(nil) { execute(new_sql, name) }
|
|
@@ -268,8 +280,8 @@ module ActiveRecord
|
|
|
268
280
|
|
|
269
281
|
def raw_execute(sql, settings: {}, except_params: [])
|
|
270
282
|
statement = Statement.new(sql, format: @response_format)
|
|
271
|
-
|
|
272
|
-
statement.processed_response
|
|
283
|
+
response = request(statement, settings: settings, except_params: except_params)
|
|
284
|
+
statement.processed_response(response)
|
|
273
285
|
end
|
|
274
286
|
|
|
275
287
|
# Make HTTP request to ClickHouse server
|
|
@@ -277,12 +289,13 @@ module ActiveRecord
|
|
|
277
289
|
# @param [Hash] settings
|
|
278
290
|
# @param [Array] except_params
|
|
279
291
|
# @return [Net::HTTPResponse]
|
|
280
|
-
def request(statement, settings: {}, except_params: [])
|
|
292
|
+
def request(statement, settings: {}, except_params: [], &block)
|
|
281
293
|
@lock.synchronize do
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
294
|
+
req = Net::HTTP::Post.new("/?#{settings_params(settings, except: except_params)}", {
|
|
295
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
296
|
+
'User-Agent' => ClickhouseAdapter::USER_AGENT,
|
|
297
|
+
})
|
|
298
|
+
@connection.request(req, statement.formatted_sql, &block)
|
|
286
299
|
end
|
|
287
300
|
end
|
|
288
301
|
|
|
@@ -8,14 +8,18 @@ module ActiveRecord
|
|
|
8
8
|
|
|
9
9
|
DB_EXCEPTION_REGEXP = /\ACode:\s+\d+\.\s+DB::Exception:/.freeze
|
|
10
10
|
|
|
11
|
+
# @param [Net::HTTPResponse] raw_response
|
|
12
|
+
# @param [String, nil] format
|
|
13
|
+
# @param [String] sql
|
|
11
14
|
def initialize(raw_response, format, sql)
|
|
12
15
|
@raw_response = raw_response
|
|
13
|
-
@body = raw_response.body
|
|
14
16
|
@format = format
|
|
15
17
|
@sql = sql
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
# @return [String, Hash, Array, nil]
|
|
18
21
|
def process
|
|
22
|
+
@body = @raw_response.body
|
|
19
23
|
if success?
|
|
20
24
|
process_successful_response
|
|
21
25
|
else
|
|
@@ -25,12 +29,28 @@ module ActiveRecord
|
|
|
25
29
|
@body
|
|
26
30
|
end
|
|
27
31
|
|
|
32
|
+
# @return [String, nil]
|
|
33
|
+
def streaming_process
|
|
34
|
+
file = Tempfile.new('clickhouse-activerecord', binmode: true)
|
|
35
|
+
if success?
|
|
36
|
+
@raw_response.read_body do |chunk|
|
|
37
|
+
file.write(chunk)
|
|
38
|
+
end
|
|
39
|
+
file.close
|
|
40
|
+
file.path
|
|
41
|
+
else
|
|
42
|
+
@body = @raw_response.body
|
|
43
|
+
raise_database_error!
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
28
47
|
private
|
|
29
48
|
|
|
30
49
|
def success?
|
|
31
50
|
@raw_response.code.to_i == 200
|
|
32
51
|
end
|
|
33
52
|
|
|
53
|
+
# @return [String, Hash, Array]
|
|
34
54
|
def process_successful_response
|
|
35
55
|
raise_generic!(@sql) if @body.include?('DB::Exception') && @body.match?(DB_EXCEPTION_REGEXP)
|
|
36
56
|
|
|
@@ -9,19 +9,27 @@ module ActiveRecord
|
|
|
9
9
|
class Statement
|
|
10
10
|
|
|
11
11
|
attr_reader :format
|
|
12
|
-
attr_writer :response
|
|
13
12
|
|
|
14
13
|
def initialize(sql, format:)
|
|
15
14
|
@sql = sql
|
|
16
15
|
@format = format
|
|
17
16
|
end
|
|
18
17
|
|
|
18
|
+
# @return [String]
|
|
19
19
|
def formatted_sql
|
|
20
20
|
@formatted_sql ||= FormatManager.new(@sql, format: @format).apply
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
# @param [Net::HTTPResponse] response
|
|
24
|
+
# @return [String, Hash, Array, nil]
|
|
25
|
+
def processed_response(response)
|
|
26
|
+
ResponseProcessor.new(response, @format, @sql).process
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param [Net::HTTPResponse] response
|
|
30
|
+
# @return [String, nil]
|
|
31
|
+
def streaming_response(response)
|
|
32
|
+
ResponseProcessor.new(response, @format, @sql).streaming_process
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
end
|
|
@@ -4,10 +4,13 @@ module ClickhouseActiverecord
|
|
|
4
4
|
module TestHelper
|
|
5
5
|
def before_setup
|
|
6
6
|
super
|
|
7
|
+
original_connection_config = ActiveRecord::Base.connection_db_config
|
|
7
8
|
ActiveRecord::Base.configurations.configurations.select { |x| x.env_name == Rails.env && x.adapter == 'clickhouse' }.each do |config|
|
|
8
9
|
ActiveRecord::Base.establish_connection(config)
|
|
9
10
|
ActiveRecord::Base.connection.truncate_tables(*ActiveRecord::Base.connection.tables)
|
|
10
11
|
end
|
|
12
|
+
ensure
|
|
13
|
+
ActiveRecord::Base.establish_connection(original_connection_config) if original_connection_config
|
|
11
14
|
end
|
|
12
15
|
end
|
|
13
16
|
end
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
RSpec.configure do |config|
|
|
4
4
|
config.before do
|
|
5
|
-
ActiveRecord::Base.
|
|
6
|
-
|
|
5
|
+
original_connection_config = ActiveRecord::Base.connection_db_config
|
|
6
|
+
ActiveRecord::Base.configurations.configurations.select { |x| x.env_name == Rails.env && x.adapter == 'clickhouse' }.each do |db_config|
|
|
7
|
+
ActiveRecord::Base.establish_connection(db_config)
|
|
7
8
|
ActiveRecord::Base.connection.truncate_tables(*ActiveRecord::Base.connection.tables)
|
|
8
9
|
end
|
|
10
|
+
ActiveRecord::Base.establish_connection(original_connection_config)
|
|
9
11
|
end
|
|
10
12
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: clickhouse-activerecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.6.
|
|
4
|
+
version: 1.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sergey Odintsov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|