From 14337cf5b302c5385f0ae1393caf6df7e83fc539 Mon Sep 17 00:00:00 2001
From: znone <glyc@sina.com.cn>
Date: Sat, 07 Dec 2019 06:52:19 +0000
Subject: [PATCH] 1. 允许绑定字段到std::optional和std::any 2. 增加函数bind_fields可以一次绑定到多个字段 3. 查询函数返回数据库对象自身,以支持链式调用
---
include/qtl_common.hpp | 239 +++++++++++++++++++++++++++++++++--------------------------
1 files changed, 133 insertions(+), 106 deletions(-)
diff --git a/include/qtl_common.hpp b/include/qtl_common.hpp
index 3b2e8bb..aaaa0d6 100644
--- a/include/qtl_common.hpp
+++ b/include/qtl_common.hpp
@@ -1,11 +1,7 @@
#ifndef _QTL_COMMON_H_
#define _QTL_COMMON_H_
-#if defined(_MSC_VER)
-#if _MSC_VER<1800
-#error QTL need C++11 compiler
-#endif //MSC
-#elif __cplusplus<201103L
+#if __cplusplus<201103L && _MSC_VER<1800
#error QTL need C++11 compiler
#endif //C++11
@@ -24,6 +20,12 @@
#include <vector>
#include <functional>
#include "apply_tuple.h"
+
+#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
+#define _QTL_ENABLE_CPP17
+#include <optional>
+#include <any>
+#endif // C++17
namespace qtl
{
@@ -145,6 +147,19 @@
command.bind_param(index, param);
}
+#ifdef _QTL_ENABLE_CPP17
+
+template<typename Command, typename T>
+inline void bind_param(Command& command, size_t index, const std::optional<T>& param)
+{
+ if(param)
+ command.bind_param(index, *param);
+ else
+ command.bind_param(index, nullptr);
+}
+
+#endif // C++17
+
// The order of the overloaded functions 'bind_field' is very important
// The version with the most generic parameters is at the end
@@ -208,22 +223,6 @@
bind_field(command, index, std::forward<T>(value));
}
-template<typename FieldType, typename Command, typename BindType>
-inline void bind_field(Command& command, size_t index, BindType& value)
-{
- FieldType temp=FieldType();
- bind_field(command, index, temp);
- value=static_cast<BindType>(temp);
-}
-
-template<typename FieldType, typename Command, typename BindType, typename CastFun>
-inline void bind_field(Command& command, size_t index, BindType& value, CastFun&& fun)
-{
- FieldType temp=FieldType();
- bind_field(command, index, temp);
- fun(value, temp);
-}
-
template<typename Command, typename T, typename=typename std::enable_if<!std::is_reference<T>::value>::type>
inline void bind_field(Command& command, const char* name, T&& value)
{
@@ -244,32 +243,14 @@
bind_field(command, index, std::forward<T>(value));
}
-template<typename FieldType, typename Command, typename BindType>
-inline void bind_field(Command& command, const char* name, BindType& value)
-{
- size_t index=command.find_field(name);
- if(index==-1)
- value=BindType();
- else
- bind_field<FieldType>(command, index, value);
-}
-
-template<typename FieldType, typename Command, typename BindType, typename CastFun>
-inline void bind_field(Command& command, const char* name, BindType& value, CastFun&& fun)
-{
- size_t index=command.find_field(name);
- if(index==-1)
- value=BindType();
- else
- bind_field<FieldType>(command, index, value, fun);
-}
-
template<typename Command>
inline void bind_field(Command& command, const char* name, char* value, size_t length)
{
size_t index=command.find_field(name);
- if(index==-1)
- value[0]='\0';
+ if (index == -1)
+ {
+ if (length > 0) value[0] = '\0';
+ }
else
command.bind_field(index, value, length);
}
@@ -278,8 +259,10 @@
inline void bind_field(Command& command, const char* name, wchar_t* value, size_t length)
{
size_t index=command.find_field(name);
- if(index==-1)
- value[0]='\0';
+ if (index == -1)
+ {
+ if (length > 0) value[0] = '\0';
+ }
else
command.bind_field(index, value, length);
}
@@ -288,6 +271,47 @@
inline void bind_field(Command& command, const char* name, std::reference_wrapper<T>&& value)
{
return bind_field(command, value.get());
+}
+
+#ifdef _QTL_ENABLE_CPP17
+
+template<typename Command, typename T>
+inline void bind_field(Command& command, size_t index, std::optional<T>& value)
+{
+ value.emplace();
+ command.bind_field(index, std::forward<T>(value));
+}
+
+template<typename Command, typename T>
+inline void bind_field(Command& command, const char* name, std::optional<T>& value)
+{
+ size_t index = command.find_field(name);
+ if (index == -1)
+ value.reset();
+ else
+ bind_field(command, index, value);
+}
+
+#endif // C++17
+
+template<typename Command, typename... Fields>
+inline size_t bind_fields(Command& command, Fields&&... fields)
+{
+ return bind_fields(command, (size_t)0, std::forward<Fields>(fields)...);
+}
+
+template<typename Command, typename T>
+inline size_t bind_fields(Command& command, size_t index, T&& value)
+{
+ bind_field(command, index, std::forward<T>(value));
+ return index+1;
+}
+
+template<typename Command, typename T, typename... Other>
+inline size_t bind_fields(Command& command, size_t start, T&& value, Other&&... other)
+{
+ bind_field(command, start, std::forward<T>(value));
+ return bind_fields(command, start+1, std::forward<Other>(other)...);
}
namespace detail
@@ -835,39 +859,40 @@
{
public:
template<typename Params>
- void execute(const char* query_text, size_t text_length, const Params& params, uint64_t* affected=NULL)
+ base_database& execute(const char* query_text, size_t text_length, const Params& params, uint64_t* affected=NULL)
{
T* pThis=static_cast<T*>(this);
Command command=pThis->open_command(query_text, text_length);
command.execute(params);
if(affected) *affected=command.affetced_rows();
command.close();
+ return *this;
}
template<typename Params>
- void execute(const char* query_text, const Params& params, uint64_t* affected=NULL)
+ base_database& execute(const char* query_text, const Params& params, uint64_t* affected=NULL)
{
return execute(query_text, strlen(query_text), params, affected);
}
template<typename Params>
- void execute(const std::string& query_text, const Params& params, uint64_t* affected=NULL)
+ base_database& execute(const std::string& query_text, const Params& params, uint64_t* affected=NULL)
{
return execute(query_text.data(), query_text.length(), params, affected);
}
template<typename... Params>
- void execute_direct(const char* query_text, size_t text_length, uint64_t* affected, const Params&... params)
+ base_database& execute_direct(const char* query_text, size_t text_length, uint64_t* affected, const Params&... params)
{
- execute(query_text, text_length, std::forward_as_tuple(params...), affected);
+ return execute(query_text, text_length, std::forward_as_tuple(params...), affected);
}
template<typename... Params>
- void execute_direct(const char* query_text, uint64_t* affected, const Params&... params)
+ base_database& execute_direct(const char* query_text, uint64_t* affected, const Params&... params)
{
- execute(query_text, std::forward_as_tuple(params...), affected);
+ return execute(query_text, std::forward_as_tuple(params...), affected);
}
template<typename... Params>
- void execute_direct(const std::string& query_text, uint64_t* affected, const Params&... params)
+ base_database& execute_direct(const std::string& query_text, uint64_t* affected, const Params&... params)
{
- execute(query_text, std::forward_as_tuple(params...), affected);
+ return execute(query_text, std::forward_as_tuple(params...), affected);
}
template<typename Params>
@@ -947,7 +972,7 @@
}
template<typename Params, typename Values, typename ValueProc>
- void query_explicit(const char* query_text, size_t text_length, const Params& params, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const char* query_text, size_t text_length, const Params& params, Values&& values, ValueProc&& proc)
{
T* pThis=static_cast<T*>(this);
Command command=pThis->open_command(query_text, text_length);
@@ -957,152 +982,154 @@
if(!detail::apply(std::forward<ValueProc>(proc), std::forward<Values>(values))) break;
}
command.close();
+ return *this;
}
template<typename Params, typename Values, typename ValueProc>
- void query_explicit(const char* query_text, const Params& params, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const char* query_text, const Params& params, Values&& values, ValueProc&& proc)
{
- query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), std::forward<ValueProc>(proc));
}
template<typename Params, typename Values, typename ValueProc>
- void query_explicit(const std::string& query_text, const Params& params, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const std::string& query_text, const Params& params, Values&& values, ValueProc&& proc)
{
- query_explicit(query_text.data(), query_text.size(), params, std::forward<Values>(values), std::forward<ValueProc>(proc));
+ return query_explicit(query_text.data(), query_text.size(), params, std::forward<Values>(values), std::forward<ValueProc>(proc));
}
template<typename Values, typename ValueProc>
- void query_explicit(const char* query_text, size_t text_length, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const char* query_text, size_t text_length, Values&& values, ValueProc&& proc)
{
- query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
}
template<typename Values, typename ValueProc>
- void query_explicit(const char* query_text, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const char* query_text, Values&& values, ValueProc&& proc)
{
- query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
}
template<typename Values, typename ValueProc>
- void query_explicit(const std::string& query_text, Values&& values, ValueProc&& proc)
+ base_database& query_explicit(const std::string& query_text, Values&& values, ValueProc&& proc)
{
- query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
}
template<typename Params, typename ValueProc>
- void query(const char* query_text, size_t text_length, const Params& params, ValueProc&& proc)
+ base_database& query(const char* query_text, size_t text_length, const Params& params, ValueProc&& proc)
{
- query_explicit(query_text, text_length, params, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, text_length, params, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename Params, typename ValueProc>
- void query(const char* query_text, const Params& params, ValueProc&& proc)
+ base_database& query(const char* query_text, const Params& params, ValueProc&& proc)
{
- query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename Params, typename ValueProc>
- void query(const std::string& query_text, const Params& params, ValueProc&& proc)
+ base_database& query(const std::string& query_text, const Params& params, ValueProc&& proc)
{
- query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename ValueProc>
- void query(const char* query_text, size_t text_length, ValueProc&& proc)
+ base_database& query(const char* query_text, size_t text_length, ValueProc&& proc)
{
- query_explicit(query_text, text_length, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, text_length, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename ValueProc>
- void query(const char* query_text, ValueProc&& proc)
+ base_database& query(const char* query_text, ValueProc&& proc)
{
- query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename ValueProc>
- void query(const std::string& query_text, ValueProc&& proc)
+ base_database& query(const std::string& query_text, ValueProc&& proc)
{
- query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
+ return query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
}
template<typename Params, typename... ValueProc>
- void query_multi_with_params(const char* query_text, size_t text_length, const Params& params, ValueProc&&... proc)
+ base_database& query_multi_with_params(const char* query_text, size_t text_length, const Params& params, ValueProc&&... proc)
{
T* pThis=static_cast<T*>(this);
Command command=pThis->open_command(query_text, text_length);
command.execute(params);
detail::fetch_command(command, std::forward<ValueProc>(proc)...);
command.close();
+ return *this;
}
template<typename Params, typename... ValueProc>
- void query_multi_with_params(const char* query_text, const Params& params, ValueProc&&... proc)
+ base_database& query_multi_with_params(const char* query_text, const Params& params, ValueProc&&... proc)
{
- query_multi_with_params(query_text, strlen(query_text), params, std::forward<ValueProc>(proc)...);
+ return query_multi_with_params(query_text, strlen(query_text), params, std::forward<ValueProc>(proc)...);
}
template<typename Params, typename... ValueProc>
- void query_multi_with_params(const std::string& query_text, const Params& params, ValueProc&&... proc)
+ base_database& query_multi_with_params(const std::string& query_text, const Params& params, ValueProc&&... proc)
{
- query_multi_with_params(query_text.data(), query_text.size(), params, std::forward<ValueProc>(proc)...);
+ return query_multi_with_params(query_text.data(), query_text.size(), params, std::forward<ValueProc>(proc)...);
}
template<typename... ValueProc>
- void query_multi(const char* query_text, size_t text_length, ValueProc&&... proc)
+ base_database& query_multi(const char* query_text, size_t text_length, ValueProc&&... proc)
{
- query_multi_with_params<std::tuple<>, ValueProc...>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
+ return query_multi_with_params<std::tuple<>, ValueProc...>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
}
template<typename... ValueProc>
- void query_multi(const char* query_text, ValueProc&&... proc)
+ base_database& query_multi(const char* query_text, ValueProc&&... proc)
{
- query_multi_with_params<std::tuple<>, ValueProc...>(query_text, strlen(query_text), std::make_tuple(), std::forward<ValueProc>(proc)...);
+ return query_multi_with_params<std::tuple<>, ValueProc...>(query_text, strlen(query_text), std::make_tuple(), std::forward<ValueProc>(proc)...);
}
template<typename... ValueProc>
- void query_multi(const std::string& query_text, ValueProc&&... proc)
+ base_database& query_multi(const std::string& query_text, ValueProc&&... proc)
{
- query_multi_with_params<std::tuple<>, ValueProc...>(query_text.data(), query_text.size(), std::make_tuple(), std::forward<ValueProc>(proc)...);
+ return query_multi_with_params<std::tuple<>, ValueProc...>(query_text.data(), query_text.size(), std::make_tuple(), std::forward<ValueProc>(proc)...);
}
template<typename Params, typename Values>
- void query_first(const char* query_text, size_t text_length, const Params& params, Values&& values)
+ base_database& query_first(const char* query_text, size_t text_length, const Params& params, Values&& values)
{
- query_explicit(query_text, text_length, params, std::forward<Values>(values), first_record());
+ return query_explicit(query_text, text_length, params, std::forward<Values>(values), first_record());
}
template<typename Params, typename Values>
- void query_first(const char* query_text, const Params& params, Values&& values)
+ base_database& query_first(const char* query_text, const Params& params, Values&& values)
{
- query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), first_record());
+ return query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), first_record());
}
template<typename Params, typename Values>
- void query_first(const std::string& query_text, const Params& params, Values&& values)
+ base_database& query_first(const std::string& query_text, const Params& params, Values&& values)
{
- query_explicit(query_text, params, values, first_record());
+ return query_explicit(query_text, params, values, first_record());
}
template<typename Values>
- void query_first(const char* query_text, size_t text_length, Values&& values)
+ base_database& query_first(const char* query_text, size_t text_length, Values&& values)
{
- query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), first_record());
+ return query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), first_record());
}
template<typename Values>
- void query_first(const char* query_text, Values&& values)
+ base_database& query_first(const char* query_text, Values&& values)
{
- query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), first_record());
+ return query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), first_record());
}
template<typename Values>
- void query_first(const std::string& query_text, Values&& values)
+ base_database& query_first(const std::string& query_text, Values&& values)
{
- query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), first_record());
+ return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), first_record());
}
template<typename... Values>
- void query_first_direct(const char* query_text, size_t text_length, Values&... values)
+ base_database& query_first_direct(const char* query_text, size_t text_length, Values&... values)
{
- query_first(query_text, text_length, std::tie(values...));
+ return query_first(query_text, text_length, std::tie(values...));
}
template<typename... Values>
- void query_first_direct(const char* query_text, Values&... values)
+ base_database& query_first_direct(const char* query_text, Values&... values)
{
- query_first(query_text, std::tie(values...));
+ return query_first(query_text, std::tie(values...));
}
template<typename... Values>
- void query_first_direct(const std::string& query_text, Values&... values)
+ base_database& query_first_direct(const std::string& query_text, Values&... values)
{
- query_first(query_text, std::tie(values...));
+ return query_first(query_text, std::tie(values...));
}
protected:
--
Gitblit v1.9.3