Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MSVC #131

Merged
merged 3 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/windows_msvc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Windows

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

env:
BUILD_TYPE: Release
GTEST_FILTER: --gtest_filter=-"*"
CLICKHOUSE_USER: clickhouse_cpp_cicd
CLICKHOUSE_PASSWORD: clickhouse_cpp_cicd
#
# CLICKHOUSE_HOST: localhost
# CLICKHOUSE_PORT: 9000
# CLICKHOUSE_USER: default
# CLICKHOUSE_PASSWORD:
# CLICKHOUSE_DB: default
#
# CLICKHOUSE_SECURE_HOST: github.demo.trial.altinity.cloud
# CLICKHOUSE_SECURE_PORT: 9440
# CLICKHOUSE_SECURE_USER: demo
# CLICKHOUSE_SECURE_PASSWORD: demo
# CLICKHOUSE_SECURE_DB: default
#
# CLICKHOUSE_SECURE2_HOST: gh-api.clickhouse.tech
# CLICKHOUSE_SECURE2_PORT: 9440
# CLICKHOUSE_SECURE2_USER: explorer
# CLICKHOUSE_SECURE2_PASSWORD:
# CLICKHOUSE_SECURE2_DB: default

jobs:
build:
runs-on: windows-latest

steps:
- uses: actions/checkout@v2
- uses: ilammy/msvc-dev-cmd@v1

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBUILD_TESTS=ON

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

- name: Start tls offoader proxy
shell: bash
# that mimics non-secure clickhouse running on localhost
# by tunneling queries to remote tls server
# (needed because we can't start real clickhouse instance on windows)
run: |
choco install wget
wget https://github.com/filimonov/go-tlsoffloader/releases/download/v0.1.2/go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz
tar -xvzf go-tlsoffloader_0.1.2_Windows_x86_64.tar.gz
./go-tlsoffloader.exe -l localhost:9000 -b github.demo.trial.altinity.cloud:9440 &

- name: Test
working-directory: ${{github.workspace}}/build/ut
run: Release\clickhouse-cpp-ut.exe "${{env.GTEST_FILTER}}"
4 changes: 2 additions & 2 deletions clickhouse/base/compressed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void CompressedOutput::Compress(const void * data, size_t len) {
(const char*)data,
(char*)compressed_buffer_.data() + HEADER_SIZE,
len,
compressed_buffer_.size() - HEADER_SIZE);
static_cast<int>(compressed_buffer_.size() - HEADER_SIZE));
if (compressed_size <= 0)
throw std::runtime_error("Failed to compress chunk of " + std::to_string(len) + " bytes, "
"LZ4 error: " + std::to_string(compressed_size));
Expand All @@ -164,7 +164,7 @@ void CompressedOutput::Compress(const void * data, size_t len) {
}

