clickhouse-activerecord 1.6.1 → 1.6.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/CHANGELOG.md +8 -0
- data/README.md +8 -0
- data/lib/active_record/connection_adapters/clickhouse/schema_statements.rb +21 -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: 5bfabbcebb77881c7199f5895b1c3e4a7066c2eddaeec138432434f0a754fb70
|
|
4
|
+
data.tar.gz: a17ff604e9b01015f4a100f1e83267aad340c847541f8aeb0467d083afeb789a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 266b0794fe05ec58183b61cb7b7e8cefd99b44ce7fbc8a92810651f897dff514df09b48f16e8d50cdd394d7f00833039094caaf671c7e322a1a3b44c470b05df
|
|
7
|
+
data.tar.gz: afb3f2a22842ea4caef138ab206e73151fe237f89fa136c0fb2f4b1b160ff9e5594b4045224f8ab0c46512e1fe158eaf35cd698a66f4ff9d1542c69baebf9fa8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
### Version 1.6.3 (Feb 04, 2026)
|
|
2
|
+
|
|
3
|
+
* Rename method `execute_streaming` to `execute_to_file`
|
|
4
|
+
|
|
5
|
+
### Version 1.6.2 (Jan 30, 2026)
|
|
6
|
+
|
|
7
|
+
* Add streaming request and save response to tmp file
|
|
8
|
+
|
|
1
9
|
### Version 1.6.1 (Jan 20, 2026)
|
|
2
10
|
|
|
3
11
|
* Fix prepare rake task on ClickHouse 24.6
|
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_to_file(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,19 @@ module ActiveRecord
|
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# Execute an SQL query and save the result to a file in stream mode
|
|
57
|
+
# @return [String]
|
|
58
|
+
def execute_to_file(sql, name = nil, format: @response_format, settings: {})
|
|
59
|
+
with_response_format(format) do
|
|
60
|
+
log(sql, [adapter_name, 'Stream', name].compact.join(' ')) do
|
|
61
|
+
statement = Statement.new(sql, format: @response_format)
|
|
62
|
+
request(statement, settings: settings) do |response|
|
|
63
|
+
return statement.streaming_response(response)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
56
69
|
def exec_insert(sql, name = nil, _binds = [], _pk = nil, _sequence_name = nil, returning: nil)
|
|
57
70
|
new_sql = sql.sub(/ (DEFAULT )?VALUES/, " VALUES")
|
|
58
71
|
with_response_format(nil) { execute(new_sql, name) }
|
|
@@ -268,8 +281,8 @@ module ActiveRecord
|
|
|
268
281
|
|
|
269
282
|
def raw_execute(sql, settings: {}, except_params: [])
|
|
270
283
|
statement = Statement.new(sql, format: @response_format)
|
|
271
|
-
|
|
272
|
-
statement.processed_response
|
|
284
|
+
response = request(statement, settings: settings, except_params: except_params)
|
|
285
|
+
statement.processed_response(response)
|
|
273
286
|
end
|
|
274
287
|
|
|
275
288
|
# Make HTTP request to ClickHouse server
|
|
@@ -277,12 +290,13 @@ module ActiveRecord
|
|
|
277
290
|
# @param [Hash] settings
|
|
278
291
|
# @param [Array] except_params
|
|
279
292
|
# @return [Net::HTTPResponse]
|
|
280
|
-
def request(statement, settings: {}, except_params: [])
|
|
293
|
+
def request(statement, settings: {}, except_params: [], &block)
|
|
281
294
|
@lock.synchronize do
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
295
|
+
req = Net::HTTP::Post.new("/?#{settings_params(settings, except: except_params)}", {
|
|
296
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
|
297
|
+
'User-Agent' => ClickhouseAdapter::USER_AGENT,
|
|
298
|
+
})
|
|
299
|
+
@connection.request(req, statement.formatted_sql, &block)
|
|
286
300
|
end
|
|
287
301
|
end
|
|
288
302
|
|
|
@@ -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.3
|
|
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-
|
|
11
|
+
date: 2026-02-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|