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

ClickHouse Integration #376

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion include/boost/mysql/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class connection
* If the final handler has an associated immediate executor, and the operation
* completes immediately, the final handler is dispatched to it.
* Otherwise, the final handler is called as if it was submitted using `asio::post`,
* and is never be called inline from within this function.
* and is never to be called inline from within this function.
*/
template <
typename EndpointType,
Expand Down
16 changes: 10 additions & 6 deletions include/boost/mysql/impl/internal/auth/auth.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,17 @@ struct authentication_plugin

BOOST_INLINE_CONSTEXPR authentication_plugin all_authentication_plugins[] = {
{
make_string_view("mysql_native_password"),
&mnp_compute_response,
},
make_string_view("mysql_native_password"),
&mnp_compute_response,
},
{
make_string_view("caching_sha2_password"),
&csha2p_compute_response,
},
make_string_view("caching_sha2_password"),
&csha2p_compute_response,
},
{
make_string_view("double_sha1_password"),
&mnp_compute_response,
},
};

inline const authentication_plugin* find_plugin(string_view name)
Expand Down
3 changes: 2 additions & 1 deletion include/boost/mysql/impl/internal/protocol/db_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ namespace detail {
enum class db_flavor
{
mysql,
mariadb
mariadb,
clickhouse
};

} // namespace detail
Expand Down
34 changes: 24 additions & 10 deletions include/boost/mysql/impl/internal/protocol/deserialization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace mysql {
namespace detail {

// OK packets (views because strings are non-owning)
inline error_code deserialize_ok_packet(span<const std::uint8_t> msg, ok_view& output); // for testing
inline error_code deserialize_ok_packet(span<const std::uint8_t> msg, ok_view& output, db_flavor flavor); // for testing

// Error packets (exposed for testing)
struct err_view
Expand Down Expand Up @@ -269,7 +269,8 @@ BOOST_INLINE_CONSTEXPR std::uint8_t ok_packet_header = 0x00;
// OK packets
boost::mysql::error_code boost::mysql::detail::deserialize_ok_packet(
span<const std::uint8_t> msg,
ok_view& output
ok_view& output,
db_flavor flavor
)
{
struct ok_packet
Expand All @@ -280,7 +281,8 @@ boost::mysql::error_code boost::mysql::detail::deserialize_ok_packet(
int2 status_flags; // server_status_flags
int2 warnings;
// CLIENT_SESSION_TRACK: not implemented
string_lenenc info;
using info_type = boost::variant2::variant<string_lenenc, string_eof>;
info_type info;
} pack{};

deserialization_context ctx(msg);
Expand All @@ -290,7 +292,13 @@ boost::mysql::error_code boost::mysql::detail::deserialize_ok_packet(

if (ctx.enough_size(1)) // message is optional, may be omitted
{
err = pack.info.deserialize(ctx);
if (flavor == db_flavor::clickhouse) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can avoid the variant altogether - just create and deserialize the string_lenenc or string_eof depending on the case. Since this lib supports back to cpp11, unfortunately you can't use generic lambdas, so I think this is easier.

pack.info = string_eof{};
} else{
pack.info = string_lenenc{};
}
err = boost::variant2::visit( [&]( auto& info ){ return info.deserialize(ctx); }, pack.info );
// err = pack.info.deserialize(ctx);
if (err != deserialize_errc::ok)
return to_error_code(err);
}
Expand All @@ -300,7 +308,7 @@ boost::mysql::error_code boost::mysql::detail::deserialize_ok_packet(
pack.last_insert_id.value,
pack.status_flags.value,
pack.warnings.value,
pack.info.value,
boost::variant2::visit( [&]( auto& info ){ return info.value; }, pack.info ),
};

return ctx.check_extra_bytes();
Expand Down Expand Up @@ -473,7 +481,7 @@ boost::mysql::error_code boost::mysql::detail::deserialize_ok_response(
{
// Verify that the ok_packet is correct
ok_view ok{};
err = deserialize_ok_packet(ctx.to_span(), ok);
err = deserialize_ok_packet(ctx.to_span(), ok, flavor);
if (err)
return err;
backslash_escapes = ok.backslash_escapes();
Expand Down Expand Up @@ -574,7 +582,7 @@ boost::mysql::detail::execute_response boost::mysql::detail::deserialize_execute
if (msg_type.value == ok_packet_header)
{
ok_view ok{};
err = deserialize_ok_packet(ctx.to_span(), ok);
err = deserialize_ok_packet(ctx.to_span(), ok, flavor);
if (err)
return err;
return ok;
Expand Down Expand Up @@ -630,7 +638,7 @@ boost::mysql::detail::row_message boost::mysql::detail::deserialize_row_message(
{
// end of resultset => this is a ok_packet, not a row
ok_view ok{};
auto err = deserialize_ok_packet(ctx.to_span(), ok);
auto err = deserialize_ok_packet(ctx.to_span(), ok, flavor);
if (err)
return err;
return ok;
Expand Down Expand Up @@ -762,7 +770,13 @@ inline capabilities compose_capabilities(string_fixed<2> low, string_fixed<2> hi

inline db_flavor parse_db_version(string_view version_string)
{
return version_string.find("MariaDB") != string_view::npos ? db_flavor::mariadb : db_flavor::mysql;
if (version_string.find("MariaDB") != std::string_view::npos) {
return db_flavor::mariadb;
} else if (version_string.find("ClickHouse") != std::string_view::npos) {
return db_flavor::clickhouse;
} else {
return db_flavor::mysql;
}
}

} // namespace detail
Expand Down Expand Up @@ -940,7 +954,7 @@ boost::mysql::detail::handhake_server_response boost::mysql::detail::deserialize
if (msg_type.value == ok_packet_header)
{
ok_view ok{};
err = deserialize_ok_packet(ctx.to_span(), ok);
err = deserialize_ok_packet(ctx.to_span(), ok, flavor);
if (err)
return err;
return ok;
Expand Down
2 changes: 1 addition & 1 deletion include/boost/mysql/impl/internal/sansio/handshake.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class handshake_algo
error_code process_ok(connection_state_data& st)
{
ok_view res{};
auto ec = deserialize_ok_packet(st.reader.message(), res);
auto ec = deserialize_ok_packet(st.reader.message(), res, st.flavor);
if (ec)
return ec;
on_success(st, res);
Expand Down
6 changes: 4 additions & 2 deletions test/unit/test/protocol/deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ BOOST_AUTO_TEST_CASE(ok_view_success)
BOOST_TEST_CONTEXT(tc.name)
{
ok_view actual{};
error_code err = deserialize_ok_packet(tc.serialized, actual);
db_flavor flavor{db_flavor::mysql};
error_code err = deserialize_ok_packet(tc.serialized, actual, flavor);

// No error
BOOST_TEST(err == error_code());
Expand Down Expand Up @@ -153,7 +154,8 @@ BOOST_AUTO_TEST_CASE(ok_view_error)
BOOST_TEST_CONTEXT(tc.name)
{
ok_view value{};
error_code err = deserialize_ok_packet(tc.serialized, value);
db_flavor flavor{db_flavor::mysql};
error_code err = deserialize_ok_packet(tc.serialized, value, flavor);
BOOST_TEST(err == tc.expected_err);
}
}
Expand Down
Loading