initial matador ng commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
add_library(matador-core STATIC
|
||||
../../include/matador/utils/access.hpp
|
||||
../../include/matador/utils/attribute_reader.hpp
|
||||
../../include/matador/utils/attribute_writer.hpp
|
||||
../../include/matador/utils/base_class.hpp
|
||||
../../include/matador/utils/basic_type_converter.hpp
|
||||
../../include/matador/utils/basic_types.hpp
|
||||
../../include/matador/utils/cascade_type.hpp
|
||||
../../include/matador/utils/constraints.hpp
|
||||
../../include/matador/utils/convert.hpp
|
||||
../../include/matador/utils/data_type_traits.hpp
|
||||
../../include/matador/utils/default_type_traits.hpp
|
||||
../../include/matador/utils/di.hpp
|
||||
../../include/matador/utils/enum_mapper.hpp
|
||||
../../include/matador/utils/error.hpp
|
||||
../../include/matador/utils/errors.hpp
|
||||
../../include/matador/utils/export.hpp
|
||||
../../include/matador/utils/fetch_type.hpp
|
||||
../../include/matador/utils/field_attributes.hpp
|
||||
../../include/matador/utils/foreign_attributes.hpp
|
||||
../../include/matador/utils/identifier.hpp
|
||||
../../include/matador/utils/library.hpp
|
||||
../../include/matador/utils/os.hpp
|
||||
../../include/matador/utils/placeholder.hpp
|
||||
../../include/matador/utils/result.hpp
|
||||
../../include/matador/utils/singleton.hpp
|
||||
../../include/matador/utils/string.hpp
|
||||
../../include/matador/utils/types.hpp
|
||||
../../include/matador/utils/value.hpp
|
||||
../../include/matador/utils/version.hpp
|
||||
utils/default_type_traits.cpp
|
||||
utils/error.cpp
|
||||
utils/field_attributes.cpp
|
||||
utils/identifier.cpp
|
||||
utils/library.cpp
|
||||
utils/os.cpp
|
||||
utils/string.cpp
|
||||
utils/types.cpp
|
||||
utils/value.cpp
|
||||
utils/version.cpp
|
||||
utils/errors.cpp
|
||||
../../include/matador/object/basic_object_info.hpp
|
||||
../../include/matador/object/error_code.hpp
|
||||
../../include/matador/object/schema.hpp
|
||||
../../include/matador/object/schema_node.hpp
|
||||
object/error_code.cpp
|
||||
object/schema.cpp
|
||||
object/schema_node.cpp
|
||||
object/basic_object_info.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(matador-core ${CMAKE_DL_LIBS})
|
||||
|
||||
target_include_directories(matador-core
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "matador/object/basic_object_info.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
basic_object_info::basic_object_info(schema_node &node, const std::type_index type_index)
|
||||
: node_(node)
|
||||
, type_index_(type_index) {}
|
||||
|
||||
std::type_index basic_object_info::type_index() const { return type_index_; }
|
||||
|
||||
} // namespace matador::object
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "matador/object/error_code.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
const char * object_category_impl::name() const noexcept {
|
||||
return "sql";
|
||||
}
|
||||
|
||||
std::string object_category_impl::message(const int ev) const {
|
||||
switch (static_cast<error_code>(ev)) {
|
||||
case error_code::OK:
|
||||
return "OK";
|
||||
case error_code::NodeNotFound:
|
||||
return "Node not found";
|
||||
case error_code::NodeAlreadyExists:
|
||||
return "Node already exists";
|
||||
case error_code::Failure:
|
||||
return "Failure";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
const std::error_category & object_category() {
|
||||
static object_category_impl instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::error_code make_error_code(error_code e) {
|
||||
return {static_cast<int>(e), object_category()};
|
||||
}
|
||||
|
||||
std::error_condition make_error_condition(error_code e) {
|
||||
return {static_cast<int>(e), object_category()};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "matador/object/schema.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
utils::error make_error(const error_code ec, const std::string& msg) {
|
||||
return utils::error(ec, msg);
|
||||
}
|
||||
|
||||
schema::schema()
|
||||
: root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
|
||||
root_->first_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
|
||||
root_->last_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
|
||||
root_->first_child_->next_sibling_ = root_->last_child_;
|
||||
root_->last_child_->previous_sibling_ = root_->first_child_;
|
||||
}
|
||||
|
||||
bool schema::empty() const {
|
||||
return root_->first_child_ == root_->last_child_->previous_sibling_;
|
||||
}
|
||||
|
||||
size_t schema::size() const { return 0; }
|
||||
|
||||
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
|
||||
const std::string &parent) {
|
||||
if (!has_node(node->type_index(), node->name())) {
|
||||
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
|
||||
}
|
||||
|
||||
// set node to root node
|
||||
auto parent_node = root_;
|
||||
auto result = find_parent(parent);
|
||||
if (!result.is_ok() && result.err().ec() != error_code::NodeNotFound) {
|
||||
return result;
|
||||
}
|
||||
parent_node = *result;
|
||||
|
||||
result = push_back_child(root_, node);
|
||||
|
||||
// if (!pk.is_null()) {
|
||||
// node->primary_key_ = pk;
|
||||
// }
|
||||
// store prototype in map
|
||||
// Todo: check return value
|
||||
node_map_.insert(std::make_pair(node->name(), node))/*.first*/;
|
||||
type_index_node_map_[node->type_index()].insert(std::make_pair(node->name(), node));
|
||||
|
||||
// return nptr.release();
|
||||
return {};
|
||||
}
|
||||
|
||||
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_parent(const std::string &name) const {
|
||||
if (name.empty()) {
|
||||
return utils::failure(make_error(error_code::Failure, "Name of parent cannot be empty"));
|
||||
}
|
||||
|
||||
return find_node(name);
|
||||
}
|
||||
|
||||
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(const std::string &name) const {
|
||||
// first search in the prototype map
|
||||
const auto i = node_map_.find(name);
|
||||
if (i == node_map_.end()) {
|
||||
// if not found search in the typeid to prototype map
|
||||
// const auto j = type_index_node_map_.find(name);
|
||||
// if (j == type_index_node_map_.end()) {
|
||||
// return utils::failure(
|
||||
// make_error(error_code::NodeNotFound, std::string("Could not find node with name '") + name + "'"));
|
||||
// }
|
||||
// const t_node_map &val = j->second;
|
||||
/*
|
||||
* if size is greater one (1) the name
|
||||
* is a typeid and has more than one prototype
|
||||
* node and therefor it is not unique and an
|
||||
* exception is thrown
|
||||
*/
|
||||
// if (val.size() > 1) {
|
||||
// return utils::failure(make_error(error_code::NodeNotFound, std::string("Type id '") + name + "' is not unique"));
|
||||
// }
|
||||
// // return the only prototype
|
||||
// return utils::ok(val.begin()->second);
|
||||
}
|
||||
return utils::ok(i->second);
|
||||
}
|
||||
utils::result<std::shared_ptr<schema_node>, utils::error> schema::push_back_child(const node_ptr &parent, const node_ptr &child) {
|
||||
child->parent_ = parent;
|
||||
child->previous_sibling_ = parent->last_child_->previous_sibling_;
|
||||
child->next_sibling_ = parent->last_child_;
|
||||
parent->last_child_->previous_sibling_->next_sibling_ = child;
|
||||
parent->last_child_->previous_sibling_ = child;
|
||||
// set depth
|
||||
// child->depth = depth + 1;
|
||||
}
|
||||
|
||||
bool schema::has_node(const std::type_index &index, const std::string &name) const {
|
||||
return node_map_.count(name) > 0 || type_index_node_map_.count(index) > 0;
|
||||
}
|
||||
|
||||
} // namespace matador::object
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <utility>
|
||||
|
||||
#include "matador/object/schema_node.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
schema_node::schema_node(schema &tree)
|
||||
: schema_(tree)
|
||||
, info_(std::make_unique<null_info>(*this))
|
||||
{}
|
||||
|
||||
std::string schema_node::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::type_index schema_node::type_index() const {
|
||||
return info_->type_index();
|
||||
}
|
||||
|
||||
void schema_node::append(const std::shared_ptr<schema_node> &sibling) {
|
||||
sibling->parent_ = parent_;
|
||||
|
||||
// sibling->previous_sibling_ = this;
|
||||
// sibling->next_sibling_ = next_sibling_;
|
||||
// next_sibling_ = sibling;
|
||||
// sibling->next_sibling_->previous_sibling_ = sibling;
|
||||
// sibling->depth = depth;
|
||||
|
||||
// if (!parent_) {
|
||||
// sibling->op_first = new object_proxy();
|
||||
// sibling->op_last = sibling->op_marker = new object_proxy();
|
||||
// sibling->op_first->link(sibling->op_last);
|
||||
// } else {
|
||||
// throw object_exception("failed to add node as sibling: node has no parent");
|
||||
// }
|
||||
}
|
||||
|
||||
void schema_node::insert(const std::shared_ptr<schema_node> &child) {
|
||||
// child->parent_ = this;
|
||||
// child->previous_sibling_ = last_child_->previous_sibling_;
|
||||
// child->next_sibling_ = last_child_;
|
||||
// last_child_->previous_sibling_->next_sibling_ = child;
|
||||
// last_child_->previous_sibling_ = child;
|
||||
// set depth
|
||||
// child->depth = depth + 1;
|
||||
// set object proxy pointer
|
||||
// 1. first
|
||||
// if (op_first->next() == op_last) {
|
||||
// // node hasn't any serializable (proxy)
|
||||
// child->op_first = op_first;
|
||||
// } else {
|
||||
// // node has some objects (proxy)
|
||||
// child->op_first = op_last->prev();
|
||||
// }
|
||||
// // 2. marker
|
||||
// child->op_marker = op_last;
|
||||
// // 3. last
|
||||
// child->op_last = op_last;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -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()};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user