added data binding traits

This commit is contained in:
2023-12-11 17:20:42 +01:00
parent 8ad13076c8
commit 1c92e07173
17 changed files with 378 additions and 146 deletions
+74 -25
View File
@@ -2,7 +2,9 @@
#define QUERY_OBJECT_BINDER_HPP
#include "matador/sql/parameter_binder.hpp"
#include "matador/sql/types.hpp"
#include "matador/utils/access.hpp"
#include "matador/utils/cascade_type.hpp"
#include "matador/utils/field_attributes.hpp"
@@ -10,37 +12,31 @@
namespace matador::sql {
class object_binder
namespace detail {
class fk_binder
{
public:
explicit object_binder(parameter_binder &binder);
explicit fk_binder(parameter_binder &binder);
void reset();
template < class V >
void on_primary_key(const char *id, V &val, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
template<class Type>
void bind(Type &obj, size_t column_index)
{
binder_.bind(index_++, val);
}
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 &val, const utils::field_attributes &/*attr*/ = utils::null_attributes)
{
binder_.bind(index_++, val);
index_ = column_index;
utils::access::process(*this, obj);
}
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char *id, Pointer<Type> &x, utils::cascade_type)
{
// binder_.bind(index_++, val);
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, utils::cascade_type)
{
// binder_.bind(index_++, val);
}
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, std::string &value, size_t size);
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
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) {}
template < class Pointer >
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) {}
template<class ContainerType>
@@ -51,5 +47,58 @@ private:
size_t index_{0};
};
}
class object_binder
{
public:
explicit object_binder(parameter_binder &binder);
void reset();
template < class Type >
void on_primary_key(const char *id, Type &val, typename std::enable_if<std::is_integral<Type>::value && !std::is_same<bool, Type>::value>::type* = 0)
{
data_type_traits<Type>::bind_value(binder_, index_++, val);
}
void on_primary_key(const char *id, std::string &, size_t size);
void on_revision(const char *id, unsigned long long &/*rev*/);
template<typename Type>
void on_attribute(const char *id, Type &val, const utils::field_attributes &/*attr*/ = utils::null_attributes)
{
data_type_traits<Type>::bind_value(binder_, index_++, val);
}
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char *id, Pointer<Type> &x, utils::cascade_type)
{
fk_binder_.bind(index_++, x);
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, utils::cascade_type)
{
fk_binder_.bind(index_++, x);
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, utils::cascade_type) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, utils::cascade_type) {}
private:
parameter_binder &binder_;
size_t index_{0};
detail::fk_binder fk_binder_;
};
namespace detail {
template<typename ValueType>
void fk_binder::on_primary_key(const char *id, ValueType &value, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type *)
{
data_type_traits<ValueType>::bind_value(binder_, index_++, value);
}
}
}
#endif //QUERY_OBJECT_BINDER_HPP
+1 -1
View File
@@ -123,7 +123,7 @@ namespace detail {
template<typename ValueType>
void detail::pk_reader::on_primary_key(const char *id, ValueType &value, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type *)
{
reader_.read_value(id, column_index_++, value);
data_type_traits<ValueType>::read_value(reader_, id, column_index_++, value);
}
}
+2
View File
@@ -23,6 +23,8 @@ public:
return *this;
}
statement& bind(size_t pos, const char *value);
statement& bind(size_t pos, std::string &val, size_t size);
template < class Type >
+3 -2
View File
@@ -14,14 +14,15 @@ class connection;
struct cache_info
{
std::unique_ptr<statement> statement_;
statement statement_;
// std::unique_ptr<statement> statement_;
size_t connection_id_;
};
class statement_cache
{
public:
statement& acquire(const std::string &stmt, const connection &conn);
statement& acquire(query_context &&context, const connection &conn);
void release(const statement &stmt);
private:
+10 -4
View File
@@ -4,6 +4,7 @@
#include "matador/sql/query_context.hpp"
#include "matador/sql/query_result_impl.hpp"
#include "matador/sql/parameter_binder.hpp"
#include "matador/sql/types.hpp"
#include <memory>
@@ -20,15 +21,20 @@ public:
virtual size_t execute() = 0;
virtual std::unique_ptr<query_result_impl> fetch() = 0;
template < class V >
void bind(size_t pos, V &val)
template < class Type >
void bind(size_t pos, Type &val)
{
binder().bind(pos, val);
data_type_traits<Type>::bind_value(binder(), pos, val);
}
void bind(size_t pos, const char *value, size_t size)
{
data_type_traits<const char*>::bind_value(binder(), pos, value, size);
}
void bind(size_t pos, std::string &val, size_t size)
{
binder().bind(pos, val, size);
data_type_traits<std::string>::bind_value(binder(), pos, val, size);
}
virtual void reset() = 0;
+40 -71
View File
@@ -1,12 +1,15 @@
#ifndef QUERY_TYPES_HPP
#define QUERY_TYPES_HPP
#include "matador/sql/any_type.hpp"
#include <cstdint>
#include <string>
namespace matador::sql {
class query_result_reader;
class parameter_binder;
/**
* @brief Enumeration type of all supported builtin data types
@@ -34,26 +37,6 @@ enum class data_type_t : uint8_t {
type_null, /*!< Data type null */
type_unknown /*!< Data type unknown */
};
/**
* @brief Enumeration of database data types
*/
enum struct database_type_t : uint8_t {
type_char = 0, /*!< Data type char */
type_float, /*!< Data type float */
type_double, /*!< Data type double */
type_smallint, /*!< Data type small int */
type_int, /*!< Data type integer */
type_bigint, /*!< Data type big integer */
type_bool, /*!< Data type bool */
type_char_pointer, /*!< Data type character pointer */
type_varchar, /*!< Data type varchar */
type_text, /*!< Data type text */
type_date, /*!< Data type date */
type_time, /*!< Data type time */
type_blob, /*!< Data type blob */
type_null, /*!< Data type null */
type_unknown /*!< Data type unknown */
};
enum class sql_function_t {
NONE,
@@ -79,146 +62,130 @@ struct data_type_traits;
/// @cond MATADOR_DEV
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, char &value);
inline static any_type create_value(char &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, short &value);
inline static any_type create_value(short &value) { return value; }
};
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 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, int &value);
// inline static unsigned long size() { return sizeof(int); }
// inline static const char* name() { return "int"; }
static void bind_value(parameter_binder &binder, size_t index, int &value);
inline static any_type create_value(int &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, long &value);
inline static any_type create_value(long &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, long long &value);
inline static any_type create_value(long long &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, unsigned char &value);
inline static any_type create_value(unsigned char &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, unsigned short &value);
inline static any_type create_value(unsigned short &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, unsigned int &value);
inline static any_type create_value(unsigned int &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/ = 0) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, unsigned long &value);
inline static any_type create_value(unsigned long &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, unsigned long long &value);
inline static any_type create_value(unsigned long long &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, bool &value);
inline static any_type create_value(bool &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, float &value);
inline static any_type create_value(float &value) { return value; }
};
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 data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_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"; }
static void bind_value(parameter_binder &binder, size_t index, double &value);
inline static any_type create_value(double &value) { return value; }
};
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 data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_char_pointer; }
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*"; }
static void bind_value(parameter_binder &binder, size_t index, const char *value, size_t size = 0);
inline static any_type create_value(const char *value) { return value; }
};
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 data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; }
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*"; }
static void bind_value(parameter_binder &binder, size_t index, char *value, size_t size = 0);
inline static any_type create_value(const char *value) { return value; }
};
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 data_type_t builtin_type(std::size_t size) { return size == 0 ? data_type_t::type_text : data_type_t::type_varchar; }
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"; }
static void bind_value(parameter_binder &binder, size_t index, std::string &value, size_t size = 0);
inline static any_type create_value(std::string &value) { return value; }
};
//template <> struct data_type_traits<matador::date>
@@ -240,14 +207,16 @@ template <> struct data_type_traits<std::string, void>
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"; }
static void bind_value(parameter_binder &binder, size_t index, EnumType &value)
{
data_type_traits<int>::bind_value(binder, index, (int&)value);
}
inline static any_type create_value(EnumType &value) { return (int)value; }
};
/// @endcond
+3 -7
View File
@@ -2,6 +2,7 @@
#define QUERY_VALUE_EXTRACTOR_HPP
#include "matador/sql/fk_value_extractor.hpp"
#include "matador/sql/types.hpp"
#include <vector>
@@ -56,14 +57,9 @@ public:
private:
template<typename Type>
void append(Type &value, typename std::enable_if<!std::is_enum<Type>::value>::type* = 0)
void append(Type &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);
values_.emplace_back(data_type_traits<Type>::create_value(value));
}
private: