MySQL Forums
Forum List  »  Connector/C++

Reading DATE, DATETIME via mysqlx (MySQL Connector/C++ 8.0 X DevAPI)
Posted by: Kira Backes
Date: October 19, 2022 07:53AM

Since this is still not implemented into the C++ Connector we developed the following C++20 helper methods for production use with mysqlx (MySQL Connector/C++ 8.0 X DevAPI) to properly read DATE, DATETIME and TIMESTAMP fields:

#pragma once

#include <vector>
#include <cstddef>
#include <chrono>
#include <mysqlx/xdevapi.h>

namespace mysqlx {

static inline std::vector<uint64_t>
mysqlx_raw_as_u64_vector(const mysqlx::Value& in_value)
{
std::vector<uint64_t> out;

const auto bytes = in_value.getRawBytes();
auto ptr = reinterpret_cast<const std::byte*>(bytes.first);
auto end = reinterpret_cast<const std::byte*>(bytes.first) + bytes.second;

while (ptr != end) {
static constexpr std::byte carry_flag{0b1000'0000};
static constexpr std::byte value_mask{0b0111'1111};

uint64_t v = 0;
uint64_t shift = 0;
bool is_carry;
do {
auto byte = *ptr;
is_carry = (byte & carry_flag) == carry_flag;
v |= std::to_integer<uint64_t>(byte & value_mask) << shift;

++ptr;
shift += 7;
} while (is_carry && ptr != end && shift <= 63);

out.push_back(v);
}

return out;
}

static inline std::chrono::year_month_day
read_date(const mysqlx::Value& value)
{
const auto vector = mysqlx_raw_as_u64_vector(value);
if (vector.size() < 3)
throw std::out_of_range{"Value is not a valid DATE"};

return std::chrono::year{static_cast<int>(vector.at(0))} / static_cast<int>(vector.at(1)) / static_cast<int>(vector.at(2));
}

static inline std::chrono::system_clock::time_point
read_date_time(const mysqlx::Value& value)
{
const auto vector = mysqlx_raw_as_u64_vector(value);
if (vector.size() < 3)
throw std::out_of_range{"Value is not a valid DATETIME"};

auto ymd = std::chrono::year{static_cast<int>(vector.at(0))} / static_cast<int>(vector.at(1)) / static_cast<int>(vector.at(2));
auto sys_days = std::chrono::sys_days{ymd};

auto out = std::chrono::system_clock::time_point(sys_days);

auto it = vector.begin() + 2;
auto end = vector.end();

if (++it == end)
return out;
out += std::chrono::hours{*it};

if (++it == end)
return out;
out += std::chrono::minutes{*it};

if (++it == end)
return out;
out += std::chrono::seconds{*it};

if (++it == end)
return out;
out += std::chrono::microseconds{*it};

return out;
}

} //namespace



Which can then be used as follows:



auto row = table.select("datetime", "date").execute().fetchOne();
auto time_point = read_date_time(row[0]);
auto year_month_day = read_date(row[1]);



rgds Kira

Options: ReplyQuote


Subject
Views
Written By
Posted
Reading DATE, DATETIME via mysqlx (MySQL Connector/C++ 8.0 X DevAPI)
517
October 19, 2022 07:53AM


Sorry, you can't reply to this topic. It has been closed.

Content reproduced on this site is the property of the respective copyright holders. It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.