Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'gems/click_house-client/spec/click_house')
-rw-r--r--gems/click_house-client/spec/click_house/client/bind_index_manager_spec.rb33
-rw-r--r--gems/click_house-client/spec/click_house/client/database_spec.rb1
-rw-r--r--gems/click_house-client/spec/click_house/client/formatter_spec.rb63
-rw-r--r--gems/click_house-client/spec/click_house/client/query_like_spec.rb15
-rw-r--r--gems/click_house-client/spec/click_house/client/query_spec.rb125
-rw-r--r--gems/click_house-client/spec/click_house/client_spec.rb34
6 files changed, 269 insertions, 2 deletions
diff --git a/gems/click_house-client/spec/click_house/client/bind_index_manager_spec.rb b/gems/click_house-client/spec/click_house/client/bind_index_manager_spec.rb
new file mode 100644
index 00000000000..38e0865676a
--- /dev/null
+++ b/gems/click_house-client/spec/click_house/client/bind_index_manager_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClickHouse::Client::BindIndexManager do
+ describe '#next_bind_str' do
+ context 'when initialized without a start index' do
+ let(:bind_manager) { described_class.new }
+
+ it 'starts from index 1 by default' do
+ expect(bind_manager.next_bind_str).to eq('$1')
+ end
+
+ it 'increments the bind string on subsequent calls' do
+ bind_manager.next_bind_str
+ expect(bind_manager.next_bind_str).to eq('$2')
+ end
+ end
+
+ context 'when initialized with a start index' do
+ let(:bind_manager) { described_class.new(2) }
+
+ it 'starts from the given index' do
+ expect(bind_manager.next_bind_str).to eq('$2')
+ end
+
+ it 'increments the bind string on subsequent calls' do
+ bind_manager.next_bind_str
+ expect(bind_manager.next_bind_str).to eq('$3')
+ end
+ end
+ end
+end
diff --git a/gems/click_house-client/spec/click_house/client/database_spec.rb b/gems/click_house-client/spec/click_house/client/database_spec.rb
index a74d4a119a4..fdb4c72c0cb 100644
--- a/gems/click_house-client/spec/click_house/client/database_spec.rb
+++ b/gems/click_house-client/spec/click_house/client/database_spec.rb
@@ -24,7 +24,6 @@ RSpec.describe ClickHouse::Client::Database do
describe '#headers' do
it 'returns the correct headers' do
expect(database.headers).to eq({
- "Content-Encoding" => "gzip",
"X-ClickHouse-Format" => "JSON",
'X-ClickHouse-User' => 'user',
'X-ClickHouse-Key' => 'pass'
diff --git a/gems/click_house-client/spec/click_house/client/formatter_spec.rb b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
new file mode 100644
index 00000000000..0af3aa0bdbc
--- /dev/null
+++ b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClickHouse::Client::Formatter do
+ it 'formats values according to types in metadata' do
+ # this query here is just for documentation purposes, it generates the response below
+ _query = <<~SQL.squish
+ SELECT toUInt64(1) as uint64,
+ toDateTime64('2016-06-15 23:00:00', 6, 'UTC') as datetime64_6,
+ INTERVAL 1 second as interval_second
+ SQL
+
+ response_json = <<~JSON
+{
+ "meta":
+ [
+ {
+ "name": "uint64",
+ "type": "UInt64"
+ },
+ {
+ "name": "datetime64_6",
+ "type": "DateTime64(6, 'UTC')"
+ },
+ {
+ "name": "interval_second",
+ "type": "IntervalSecond"
+ }
+ ],
+
+ "data":
+ [
+ {
+ "uint64": "1",
+ "datetime64_6": "2016-06-15 23:00:00.000000",
+ "interval_second": "1"
+ }
+ ],
+
+ "rows": 1,
+
+ "statistics":
+ {
+ "elapsed": 0.002101,
+ "rows_read": 1,
+ "bytes_read": 1
+ }
+}
+ JSON
+
+ parsed_response = JSON.parse(response_json)
+ formatted_response = described_class.format(parsed_response)
+
+ expect(formatted_response).to(
+ eq(
+ [{ "uint64" => 1,
+ "datetime64_6" => ActiveSupport::TimeZone["UTC"].parse("2016-06-15 23:00:00"),
+ "interval_second" => 1.second }]
+ )
+ )
+ end
+end
diff --git a/gems/click_house-client/spec/click_house/client/query_like_spec.rb b/gems/click_house-client/spec/click_house/client/query_like_spec.rb
new file mode 100644
index 00000000000..8b8426bd5fd
--- /dev/null
+++ b/gems/click_house-client/spec/click_house/client/query_like_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClickHouse::Client::QueryLike do
+ subject(:query) { described_class.new }
+
+ describe '#to_sql' do
+ it { expect { query.to_sql }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#to_redacted_sql' do
+ it { expect { query.to_redacted_sql }.to raise_error(NotImplementedError) }
+ end
+end
diff --git a/gems/click_house-client/spec/click_house/client/query_spec.rb b/gems/click_house-client/spec/click_house/client/query_spec.rb
new file mode 100644
index 00000000000..82733e523b1
--- /dev/null
+++ b/gems/click_house-client/spec/click_house/client/query_spec.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClickHouse::Client::Query do
+ subject(:query) { described_class.new(raw_query: raw_query, placeholders: placeholders) }
+
+ let(:sql) { query.to_sql }
+ let(:redacted_sql) { query.to_redacted_sql }
+
+ context 'when using no placeholders' do
+ let(:raw_query) { 'SELECT * FROM events' }
+ let(:placeholders) { nil }
+
+ it { expect(sql).to eq(raw_query) }
+ it { expect(redacted_sql).to eq(raw_query) }
+
+ context 'when placeholders is an empty hash' do
+ let(:placeholders) { {} }
+
+ it { expect(sql).to eq(raw_query) }
+ it { expect(redacted_sql).to eq(raw_query) }
+ end
+ end
+
+ context 'when placeholders are given' do
+ let(:raw_query) { 'SELECT * FROM events WHERE id = {id:UInt64}' }
+ let(:placeholders) { { id: 1 } }
+
+ it { expect(sql).to eq(raw_query) }
+ it { expect(redacted_sql).to eq('SELECT * FROM events WHERE id = $1') }
+ end
+
+ context 'when multiple placeholders are given' do
+ let(:raw_query) do
+ <<~SQL.squish
+ SELECT *
+ FROM events
+ WHERE
+ id = {id:UInt64} AND
+ title = {some_title:String} AND
+ another_id = {id:UInt64}
+ SQL
+ end
+
+ let(:placeholders) { { id: 1, some_title: "'title'" } }
+
+ it do
+ expect(sql).to eq(raw_query)
+ end
+
+ it do
+ expect(redacted_sql).to eq(
+ <<~SQL.squish
+ SELECT *
+ FROM events
+ WHERE
+ id = $1 AND
+ title = $2 AND
+ another_id = $3
+ SQL
+ )
+ end
+ end
+
+ context 'when dealing with subqueries' do
+ let(:raw_query) { 'SELECT * FROM events WHERE id < {min_id:UInt64} AND id IN ({q:Subquery})' }
+
+ let(:subquery) do
+ described_class.new(raw_query: 'SELECT id FROM events WHERE id > {max_id:UInt64}', placeholders: { max_id: 11 })
+ end
+
+ let(:placeholders) { { min_id: 100, q: subquery } }
+
+ it 'replaces the subquery but preserves the other placeholders' do
+ q = 'SELECT * FROM events WHERE id < {min_id:UInt64} AND id IN (SELECT id FROM events WHERE id > {max_id:UInt64})'
+ expect(sql).to eq(q)
+ end
+
+ it 'replaces the subquery and replaces the placeholders with indexed values' do
+ expect(redacted_sql).to eq('SELECT * FROM events WHERE id < $1 AND id IN (SELECT id FROM events WHERE id > $2)')
+ end
+
+ it 'merges the placeholders' do
+ expect(query.placeholders).to eq({ min_id: 100, max_id: 11 })
+ end
+ end
+
+ describe 'validation' do
+ context 'when SQL string is empty' do
+ let(:raw_query) { '' }
+ let(:placeholders) { {} }
+
+ it 'raises error' do
+ expect { query }.to raise_error(ClickHouse::Client::QueryError, /Empty query string given/)
+ end
+ end
+
+ context 'when SQL string is nil' do
+ let(:raw_query) { nil }
+ let(:placeholders) { {} }
+
+ it 'raises error' do
+ expect { query }.to raise_error(ClickHouse::Client::QueryError, /Empty query string given/)
+ end
+ end
+
+ context 'when same placeholder value does not match' do
+ let(:raw_query) { 'SELECT id FROM events WHERE id = {id:UInt64} AND id IN ({q:Subquery})' }
+
+ let(:subquery) do
+ subquery_string = 'SELECT id FROM events WHERE id = {id:UInt64}'
+ described_class.new(raw_query: subquery_string, placeholders: { id: 10 })
+ end
+
+ let(:placeholders) { { id: 5, q: subquery } }
+
+ it 'raises error' do
+ expect do
+ query.placeholders
+ end.to raise_error(ClickHouse::Client::QueryError, /mismatching values for the 'id' placeholder/)
+ end
+ end
+ end
+end
diff --git a/gems/click_house-client/spec/click_house/client_spec.rb b/gems/click_house-client/spec/click_house/client_spec.rb
index 883199198ba..ab2407a83d7 100644
--- a/gems/click_house-client/spec/click_house/client_spec.rb
+++ b/gems/click_house-client/spec/click_house/client_spec.rb
@@ -30,6 +30,9 @@ RSpec.describe ClickHouse::Client do
let(:configuration) do
ClickHouse::Client::Configuration.new.tap do |config|
+ config.log_proc = ->(query) do
+ { query_string: query.to_sql }
+ end
config.register_database(:test_db, **database_config)
config.http_post_proc = ->(_url, _headers, _query) {
body = File.read(query_result_fixture)
@@ -71,7 +74,7 @@ RSpec.describe ClickHouse::Client do
end
context 'when the DB is not configured' do
- it 'raises erro' do
+ it 'raises error' do
expect do
described_class.select('SELECT * FROM issues', :different_db, configuration)
end.to raise_error(ClickHouse::Client::ConfigurationError, /not configured/)
@@ -94,5 +97,34 @@ RSpec.describe ClickHouse::Client do
end.to raise_error(ClickHouse::Client::DatabaseError, 'some error')
end
end
+
+ describe 'default logging' do
+ let(:fake_logger) { instance_double("Logger", info: 'logged!') }
+ let(:query_string) { 'SELECT * FROM issues' }
+
+ before do
+ configuration.logger = fake_logger
+ end
+
+ shared_examples 'proper logging' do
+ it 'calls the custom logger and log_proc' do
+ expect(fake_logger).to receive(:info).at_least(:once).with({ query_string: query_string })
+
+ described_class.select(query_object, :test_db, configuration)
+ end
+ end
+
+ context 'when query is a string' do # rubocop:disable RSpec/MultipleMemoizedHelpers
+ let(:query_object) { query_string }
+
+ it_behaves_like 'proper logging'
+ end
+
+ context 'when query is a Query object' do # rubocop:disable RSpec/MultipleMemoizedHelpers
+ let(:query_object) { ClickHouse::Client::Query.new(raw_query: query_string) }
+
+ it_behaves_like 'proper logging'
+ end
+ end
end
end