Packages

Elixir client for ClickHouse database via FINE + clickhouse-cpp (native TCP)

Current section

Files

Jump to
natch native clickhouse-cpp ut utils.h
Raw

native/clickhouse-cpp/ut/utils.h

#pragma once
#include <clickhouse/base/platform.h>
#include <clickhouse/base/uuid.h>
#include "clickhouse/columns/itemview.h"
#include "clickhouse/query.h"
#include "utils_meta.h"
#include "utils_comparison.h"
#include <iterator>
#include <optional>
#include <ostream>
#include <ratio>
#include <string_view>
#include <system_error>
#include <type_traits>
#include <vector>
#include <cmath>
#include <time.h>
#include <gtest/gtest.h>
namespace clickhouse {
class Client;
class Block;
class Type;
struct ServerInfo;
struct Profile;
struct QuerySettingsField;
struct Progress;
}
template <typename ResultType = std::string>
auto getEnvOrDefault(const std::string& env, const char * default_val) {
const char* v = std::getenv(env.c_str());
if (!v && !default_val)
throw std::runtime_error("Environment var '" + env + "' is not set.");
const std::string value = v ? v : default_val;
if constexpr (std::is_same_v<ResultType, std::string>) {
return value;
} else if constexpr (std::is_integral_v<ResultType>) {
// since std::from_chars is not available on GCC-7 on linux
if constexpr (std::is_signed_v<ResultType>) {
if constexpr (sizeof(ResultType) <= sizeof(int))
return std::stoi(value);
else if constexpr (sizeof(ResultType) <= sizeof(long))
return std::stol(value);
else if constexpr (sizeof(ResultType) <= sizeof(long long))
return std::stoll(value);
} else if constexpr (std::is_unsigned_v<ResultType>) {
if constexpr (sizeof(ResultType) <= sizeof(unsigned long))
// For cases when ResultType is unsigned int.
return static_cast<ResultType>(std::stoul(value));
else if constexpr (sizeof(ResultType) <= sizeof(unsigned long long))
return std::stoull(value);
}
}
}
template <typename R>
inline const char * getPrefix() {
const char * prefix = "?";
if constexpr (std::ratio_equal_v<R, std::nano>) {
prefix = "n";
} else if constexpr (std::ratio_equal_v<R, std::micro>) {
prefix = "u";
} else if constexpr (std::ratio_equal_v<R, std::milli>) {
prefix = "m";
} else if constexpr (std::ratio_equal_v<R, std::centi>) {
prefix = "c";
} else if constexpr (std::ratio_equal_v<R, std::deci>) {
prefix = "d";
} else if constexpr (std::ratio_equal_v<R, std::ratio<1, 1>>) {
prefix = "";
} else {
static_assert("Unsupported ratio");
}
return prefix;
}
template <typename T, size_t index = std::tuple_size_v<T> >
inline std::ostream & printTuple(std::ostream & ostr, [[maybe_unused]] const T & t) {
static_assert(index <= std::tuple_size_v<T>);
if constexpr (index == 0) {
return ostr << "( ";
} else {
printTuple<T, index - 1>(ostr, t);
using ElementType = std::tuple_element_t<index - 1, T>;
if constexpr (is_container_v<ElementType>) {
ostr << PrintContainer{std::get<index - 1>(t)};
} else {
ostr << std::get<0>(t);
}
if constexpr (index == std::tuple_size_v<T>) {
return ostr << " )";
} else {
return ostr << ", ";
}
}
}
namespace std {
template <typename R, typename P>
inline ostream & operator<<(ostream & ostr, const chrono::duration<R, P> & d) {
return ostr << d.count() << ::getPrefix<P>() << "s";
}
template <typename F, typename S>
inline ostream & operator<<(ostream & ostr, const pair<F, S> & t) {
return ostr << "{ " << t.first << ", " << t.second << " }";
}
template <typename ... T>
inline ostream & operator<<(ostream & ostr, const tuple<T...> & t) {
return printTuple(ostr, t);
}
template <typename T>
inline ostream & operator<<(ostream & ostr, const optional<T> & t) {
if (t.has_value()) {
return ostr << *t;
} else {
return ostr << "NULL";
}
}
}
struct in_addr;
struct in6_addr;
// Helper for pretty-printing of the Block
struct PrettyPrintBlock {
const clickhouse::Block & block;
};
namespace clickhouse {
std::ostream& operator<<(std::ostream & ostr, const Block & block);
std::ostream& operator<<(std::ostream & ostr, const Type & type);
std::ostream & operator<<(std::ostream & ostr, const ServerInfo & server_info);
std::ostream & operator<<(std::ostream & ostr, const Profile & profile);
std::ostream & operator<<(std::ostream & ostr, const Progress & progress);
std::ostream & operator<<(std::ostream& ostr, const ItemView& item_view);
}
std::ostream& operator<<(std::ostream & ostr, const PrettyPrintBlock & block);
std::ostream& operator<<(std::ostream& ostr, const in_addr& addr);
std::ostream& operator<<(std::ostream& ostr, const in6_addr& addr);
template <typename Container>
struct PrintContainer {
const Container & container_;
explicit PrintContainer(const Container& container)
: container_(container)
{}
};
template <typename T>
std::ostream& operator<<(std::ostream & ostr, const PrintContainer<T>& print_container) {
ostr << "[";
const auto & container = print_container.container_;
for (auto i = std::begin(container); i != std::end(container); /*intentionally no ++i*/) {
const auto & elem = *i;
if constexpr (is_string_v<decltype(elem)>) {
ostr << '"' << elem << '"';
}
else if constexpr (is_container_v<std::decay_t<decltype(elem)>>) {
ostr << PrintContainer{elem};
} else {
ostr << elem;
}
if (++i != std::end(container)) {
ostr << ", ";
}
}
return ostr << "] (" << std::size(container) << " items)";
}
inline uint64_t versionNumber(
uint64_t version_major,
uint64_t version_minor,
uint64_t version_patch = 0,
uint64_t revision = 0) {
// in this case version_major can be up to 1000
static auto revision_decimal_places = 8;
static auto patch_decimal_places = 4;
static auto minor_decimal_places = 4;
auto const result = version_major * static_cast<uint64_t>(std::pow(10, minor_decimal_places + patch_decimal_places + revision_decimal_places))
+ version_minor * static_cast<uint64_t>(std::pow(10, patch_decimal_places + revision_decimal_places))
+ version_patch * static_cast<uint64_t>(std::pow(10, revision_decimal_places))
+ revision;
return result;
}
uint64_t versionNumber(const clickhouse::ServerInfo & server_info);
std::string ToString(const clickhouse::UUID& v);