void CompressedOutput::PreallocateCompressBuffer(size_t input_size) {
const auto estimated_compressed_buffer_size = LZ4_compressBound(input_size);
const auto estimated_compressed_buffer_size = LZ4_compressBound(static_cast<int>(input_size));
if (estimated_compressed_buffer_size <= 0)
throw std::runtime_error("Failed to estimate compressed buffer size, LZ4 error: " + std::to_string(estimated_compressed_buffer_size));

Expand Down
2 changes: 2 additions & 0 deletions clickhouse/base/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#if defined(_win32_) || defined(_win64_)
# define _win_
# define _WIN32_WINNT 0x0600 // The WSAPoll function is defined on Windows Vista and later.
# define WIN32_LEAN_AND_MEAN 1 // don't include too much header automatically
#endif

#if defined(_linux_) || defined (_darwin_)
Expand Down
77 changes: 55 additions & 22 deletions clickhouse/base/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,33 @@
# include <netinet/tcp.h>
# include <signal.h>
# include <unistd.h>
# include <netinet/tcp.h>
#endif

namespace clickhouse {

#if defined(_win_)
char const* windowsErrorCategory::name() const noexcept {
return "WindowsSocketError";
}

std::string windowsErrorCategory::message(int c) const {
char error[UINT8_MAX];
auto len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, static_cast<DWORD>(c), 0, error, sizeof(error), nullptr);
if (len == 0) {
return "unknown";
}
while (len && (error[len - 1] == '\r' || error[len - 1] == '\n')) {
--len;
}
return std::string(error, len);
}

windowsErrorCategory const& windowsErrorCategory::category() {
static windowsErrorCategory c;
return c;
}
#endif

namespace {

class LocalNames : public std::unordered_set<std::string> {
Expand All @@ -37,6 +59,22 @@ class LocalNames : public std::unordered_set<std::string> {
}
};

inline int getSocketErrorCode() {
#if defined(_win_)
return WSAGetLastError();
#else
return errno;
#endif
}

const std::error_category& getErrorCategory() noexcept {
#if defined(_win_)
return windowsErrorCategory::category();
#else
return std::system_category();
#endif
}

void SetNonBlock(SOCKET fd, bool value) {
#if defined(_unix_)
int flags;
Expand All @@ -55,8 +93,7 @@ void SetNonBlock(SOCKET fd, bool value) {
return ioctl(fd, FIOBIO, &flags);
#endif
if (ret == -1) {
throw std::system_error(
errno, std::system_category(), "fail to set nonblocking mode");
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "fail to set nonblocking mode");
}
#elif defined(_win_)
unsigned long inbuf = value;
Expand All @@ -68,8 +105,7 @@ void SetNonBlock(SOCKET fd, bool value) {
}

if (WSAIoctl(fd, FIONBIO, &inbuf, sizeof(inbuf), &outbuf, sizeof(outbuf), &written, 0, 0) == SOCKET_ERROR) {
throw std::system_error(
errno, std::system_category(), "fail to set nonblocking mode");
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "fail to set nonblocking mode");
}
#endif
}
Expand All @@ -94,16 +130,21 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
SetNonBlock(s, true);

if (connect(s, res->ai_addr, (int)res->ai_addrlen) != 0) {
int err = errno;
if (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK) {
int err = getSocketErrorCode();
if (
err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK
#if defined(_win_)
|| err == WSAEWOULDBLOCK || err == WSAEINPROGRESS
#endif
) {
pollfd fd;
fd.fd = s;
fd.events = POLLOUT;
fd.revents = 0;
ssize_t rval = Poll(&fd, 1, 5000);

if (rval == -1) {
throw std::system_error(errno, std::system_category(), "fail to connect");
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "fail to connect");
}
if (rval > 0) {
socklen_t len = sizeof(err);
Expand All @@ -122,11 +163,9 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
}
}
if (last_err > 0) {
throw std::system_error(last_err, std::system_category(), "fail to connect");
throw std::system_error(last_err, getErrorCategory(), "fail to connect");
}
throw std::system_error(
errno, std::system_category(), "fail to connect"
);
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "fail to connect");
}

} // namespace
Expand Down Expand Up @@ -156,7 +195,7 @@ NetworkAddress::NetworkAddress(const std::string& host, const std::string& port)
const int error = getaddrinfo(host.c_str(), port.c_str(), &hints, &info_);

if (error) {
throw std::system_error(errno, std::system_category());
throw std::system_error(getSocketErrorCode(), getErrorCategory());
}
}

Expand Down Expand Up @@ -262,14 +301,10 @@ size_t SocketInput::DoRead(void* buf, size_t len) {
}

if (ret == 0) {
throw std::system_error(
errno, std::system_category(), "closed"
);
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "closed");
}

throw std::system_error(
errno, std::system_category(), "can't receive string data"
);
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "can't receive string data");
}

