implemented specialization of data types via type traits and handling of embedded non-trivial types

This commit is contained in:
2023-12-10 22:40:01 +01:00
parent da423ea8bb
commit 8ad13076c8
17 changed files with 346 additions and 90 deletions
+2
View File
@@ -1,6 +1,8 @@
#ifndef QUERY_CONNECTION_POOL_HPP
#define QUERY_CONNECTION_POOL_HPP
#include "matador/sql/connection_info.hpp"
#include <chrono>
#include <mutex>
#include <string>
+2 -2
View File
@@ -1,6 +1,8 @@
#ifndef QUERY_OBJECT_BINDER_HPP
#define QUERY_OBJECT_BINDER_HPP
#include "matador/sql/parameter_binder.hpp"
#include "matador/utils/cascade_type.hpp"
#include "matador/utils/field_attributes.hpp"
@@ -8,8 +10,6 @@
namespace matador::sql {
class parameter_binder;
class object_binder
{
public:
+4 -4
View File
@@ -35,9 +35,9 @@ public:
template < class Type >
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template < class Pointer >
void on_belongs_to(const char *id, Pointer &x, utils::cascade_type) {}
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
template < class Pointer >
void on_has_one(const char *id, Pointer &x, utils::cascade_type) {}
void on_has_one(const char * /*id*/, Pointer &/*x*/, utils::cascade_type) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
@@ -59,7 +59,7 @@ public:
template<typename ValueType>
void on_primary_key(const char *id, ValueType &value, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
{
reader_->read_value(id, column_index_++, value);
data_type_traits<ValueType>::read_value(*reader_, id, column_index_++, value);
}
void on_primary_key(const char *id, std::string &value, size_t size);
void on_revision(const char *id, unsigned long long &rev);
@@ -67,7 +67,7 @@ public:
template < class Type >
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes)
{
reader_->read_value(id, column_index_++, x);
data_type_traits<Type>::read_value(*reader_, id, column_index_++, x);
}
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);
+95 -65
View File
@@ -6,6 +6,8 @@
namespace matador::sql {
class query_result_reader;
/**
* @brief Enumeration type of all supported builtin data types
*/
@@ -71,136 +73,152 @@ enum class sql_function_t {
* provide the correct size information
* for a data type
*/
template < class T >
template < class Type, class Enable = void >
struct data_type_traits;
/// @cond MATADOR_DEV
template <> struct data_type_traits<char>
template <> struct data_type_traits<char, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; }
inline static unsigned long size() { return sizeof(char); }
inline static const char* name() { return "char"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, char &value);
// inline static unsigned long size() { return sizeof(char); }
// inline static const char* name() { return "char"; }
};
template <> struct data_type_traits<short>
template <> struct data_type_traits<short, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_short; }
inline static unsigned long size() { return sizeof(short); }
inline static const char* name() { return "short"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, short &value);
// inline static unsigned long size() { return sizeof(short); }
// inline static const char* name() { return "short"; }
};
template <> struct data_type_traits<int>
template <> struct data_type_traits<int, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; }
inline static unsigned long size() { return sizeof(int); }
inline static const char* name() { return "int"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, int &value);
// inline static unsigned long size() { return sizeof(int); }
// inline static const char* name() { return "int"; }
};
template <> struct data_type_traits<long>
template <> struct data_type_traits<long, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_long; }
inline static unsigned long size() { return sizeof(long); }
inline static const char* name() { return "long"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, long &value);
// inline static unsigned long size() { return sizeof(long); }
// inline static const char* name() { return "long"; }
};
template <> struct data_type_traits<long long>
template <> struct data_type_traits<long long, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_long_long; }
inline static unsigned long size() { return sizeof(long long); }
inline static const char* name() { return "long long"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, long long &value);
// inline static unsigned long size() { return sizeof(long long); }
// inline static const char* name() { return "long long"; }
};
template <> struct data_type_traits<unsigned char>
template <> struct data_type_traits<unsigned char, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_char; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_char; }
inline static unsigned long size() { return sizeof(unsigned char); }
inline static const char* name() { return "unsigned char"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value);
// inline static unsigned long size() { return sizeof(unsigned char); }
// inline static const char* name() { return "unsigned char"; }
};
template <> struct data_type_traits<unsigned short>
template <> struct data_type_traits<unsigned short, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_smallint; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_short; }
inline static unsigned long size() { return sizeof(unsigned short); }
inline static const char* name() { return "unsigned short"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value);
// inline static unsigned long size() { return sizeof(unsigned short); }
// inline static const char* name() { return "unsigned short"; }
};
template <> struct data_type_traits<unsigned int>
template <> struct data_type_traits<unsigned int, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_int; }
inline static unsigned long size() { return sizeof(unsigned int); }
inline static const char* name() { return "unsigned int"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value);
// inline static unsigned long size() { return sizeof(unsigned int); }
// inline static const char* name() { return "unsigned int"; }
};
template <> struct data_type_traits<unsigned long>
template <> struct data_type_traits<unsigned long, void>
{
inline static database_type_t type(std::size_t /*size*/ = 0) { return database_type_t::type_bigint; }
// inline static database_type_t type(std::size_t /*size*/ = 0) { return database_type_t::type_bigint; }
inline static data_type_t builtin_type(std::size_t /*size*/ = 0) { return data_type_t::type_unsigned_long; }
inline static unsigned long size() { return sizeof(unsigned long); }
inline static const char* name() { return "unsigned long"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value);
// inline static unsigned long size() { return sizeof(unsigned long); }
// inline static const char* name() { return "unsigned long"; }
};
template <> struct data_type_traits<unsigned long long>
template <> struct data_type_traits<unsigned long long, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bigint; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_unsigned_long_long; }
inline static unsigned long size() { return sizeof(unsigned long long); }
inline static const char* name() { return "unsigned long long"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value);
// inline static unsigned long size() { return sizeof(unsigned long long); }
// inline static const char* name() { return "unsigned long long"; }
};
template <> struct data_type_traits<bool>
template <> struct data_type_traits<bool, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bool; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_bool; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_bool; }
inline static unsigned long size() { return sizeof(bool); }
inline static const char* name() { return "bool"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, bool &value);
// inline static unsigned long size() { return sizeof(bool); }
// inline static const char* name() { return "bool"; }
};
template <> struct data_type_traits<float>
template <> struct data_type_traits<float, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_float; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_float; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_float; }
inline static unsigned long size() { return sizeof(float); }
inline static const char* name() { return "float"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, float &value);
// inline static unsigned long size() { return sizeof(float); }
// inline static const char* name() { return "float"; }
};
template <> struct data_type_traits<double>
template <> struct data_type_traits<double, void>
{
inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_double; }
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_double; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_double; }
inline static unsigned long size() { return sizeof(double); }
inline static const char* name() { return "double"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, double &value);
// inline static unsigned long size() { return sizeof(double); }
// inline static const char* name() { return "double"; }
};
template <> struct data_type_traits<const char*>
template <> struct data_type_traits<const char*, void>
{
inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_char_pointer; }
inline static unsigned long size() { return sizeof(const char*); }
inline static const char* name() { return "const char*"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, const char* value, size_t size);
// inline static unsigned long size() { return sizeof(const char*); }
// inline static const char* name() { return "const char*"; }
};
template <> struct data_type_traits<char*>
template <> struct data_type_traits<char*, void>
{
inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; }
inline static unsigned long size() { return sizeof(char*); }
inline static const char* name() { return "char*"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, char *value, size_t size);
// inline static unsigned long size() { return sizeof(char*); }
// inline static const char* name() { return "char*"; }
};
template <> struct data_type_traits<std::string>
template <> struct data_type_traits<std::string, void>
{
inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
// inline static database_type_t type(std::size_t size) { return size == 0 ? database_type_t::type_text : database_type_t::type_varchar; }
inline static data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; }
inline static unsigned long size() { return 1023; }
inline static const char* name() { return "std::string"; }
static void read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size);
// inline static unsigned long size() { return 1023; }
// inline static const char* name() { return "std::string"; }
};
//template <> struct data_type_traits<matador::date>
@@ -219,6 +237,18 @@ template <> struct data_type_traits<std::string>
// inline static const char* name() { return "matador::time"; }
//};
template < typename EnumType >
struct data_type_traits<EnumType, typename std::enable_if<std::is_enum<EnumType>::value>::type>
{
// inline static database_type_t type(std::size_t /*size*/) { return database_type_t::type_int; }
inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; }
static void read_value(query_result_reader &reader, const char *id, size_t index, EnumType &value)
{
data_type_traits<int>::read_value(reader, id, index, reinterpret_cast<int&>(value));
}
// inline static unsigned long size() { return sizeof(int); }
// inline static const char* name() { return "int"; }
};
/// @endcond
}
+6 -1
View File
@@ -56,10 +56,15 @@ public:
private:
template<typename Type>
void append(Type &value)
void append(Type &value, typename std::enable_if<!std::is_enum<Type>::value>::type* = 0)
{
values_.emplace_back(value);
}
template<typename Type>
void append(Type &value, typename std::enable_if<std::is_enum<Type>::value>::type* = 0)
{
values_.emplace_back((int)value);
}
private:
detail::fk_value_extractor fk_value_extractor_;