C++ client for ClickHouse.
- Array(T)
- Date
- DateTime, DateTime64
- DateTime([timezone]), DateTime64(N, [timezone])
- Decimal32, Decimal64, Decimal128
- Enum8, Enum16
- FixedString(N)
- Float32, Float64
- IPv4, IPv6
- Nullable(T)
- String
- LowCardinality(String) or LowCardinality(FixedString(N))
- Tuple
- UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
- Int128
- UUID
- Map
- Point, Ring, Polygon, MultiPolygon
In the most basic case one needs only:
- C++-17 complaint compiler (e.g. Clang-6, GCC-7)
cmake
(3.20 or newer)ninja
Optional dependencies:
- openssl
- liblz4
- libabsl
$ mkdir build .
$ cd build
$ cmake .. [-DBUILD_TESTS=ON]
$ make
Plese refer to the workflows for the reference on dependencies/build options
- https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/linux.yml
- https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/windows_msvc.yml
- https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/windows_mingw.yml
- https://github.com/ClickHouse/clickhouse-cpp/blob/master/.github/workflows/macos.yml
#include <iostream>
#include <clickhouse/client.h>
using namespace clickhouse;
int main()
{
/// Initialize client connection.
Client client(ClientOptions().SetHost("localhost"));
/// Create a table.
client.Execute("CREATE TABLE IF NOT EXISTS default.numbers (id UInt64, name String) ENGINE = Memory");
/// Insert some values.
{
Block block;
auto id = std::make_shared<ColumnUInt64>();
id->Append(1);
id->Append(7);
auto name = std::make_shared<ColumnString>();
name->Append("one");
name->Append("seven");
block.AppendColumn("id" , id);
block.AppendColumn("name", name);
client.Insert("default.numbers", block);
}
/// Select values inserted in the previous step.
client.Select("SELECT id, name FROM default.numbers", [] (const Block& block)
{
for (size_t i = 0; i < block.GetRowCount(); ++i) {
std::cout << block[0]->As<ColumnUInt64>()->At(i) << " "
<< block[1]->As<ColumnString>()->At(i) << "\n";
}
}
);
/// Delete table.
client.Execute("DROP TABLE default.numbers");
return 0;
}
⚠ Please note that Client
instance is NOT thread-safe. I.e. you must create a separate Client
for each thread or utilize some synchronization techniques. ⚠
If you wish to implement some retry logic atop of clickhouse::Client
there are few simple rules to make you life easier:
- If previous attempt threw an exception, then make sure to call
clickhouse::Client::ResetConnection()
before the next try. - For
clickhouse::Client::Insert()
you can reuse a block from previous try, no need to rebuild it from scratch.
See ClickHouse#184 for details.