bool SocketInput::Skip(size_t /*bytes*/) {
Expand All @@ -292,9 +327,7 @@ size_t SocketOutput::DoWrite(const void* data, size_t len) {
#endif

if (::send(s_, (const char*)data, (int)len, flags) != (int)len) {
throw std::system_error(
errno, std::system_category(), "fail to send " + std::to_string(len) + " bytes of data"
);
throw std::system_error(getSocketErrorCode(), getErrorCategory(), "fail to send " + std::to_string(len) + " bytes of data");
}

return len;
Expand Down
15 changes: 13 additions & 2 deletions clickhouse/base/socket.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include "platform.h"
#include "input.h"
#include "output.h"
#include "platform.h"

#include <cstddef>
#include <string>
Expand All @@ -24,7 +24,7 @@
#endif

#include <memory>

#include <system_error>

struct addrinfo;

Expand All @@ -47,6 +47,17 @@ class NetworkAddress {
struct addrinfo* info_;
};

#if defined(_win_)

class windowsErrorCategory : public std::error_category {
public:
char const* name() const noexcept override final;
std::string message(int c) const override final;

static windowsErrorCategory const& category();
};

#endif

class Socket {
public:
Expand Down
7 changes: 4 additions & 3 deletions clickhouse/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,10 @@ void Client::Impl::ResetConnection() {
socket = std::make_unique<Socket>(address);

if (options_.tcp_keepalive) {
socket->SetTcpKeepAlive(options_.tcp_keepalive_idle.count(),
options_.tcp_keepalive_intvl.count(),
options_.tcp_keepalive_cnt);
socket->SetTcpKeepAlive(
static_cast<int>(options_.tcp_keepalive_idle.count()),
static_cast<int>(options_.tcp_keepalive_intvl.count()),
static_cast<int>(options_.tcp_keepalive_cnt));
}
if (options_.tcp_nodelay) {
socket->SetTcpNoDelay(options_.tcp_nodelay);
Expand Down
2 changes: 1 addition & 1 deletion clickhouse/columns/decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ void ColumnDecimal::Append(const std::string& value) {
bool sign = true;
bool has_dot = false;

int zeros = 0;
size_t zeros = 0;

while (c != end) {
if (*c == '-') {
Expand Down
2 changes: 1 addition & 1 deletion tests/simple/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ADD_EXECUTABLE (simple-test
)

TARGET_LINK_LIBRARIES (simple-test
clickhouse-cpp-lib
clickhouse-cpp-lib-static
)

IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Expand Down
2 changes: 1 addition & 1 deletion ut/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ ADD_EXECUTABLE (clickhouse-cpp-ut
)

TARGET_LINK_LIBRARIES (clickhouse-cpp-ut
clickhouse-cpp-lib
clickhouse-cpp-lib-static
gtest-lib
)
IF (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
Expand Down
11 changes: 10 additions & 1 deletion ut/columns_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,17 @@ TEST(ColumnsCase, Int128) {
absl::MakeInt128(0x8000000000000000ll, 0),
Int128(0)
});

EXPECT_EQ(-1, col->At(0));
EXPECT_EQ(0xffffffffffffffffll, col->At(1));

EXPECT_EQ(absl::MakeInt128(0, 0xffffffffffffffffll), col->At(1));
EXPECT_EQ(0ll, absl::Int128High64(col->At(1)));
EXPECT_EQ(0xffffffffffffffffull, absl::Int128Low64(col->At(1)));

EXPECT_EQ(absl::MakeInt128(0xffffffffffffffffll, 0), col->At(2));
EXPECT_EQ(static_cast<int64_t>(0xffffffffffffffffll), absl::Int128High64(col->At(2)));
EXPECT_EQ(0ull, absl::Int128Low64(col->At(2)));

EXPECT_EQ(0, col->At(4));
}

Expand Down
2 changes: 2 additions & 0 deletions ut/readonly_client_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ void ReadonlyClientTest::TearDown() {
client_.reset();
}

// Sometimes gtest fails to detect that this test is instantiated elsewhere, suppress the error explicitly.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadonlyClientTest);
TEST_P(ReadonlyClientTest, Select) {

const auto & queries = std::get<1>(GetParam());
Expand Down
Loading