added value class
This commit is contained in:
@@ -53,6 +53,15 @@ template < class Type, class Enable = void >
|
||||
struct data_type_traits;
|
||||
|
||||
/// @cond MATADOR_DEV
|
||||
template <> struct data_type_traits<nullptr_t, void>
|
||||
{
|
||||
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_null; }
|
||||
static void read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/);
|
||||
static void bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/);
|
||||
static void bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/);
|
||||
inline static any_type create_value(char &value) { return value; }
|
||||
};
|
||||
|
||||
template <> struct data_type_traits<char, void>
|
||||
{
|
||||
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; }
|
||||
@@ -199,7 +208,7 @@ template <> struct data_type_traits<std::string, void>
|
||||
|
||||
template <> struct data_type_traits<utils::blob, void>
|
||||
{
|
||||
inline static data_type_t builtin_type(std::size_t size) { return data_type_t::type_blob; }
|
||||
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_blob; }
|
||||
static void read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value);
|
||||
static void bind_value(parameter_binder &binder, size_t index, utils::blob &value);
|
||||
static void bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "matador/sql/query_context.hpp"
|
||||
#include "matador/sql/query.hpp"
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
#include "matador/sql/value.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -24,20 +25,19 @@ struct entity_query_data {
|
||||
std::unique_ptr<basic_condition> where_clause;
|
||||
};
|
||||
|
||||
template < typename PrimaryKeyType >
|
||||
class entity_query_builder
|
||||
{
|
||||
public:
|
||||
explicit entity_query_builder(const PrimaryKeyType &pk, const schema &scm)
|
||||
: pk_(pk)
|
||||
, schema_(scm) {}
|
||||
explicit entity_query_builder(const schema &scm)
|
||||
: schema_(scm) {}
|
||||
|
||||
template<class EntityType>
|
||||
std::optional<entity_query_data> build() {
|
||||
template<class EntityType, typename PrimaryKeyType>
|
||||
std::optional<entity_query_data> build(const PrimaryKeyType &pk) {
|
||||
const auto info = schema_.info<EntityType>();
|
||||
if (!info) {
|
||||
return std::nullopt;
|
||||
}
|
||||
pk_ = pk;
|
||||
table_info_stack_.push(info.value());
|
||||
entity_query_data_ = { info->name };
|
||||
EntityType obj;
|
||||
@@ -50,24 +50,13 @@ public:
|
||||
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
||||
{
|
||||
push(id);
|
||||
if (is_root_entity() && std::is_integral_v<PrimaryKeyType>) {
|
||||
entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == pk_);
|
||||
if (is_root_entity() && pk_.is_integer()) {
|
||||
entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == *pk_.as<V>());
|
||||
}
|
||||
}
|
||||
|
||||
void on_primary_key(const char *id, std::string &, size_t)
|
||||
{
|
||||
push(id);
|
||||
if (!is_root_entity()) {
|
||||
auto b = std::is_same_v<PrimaryKeyType, std::string>;
|
||||
std::cout << "is matching primary key: " << std::boolalpha << b << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void on_revision(const char *id, unsigned long long &/*rev*/)
|
||||
{
|
||||
push(id);
|
||||
}
|
||||
void on_primary_key(const char *id, std::string &, size_t);
|
||||
void on_revision(const char *id, unsigned long long &/*rev*/);
|
||||
|
||||
template<typename Type>
|
||||
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||
@@ -174,26 +163,12 @@ public:
|
||||
void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &/*attr*/) {}
|
||||
|
||||
private:
|
||||
void push(const std::string &column_name)
|
||||
{
|
||||
char str[4];
|
||||
snprintf(str, 4, "c%02d", ++column_index);
|
||||
entity_query_data_.columns.emplace_back(table_info_stack_.top().name, column_name, str);
|
||||
}
|
||||
void push(const std::string &column_name);
|
||||
[[nodiscard]] bool is_root_entity() const;
|
||||
void append_join(const column &left, const column &right);
|
||||
|
||||
[[nodiscard]] bool is_root_entity() const {
|
||||
return table_info_stack_.size() == 1;
|
||||
}
|
||||
|
||||
void append_join(const column &left, const column &right)
|
||||
{
|
||||
entity_query_data_.joins.push_back({
|
||||
{ left.table },
|
||||
make_condition(left == right)
|
||||
});
|
||||
}
|
||||
private:
|
||||
PrimaryKeyType pk_;
|
||||
value pk_;
|
||||
std::stack<table_info> table_info_stack_;
|
||||
const schema &schema_;
|
||||
entity_query_data entity_query_data_;
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#ifndef QUERY_FIELD_HPP
|
||||
#define QUERY_FIELD_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/types.hpp"
|
||||
#include "matador/sql/value.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -19,10 +15,8 @@ public:
|
||||
template<typename Type>
|
||||
field(std::string name, Type value, size_t size = 0, int index = -1)
|
||||
: name_(std::move(name))
|
||||
, size_(size)
|
||||
, index_(index)
|
||||
, value_(value)
|
||||
, type_(data_type_traits<Type>::builtin_type(size)) {}
|
||||
, value_(value, size) {}
|
||||
field(std::string name, data_type_t data_type, size_t size = 0, int index = -1);
|
||||
field(const field &x) = default;
|
||||
field& operator=(const field &x) = default;
|
||||
@@ -32,7 +26,7 @@ public:
|
||||
template<typename Type>
|
||||
field& operator=(Type value) {
|
||||
value_ = std::move(value);
|
||||
type_ = data_type_traits<Type>::builtin_type(-1);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -43,9 +37,7 @@ public:
|
||||
template<class Type>
|
||||
std::optional<Type> as() const
|
||||
{
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
return value_.as<Type>();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string str() const;
|
||||
@@ -65,7 +57,7 @@ private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, size_);
|
||||
op.on_attribute(name_.c_str(), value_, value_.size());
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -73,9 +65,8 @@ private:
|
||||
|
||||
std::string name_;
|
||||
int index_{-1};
|
||||
any_type value_;
|
||||
size_t size_{};
|
||||
data_type_t type_;
|
||||
|
||||
value value_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class value;
|
||||
|
||||
namespace detail {
|
||||
class pk_reader
|
||||
{
|
||||
@@ -74,7 +76,7 @@ public:
|
||||
}
|
||||
void on_attribute(const char *id, char *value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, any_type &value, data_type_t type, const utils::field_attributes &attr = utils::null_attributes);
|
||||
void on_attribute(const char *id, value &val, const utils::field_attributes &attr = utils::null_attributes);
|
||||
|
||||
template < class Pointer >
|
||||
void on_belongs_to(const char * /*id*/, Pointer &x, const utils::foreign_attributes &attr)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class value;
|
||||
|
||||
class query_result_reader
|
||||
{
|
||||
public:
|
||||
@@ -34,7 +36,7 @@ public:
|
||||
virtual void read_value(const char *id, size_t index, std::string &value);
|
||||
virtual void read_value(const char *id, size_t index, std::string &value, size_t s);
|
||||
virtual void read_value(const char *id, size_t index, utils::blob &value);
|
||||
virtual void read_value(const char *id, size_t index, any_type &value, data_type_t type, size_t size);
|
||||
virtual void read_value(const char *id, size_t index, value &val, size_t size);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
entity_query_builder<PrimaryKeyType> eqb(pk, *schema_);
|
||||
auto data = eqb.template build<Type>();
|
||||
entity_query_builder eqb(*schema_);
|
||||
auto data = eqb.build<Type>(pk);
|
||||
|
||||
auto q = c->query(*schema_)
|
||||
.select(data->columns)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef QUERY_VALUE_HPP
|
||||
#define QUERY_VALUE_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
namespace detail {
|
||||
template<typename Type>
|
||||
size_t determine_size(const Type &/*val*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
size_t determine_size(const std::string &val);
|
||||
size_t determine_size(const char *val);
|
||||
size_t determine_size(const utils::blob &val);
|
||||
|
||||
}
|
||||
class value
|
||||
{
|
||||
public:
|
||||
value() = default;
|
||||
template<typename Type>
|
||||
explicit value(Type value, size_t size = 0)
|
||||
: size_(size)
|
||||
, value_(value)
|
||||
, type_(data_type_traits<Type>::builtin_type(size)) {}
|
||||
explicit value(data_type_t data_type, size_t size = 0);
|
||||
value(const value &x) = default;
|
||||
value& operator=(const value &x) = default;
|
||||
template<typename Type>
|
||||
value& operator=(Type val)
|
||||
{
|
||||
value_ = val;
|
||||
size_ = detail::determine_size(val);
|
||||
type_ = data_type_traits<Type>::builtin_type(size_);
|
||||
return *this;
|
||||
}
|
||||
value(value &&x) noexcept;
|
||||
value& operator=(value &&x) noexcept;
|
||||
|
||||
template<class Type>
|
||||
std::optional<Type> as() const
|
||||
{
|
||||
if (std::holds_alternative<Type>(value_)) {
|
||||
return std::get<Type>(value_);
|
||||
} else {
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type &>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
}
|
||||
[[nodiscard]] std::string str() const;
|
||||
|
||||
[[nodiscard]] size_t size() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
|
||||
[[nodiscard]] bool is_integer() const;
|
||||
[[nodiscard]] bool is_floating_point() const;
|
||||
[[nodiscard]] bool is_bool() const;
|
||||
[[nodiscard]] bool is_string() const;
|
||||
[[nodiscard]] bool is_varchar() const;
|
||||
[[nodiscard]] bool is_blob() const;
|
||||
[[nodiscard]] bool is_null() const;
|
||||
[[nodiscard]] bool is_unknown() const;
|
||||
|
||||
private:
|
||||
any_type value_;
|
||||
size_t size_{};
|
||||
data_type_t type_{data_type_t::type_unknown};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_VALUE_HPP
|
||||
Reference in New Issue
Block a user