implemented specialization of data types via type traits and handling of embedded non-trivial types
This commit is contained in:
parent
da423ea8bb
commit
8ad13076c8
|
|
@ -94,7 +94,11 @@ size_t postgres_connection::execute(const std::string &stmt)
|
||||||
|
|
||||||
throw_postgres_error(res, conn_, "postgres", stmt);
|
throw_postgres_error(res, conn_, "postgres", stmt);
|
||||||
|
|
||||||
return sql::to_long_long(PQcmdTuples(res));
|
const auto affected_rows = sql::to_long_long(PQcmdTuples(res));
|
||||||
|
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
return affected_rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
sql::data_type_t string2type(const char *type)
|
sql::data_type_t string2type(const char *type)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
#include "sqlite_result_reader.hpp"
|
#include "sqlite_result_reader.hpp"
|
||||||
|
|
||||||
#include "matador/sql/to_value.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace matador::backends::sqlite {
|
namespace matador::backends::sqlite {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef QUERY_CONNECTION_POOL_HPP
|
#ifndef QUERY_CONNECTION_POOL_HPP
|
||||||
#define QUERY_CONNECTION_POOL_HPP
|
#define QUERY_CONNECTION_POOL_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/connection_info.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef QUERY_OBJECT_BINDER_HPP
|
#ifndef QUERY_OBJECT_BINDER_HPP
|
||||||
#define QUERY_OBJECT_BINDER_HPP
|
#define QUERY_OBJECT_BINDER_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/parameter_binder.hpp"
|
||||||
|
|
||||||
#include "matador/utils/cascade_type.hpp"
|
#include "matador/utils/cascade_type.hpp"
|
||||||
#include "matador/utils/field_attributes.hpp"
|
#include "matador/utils/field_attributes.hpp"
|
||||||
|
|
||||||
|
|
@ -8,8 +10,6 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
class parameter_binder;
|
|
||||||
|
|
||||||
class object_binder
|
class object_binder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ public:
|
||||||
template < class Type >
|
template < class Type >
|
||||||
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||||
template < class Pointer >
|
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 >
|
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>
|
template<class ContainerType>
|
||||||
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
|
||||||
|
|
@ -59,7 +59,7 @@ public:
|
||||||
template<typename ValueType>
|
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)
|
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_primary_key(const char *id, std::string &value, size_t size);
|
||||||
void on_revision(const char *id, unsigned long long &rev);
|
void on_revision(const char *id, unsigned long long &rev);
|
||||||
|
|
@ -67,7 +67,7 @@ public:
|
||||||
template < class Type >
|
template < class Type >
|
||||||
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
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, 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, std::string &value, const utils::field_attributes &attr = utils::null_attributes);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class query_result_reader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enumeration type of all supported builtin data types
|
* @brief Enumeration type of all supported builtin data types
|
||||||
*/
|
*/
|
||||||
|
|
@ -71,136 +73,152 @@ enum class sql_function_t {
|
||||||
* provide the correct size information
|
* provide the correct size information
|
||||||
* for a data type
|
* for a data type
|
||||||
*/
|
*/
|
||||||
template < class T >
|
template < class Type, class Enable = void >
|
||||||
struct data_type_traits;
|
struct data_type_traits;
|
||||||
|
|
||||||
/// @cond MATADOR_DEV
|
/// @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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_char; }
|
||||||
inline static unsigned long size() { return sizeof(char); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, char &value);
|
||||||
inline static const char* name() { return "char"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_short; }
|
||||||
inline static unsigned long size() { return sizeof(short); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, short &value);
|
||||||
inline static const char* name() { return "short"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; }
|
||||||
inline static unsigned long size() { return sizeof(int); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, int &value);
|
||||||
inline static const char* name() { return "int"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_long; }
|
||||||
inline static unsigned long size() { return sizeof(long); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, long &value);
|
||||||
inline static const char* name() { return "long"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, long long &value);
|
||||||
inline static const char* name() { return "long long"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value);
|
||||||
inline static const char* name() { return "unsigned char"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value);
|
||||||
inline static const char* name() { return "unsigned short"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value);
|
||||||
inline static const char* name() { return "unsigned int"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value);
|
||||||
inline static const char* name() { return "unsigned long"; }
|
// 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 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); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value);
|
||||||
inline static const char* name() { return "unsigned long long"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_bool; }
|
||||||
inline static unsigned long size() { return sizeof(bool); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, bool &value);
|
||||||
inline static const char* name() { return "bool"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_float; }
|
||||||
inline static unsigned long size() { return sizeof(float); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, float &value);
|
||||||
inline static const char* name() { return "float"; }
|
// 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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_double; }
|
||||||
inline static unsigned long size() { return sizeof(double); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, double &value);
|
||||||
inline static const char* name() { return "double"; }
|
// 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 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*); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, const char* value, size_t size);
|
||||||
inline static const char* name() { return "const char*"; }
|
// 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 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*); }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, char *value, size_t size);
|
||||||
inline static const char* name() { return "char*"; }
|
// 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 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; }
|
static void read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size);
|
||||||
inline static const char* name() { return "std::string"; }
|
// inline static unsigned long size() { return 1023; }
|
||||||
|
// inline static const char* name() { return "std::string"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//template <> struct data_type_traits<matador::date>
|
//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"; }
|
// 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
|
/// @endcond
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename Type>
|
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);
|
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:
|
private:
|
||||||
detail::fk_value_extractor fk_value_extractor_;
|
detail::fk_value_extractor fk_value_extractor_;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class container;
|
||||||
class field_attributes;
|
class field_attributes;
|
||||||
|
|
||||||
namespace access {
|
namespace access {
|
||||||
|
|
||||||
template<class Operator, class Type>
|
template<class Operator, class Type>
|
||||||
void process(Operator &op, Type &object) {
|
void process(Operator &op, Type &object) {
|
||||||
object.process(op);
|
object.process(op);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ set(SQL_SOURCES
|
||||||
sql/dialect_builder.cpp
|
sql/dialect_builder.cpp
|
||||||
sql/object_binder.cpp
|
sql/object_binder.cpp
|
||||||
sql/placeholder_generator.cpp
|
sql/placeholder_generator.cpp
|
||||||
|
sql/types.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SQL_HEADER
|
set(SQL_HEADER
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,23 @@ query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&read
|
||||||
|
|
||||||
void query_result_impl::on_primary_key(const char *id, std::string &value, size_t size)
|
void query_result_impl::on_primary_key(const char *id, std::string &value, size_t size)
|
||||||
{
|
{
|
||||||
reader_->read_value(id, column_index_++, value, size);
|
data_type_traits<std::string>::read_value(*reader_, id, column_index_++, value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_revision(const char *id, unsigned long long int &rev)
|
void query_result_impl::on_revision(const char *id, unsigned long long int &rev)
|
||||||
{
|
{
|
||||||
|
data_type_traits<unsigned long long int>::read_value(*reader_, id, column_index_++, rev);
|
||||||
reader_->read_value(id, column_index_++, rev);
|
reader_->read_value(id, column_index_++, rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr)
|
void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr)
|
||||||
{
|
{
|
||||||
reader_->read_value(id, column_index_++, value, attr.size());
|
data_type_traits<char*>::read_value(*reader_, id, column_index_++, value, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr)
|
void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr)
|
||||||
{
|
{
|
||||||
reader_->read_value(id, column_index_++, value, attr.size());
|
data_type_traits<std::string>::read_value(*reader_, id, column_index_++, value, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "matador/sql/types.hpp"
|
||||||
|
|
||||||
|
#include "matador/sql/query_result_reader.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
void data_type_traits<char>::read_value(query_result_reader &reader, const char *id, size_t index, char &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<short>::read_value(query_result_reader &reader, const char *id, size_t index, short &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<int>::read_value(query_result_reader &reader, const char *id, size_t index, int &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<long>::read_value(query_result_reader &reader, const char *id, size_t index, long &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<long long>::read_value(query_result_reader &reader, const char *id, size_t index, long long &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<unsigned char>::read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<unsigned short>::read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<unsigned int>::read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<unsigned long>::read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<unsigned long long>::read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<bool>::read_value(query_result_reader &reader, const char *id, size_t index, bool &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
void data_type_traits<float>::read_value(query_result_reader &reader, const char *id, size_t index, float &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
void data_type_traits<double>::read_value(query_result_reader &reader, const char *id, size_t index, double &value)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<const char*>::read_value(query_result_reader &reader, const char *id, size_t index, const char* value, size_t size)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, const_cast<char*>(value), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<char*>::read_value(query_result_reader &reader, const char *id, size_t index, char* value, size_t size)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void data_type_traits<std::string>::read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size)
|
||||||
|
{
|
||||||
|
reader.read_value(id, index, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,11 @@ add_executable(tests QueryBuilderTest.cpp
|
||||||
ColumnTest.cpp
|
ColumnTest.cpp
|
||||||
SessionRecordTest.cpp
|
SessionRecordTest.cpp
|
||||||
StatementCacheTest.cpp
|
StatementCacheTest.cpp
|
||||||
StatementTest.cpp)
|
StatementTest.cpp
|
||||||
|
models/coordinate.hpp
|
||||||
|
models/location.hpp
|
||||||
|
TypeTraitsTest.cpp
|
||||||
|
Databases.hpp)
|
||||||
target_link_libraries(tests PRIVATE
|
target_link_libraries(tests PRIVATE
|
||||||
Catch2::Catch2WithMain
|
Catch2::Catch2WithMain
|
||||||
matador
|
matador
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef QUERY_DATABASES_HPP
|
||||||
|
#define QUERY_DATABASES_HPP
|
||||||
|
|
||||||
|
struct Postgres
|
||||||
|
{
|
||||||
|
// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"};
|
||||||
|
constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Sqlite
|
||||||
|
{
|
||||||
|
constexpr static const char *dns{"sqlite://sqlite.db"};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //QUERY_DATABASES_HPP
|
||||||
|
|
@ -7,22 +7,13 @@
|
||||||
#include "matador/sql/connection_pool.hpp"
|
#include "matador/sql/connection_pool.hpp"
|
||||||
#include "matador/sql/session.hpp"
|
#include "matador/sql/session.hpp"
|
||||||
|
|
||||||
|
#include "Databases.hpp"
|
||||||
|
|
||||||
#include "models/airplane.hpp"
|
#include "models/airplane.hpp"
|
||||||
|
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::test;
|
using namespace matador::test;
|
||||||
|
|
||||||
struct Postgres
|
|
||||||
{
|
|
||||||
// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"};
|
|
||||||
constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sqlite
|
|
||||||
{
|
|
||||||
constexpr static const char *dns{"sqlite://sqlite.db"};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
class StatementTestFixture
|
class StatementTestFixture
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/catch_template_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/sql/connection_pool.hpp"
|
||||||
|
#include "matador/sql/session.hpp"
|
||||||
|
|
||||||
|
#include "Databases.hpp"
|
||||||
|
|
||||||
|
#include "models/location.hpp"
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
using namespace matador::test;
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
using namespace matador::test;
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
class TypeTraitsTestFixture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TypeTraitsTestFixture()
|
||||||
|
: pool_(Type::dns, 4), session_(pool_)
|
||||||
|
{
|
||||||
|
auto res = session_.create()
|
||||||
|
.table<location>("location")
|
||||||
|
.execute();
|
||||||
|
REQUIRE(res.first == 0);
|
||||||
|
REQUIRE(res.second == R"(CREATE TABLE "location" ("id" BIGINT, "name" VARCHAR(255), "coordinate_x" INTEGER, "coordinate_y" INTEGER, "coordinate_z" INTEGER, "color" INTEGER, CONSTRAINT PK_location PRIMARY KEY (id)))");
|
||||||
|
}
|
||||||
|
|
||||||
|
~TypeTraitsTestFixture()
|
||||||
|
{
|
||||||
|
session_.drop().table("location").execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
matador::sql::session &session()
|
||||||
|
{ return session_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
matador::sql::connection_pool<matador::sql::connection> pool_;
|
||||||
|
matador::sql::session session_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEMPLATE_TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]", Sqlite, Postgres)
|
||||||
|
{
|
||||||
|
auto &s = TypeTraitsTestFixture<TestType>::session();
|
||||||
|
|
||||||
|
location loc{1, "center", {1, 2, 3}, Color::Black};
|
||||||
|
|
||||||
|
auto res = s.insert().template into<location>("location").values(loc).execute();
|
||||||
|
REQUIRE(res.first == 1);
|
||||||
|
|
||||||
|
auto result = s.template select<location>().from("location").template fetch_all<location>();
|
||||||
|
|
||||||
|
for (const auto &l : result) {
|
||||||
|
REQUIRE(l.name == "center");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef QUERY_COORDINATE_HPP
|
||||||
|
#define QUERY_COORDINATE_HPP
|
||||||
|
|
||||||
|
#include "matador/utils/access.hpp"
|
||||||
|
|
||||||
|
namespace matador::test {
|
||||||
|
struct coordinate
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace matador::utils::access {
|
||||||
|
|
||||||
|
template<class Operator>
|
||||||
|
void attribute(Operator &op, const char *id, test::coordinate &value, const field_attributes &attr = null_attributes) {
|
||||||
|
attribute(op, (std::string(id) + "_x").c_str(), value.x, attr);
|
||||||
|
attribute(op, (std::string(id) + "_y").c_str(), value.y, attr);
|
||||||
|
attribute(op, (std::string(id) + "_z").c_str(), value.z, attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif //QUERY_COORDINATE_HPP
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef QUERY_LOCATION_HPP
|
||||||
|
#define QUERY_LOCATION_HPP
|
||||||
|
|
||||||
|
#include "matador/utils/access.hpp"
|
||||||
|
|
||||||
|
#include "coordinate.hpp"
|
||||||
|
|
||||||
|
namespace matador::test {
|
||||||
|
|
||||||
|
enum class Color : uint8_t {
|
||||||
|
Green, Red, Blue, Yellow, Black, White, Brown
|
||||||
|
};
|
||||||
|
|
||||||
|
struct location
|
||||||
|
{
|
||||||
|
unsigned long id;
|
||||||
|
std::string name;
|
||||||
|
coordinate coord;
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
template < class Operator >
|
||||||
|
void process(Operator &op)
|
||||||
|
{
|
||||||
|
namespace field = matador::utils::access;
|
||||||
|
field::primary_key(op, "id", id);
|
||||||
|
field::attribute(op, "name", name, 255);
|
||||||
|
field::attribute(op, "coordinate", coord);
|
||||||
|
field::attribute(op, "color", color);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //QUERY_LOCATION_HPP
|
||||||
Loading…
Reference in New Issue