clickhouse-native 0.10.0 → 0.11.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 984a63d34de19388f777cfe71ecd0a844d22f0b67b89e9fddfe07c5c0ac1cc05
|
|
4
|
+
data.tar.gz: 78f829e40f715aef0264e1419cb9b06b97faab1ac38f33329c5da6ada1dd251b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c579da78d2185108712c92e902217c2e508655533c2e78efc7e36ae358a826f809f41d884684b8fcb0e1b36749bc80be5f23b76c85ebf081423adb615d73928b
|
|
7
|
+
data.tar.gz: 93259646a6f150ed271202e3eaca075e0d1cf8d707aed5ac2ac9b530061de47cf1a65082289718857b367dd5b8d764c73cf270c34d080018ce8caac540d8bab6
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
#include <clickhouse/exceptions.h>
|
|
18
18
|
#include <clickhouse/types/types.h>
|
|
19
19
|
|
|
20
|
+
#include <chrono>
|
|
20
21
|
#include <cstdint>
|
|
21
22
|
#include <exception>
|
|
22
23
|
#include <memory>
|
|
23
24
|
#include <string>
|
|
24
25
|
#include <system_error>
|
|
26
|
+
#include <utility>
|
|
25
27
|
#include <vector>
|
|
26
28
|
|
|
27
29
|
using namespace clickhouse;
|
|
@@ -666,6 +668,11 @@ static void append_value(const ColumnRef& col, VALUE value) {
|
|
|
666
668
|
|
|
667
669
|
struct CHClient {
|
|
668
670
|
std::unique_ptr<Client> client;
|
|
671
|
+
// Session settings applied to *every* query as per-query settings, rather
|
|
672
|
+
// than a one-time session `SET`. Per-query settings ride each query packet,
|
|
673
|
+
// so they survive a transparent ping_before_query reconnect (a fresh socket
|
|
674
|
+
// would otherwise lose a session-level SET and fall back to server defaults).
|
|
675
|
+
std::vector<std::pair<std::string, std::string>> default_settings;
|
|
669
676
|
};
|
|
670
677
|
|
|
671
678
|
static void ch_client_free(void* p) {
|
|
@@ -707,6 +714,18 @@ static uint16_t kwarg_uint16(VALUE kwargs, const char* key, uint16_t fallback) {
|
|
|
707
714
|
return static_cast<uint16_t>(NUM2UINT(v));
|
|
708
715
|
}
|
|
709
716
|
|
|
717
|
+
static bool kwarg_bool(VALUE kwargs, const char* key, bool fallback) {
|
|
718
|
+
VALUE v = rb_hash_lookup2(kwargs, ID2SYM(rb_intern(key)), Qundef);
|
|
719
|
+
if (v == Qundef) return fallback;
|
|
720
|
+
return RTEST(v);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
static unsigned int kwarg_uint(VALUE kwargs, const char* key, unsigned int fallback) {
|
|
724
|
+
VALUE v = rb_hash_lookup2(kwargs, ID2SYM(rb_intern(key)), Qundef);
|
|
725
|
+
if (v == Qundef || NIL_P(v)) return fallback;
|
|
726
|
+
return NUM2UINT(v);
|
|
727
|
+
}
|
|
728
|
+
|
|
710
729
|
static CompressionMethod kwarg_compression(VALUE kwargs) {
|
|
711
730
|
VALUE v = rb_hash_lookup2(kwargs, ID2SYM(rb_intern("compression")), Qundef);
|
|
712
731
|
if (v == Qundef || NIL_P(v)) return CompressionMethod::None;
|
|
@@ -742,6 +761,16 @@ static int apply_settings_cb(VALUE key, VALUE val, VALUE arg) {
|
|
|
742
761
|
return ST_CONTINUE;
|
|
743
762
|
}
|
|
744
763
|
|
|
764
|
+
// Collect a `settings:` Hash into a client's default_settings vector at
|
|
765
|
+
// construction. Values are stringified the same way per-query settings are.
|
|
766
|
+
static int collect_setting_cb(VALUE key, VALUE val, VALUE arg) {
|
|
767
|
+
auto* vec = reinterpret_cast<std::vector<std::pair<std::string, std::string>>*>(arg);
|
|
768
|
+
VALUE k = SYMBOL_P(key) ? rb_sym2str(key) : key;
|
|
769
|
+
StringValue(k);
|
|
770
|
+
vec->emplace_back(std::string(RSTRING_PTR(k), RSTRING_LEN(k)), stringify_setting_value(val));
|
|
771
|
+
return ST_CONTINUE;
|
|
772
|
+
}
|
|
773
|
+
|
|
745
774
|
// Read a `settings:` Hash out of the parsed kwargs and stamp each entry
|
|
746
775
|
// onto `q` as a per-query setting. No-op if kwargs is nil or settings is
|
|
747
776
|
// missing/empty. Raises TypeError if settings is not a Hash.
|
|
@@ -765,6 +794,16 @@ static void apply_read_settings(Query& q, VALUE kwargs) {
|
|
|
765
794
|
apply_settings(q, kwargs);
|
|
766
795
|
}
|
|
767
796
|
|
|
797
|
+
// Stamp the client's construction-time `settings:` onto `q`. Marked important
|
|
798
|
+
// (flag 1) so an unknown setting name errors — matching the old session `SET`,
|
|
799
|
+
// which failed loudly instead of silently ignoring a typo'd setting. Applied
|
|
800
|
+
// before per-call settings so an explicit `settings:` on the call still wins.
|
|
801
|
+
static void apply_default_settings(Query& q, CHClient* c) {
|
|
802
|
+
for (const auto& kv : c->default_settings) {
|
|
803
|
+
q.SetSetting(kv.first, QuerySettingsField{kv.second, 1});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
768
807
|
// Client.new(host:, port:, database:, user:, password:)
|
|
769
808
|
static VALUE ch_client_initialize(int argc, VALUE* argv, VALUE self) {
|
|
770
809
|
VALUE kwargs = Qnil;
|
|
@@ -778,12 +817,35 @@ static VALUE ch_client_initialize(int argc, VALUE* argv, VALUE self) {
|
|
|
778
817
|
std::string password = kwarg_str(kwargs, "password", "");
|
|
779
818
|
CompressionMethod compression = kwarg_compression(kwargs);
|
|
780
819
|
|
|
820
|
+
// Connection-resilience defaults. Long-lived pooled connections get
|
|
821
|
+
// silently closed by the server (idle_connection_timeout) or an LB, so
|
|
822
|
+
// the next use of a checked-out client would otherwise hit recv()==0 and
|
|
823
|
+
// raise ConnectionError("closed: ..."). ping_before_query makes the driver
|
|
824
|
+
// ping first and transparently reconnect on a dead socket; tcp_keepalive
|
|
825
|
+
// keeps idle sockets healthy at the OS level. retry_timeout is the backoff
|
|
826
|
+
// before each reconnect attempt — kept low (1s) since a pooled reconnect
|
|
827
|
+
// to a live server should be quick and we don't want to stall queries.
|
|
828
|
+
bool ping_before_query = kwarg_bool(kwargs, "ping_before_query", true);
|
|
829
|
+
bool tcp_keepalive = kwarg_bool(kwargs, "tcp_keepalive", true);
|
|
830
|
+
unsigned int retry_timeout = kwarg_uint(kwargs, "retry_timeout", 1);
|
|
831
|
+
|
|
781
832
|
CHClient* c = as_client(self);
|
|
833
|
+
|
|
834
|
+
VALUE settings = rb_hash_lookup2(kwargs, ID2SYM(rb_intern("settings")), Qnil);
|
|
835
|
+
if (!NIL_P(settings)) {
|
|
836
|
+
Check_Type(settings, T_HASH);
|
|
837
|
+
rb_hash_foreach(settings, collect_setting_cb,
|
|
838
|
+
reinterpret_cast<VALUE>(&c->default_settings));
|
|
839
|
+
}
|
|
840
|
+
|
|
782
841
|
try {
|
|
783
842
|
ClientOptions opts;
|
|
784
843
|
opts.SetHost(host).SetPort(port)
|
|
785
844
|
.SetDefaultDatabase(database).SetUser(user).SetPassword(password)
|
|
786
|
-
.SetCompressionMethod(compression)
|
|
845
|
+
.SetCompressionMethod(compression)
|
|
846
|
+
.SetPingBeforeQuery(ping_before_query)
|
|
847
|
+
.TcpKeepAlive(tcp_keepalive)
|
|
848
|
+
.SetRetryTimeout(std::chrono::seconds(retry_timeout));
|
|
787
849
|
c->client = std::make_unique<Client>(opts);
|
|
788
850
|
} catch (const std::exception& e) {
|
|
789
851
|
raise_mapped_ex(e);
|
|
@@ -792,6 +854,9 @@ static VALUE ch_client_initialize(int argc, VALUE* argv, VALUE self) {
|
|
|
792
854
|
rb_ivar_set(self, rb_intern("@host"), rb_utf8_str_new(host.data(), host.size()));
|
|
793
855
|
rb_ivar_set(self, rb_intern("@port"), UINT2NUM(port));
|
|
794
856
|
rb_ivar_set(self, rb_intern("@database"), rb_utf8_str_new(database.data(), database.size()));
|
|
857
|
+
rb_ivar_set(self, rb_intern("@ping_before_query"), ping_before_query ? Qtrue : Qfalse);
|
|
858
|
+
rb_ivar_set(self, rb_intern("@tcp_keepalive"), tcp_keepalive ? Qtrue : Qfalse);
|
|
859
|
+
rb_ivar_set(self, rb_intern("@retry_timeout"), UINT2NUM(retry_timeout));
|
|
795
860
|
|
|
796
861
|
VALUE logger = rb_hash_lookup2(kwargs, ID2SYM(rb_intern("logger")), Qnil);
|
|
797
862
|
rb_ivar_set(self, rb_intern("@logger"), logger);
|
|
@@ -835,6 +900,7 @@ static VALUE ch_client_execute(int argc, VALUE* argv, VALUE self) {
|
|
|
835
900
|
if (!c->client) rb_raise(err_connection, "clickhouse-native: client is closed");
|
|
836
901
|
|
|
837
902
|
Query q(std::string(RSTRING_PTR(rb_sql), RSTRING_LEN(rb_sql)));
|
|
903
|
+
apply_default_settings(q, c);
|
|
838
904
|
apply_settings(q, kwargs);
|
|
839
905
|
|
|
840
906
|
ExecuteNoGVL args{c->client.get(), &q, nullptr};
|
|
@@ -866,6 +932,7 @@ static VALUE ch_client_query(int argc, VALUE* argv, VALUE self) {
|
|
|
866
932
|
try {
|
|
867
933
|
std::vector<ID> col_ids;
|
|
868
934
|
Query q(std::string(RSTRING_PTR(rb_sql), RSTRING_LEN(rb_sql)));
|
|
935
|
+
apply_default_settings(q, c);
|
|
869
936
|
apply_read_settings(q, kwargs);
|
|
870
937
|
q.OnData([&](const Block& block) {
|
|
871
938
|
size_t ncols = block.GetColumnCount();
|
|
@@ -911,6 +978,7 @@ static VALUE ch_client_query_value(int argc, VALUE* argv, VALUE self) {
|
|
|
911
978
|
VALUE out = Qnil;
|
|
912
979
|
bool seen = false;
|
|
913
980
|
Query q(std::string(RSTRING_PTR(rb_sql), RSTRING_LEN(rb_sql)));
|
|
981
|
+
apply_default_settings(q, c);
|
|
914
982
|
apply_read_settings(q, kwargs);
|
|
915
983
|
q.OnData([&](const Block& block) {
|
|
916
984
|
if (seen) return;
|
|
@@ -936,6 +1004,7 @@ struct InsertNoGVL {
|
|
|
936
1004
|
Client* client;
|
|
937
1005
|
const std::string* table;
|
|
938
1006
|
const Block* block;
|
|
1007
|
+
const std::vector<std::pair<std::string, std::string>>* settings;
|
|
939
1008
|
std::exception_ptr err;
|
|
940
1009
|
};
|
|
941
1010
|
} // namespace
|
|
@@ -943,7 +1012,7 @@ struct InsertNoGVL {
|
|
|
943
1012
|
static void* insert_no_gvl(void* data) {
|
|
944
1013
|
auto* a = static_cast<InsertNoGVL*>(data);
|
|
945
1014
|
try {
|
|
946
|
-
a->client->Insert(*a->table, *a->block);
|
|
1015
|
+
a->client->Insert(*a->table, *a->block, *a->settings);
|
|
947
1016
|
} catch (...) {
|
|
948
1017
|
a->err = std::current_exception();
|
|
949
1018
|
}
|
|
@@ -1009,7 +1078,7 @@ static VALUE ch_client_insert_block(VALUE self, VALUE rb_table, VALUE rb_columns
|
|
|
1009
1078
|
block.AppendColumn(names[i], cols[i]);
|
|
1010
1079
|
}
|
|
1011
1080
|
|
|
1012
|
-
InsertNoGVL args{c->client.get(), &table, &block, nullptr};
|
|
1081
|
+
InsertNoGVL args{c->client.get(), &table, &block, &c->default_settings, nullptr};
|
|
1013
1082
|
rb_thread_call_without_gvl(insert_no_gvl, &args, insert_unblock, &args);
|
|
1014
1083
|
if (args.err) {
|
|
1015
1084
|
try { c->client->ResetConnection(); } catch (...) {}
|
|
@@ -1110,6 +1179,7 @@ static VALUE ch_client_query_each(int argc, VALUE* argv, VALUE self) {
|
|
|
1110
1179
|
|
|
1111
1180
|
QueryEachState state{rb_block_proc(), {}, 0, false};
|
|
1112
1181
|
Query q(std::string(RSTRING_PTR(rb_sql), RSTRING_LEN(rb_sql)));
|
|
1182
|
+
apply_default_settings(q, c);
|
|
1113
1183
|
apply_read_settings(q, kwargs);
|
|
1114
1184
|
q.OnDataCancelable([&state](const Block& block) -> bool {
|
|
1115
1185
|
if (state.aborted) return false;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
diff --git a/clickhouse/client.cpp b/clickhouse/client.cpp
|
|
2
|
+
index 34a733d..c9732f4 100644
|
|
3
|
+
--- a/clickhouse/client.cpp
|
|
4
|
+
+++ b/clickhouse/client.cpp
|
|
5
|
+
@@ -211,7 +211,8 @@ public:
|
|
6
|
+
|
|
7
|
+
bool IsSelecting() const { return state_ == State::Selecting; }
|
|
8
|
+
|
|
9
|
+
- void Insert(const std::string& table_name, const std::string& query_id, const Block& block);
|
|
10
|
+
+ void Insert(const std::string& table_name, const std::string& query_id, const Block& block,
|
|
11
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings = {});
|
|
12
|
+
|
|
13
|
+
Block BeginInsert(Query query);
|
|
14
|
+
|
|
15
|
+
@@ -485,7 +486,8 @@ std::string NameToQueryString(const std::string &input)
|
|
16
|
+
return output;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
-void Client::Impl::Insert(const std::string& table_name, const std::string& query_id, const Block& block) {
|
|
20
|
+
+void Client::Impl::Insert(const std::string& table_name, const std::string& query_id, const Block& block,
|
|
21
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings) {
|
|
22
|
+
if (state_ == State::Inserting) {
|
|
23
|
+
throw ValidationError("cannot execute query while inserting, use SendInsertData instead");
|
|
24
|
+
}
|
|
25
|
+
@@ -511,6 +513,9 @@ void Client::Impl::Insert(const std::string& table_name, const std::string& quer
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Query query("INSERT INTO " + table_name + " ( " + fields_section.str() + " ) VALUES", query_id);
|
|
29
|
+
+ for (const auto& kv : settings) {
|
|
30
|
+
+ query.SetSetting(kv.first, QuerySettingsField{kv.second, 1});
|
|
31
|
+
+ }
|
|
32
|
+
SendQuery(query);
|
|
33
|
+
|
|
34
|
+
// Wait for a data packet and return
|
|
35
|
+
@@ -1365,12 +1370,14 @@ bool Client::IsSelecting() const
|
|
36
|
+
return impl_->IsSelecting();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
-void Client::Insert(const std::string& table_name, const Block& block) {
|
|
40
|
+
- impl_->Insert(table_name, Query::default_query_id, block);
|
|
41
|
+
+void Client::Insert(const std::string& table_name, const Block& block,
|
|
42
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings) {
|
|
43
|
+
+ impl_->Insert(table_name, Query::default_query_id, block, settings);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
-void Client::Insert(const std::string& table_name, const std::string& query_id, const Block& block) {
|
|
47
|
+
- impl_->Insert(table_name, query_id, block);
|
|
48
|
+
+void Client::Insert(const std::string& table_name, const std::string& query_id, const Block& block,
|
|
49
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings) {
|
|
50
|
+
+ impl_->Insert(table_name, query_id, block, settings);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Block Client::BeginInsert(const std::string& query) {
|
|
54
|
+
diff --git a/clickhouse/client.h b/clickhouse/client.h
|
|
55
|
+
index a55fd74..6c6ff53 100644
|
|
56
|
+
--- a/clickhouse/client.h
|
|
57
|
+
+++ b/clickhouse/client.h
|
|
58
|
+
@@ -23,6 +23,8 @@
|
|
59
|
+
#include "columns/bool.h"
|
|
60
|
+
|
|
61
|
+
#include <chrono>
|
|
62
|
+
+#include <utility>
|
|
63
|
+
+#include <vector>
|
|
64
|
+
#include <cstdint>
|
|
65
|
+
#include <memory>
|
|
66
|
+
#include <ostream>
|
|
67
|
+
@@ -298,8 +300,13 @@ public:
|
|
68
|
+
bool IsSelecting() const;
|
|
69
|
+
|
|
70
|
+
/// Intends for insert block of data into a table \p table_name.
|
|
71
|
+
- void Insert(const std::string& table_name, const Block& block);
|
|
72
|
+
- void Insert(const std::string& table_name, const std::string& query_id, const Block& block);
|
|
73
|
+
+ /// \p settings are applied to the generated INSERT query as per-query
|
|
74
|
+
+ /// settings (patched-in for clickhouse-native: lets a pooled client carry
|
|
75
|
+
+ /// its session settings into inserts without a session-level SET).
|
|
76
|
+
+ void Insert(const std::string& table_name, const Block& block,
|
|
77
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings = {});
|
|
78
|
+
+ void Insert(const std::string& table_name, const std::string& query_id, const Block& block,
|
|
79
|
+
+ const std::vector<std::pair<std::string, std::string>>& settings = {});
|
|
80
|
+
|
|
81
|
+
/// Start an \p INSERT statement, insert batches of data, then finish the insert.
|
|
82
|
+
Block BeginInsert(const std::string& query);
|
|
@@ -8,16 +8,17 @@ module ClickhouseNative
|
|
|
8
8
|
|
|
9
9
|
def initialize(host:, port:, database: "default", user: "default", password: "",
|
|
10
10
|
compression: :none, logger: nil, settings: {},
|
|
11
|
-
pool_size: 5, pool_timeout: 5
|
|
11
|
+
pool_size: 5, pool_timeout: 5,
|
|
12
|
+
ping_before_query: true, tcp_keepalive: true, retry_timeout: 1)
|
|
12
13
|
@host = host
|
|
13
14
|
@port = port
|
|
14
15
|
@database = database
|
|
15
|
-
client_kwargs = {
|
|
16
|
-
|
|
16
|
+
client_kwargs = {
|
|
17
|
+
host:, port:, database:, user:, password:, compression:, logger:, settings:,
|
|
18
|
+
ping_before_query:, tcp_keepalive:, retry_timeout:
|
|
19
|
+
}
|
|
17
20
|
@pool = ConnectionPool.new(size: pool_size, timeout: pool_timeout) do
|
|
18
|
-
|
|
19
|
-
client.execute(@set_sql) if @set_sql
|
|
20
|
-
client
|
|
21
|
+
Client.new(**client_kwargs)
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -25,18 +26,24 @@ module ClickhouseNative
|
|
|
25
26
|
# path leaves the socket in an unknown state. The C++ binding issues
|
|
26
27
|
# ResetConnection, but a subsequent send can still surface buffered
|
|
27
28
|
# protocol errors from the prior aborted operation — those get
|
|
28
|
-
# attributed to whatever SQL we tried next
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# debugging that.
|
|
29
|
+
# attributed to whatever SQL we tried next, producing misleading log
|
|
30
|
+
# lines and re-raises in unrelated code. A fresh socket + handshake is
|
|
31
|
+
# cheap relative to debugging that.
|
|
32
32
|
#
|
|
33
33
|
# ConnectionError gets one automatic retry: pooled connections that
|
|
34
34
|
# have been idle long enough for the server / an LB to FIN them
|
|
35
|
-
# surface as "closed" on the very next recv (errno
|
|
36
|
-
# "closed: Success"
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
35
|
+
# surface as "closed" on the very next recv (errno is whatever stale
|
|
36
|
+
# value was left in the thread — "closed: Success", "closed: Operation
|
|
37
|
+
# now in progress", etc. all mean the same recv()==0). Discarding and
|
|
38
|
+
# re-checking out lands a fresh socket and the operation succeeds. The
|
|
39
|
+
# retry only triggers when the dead-connection error fired before any
|
|
40
|
+
# data was sent, so write operations don't risk double-execution.
|
|
41
|
+
#
|
|
42
|
+
# This is the backstop: with ping_before_query on (the default) the
|
|
43
|
+
# driver already pings and transparently reconnects a dead socket
|
|
44
|
+
# before running the query, so most stale connections never surface as
|
|
45
|
+
# a ConnectionError here at all. This retry still covers the residual
|
|
46
|
+
# race (socket dies between the ping and the query).
|
|
40
47
|
def with
|
|
41
48
|
attempts = 0
|
|
42
49
|
begin
|
|
@@ -84,21 +91,5 @@ module ClickhouseNative
|
|
|
84
91
|
def describe_table(table, db_name: nil)
|
|
85
92
|
with { |c| c.describe_table(table, db_name:) }
|
|
86
93
|
end
|
|
87
|
-
|
|
88
|
-
private
|
|
89
|
-
|
|
90
|
-
# Render a `SET key1 = val1, key2 = val2` statement once at pool setup
|
|
91
|
-
# so every checked-out connection starts with the same session
|
|
92
|
-
# settings. Matches how the HTTP driver injected global_params per
|
|
93
|
-
# request. Values: Integer / Float render bare; anything else is
|
|
94
|
-
# quoted as a SQL string literal.
|
|
95
|
-
def settings_sql(settings)
|
|
96
|
-
return nil if settings.nil? || settings.empty?
|
|
97
|
-
parts = settings.map do |k, v|
|
|
98
|
-
literal = v.is_a?(Numeric) ? v.to_s : "'#{v.to_s.gsub("'", "''")}'"
|
|
99
|
-
"#{k} = #{literal}"
|
|
100
|
-
end
|
|
101
|
-
"SET #{parts.join(', ')}"
|
|
102
|
-
end
|
|
103
94
|
end
|
|
104
95
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: clickhouse-native
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yuri Smirnov
|
|
@@ -35,6 +35,7 @@ files:
|
|
|
35
35
|
- ext/clickhouse_native/client.cpp
|
|
36
36
|
- ext/clickhouse_native/extconf.rb
|
|
37
37
|
- ext/clickhouse_native/patches/0001-preserve-declared-column-type.patch
|
|
38
|
+
- ext/clickhouse_native/patches/0002-carry-settings-into-insert.patch
|
|
38
39
|
- ext/clickhouse_native/vendor/clickhouse-cpp/.clang-format
|
|
39
40
|
- ext/clickhouse_native/vendor/clickhouse-cpp/.git
|
|
40
41
|
- ext/clickhouse_native/vendor/clickhouse-cpp/.gitattributes
|
|
@@ -323,7 +324,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
323
324
|
- !ruby/object:Gem::Version
|
|
324
325
|
version: '0'
|
|
325
326
|
requirements: []
|
|
326
|
-
rubygems_version: 4.0.
|
|
327
|
+
rubygems_version: 4.0.16
|
|
327
328
|
specification_version: 4
|
|
328
329
|
summary: ClickHouse Ruby driver over the native TCP protocol
|
|
329
330
|
test_files: []
|