initial matador ng commit

This commit is contained in:
2025-02-02 20:37:12 +01:00
parent 19de5714f4
commit ded3daceb3
378 changed files with 14913 additions and 13431 deletions
+184
View File
@@ -0,0 +1,184 @@
#include "matador/utils/default_type_traits.hpp"
#include "matador/utils/attribute_reader.hpp"
#include "matador/utils/attribute_writer.hpp"
namespace matador::utils {
void data_type_traits<nullptr_t>::read_value(attribute_reader &/*reader*/, const char * /*id*/, size_t /*index*/, nullptr_t &/*value*/)
{}
void data_type_traits<nullptr_t>::bind_value(attribute_writer &/*binder*/, size_t /*index*/, nullptr_t &/*value*/)
{}
void data_type_traits<int8_t>::read_value(attribute_reader &reader, const char *id, const size_t index, int8_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<int8_t>::bind_value(attribute_writer &binder, const size_t index, const int8_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<int16_t>::read_value(attribute_reader &reader, const char *id, const size_t index, int16_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<int16_t>::bind_value(attribute_writer &binder, const size_t index, const int16_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<int32_t>::read_value(attribute_reader &reader, const char *id, const size_t index, int32_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<int32_t>::bind_value(attribute_writer &binder, const size_t index, const int32_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<int64_t>::read_value(attribute_reader &reader, const char *id, const size_t index, int64_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<int64_t>::bind_value(attribute_writer &binder, const size_t index, const int64_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<uint8_t>::read_value(attribute_reader &reader, const char *id, const size_t index, uint8_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<uint8_t>::bind_value(attribute_writer &binder, const size_t index, const uint8_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<uint16_t>::read_value(attribute_reader &reader, const char *id, const size_t index, uint16_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<uint16_t>::bind_value(attribute_writer &binder, const size_t index, const uint16_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<uint32_t>::read_value(attribute_reader &reader, const char *id, const size_t index, uint32_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<uint32_t>::bind_value(attribute_writer &binder, const size_t index, const uint32_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<uint64_t>::read_value(attribute_reader &reader, const char *id, const size_t index, uint64_t &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<uint64_t>::bind_value(attribute_writer &binder, const size_t index, const uint64_t &value)
{
binder.write_value(index, value);
}
void data_type_traits<bool>::read_value(attribute_reader &reader, const char *id, const size_t index, bool &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<bool>::bind_value(attribute_writer &binder, const size_t index, const bool &value)
{
binder.write_value(index, value);
}
void data_type_traits<float>::read_value(attribute_reader &reader, const char *id, const size_t index, float &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<float>::bind_value(attribute_writer &binder, const size_t index, const float &value)
{
binder.write_value(index, value);
}
void data_type_traits<double>::read_value(attribute_reader &reader, const char *id, const size_t index, double &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<double>::bind_value(attribute_writer &binder, const size_t index, const double &value)
{
binder.write_value(index, value);
}
void data_type_traits<const char*>::read_value(attribute_reader &reader, const char *id, const size_t index, const char* value, const size_t size)
{
reader.read_value(id, index, const_cast<char*>(value), size);
}
void data_type_traits<const char *>::bind_value(attribute_writer &binder, const size_t index, const char *value, const size_t size)
{
binder.write_value(index, value, size);
}
void data_type_traits<char*>::read_value(attribute_reader &reader, const char *id, const size_t index, char* value, const size_t size)
{
reader.read_value(id, index, value, size);
}
void data_type_traits<char *>::bind_value(attribute_writer &binder, const size_t index, const char *value, const size_t size)
{
binder.write_value(index, value, size);
}
void data_type_traits<std::string>::read_value(attribute_reader &reader, const char *id, size_t index, std::string &value, size_t size)
{
reader.read_value(id, index, value, size);
}
void data_type_traits<std::string>::bind_value(attribute_writer &binder, size_t index, std::string &value, size_t size)
{
binder.write_value(index, value, size);
}
void data_type_traits<utils::blob, void>::read_value(attribute_reader &reader, const char *id, size_t index, utils::blob &value)
{
reader.read_value(id, index, value);
}
void data_type_traits<utils::blob, void>::bind_value(attribute_writer &binder, size_t index, utils::blob &value)
{
binder.write_value(index, value);
}
// void data_type_traits<matador::date>::read_value(attribute_reader &reader, const char *id, size_t index, date &value)
// {
// reader.read_value(id, index, value);
// }
//
// void data_type_traits<matador::date>::bind_value(attribute_writer &binder, size_t index, date &value)
// {
// binder.write_value(index, value);
// }
//
// void data_type_traits<matador::time>::read_value(attribute_reader &reader, const char *id, size_t index, time &value)
// {
// reader.read_value(id, index, value);
// }
//
// void data_type_traits<matador::time>::bind_value(attribute_writer &binder, size_t index, time &value)
// {
// binder.write_value(index, value);
// }
}
+89
View File
@@ -0,0 +1,89 @@
#include "matador/utils/error.hpp"
#include <utility>
#include <algorithm>
namespace matador::utils {
std::string error::message() const {
return ec_.message();
}
std::string error::category() const {
return ec_.category().name();
}
std::error_code error::ec() const {
return ec_;
}
const std::vector<error> & error::error_trace() const {
return error_trace_;
}
std::optional<std::string> error::error_info(const std::string &key) const {
const auto info = error_infos_.find(key);
if (info == error_infos_.end()) {
return std::nullopt;
}
return info->second;
}
void error::add_error_info(const std::string &key, std::string value) {
error_infos_[key] = std::move(value);
}
void error::remove_error_info(const std::string &key) {
error_infos_.erase(key);
}
std::vector<std::string> error::error_info_keys() const {
std::vector<std::string> keys;
std::transform(
std::begin(error_infos_),
std::end(error_infos_),
std::back_inserter(keys),
[](const auto &pair){return pair.first;});
return keys;
}
bool operator==(const error &lhs, const error &rhs) {
return lhs.ec_ == rhs.ec_;
}
bool operator==(const error &lhs, const std::error_code &rhs) {
return lhs.ec_ == rhs;
}
bool operator==(const error &lhs, const std::error_condition &rhs) {
return lhs.ec_ == rhs;
}
bool operator!=(const error &lhs, const error &rhs) {
return !(lhs == rhs);
}
bool operator!=(const error &lhs, const std::error_code &rhs) {
return !(lhs == rhs);
}
bool operator!=(const error &lhs, const std::error_condition &rhs) {
return !(lhs == rhs);
}
bool operator<(const error &lhs, const error &rhs) {
return lhs.ec_ < rhs.ec_;
}
bool operator<(const error &lhs, const std::error_code &rhs) {
return lhs.ec_ < rhs;
}
// std::ostream & operator<<(std::ostream &out, const error &err) {
// out << err.ec_ << " " << err.ec_.message();
// return out;
// }
}
+31
View File
@@ -0,0 +1,31 @@
#include "matador/utils/errors.hpp"
namespace matador::utils {
const char * utils_category_impl::name() const noexcept {
return "utils";
}
std::string utils_category_impl::message(const int ev) const {
switch (static_cast<utils_error>(ev)) {
case (utils_error::InvalidVersionString):
return "Invalid version string";
default:
return "Unknown error";
}
}
const std::error_category & sql_category() {
static utils_category_impl instance;
return instance;
}
std::error_code make_error_code(utils_error e) {
return {static_cast<int>(e), sql_category()};
}
std::error_condition make_error_condition(utils_error e) {
return {static_cast<int>(e), sql_category()};
}
}
+38
View File
@@ -0,0 +1,38 @@
#include "matador/utils/field_attributes.hpp"
namespace matador::utils {
field_attributes::field_attributes(const size_t size)
: size_(size)
{}
field_attributes::field_attributes(const constraints options)
: options_(options)
{}
field_attributes::field_attributes(const size_t size, const constraints options)
: size_(size), options_(options)
{}
field_attributes& field_attributes::operator=(const size_t size) {
size_ = size;
options_ = constraints::NONE;
return *this;
}
field_attributes& field_attributes::operator=(constraints opt) {
options_ = opt;
size_ = 0;
return *this;
}
size_t field_attributes::size() const
{
return size_;
}
constraints field_attributes::options() const
{
return options_;
}
}
+203
View File
@@ -0,0 +1,203 @@
#include "matador/utils/identifier.hpp"
#include <cstring>
#include <stdexcept>
#include <ostream>
namespace matador::utils {
size_t detail::hash(const char *value) {
return std::hash<std::string_view>()(std::string_view(value, std::strlen(value)));
}
bool identifier_type_traits<const char*>::is_valid(const char *value) {
return value != nullptr && strlen(value) > 0;
}
std::string identifier_type_traits<const char*>::to_string(const char *value) {
return value;
}
identifier::base::base(const std::type_index &ti, const basic_type type)
: type_index_(ti)
, type_(type)
{}
identifier::null_pk::null_pk()
: base(std::type_index(typeid(null_type_t)), basic_type::type_null)
{}
identifier::base* identifier::null_pk::copy() const
{
return new null_pk;
}
bool identifier::null_pk::equal_to(const base &x) const
{
return type_index_ == x.type_index_;
}
bool identifier::null_pk::less(const base &x) const
{
return type_index_ == x.type_index_;
}
bool identifier::null_pk::is_valid() const
{
return identifier_type_traits<null_type_t>::is_valid();
}
std::string identifier::null_pk::str() const
{
return identifier_type_traits<null_type_t>::to_string();
}
void identifier::null_pk::serialize(identifier_serializer &s)
{
s.serialize(null_, {});
}
size_t identifier::null_pk::hash() const
{
return std::hash<nullptr_t>()(nullptr);
}
identifier::identifier()
: id_(std::make_shared<null_pk>()) {}
identifier::identifier(const identifier &x)
: id_(x.id_->copy()) {}
identifier &identifier::operator=(const identifier &x) {
if (this == &x) {
return *this;
}
id_.reset(x.id_->copy());
return *this;
}
identifier::identifier(identifier &&x) noexcept
: id_(std::move(x.id_)) {
x.clear();
}
identifier &identifier::operator=(identifier &&x) noexcept {
id_ = std::move(x.id_);
x.clear();
return *this;
}
bool identifier::operator==(const identifier &x) const {
return id_->equal_to(*x.id_);
}
bool identifier::operator!=(const identifier &x) const {
return !operator==(x);
}
bool identifier::operator<(const identifier &x) const {
return id_->less(*x.id_);
}
bool identifier::operator<=(const identifier &x) const {
return operator==(x) || operator<(x);
}
bool identifier::operator>(const identifier &x) const {
return !operator<=(x);
}
bool identifier::operator>=(const identifier &x) const {
return !operator<(x);
}
std::string identifier::str() const {
return id_->str();
}
const std::type_index &identifier::type_index() const {
return id_->type_index_;
}
basic_type identifier::type() const {
return id_->type_;
}
identifier identifier::share() const
{
return identifier(id_);
}
size_t identifier::use_count() const
{
return id_.use_count();
}
bool identifier::is_integer() const {
return id_->type_ >= basic_type::type_int8 && id_->type_ <= basic_type::type_uint64;
}
bool identifier::is_floating_point() const {
return id_->type_ == basic_type::type_float || id_->type_ == basic_type::type_double;
}
bool identifier::is_bool() const {
return id_->type_ == basic_type::type_bool;
}
bool identifier::is_varchar() const {
return id_->type_ == basic_type::type_varchar;
}
bool identifier::is_date() const {
return id_->type_ == basic_type::type_date;
}
bool identifier::is_time() const {
return id_->type_ == basic_type::type_time;
}
bool identifier::is_blob() const {
return id_->type_ == basic_type::type_blob;
}
bool identifier::is_null() const
{
return type_index() == null_identifier.type_index();
}
bool identifier::is_valid() const
{
return id_->is_valid();
}
void identifier::clear()
{
id_ = std::make_unique<null_pk>();
}
void identifier::serialize(identifier_serializer &s) const {
id_->serialize(s);
}
size_t identifier::hash() const
{
return id_->hash();
}
identifier::identifier(const std::shared_ptr<base> &id)
: id_(id)
{}
std::ostream &operator<<(std::ostream &out, const identifier &id)
{
out << id.str();
return out;
}
size_t id_pk_hash::operator()(const identifier &id) const
{
return id.hash();
}
}
+77
View File
@@ -0,0 +1,77 @@
#include "matador/utils/library.hpp"
#include "matador/utils/os.hpp"
#include <utility>
namespace matador::utils {
library::library(std::string lib)
: lib_(std::move(lib))
{}
library::~library()
{
unload();
}
bool library::load()
{
auto path = os::getenv("MATADOR_BACKENDS_PATH");
#if defined(_MSC_VER) || defined(__MINGW32__)
auto cookie = AddDllDirectory(std::wstring(path.begin(), path.end()).c_str());
handle_ = LoadLibraryExA((lib_ + ".dll").c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
RemoveDllDirectory(cookie);
#elif defined(__APPLE__)
handle_ = dlopen(std::string("lib" + lib_ + ".dylib").c_str(), RTLD_LAZY);
#else
handle_ = dlopen((path + "/lib" + lib_ + ".so").c_str(), RTLD_LAZY);
#endif
if (!handle_) {
#if defined(_MSC_VER) || defined(__MINGW32__)
DWORD errorMessageID = ::GetLastError();
auto errstr = utils::os::error_string(errorMessageID);
#else
// TODO: handle win32 and linux error
fprintf(stdout, "dlopen error: %s", dlerror());
#endif
return false;
}
return true;
}
bool library::load(const std::string &lib)
{
if (handle_) {
return false;
}
lib_ = lib;
return load();
}
bool library::unload()
{
bool ret(true);
if (handle_) {
#if defined(_MSC_VER) || defined(__MINGW32__)
ret = FreeLibrary(handle_) == TRUE;
#else
ret = dlclose(handle_) == 0;
#endif
if (!ret) {
} else {
handle_ = nullptr;
}
}
return ret;
}
func_ptr library::function(const std::string &f) const
{
#if defined(_MSC_VER) || defined(__MINGW32__)
return GetProcAddress(handle_, f.c_str());
#else
return dlsym(handle_, f.c_str());
#endif
}
}
+360
View File
@@ -0,0 +1,360 @@
#include "matador/utils/os.hpp"
#include <sys/stat.h>
#include <cstring>
#include <vector>
#include <stdexcept>
#include <algorithm>
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#include <windows.h>
#else
#include <unistd.h>
#endif
namespace matador::utils::os {
void setenv(const char *name, const char *value, override_env_value override_value)
{
#ifdef _WIN32
_putenv_s(name, value);
#else
::setenv(name, value, static_cast<int>(override_value));
#endif
}
#ifdef _WIN32
std::string error_string(unsigned long error) {
char* lpMsgBuf;
auto bufLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
nullptr);
std::string result;
if (bufLen) {
result.append(lpMsgBuf, lpMsgBuf+bufLen);
LocalFree(lpMsgBuf);
}
return result;
}
#endif
std::string getenv(const char *name) {
#ifdef _WIN32
char var[1024];
size_t len{};
const auto error = getenv_s(&len, var, 1024, name);
if (error > 0) {
throw std::logic_error(error_string(error));
};
return var;
#else
const char *path = ::getenv(name);
return path == nullptr ? "" : path;
#endif
}
void unsetenv(const char *name)
{
#ifdef _WIN32
_putenv_s(name, nullptr);
#else
::unsetenv(name);
#endif
}
}
namespace matador::os {
FILE* fopen(const std::string &path, const char *modes)
{
return fopen(path.c_str(), modes);
}
FILE* fopen(const char *path, const char *modes)
{
#ifdef _WIN32
return _fsopen(path, modes, _SH_DENYWR);
#else
return ::fopen(path, modes);
#endif
}
FILE* freopen(const std::string &path, const char *modes, FILE *stream)
{
return os::freopen(path.c_str(), modes, stream);
}
FILE* freopen(const char *path, const char *modes, FILE *stream)
{
#ifdef _WIN32
FILE* redirected_stream;
freopen_s(&redirected_stream, path, "w+", stream);
return redirected_stream;
#else
return ::freopen(path, modes, stream);
#endif
}
bool fclose(FILE *f)
{
return ::fclose(f) == 0;
}
bool remove(const std::string &name)
{
return os::remove(name.c_str());
}
bool remove(const char *name)
{
return ::remove(name) == 0;
}
bool rename(const std::string &old_name, const std::string &new_name)
{
return os::rename(old_name.c_str(), new_name.c_str());
}
bool rename(const char *old_name, const char *new_name)
{
return ::rename(old_name, new_name) == 0;
}
bool access(const std::string &path, int mode)
{
return os::access(path.c_str(), mode);
}
bool access(const char *path, int mode)
{
#ifdef _WIN32
return _access(path, mode) == 0;
#else
return ::access(path, mode) == 0;
#endif
}
int dup(FILE *stream)
{
#ifdef _WIN32
return _dup(_fileno(stream));
#else
return ::dup(fileno(stream));
#endif
}
bool mkdir(const std::string &dirname)
{
return os::mkdir(dirname.c_str());
}
bool mkdir(const char *dirname)
{
if (dirname == nullptr || strlen(dirname) == 0) {
return true;
}
#ifdef _WIN32
return ::_mkdir(dirname) == 0;
#else
return ::mkdir(dirname, S_IRWXU) == 0;
#endif
}
bool chdir(const std::string &dirname)
{
return os::chdir(dirname.c_str());
}
bool chdir(const char *dirname)
{
if (dirname == nullptr || strlen(dirname) == 0) {
return true;
}
#ifdef _WIN32
return _chdir(dirname) == 0;
#else
return ::chdir(dirname) == 0;
#endif
}
bool rmdir(const std::string &dirname)
{
return os::rmdir(dirname.c_str());
}
bool rmdir(const char *dirname)
{
#ifdef _WIN32
return _rmdir(dirname) == 0;
#else
return ::rmdir(dirname) == 0;
#endif
}
std::string get_current_dir()
{
char buffer[1024];
#ifdef _WIN32
char *dir = _getcwd(buffer, 1024);
#else
char *dir = ::getcwd(buffer, 1024);
#endif
if (dir == nullptr) {
#ifdef _WIN32
::strerror_s(buffer, 1024, errno);
throw std::logic_error(buffer);
#else
throw std::logic_error(::strerror(errno));
#endif
}
return std::string(buffer);
}
bool mkpath(const std::string &path)
{
return os::mkpath(path.c_str());
}
#ifdef _WIN32
char DIR_SEPARATOR = '\\';
const char* DIR_SEPARATOR_STRING = "\\";
#else
char DIR_SEPARATOR = '/';
const char* DIR_SEPARATOR_STRING = "/";
#endif
bool mkpath(const char *path)
{
char tmp[256];
char *p = nullptr;
size_t len;
snprintf(tmp, sizeof(tmp),"%s",path);
len = strlen(tmp);
if (len == 0) {
return true;
}
if(tmp[len - 1] == DIR_SEPARATOR) {
tmp[len - 1] = 0;
}
for(p = tmp + 1; *p; p++) {
if (*p == DIR_SEPARATOR) {
*p = 0;
if (!os::mkdir(tmp)) {
return false;
}
*p = DIR_SEPARATOR;
}
}
return os::mkdir(tmp);
}
bool rmpath(const std::string &path)
{
return os::rmpath(path.c_str());
}
bool rmpath(const char *path)
{
// change next to last path segment
std::vector<char> pathcopy(path, path+::strlen(path)+1);
std::vector<std::string> segments;
#ifdef _WIN32
char *next_token = nullptr;
char *segment = ::strtok_s(pathcopy.data(), DIR_SEPARATOR_STRING, &next_token);
#else
char *segment = ::strtok(pathcopy.data(), DIR_SEPARATOR_STRING);
#endif
while (segment != nullptr) {
os::chdir(segment);
segments.emplace_back(segment);
#ifdef _WIN32
segment = ::strtok_s(nullptr, DIR_SEPARATOR_STRING, &next_token);
#else
segment = ::strtok(nullptr, DIR_SEPARATOR_STRING);
#endif
}
auto first = segments.rbegin();
for (auto it=first; it!=segments.rend(); ++it) {
os::chdir("..");
os::rmdir(*it);
}
return true;
}
bool is_readable(const std::string &path)
{
return is_readable(path.c_str());
}
bool is_readable(const char *path)
{
return os::access(path, 2);
}
bool is_writable(const std::string &path)
{
return is_writable(path.c_str());
}
bool is_writable(const char *path)
{
return os::access(path, 4);
}
bool exists(const std::string &path)
{
return exists(path.c_str());
}
bool exists(const char *path)
{
return os::access(path, 0);
}
size_t file_size(FILE *stream)
{
#ifdef _WIN32
int fd = _fileno(stream);
return ::_filelength(fd);
#else
int fd = ::fileno(stream);
struct stat buf{};
::fstat(fd, &buf);
return buf.st_size;
#endif
}
std::string build_path(const std::string &a, const std::string &b)
{
return a + DIR_SEPARATOR_STRING + b;
}
char* strerror(int err, char* errbuf, size_t bufsize)
{
#ifdef _WIN32
::strerror_s(errbuf, bufsize, err);
return errbuf;
#else
auto msg = ::strerror(err);
auto s = strlen(msg);
if (s < bufsize - 1) {
return strcpy(errbuf, msg);
} else {
errbuf[bufsize - 1] = '\0';
return strncpy(errbuf, msg, bufsize - 1);
}
#endif
}
}
+81
View File
@@ -0,0 +1,81 @@
#include "matador/utils/string.hpp"
#include "matador/utils/export.hpp"
#include <sstream>
namespace matador::utils {
std::string to_string(const blob& data) {
static constexpr char HEXITS[] = "0123456789ABCDEF";
std::string str(2 * data.size(), '\0');
auto item = str.begin();
for(const auto c : data) {
*item++ = HEXITS[c >> 4];
*item++ = HEXITS[c & 0x0F];
}
return str;
}
size_t split(const std::string &str, char delim, std::vector<std::string> &values)
{
std::stringstream ss(str);
std::string item;
while (std::getline(ss, item, delim)) {
values.push_back(item);
}
return values.size();
}
std::vector<std::string> split(const std::string &str, char delim)
{
std::stringstream ss(str);
std::string item;
std::vector<std::string> result;
while (std::getline(ss, item, delim)) {
result.push_back(item);
}
return result;
}
size_t split(const std::string &str, const char delim, std::list<std::string> &values)
{
std::stringstream ss(str);
std::string item;
while (std::getline(ss, item, delim)) {
values.push_back(item);
}
return values.size();
}
#ifdef _MSC_VER
// const char* date_format::ISO8601 = "%Y-%m-%d";
// const char* time_format::ISO8601 = "%Y-%m-%dT%H:%M:%S";
#endif
std::string trim(const std::string& str, const std::string& whitespace)
{
const auto first = str.find_first_not_of(whitespace);
if (first == std::string::npos)
return ""; // no content
const auto end = str.find_last_not_of(whitespace);
const auto range = end - first + 1;
return str.substr(first, range);
}
void replace_all(std::string &in, const std::string &from, const std::string &to)
{
if(from.empty()) {
return;
}
size_t start_pos = 0;
while((start_pos = in.find(from, start_pos)) != std::string::npos) {
in.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
}
+61
View File
@@ -0,0 +1,61 @@
#include "matador/utils/types.hpp"
#include "matador/utils/basic_types.hpp"
namespace matador::utils {
void initialize_by_basic_type(const basic_type type, database_type &val)
{
switch (type) {
case basic_type::type_int8:
val.emplace<int8_t>();
break;
case basic_type::type_int16:
val.emplace<int16_t>();
break;
case basic_type::type_int32:
val.emplace<int32_t>();
break;
case basic_type::type_int64:
val.emplace<int64_t>();
break;
case basic_type::type_uint8:
val.emplace<uint8_t>();
break;
case basic_type::type_uint16:
val.emplace<uint16_t>();
break;
case basic_type::type_uint32:
val.emplace<uint32_t>();
break;
case basic_type::type_uint64:
val.emplace<uint64_t>();
break;
case basic_type::type_bool:
val.emplace<bool>();
break;
case basic_type::type_float:
val.emplace<float>();
break;
case basic_type::type_double:
val.emplace<double>();
break;
case basic_type::type_varchar:
case basic_type::type_text:
val.emplace<std::string>();
break;
// case basic_type::type_date:
// val.emplace<date>();
// break;
// case basic_type::type_time:
// val.emplace<time>();
// break;
case basic_type::type_blob:
val.emplace<utils::blob>();
break;
default:
val.emplace<nullptr_t>();
}
}
}
+109
View File
@@ -0,0 +1,109 @@
#include "matador/utils/value.hpp"
#include <cstring>
namespace matador::utils {
namespace detail {
size_t determine_size(const std::string &val)
{
return val.size();
}
size_t determine_size(const char *val)
{
return strlen(val);
}
size_t determine_size(const blob &val)
{
return val.size();
}
}
value::value(const basic_type data_type, const size_t size)
: size_(size)
, type_(data_type)
{
initialize_by_basic_type(type_, value_);
}
value::value(value &&x) noexcept
: value_(std::move(x.value_))
, type_(x.type_)
{
x.value_ = nullptr;
x.type_ = basic_type::type_null;
}
value &value::operator=(value &&x) noexcept
{
value_ = std::move(x.value_);
type_ = x.type_;
x.value_ = nullptr;
x.type_ = basic_type::type_null;
return *this;
}
std::string value::str() const
{
return as<std::string>().value_or("");
}
size_t value::size() const
{
return size_;
}
basic_type value::type() const
{
return type_;
}
bool value::is_integer() const
{
return type_ >= basic_type::type_int8 && type_ <= basic_type::type_uint64;
}
bool value::is_floating_point() const
{
return type_ == basic_type::type_float || type_ == basic_type::type_double;
}
bool value::is_bool() const
{
return type_ == basic_type::type_bool;
}
bool value::is_string() const
{
return type_ == basic_type::type_text;
}
bool value::is_varchar() const
{
return type_ == basic_type::type_varchar;
}
bool value::is_date() const
{
return type_ == basic_type::type_date;
}
bool value::is_time() const
{
return type_ == basic_type::type_time;
}
bool value::is_blob() const
{
return type_ == basic_type::type_blob;
}
bool value::is_null() const
{
return type_ == basic_type::type_null;
}
}
+100
View File
@@ -0,0 +1,100 @@
#include <matador/utils/version.hpp>
#include <matador/utils/errors.hpp>
namespace matador::utils {
version::version(unsigned int major, unsigned int minor, unsigned int patch)
: major_(major)
, minor_(minor)
, patch_(patch)
{}
bool version::operator==(const version &x) const
{
return major_ == x.major_ &&
minor_ == x.minor_ &&
patch_ == x.patch_;
}
bool version::operator!=(const version &x) const
{
return !(*this == x);
}
bool version::operator>(const version &x) const
{
return !(*this <= x);
}
bool version::operator>=(const version &x) const
{
return !(*this < x);
}
bool version::operator<(const version &x) const
{
return (major_ < x.major_) ||
(major_ == x.major_ && minor_ < x.minor_) ||
(major_ == x.major_ && minor_ == x.minor_ && patch_ < x.patch_);
}
bool version::operator<=(const version &x) const
{
return *this < x || *this == x;
}
std::string version::str() const
{
char buf[32];
sprintf(buf, "%d.%d.%d", major_, minor_, patch_);
return buf;
}
std::ostream &operator<<(std::ostream &out, const version &v)
{
out << v.str();
return out;
}
result<version, error> version::from_string(const std::string &version_string)
{
version result;
if (const auto ret = sscanf(version_string.c_str(), "%u.%u.%u", &result.major_, &result.minor_, &result.patch_); ret != 3) {
return failure(error(utils_error::InvalidVersionString, version_string));
}
return ok(result);
}
unsigned int version::major() const
{
return major_;
}
unsigned int version::minor() const
{
return minor_;
}
unsigned int version::patch() const
{
return patch_;
}
void version::major(unsigned int m)
{
major_ = m;
}
void version::minor(unsigned int m)
{
minor_ = m;
}
void version::patch(unsigned int p)
{
patch_ = p;
}
}