Ferenc Szontágh
2024-07-01 abf49b44cc47f39d6cceb83866f915bc03b7d900
include/qtl_common.hpp
@@ -1,15 +1,15 @@
#ifndef _QTL_COMMON_H_
#define _QTL_COMMON_H_
#if __cplusplus<201103L && _MSC_VER<1800
#if __cplusplus < 201103L && _MSC_VER < 1800
#error QTL need C++11 compiler
#endif //C++11
#endif // C++11
#if _MSC_VER>=1800 && _MSC_VER<1900
#if _MSC_VER >= 1800 && _MSC_VER < 1900
#define NOEXCEPT throw()
#else
#define NOEXCEPT noexcept
#endif //NOEXCEPT
#endif // NOEXCEPT
#include <stdint.h>
#include <string.h>
@@ -31,1426 +31,1457 @@
namespace qtl
{
struct null { };
struct blob_data
{
   void* data;
   size_t size;
   blob_data() : data(NULL), size(0) { }
   blob_data(void* d, size_t n) : data(d), size(n) { }
};
struct const_blob_data
{
   const void* data;
   size_t size;
   const_blob_data() : data(NULL), size(0) { }
   const_blob_data(const void* d, size_t n) : data(d), size(n) { }
};
const size_t blob_buffer_size=64*1024;
inline std::string& trim_string(std::string& str, const char* target)
{
   str.erase(0, str.find_first_not_of(target));
   str.erase(str.find_last_not_of(target)+1);
   return str;
}
template<typename T>
struct indicator
{
   typedef T data_type;
   data_type data;
   size_t length;
   bool is_null;
   bool is_truncated;
   indicator()
      : is_null(false), is_truncated(false), length(0) { }
   explicit indicator(const data_type& src)
      : is_null(false), is_truncated(false), length(0), data(src) { }
   explicit indicator(data_type&& src)
      : is_null(false), is_truncated(false), length(0), data(std::move(src)) { }
   operator bool() const { return is_null; }
   operator data_type&() { return data; }
   operator const data_type&() const { return data; }
};
template<typename StringT>
struct bind_string_helper
{
   typedef StringT string_type;
   typedef typename string_type::value_type char_type;
   bind_string_helper(string_type&& value) : m_value(std::forward<string_type>(value)) { }
   bind_string_helper(const bind_string_helper& src)
      : m_value(std::forward<StringT>(src.m_value))
   struct null
   {
   };
   struct blob_data
   {
      void *data;
      size_t size;
      blob_data() : data(NULL), size(0) {}
      blob_data(void *d, size_t n) : data(d), size(n) {}
   };
   struct const_blob_data
   {
      const void *data;
      size_t size;
      const_blob_data() : data(NULL), size(0) {}
      const_blob_data(const void *d, size_t n) : data(d), size(n) {}
   };
   const size_t blob_buffer_size = 64 * 1024;
   inline std::string &trim_string(std::string &str, const char *target)
   {
      str.erase(0, str.find_first_not_of(target));
      str.erase(str.find_last_not_of(target) + 1);
      return str;
   }
   bind_string_helper(bind_string_helper&& src)
      : m_value(std::forward<StringT>(src.m_value))
   template <typename T>
   struct indicator
   {
   }
   bind_string_helper& operator=(const bind_string_helper& src)
      typedef T data_type;
      data_type data;
      size_t length;
      bool is_null;
      bool is_truncated;
      indicator()
         : is_null(false), is_truncated(false), length(0) {}
      explicit indicator(const data_type &src)
         : is_null(false), is_truncated(false), length(0), data(src) {}
      explicit indicator(data_type &&src)
         : is_null(false), is_truncated(false), length(0), data(std::move(src)) {}
      operator bool() const { return is_null; }
      operator data_type &() { return data; }
      operator const data_type &() const { return data; }
   };
   template <typename StringT>
   struct bind_string_helper
   {
      if (this != &src)
      typedef StringT string_type;
      typedef typename string_type::value_type char_type;
      bind_string_helper(string_type &&value) : m_value(std::forward<string_type>(value)) {}
      bind_string_helper(const bind_string_helper &src)
         : m_value(std::forward<StringT>(src.m_value))
      {
         m_value = std::forward<StringT>(src.m_value);
      }
      return *this;
   }
   bind_string_helper& operator=(bind_string_helper&& src)
   {
      if (this != &src)
      bind_string_helper(bind_string_helper &&src)
         : m_value(std::forward<StringT>(src.m_value))
      {
         m_value = std::forward<StringT>(src.m_value);
      }
      return *this;
      bind_string_helper &operator=(const bind_string_helper &src)
      {
         if (this != &src)
         {
            m_value = std::forward<StringT>(src.m_value);
         }
         return *this;
      }
      bind_string_helper &operator=(bind_string_helper &&src)
      {
         if (this != &src)
         {
            m_value = std::forward<StringT>(src.m_value);
         }
         return *this;
      }
      void clear() { m_value.clear(); }
      char_type *alloc(size_t n)
      {
         m_value.resize(n);
         return (char_type *)m_value.data();
      }
      void truncate(size_t n) { m_value.resize(n); }
      void assign(const char_type *str, size_t n) { m_value.assign(str, n); }
      const char_type *data() const { return m_value.data(); }
      size_t size() const { return m_value.size(); }
   private:
      string_type &&m_value;
   };
   template <typename StringT>
   inline bind_string_helper<typename std::decay<StringT>::type> bind_string(StringT &&value)
   {
      typedef typename std::decay<StringT>::type string_type;
      return bind_string_helper<string_type>(std::forward<string_type>(value));
   }
   void clear() { m_value.clear(); }
   char_type* alloc(size_t n) { m_value.resize(n); return (char_type*)m_value.data(); }
   void truncate(size_t n) { m_value.resize(n); }
   void assign(const char_type* str, size_t n) { m_value.assign(str, n); }
   const char_type* data() const { return m_value.data(); }
   size_t size() const { return m_value.size(); }
private:
   string_type&& m_value;
};
   template <typename Command>
   inline void bind_param(Command &command, size_t index, const std::string &param)
   {
      command.bind_param(index, param.data(), param.size());
   }
template<typename StringT>
inline bind_string_helper<typename std::decay<StringT>::type> bind_string(StringT&& value)
{
   typedef typename std::decay<StringT>::type string_type;
   return bind_string_helper<string_type>(std::forward<string_type>(value));
}
   template <typename Command>
   inline void bind_param(Command &command, size_t index, std::istream &param)
   {
      command.bind_param(index, param);
   }
template<typename Command>
inline void bind_param(Command& command, size_t index, const std::string& param)
{
   command.bind_param(index, param.data(), param.size());
}
template<typename Command>
inline void bind_param(Command& command, size_t index, std::istream& param)
{
   command.bind_param(index, param);
}
template<typename Command, typename T>
inline void bind_param(Command& command, size_t index, const T& param)
{
   command.bind_param(index, param);
}
   template <typename Command, typename T>
   inline void bind_param(Command &command, size_t index, const T &param)
   {
      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);
}
   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
   // The order of the overloaded functions 'bind_field' is very important
   // The version with the most generic parameters is at the end
template<typename Command, size_t N>
inline void bind_field(Command& command, size_t index, char (&value)[N])
{
   command.bind_field(index, value, N);
}
   template <typename Command, size_t N>
   inline void bind_field(Command &command, size_t index, char (&value)[N])
   {
      command.bind_field(index, value, N);
   }
template<typename Command, size_t N>
inline void bind_field(Command& command, size_t index, wchar_t (&value)[N])
{
   command.bind_field(index, value, N);
}
   template <typename Command, size_t N>
   inline void bind_field(Command &command, size_t index, wchar_t (&value)[N])
   {
      command.bind_field(index, value, N);
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, char* value, size_t length)
{
   command.bind_field(index, value, length);
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, char *value, size_t length)
   {
      command.bind_field(index, value, length);
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, wchar_t* value, size_t length)
{
   command.bind_field(index, value, length);
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, wchar_t *value, size_t length)
   {
      command.bind_field(index, value, length);
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, std::string&& value)
{
   command.bind_field(index, bind_string(std::forward<std::string>(value)));
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, std::string &&value)
   {
      command.bind_field(index, bind_string(std::forward<std::string>(value)));
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, std::wstring&& value)
{
   command.bind_field(index, bind_string(std::forward<std::wstring>(value)));
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, std::wstring &&value)
   {
      command.bind_field(index, bind_string(std::forward<std::wstring>(value)));
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, std::vector<char>&& value)
{
   command.bind_field(index, bind_string(std::forward<std::vector<char>>(value)));
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, std::vector<char> &&value)
   {
      command.bind_field(index, bind_string(std::forward<std::vector<char>>(value)));
   }
template<typename Command>
inline void bind_field(Command& command, size_t index, std::vector<wchar_t>&& value)
{
   command.bind_field(index, bind_string(std::forward<std::vector<wchar_t>>(value)));
}
   template <typename Command>
   inline void bind_field(Command &command, size_t index, std::vector<wchar_t> &&value)
   {
      command.bind_field(index, bind_string(std::forward<std::vector<wchar_t>>(value)));
   }
template<typename Command, typename T, typename=typename std::enable_if<!std::is_reference<T>::value>::type>
inline void bind_field(Command& command, size_t index, T&& value)
{
   command.bind_field(index, std::forward<T>(value));
}
template<typename Command, typename T>
inline void bind_field(Command& command, size_t index, T& value)
{
   bind_field(command, index, std::forward<T>(value));
}
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)
{
   size_t index=command.find_field(name);
   if(index==-1)
      value=T();
   else
   template <typename Command, typename T, typename = typename std::enable_if<!std::is_reference<T>::value>::type>
   inline void bind_field(Command &command, size_t index, T &&value)
   {
      command.bind_field(index, std::forward<T>(value));
}
   }
template<typename Command, typename T>
inline void bind_field(Command& command, const char* name, T& value)
{
   size_t index=command.find_field(name);
   if(index==-1)
      value=T();
   else
   template <typename Command, typename T>
   inline void bind_field(Command &command, size_t index, T &value)
   {
      bind_field(command, index, std::forward<T>(value));
}
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)
   {
      if (length > 0) value[0] = '\0';
   }
   else
      command.bind_field(index, value, length);
}
template<typename Command>
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)
   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)
   {
      if (length > 0) value[0] = '\0';
      size_t index = command.find_field(name);
      if (index == -1)
         value = T();
      else
         command.bind_field(index, std::forward<T>(value));
   }
   else
      command.bind_field(index, value, length);
}
template<typename Command, typename T>
inline void bind_field(Command& command, const char* name, std::reference_wrapper<T>&& value)
{
   return bind_field(command, value.get());
}
   template <typename Command, typename T>
   inline void bind_field(Command &command, const char *name, T &value)
   {
      size_t index = command.find_field(name);
      if (index == -1)
         value = T();
      else
         bind_field(command, index, std::forward<T>(value));
   }
   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)
      {
         if (length > 0)
            value[0] = '\0';
      }
      else
         command.bind_field(index, value, length);
   }
   template <typename Command>
   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)
      {
         if (length > 0)
            value[0] = '\0';
      }
      else
         command.bind_field(index, value, length);
   }
   template <typename Command, typename T>
   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, 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);
}
   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 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>
   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)...);
}
   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)...);
   }
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... Fields>
   inline size_t bind_fields(Command &command, Fields &&...fields)
   {
      return bind_fields(command, (size_t)0, std::forward<Fields>(fields)...);
   }
namespace detail
{
   namespace detail
   {
template<typename F, typename T>
struct apply_impl
{
private:
      template <typename F, typename T>
      struct apply_impl
      {
      private:
#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L
   typedef typename std::invoke_result<F, T>::type raw_result_type;
         typedef typename std::invoke_result<F, T>::type raw_result_type;
#else
   typedef typename std::result_of<F(T)>::type raw_result_type;
         typedef typename std::result_of<F(T)>::type raw_result_type;
#endif
   template<typename Ret, bool>
   struct impl {};
   template<typename Ret>
   struct impl<Ret, true>
   {
      typedef bool result_type;
      result_type operator()(F&& f, T&& v)
      {
         f(std::forward<T>(v));
         return true;
      }
   };
   template<typename Ret>
   struct impl<Ret, false>
   {
      typedef Ret result_type;
      result_type operator()(F&& f, T&& v)
      {
         return f(std::forward<T>(v));
      }
   };
         template <typename Ret, bool>
         struct impl
         {
         };
         template <typename Ret>
         struct impl<Ret, true>
         {
            typedef bool result_type;
            result_type operator()(F &&f, T &&v)
            {
               f(std::forward<T>(v));
               return true;
            }
         };
         template <typename Ret>
         struct impl<Ret, false>
         {
            typedef Ret result_type;
            result_type operator()(F &&f, T &&v)
            {
               return f(std::forward<T>(v));
            }
         };
public:
   typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
   result_type operator()(F&& f, T&& v)
   {
      return impl<raw_result_type, std::is_void<raw_result_type>::value>()(std::forward<F>(f), std::forward<T>(v));
   }
};
      public:
         typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
         result_type operator()(F &&f, T &&v)
         {
            return impl<raw_result_type, std::is_void<raw_result_type>::value>()(std::forward<F>(f), std::forward<T>(v));
         }
      };
template<typename F, typename... Types>
struct apply_impl<F, std::tuple<Types...>>
{
private:
   typedef typename std::remove_reference<F>::type fun_type;
   typedef std::tuple<Types...> arg_type;
      template <typename F, typename... Types>
      struct apply_impl<F, std::tuple<Types...>>
      {
      private:
         typedef typename std::remove_reference<F>::type fun_type;
         typedef std::tuple<Types...> arg_type;
#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L
   typedef typename std::invoke_result<F, Types...>::type raw_result_type;
         typedef typename std::invoke_result<F, Types...>::type raw_result_type;
#else
   typedef typename std::result_of<F(Types...)>::type raw_result_type;
         typedef typename std::result_of<F(Types...)>::type raw_result_type;
#endif
   template<typename Ret, bool>
   struct impl {};
   template<typename Ret>
   struct impl<Ret, true>
   {
      typedef bool result_type;
      result_type operator()(F&& f, arg_type&& v)
         template <typename Ret, bool>
         struct impl
         {
         };
         template <typename Ret>
         struct impl<Ret, true>
         {
            typedef bool result_type;
            result_type operator()(F &&f, arg_type &&v)
            {
               qtl::detail::apply_tuple(std::forward<F>(f), std::forward<arg_type>(v));
               return true;
            }
         };
         template <typename Ret>
         struct impl<Ret, false>
         {
            typedef Ret result_type;
            result_type operator()(F &&f, arg_type &&v)
            {
               return qtl::detail::apply_tuple(std::forward<F>(f), std::forward<arg_type>(v));
            }
         };
      public:
         typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
         result_type operator()(F &&f, arg_type &&v)
         {
            return impl<raw_result_type, std::is_void<raw_result_type>::value>()(std::forward<F>(f), std::forward<arg_type>(v));
         }
      };
      template <typename Type, typename R>
      struct apply_impl<R (Type::*)(), Type>
      {
         qtl::detail::apply_tuple(std::forward<F>(f), std::forward<arg_type>(v));
         return true;
      }
   };
   template<typename Ret>
   struct impl<Ret, false>
   {
      typedef Ret result_type;
      result_type operator()(F&& f, arg_type&& v)
      private:
         typedef R (Type::*fun_type)();
         typedef R raw_result_type;
         template <typename Ret, bool>
         struct impl
         {
         };
         template <typename Ret>
         struct impl<Ret, true>
         {
            typedef bool result_type;
            result_type operator()(fun_type f, Type &&v)
            {
               (v.*f)();
               return true;
            }
         };
         template <typename Ret>
         struct impl<Ret, false>
         {
            typedef Ret result_type;
            result_type operator()(fun_type f, Type &&v)
            {
               return (v.*f)();
            }
         };
      public:
         typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
         result_type operator()(R (Type::*f)(), Type &&v)
         {
            return impl<raw_result_type, std::is_void<raw_result_type>::value>()(f, std::forward<Type>(v));
         }
      };
      template <typename Type, typename R>
      struct apply_impl<R (Type::*)() const, Type>
      {
         return qtl::detail::apply_tuple(std::forward<F>(f), std::forward<arg_type>(v));
      }
   };
      private:
         typedef R (Type::*fun_type)() const;
         typedef R raw_result_type;
         template <typename Ret, bool>
         struct impl
         {
         };
         template <typename Ret>
         struct impl<Ret, true>
         {
            typedef bool result_type;
            result_type operator()(fun_type f, Type &&v)
            {
               (v.*f)();
               return true;
            }
         };
         template <typename Ret>
         struct impl<Ret, false>
         {
            typedef Ret result_type;
            result_type operator()(fun_type f, Type &&v)
            {
               return (v.*f)();
            }
         };
public:
   typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
   result_type operator()(F&& f, arg_type&& v)
   {
      return impl<raw_result_type, std::is_void<raw_result_type>::value>()(std::forward<F>(f), std::forward<arg_type>(v));
   }
};
      public:
         typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
         result_type operator()(fun_type f, Type &&v)
         {
            return impl<raw_result_type, std::is_void<raw_result_type>::value>()(f, std::forward<Type>(v));
         }
      };
template<typename Type, typename R>
struct apply_impl<R (Type::*)(), Type>
{
private:
   typedef R (Type::*fun_type)();
   typedef R raw_result_type;
   template<typename Ret, bool>
   struct impl {};
   template<typename Ret>
   struct impl<Ret, true>
   {
      typedef bool result_type;
      result_type operator()(fun_type f, Type&& v)
      template <typename F, typename T>
      typename apply_impl<F, T>::result_type apply(F &&f, T &&v)
      {
         (v.*f)();
         return true;
         return apply_impl<F, T>()(std::forward<F>(f), std::forward<T>(v));
      }
   };
   template<typename Ret>
   struct impl<Ret, false>
   {
      typedef Ret result_type;
      result_type operator()(fun_type f, Type&& v)
      template <typename Command, size_t N, typename... Types>
      struct bind_helper
      {
         return (v.*f)();
      }
   };
      public:
         explicit bind_helper(Command &command) : m_command(command) {}
         void operator()(const std::tuple<Types...> &params) const
         {
            bind_param(m_command, N - 1, std::get<N - 1>(params));
            (bind_helper<Command, N - 1, Types...>(m_command))(params);
         }
         void operator()(std::tuple<Types...> &&params) const
         {
            typedef typename std::remove_reference<typename std::tuple_element<N - 1, tuple_type>::type>::type param_type;
            bind_field(m_command, N - 1, std::forward<param_type>(std::get<N - 1>(std::forward<tuple_type>(params))));
            (bind_helper<Command, N - 1, Types...>(m_command))(std::forward<tuple_type>(params));
         }
public:
   typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
   result_type operator()(R (Type::*f)(), Type&& v)
   {
      return impl<raw_result_type, std::is_void<raw_result_type>::value>()(f, std::forward<Type>(v));
   }
};
      private:
         typedef std::tuple<Types...> tuple_type;
         Command &m_command;
      };
template<typename Type, typename R>
struct apply_impl<R (Type::*)() const, Type>
{
private:
   typedef R (Type::*fun_type)() const;
   typedef R raw_result_type;
   template<typename Ret, bool>
   struct impl {};
   template<typename Ret>
   struct impl<Ret, true>
   {
      typedef bool result_type;
      result_type operator()(fun_type f, Type&& v)
      template <typename Command, typename... Types>
      struct bind_helper<Command, 1, Types...>
      {
         (v.*f)();
         return true;
      }
   };
   template<typename Ret>
   struct impl<Ret, false>
   {
      typedef Ret result_type;
      result_type operator()(fun_type f, Type&& v)
      public:
         explicit bind_helper(Command &command) : m_command(command) {}
         void operator()(const std::tuple<Types...> &params) const
         {
            bind_param(m_command, 0, std::get<0>(params));
         }
         void operator()(std::tuple<Types...> &&params) const
         {
            typedef typename std::remove_reference<typename std::tuple_element<0, tuple_type>::type>::type param_type;
            bind_field(m_command, static_cast<size_t>(0), std::forward<param_type>(std::get<0>(std::forward<tuple_type>(params))));
         }
      private:
         typedef std::tuple<Types...> tuple_type;
         Command &m_command;
      };
      template <typename Command, typename... Types>
      struct bind_helper<Command, 0, Types...>
      {
         return (v.*f)();
      }
   };
public:
   typedef typename impl<raw_result_type, std::is_void<raw_result_type>::value>::result_type result_type;
   result_type operator()(fun_type f, Type&& v)
   {
      return impl<raw_result_type, std::is_void<raw_result_type>::value>()(f, std::forward<Type>(v));
   }
};
template<typename F, typename T>
typename apply_impl<F, T>::result_type apply(F&& f, T&& v)
{
   return apply_impl<F, T>()(std::forward<F>(f),  std::forward<T>(v));
}
template<typename Command, size_t N, typename... Types>
struct bind_helper
{
public:
   explicit bind_helper(Command& command) : m_command(command) { }
   void operator()(const std::tuple<Types...>& params) const
   {
      bind_param(m_command, N-1, std::get<N-1>(params));
      (bind_helper<Command, N-1, Types...>(m_command))(params);
   }
   void operator()(std::tuple<Types...>&& params) const
   {
      typedef typename std::remove_reference<typename std::tuple_element<N-1, tuple_type>::type>::type param_type;
      bind_field(m_command, N-1, std::forward<param_type>(std::get<N-1>(std::forward<tuple_type>(params))));
      (bind_helper<Command, N-1, Types...>(m_command))(std::forward<tuple_type>(params));
   }
private:
   typedef std::tuple<Types...> tuple_type;
   Command& m_command;
};
template<typename Command, typename... Types>
struct bind_helper<Command, 1, Types...>
{
public:
   explicit bind_helper(Command& command) : m_command(command) { }
   void operator()(const std::tuple<Types...>& params) const
   {
      bind_param(m_command, 0, std::get<0>(params));
   }
   void operator()(std::tuple<Types...>&& params) const
   {
      typedef typename std::remove_reference<typename std::tuple_element<0, tuple_type>::type>::type param_type;
      bind_field(m_command, static_cast<size_t>(0), std::forward<param_type>(std::get<0>(std::forward<tuple_type>(params))));
   }
private:
   typedef std::tuple<Types...> tuple_type;
   Command& m_command;
};
template<typename Command, typename... Types>
struct bind_helper<Command, 0, Types...>
{
public:
   explicit bind_helper(Command& command) { }
   void operator()(const std::tuple<Types...>& params) const
   {
   }
   void operator()(std::tuple<Types...>&& params) const
   {
   }
};
      public:
         explicit bind_helper(Command &command) {}
         void operator()(const std::tuple<Types...> &params) const
         {
         }
         void operator()(std::tuple<Types...> &&params) const
         {
         }
      };
#define QTL_ARGS_TUPLE(Arg, Others) \
   typename std::tuple<typename std::decay<Arg>::type, typename std::decay<Others>::type...>
template<typename Ret, typename Arg>
inline typename std::decay<Arg>::type make_values(Ret (*)(Arg))
{
   return typename std::decay<Arg>::type();
};
template<typename Ret, typename Arg, typename... Others>
inline auto make_values(Ret (*)(Arg, Others...)) -> QTL_ARGS_TUPLE(Arg, Others)
{
   return QTL_ARGS_TUPLE(Arg, Others)();
};
template<typename Type, typename Ret>
inline Type make_values(Ret (Type::*)())
{
   return Type();
};
template<typename Type, typename Ret>
inline Type make_values(Ret (Type::*)() const)
{
   return Type();
};
template<typename Type, typename Ret, typename... Args>
inline auto make_values(Ret (Type::*)(Args...)) -> QTL_ARGS_TUPLE(Type, Args)
{
   return QTL_ARGS_TUPLE(Type, Args)();
};
template<typename Type, typename Ret, typename... Args>
inline auto make_values(Ret (Type::*)(Args...) const) -> QTL_ARGS_TUPLE(Type, Args)
{
   return QTL_ARGS_TUPLE(Type, Args)();
};
template<typename Type, typename Ret, typename Arg>
inline typename std::decay<Arg>::type make_values_noclass(Ret (Type::*)(Arg))
{
   return typename std::decay<Arg>::type();
};
template<typename Type, typename Ret, typename Arg>
inline typename std::decay<Arg>::type make_values_noclass(Ret (Type::*)(Arg) const)
{
   return typename std::decay<Arg>::type();
};
template<typename Type, typename Ret, typename Arg, typename... Others>
inline auto make_values_noclass(Ret (Type::*)(Arg, Others...)) -> QTL_ARGS_TUPLE(Arg, Others)
{
   return QTL_ARGS_TUPLE(Arg, Others)();
};
template<typename Type, typename Ret, typename Arg, typename... Others>
inline auto make_values_noclass(Ret (Type::*)(Arg, Others...) const) -> QTL_ARGS_TUPLE(Arg, Others)
{
   return QTL_ARGS_TUPLE(Arg, Others)();
};
template<typename Functor, typename=typename std::enable_if<std::is_member_function_pointer<decltype(&Functor::operator())>::value>::type>
inline auto make_values(const Functor&)
-> decltype(make_values_noclass(&Functor::operator()))
{
   return make_values_noclass(&Functor::operator());
}
template<typename Command, typename ValueProc>
inline void fetch_command(Command& command, ValueProc&& proc)
{
   auto values=make_values(proc);
   typedef decltype(values) values_type;
   while(command.fetch(std::forward<values_type>(values)))
   {
      if(!apply(std::forward<ValueProc>(proc), std::forward<values_type>(values)))
         break;
   }
}
template<typename Command, typename ValueProc, typename... OtherProc>
inline void fetch_command(Command& command, ValueProc&& proc, OtherProc&&... other)
{
   fetch_command(command, std::forward<ValueProc>(proc));
   if(command.next_result())
   {
      fetch_command(command, std::forward<OtherProc>(other)...);
   }
}
}
template<typename Command, typename T>
struct params_binder
{
   enum { size = 1 };
   inline void operator()(Command& command, const T& param) const
   {
      qtl::bind_param(command, 0, param);
   }
};
template<typename Command, typename... Types>
struct params_binder<Command, std::tuple<Types...>>
{
   enum { size = sizeof...(Types) };
   void operator()(Command& command, const std::tuple<Types...>& params) const
   {
      (detail::bind_helper<Command, std::tuple_size<std::tuple<Types...>>::value, Types...>(command))(params);
   }
};
template<typename Command, typename Type1, typename Type2>
struct params_binder<Command, std::pair<Type1, Type2>>
{
   enum { size = 2 };
   void operator()(Command& command, std::pair<Type1, Type2>&& values) const
   {
      qtl::bind_param(command, 0, std::forward<Type1>(values.first));
      qtl::bind_param(command, 1, std::forward<Type2>(values.second));
   }
};
template<typename Command, typename T>
inline void bind_params(Command& command, const T& param)
{
   params_binder<Command, T> binder;
   binder(command, param);
}
template<typename Command, typename T>
struct record_binder
{
   inline void operator()(Command& command, T&& value) const
   {
      bind_field(command, static_cast<size_t>(0), std::forward<typename std::remove_reference<T>::type>(value));
   }
};
template<typename Command, typename T>
struct record_binder<Command, std::reference_wrapper<T>>
{
   inline void operator()(Command& command, std::reference_wrapper<T>&& value) const
   {
      bind_field(command, static_cast<size_t>(0), std::forward<typename std::remove_reference<T>::type>(value.get()));
   }
};
template<typename Command, typename... Types>
struct record_binder<Command, std::tuple<Types...>>
{
   void operator()(Command& command, std::tuple<Types...>&& values) const
   {
      (detail::bind_helper<Command, std::tuple_size<std::tuple<Types...>>::value, Types...>(command))
         (std::forward<std::tuple<Types...>>(values));
   }
};
template<typename Command, typename Type1, typename Type2>
struct record_binder<Command, std::pair<Type1, Type2>>
{
   void operator()(Command& command, std::pair<Type1, Type2>&& values) const
   {
      bind_field(command, static_cast<size_t>(0), std::forward<Type1>(values.first));
      bind_field(command, static_cast<size_t>(1), std::forward<Type2>(values.second));
   }
};
template<typename T, typename Tag>
struct record_with_tag : public T
{
};
template<typename T, typename Pred>
struct custom_binder_type : public T
{
   typedef T value_type;
   explicit custom_binder_type(Pred pred) : m_pred(pred) { }
   custom_binder_type(value_type&& v, Pred pred)
      : value_type(std::forward<value_type>(v)), m_pred(pred)
   {
   }
   template<typename... Args>
   custom_binder_type(Pred pred, Args&&... args)
      : value_type(std::forward<Args>(args)...), m_pred(pred)
   {
   }
   template<typename Command>
   void bind(Command& command)
   {
      m_pred(std::forward<T>(*this), command); // Pred maybe member function
   }
private:
   Pred m_pred;
};
template<typename T, typename Pred>
struct custom_binder_type<std::reference_wrapper<T>, Pred> : public std::reference_wrapper<T>
{
   typedef std::reference_wrapper<T> value_type;
   explicit custom_binder_type(Pred pred) : m_pred(pred) { }
   custom_binder_type(value_type&& v, Pred pred)
      : value_type(std::forward<value_type>(v)), m_pred(pred)
   {
   }
   template<typename... Args>
   custom_binder_type(Pred pred, Args&&... args)
      : T(std::forward<Args>(args)...), m_pred(pred)
   {
   }
   template<typename Command>
   void bind(Command& command)
   {
      m_pred(std::forward<T>(*this), command); // Pred maybe member function
   }
private:
   Pred m_pred;
};
template<typename T, typename Pred>
inline custom_binder_type<T, Pred> custom_bind(T&& v, Pred pred)
{
   return custom_binder_type<T, Pred>(std::forward<T>(v), pred);
}
template<typename Command, typename T, typename Pred>
struct record_binder<Command, custom_binder_type<T, Pred>>
{
   void operator()(Command& command, custom_binder_type<T, Pred>&& values) const
   {
      values.bind(command);
   }
};
template<typename Command, typename T>
inline void bind_record(Command& command, T&& value)
{
   record_binder<Command, T> binder;
   binder(command, std::forward<T>(value));
}
template<typename Command, typename Record>
class query_iterator final
{
public:
   using iterator_category = std::forward_iterator_tag;
   using value_type = Record;
   using difference_type = ptrdiff_t;
   using pointer = Record*;
   using reference = Record&;
   explicit query_iterator(Command& command)
      : m_command(command) { }
   Record* operator->() const { return m_record.get(); }
   Record& operator*() const { return *m_record; }
   query_iterator& operator++()
   {
      if(!m_record)
         m_record=std::make_shared<Record>();
      if(m_record.use_count()==1)
      template <typename Ret, typename Arg>
      inline typename std::decay<Arg>::type make_values(Ret (*)(Arg))
      {
         if(!m_command.fetch(std::forward<Record>(*m_record)))
            m_record.reset();
      }
      else
         return typename std::decay<Arg>::type();
      };
      template <typename Ret, typename Arg, typename... Others>
      inline auto make_values(Ret (*)(Arg, Others...)) -> QTL_ARGS_TUPLE(Arg, Others)
      {
         std::shared_ptr<Record> record=std::make_shared<Record>();
         if(m_command.fetch(std::forward<Record>(*record)))
            m_record=record;
         else
            m_record.reset();
      }
      return *this;
   }
   query_iterator operator++(int)
   {
      query_iterator temp=*this;
      m_record=std::make_shared<Record>();
      if(!m_command.fetch(std::forward<Record>(*m_record)))
         m_record.reset();
      return temp;
   }
         return QTL_ARGS_TUPLE(Arg, Others)();
      };
   bool operator ==(const query_iterator& rhs)
   {
      return &this->m_command==&rhs.m_command &&
         this->m_record==rhs.m_record;
   }
   bool operator !=(const query_iterator& rhs)
   {
      return !(*this==rhs);
   }
private:
   Command& m_command;
   std::shared_ptr<Record> m_record;
};
template<typename Command, typename Record>
class query_result final
{
public:
   typedef typename query_iterator<Command, Record>::value_type value_type;
   typedef typename query_iterator<Command, Record>::pointer pointer;
   typedef typename query_iterator<Command, Record>::reference reference;
   typedef query_iterator<Command, Record> iterator;
   explicit query_result(Command&& command) : m_command(std::move(command)) { }
   query_result(query_result&& src) : m_command(std::move(src.m_command)) { }
   query_result& operator=(query_result&& src)
   {
      if(this!=&src)
         m_command=std::move(src.m_command);
      return *this;
   }
   template<typename Params>
   iterator begin(const Params& params)
   {
      query_iterator<Command, Record> it(m_command);
      ++it;
      return it;
   }
   iterator begin()
   {
      return begin(std::make_tuple());
   }
   iterator end()
   {
      return query_iterator<Command, Record>(m_command);
   }
private:
   Command m_command;
};
template<typename T, class Command>
class base_database
{
public:
   template<typename Params>
   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>
   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>
   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>
   base_database& execute_direct(const char* query_text, size_t text_length, uint64_t* affected, const Params&... params)
   {
      return execute(query_text, text_length, std::forward_as_tuple(params...), affected);
   }
   template<typename... Params>
   base_database& execute_direct(const char* query_text, uint64_t* affected, const Params&... params)
   {
      return execute(query_text, std::forward_as_tuple(params...), affected);
   }
   template<typename... Params>
   base_database& execute_direct(const std::string& query_text, uint64_t* affected, const Params&... params)
   {
      return execute(query_text, std::forward_as_tuple(params...), affected);
   }
   template<typename Params>
   uint64_t insert(const char* query_text, size_t text_length, const Params& params)
   {
      uint64_t id=0;
      T* pThis=static_cast<T*>(this);
      Command command=pThis->open_command(query_text, text_length);
      command.execute(params);
      if(command.affetced_rows()>0)
         id=command.insert_id();
      return id;
   }
   template<typename Params>
   uint64_t insert(const char* query_text, const Params& params)
   {
      return insert(query_text, strlen(query_text), params);
   }
   template<typename Params>
   uint64_t insert(const std::string& query_text, const Params& params)
   {
      return insert(query_text.data(), query_text.length(), params);
   }
   template<typename... Params>
   uint64_t insert_direct(const char* query_text, size_t text_length, const Params&... params)
   {
      return insert(query_text, text_length, std::forward_as_tuple(params...));
   }
   template<typename... Params>
   uint64_t insert_direct(const char* query_text, const Params&... params)
   {
      return insert(query_text, strlen(query_text), std::forward_as_tuple(params...));
   }
   template<typename... Params>
   uint64_t insert_direct(const std::string& query_text, const Params&... params)
   {
      return insert(query_text.data(), query_text.length(), std::forward_as_tuple(params...));
   }
   template<typename Record, typename Params>
   query_result<Command, Record> result(const char* query_text, size_t text_length, const Params& params)
   {
      T* pThis=static_cast<T*>(this);
      Command command=pThis->open_command(query_text, text_length);
      command.execute(params);
      return query_result<Command, Record>(std::move(command));
   }
   template<typename Record, typename Params>
   query_result<Command, Record> result(const char* query_text, const Params& params)
   {
      return result<Record, Params>(query_text, strlen(query_text), params);
   }
   template<typename Record, typename Params>
   query_result<Command, Record> result(const std::string& query_text, const Params& params)
   {
      return result<Record, Params>(query_text.data(), query_text.length(), params);
   }
   template<typename Record>
   query_result<Command, Record> result(const char* query_text, size_t text_length)
   {
      return result<Record>(query_text, text_length, std::make_tuple());
   }
   template<typename Record>
   query_result<Command, Record> result(const char* query_text)
   {
      return result<Record>(query_text, strlen(query_text), std::make_tuple());
   }
   template<typename Record>
   query_result<Command, Record> result(const std::string& query_text)
   {
      return result<Record>(query_text.data(), query_text.length(), std::make_tuple());
   }
   template<typename Params, typename Values, typename ValueProc>
   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);
      command.execute(params);
      while(command.fetch(std::forward<Values>(values)))
      template <typename Type, typename Ret>
      inline Type make_values(Ret (Type::*)())
      {
         if(!detail::apply(std::forward<ValueProc>(proc), std::forward<Values>(values))) break;
         return Type();
      };
      template <typename Type, typename Ret>
      inline Type make_values(Ret (Type::*)() const)
      {
         return Type();
      };
      template <typename Type, typename Ret, typename... Args>
      inline auto make_values(Ret (Type::*)(Args...)) -> QTL_ARGS_TUPLE(Type, Args)
      {
         return QTL_ARGS_TUPLE(Type, Args)();
      };
      template <typename Type, typename Ret, typename... Args>
      inline auto make_values(Ret (Type::*)(Args...) const) -> QTL_ARGS_TUPLE(Type, Args)
      {
         return QTL_ARGS_TUPLE(Type, Args)();
      };
      template <typename Type, typename Ret, typename Arg>
      inline typename std::decay<Arg>::type make_values_noclass(Ret (Type::*)(Arg))
      {
         return typename std::decay<Arg>::type();
      };
      template <typename Type, typename Ret, typename Arg>
      inline typename std::decay<Arg>::type make_values_noclass(Ret (Type::*)(Arg) const)
      {
         return typename std::decay<Arg>::type();
      };
      template <typename Type, typename Ret, typename Arg, typename... Others>
      inline auto make_values_noclass(Ret (Type::*)(Arg, Others...)) -> QTL_ARGS_TUPLE(Arg, Others)
      {
         return QTL_ARGS_TUPLE(Arg, Others)();
      };
      template <typename Type, typename Ret, typename Arg, typename... Others>
      inline auto make_values_noclass(Ret (Type::*)(Arg, Others...) const) -> QTL_ARGS_TUPLE(Arg, Others)
      {
         return QTL_ARGS_TUPLE(Arg, Others)();
      };
      template <typename Functor, typename = typename std::enable_if<std::is_member_function_pointer<decltype(&Functor::operator())>::value>::type>
      inline auto make_values(const Functor &)
         -> decltype(make_values_noclass(&Functor::operator()))
      {
         return make_values_noclass(&Functor::operator());
      }
      command.close();
      return *this;
      template <typename Command, typename ValueProc>
      inline void fetch_command(Command &command, ValueProc &&proc)
      {
         auto values = make_values(proc);
         typedef decltype(values) values_type;
         while (command.fetch(std::forward<values_type>(values)))
         {
            if (!apply(std::forward<ValueProc>(proc), std::forward<values_type>(values)))
               break;
         }
      }
      template <typename Command, typename ValueProc, typename... OtherProc>
      inline void fetch_command(Command &command, ValueProc &&proc, OtherProc &&...other)
      {
         fetch_command(command, std::forward<ValueProc>(proc));
         if (command.next_result())
         {
            fetch_command(command, std::forward<OtherProc>(other)...);
         }
      }
   }
   template<typename Params, typename Values, typename ValueProc>
   base_database& query_explicit(const char* query_text, const Params& params, Values&& values, ValueProc&& proc)
   template <typename Command, typename T>
   struct params_binder
   {
      return query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), std::forward<ValueProc>(proc));
   }
   template<typename Params, typename Values, typename ValueProc>
   base_database& query_explicit(const std::string& query_text, const Params& params, Values&& values, 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>
   base_database& query_explicit(const char* query_text, size_t text_length, Values&& values, 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>
   base_database& query_explicit(const char* query_text, Values&& values, 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>
   base_database& query_explicit(const std::string& query_text, Values&& values, ValueProc&& proc)
   {
      return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
   }
   template<typename Params, typename ValueProc>
   base_database& query(const char* query_text, size_t text_length, const Params& params, ValueProc&& proc)
   {
      return query_explicit(query_text, text_length, params, detail::make_values(proc),  std::forward<ValueProc>(proc));
   }
   template<typename Params, typename ValueProc>
   base_database& query(const char* query_text, const Params& params, ValueProc&& proc)
   {
      return query_explicit(query_text, params, detail::make_values(proc),  std::forward<ValueProc>(proc));
   }
   template<typename Params, typename ValueProc>
   base_database& query(const std::string& query_text, const Params& params, ValueProc&& proc)
   {
      return query_explicit(query_text, params, detail::make_values(proc),  std::forward<ValueProc>(proc));
   }
   template<typename ValueProc>
   base_database& query(const char* query_text, size_t text_length, ValueProc&& proc)
   {
      return query_explicit(query_text, text_length, detail::make_values(proc),  std::forward<ValueProc>(proc));
   }
   template<typename ValueProc>
   base_database& query(const char* query_text, ValueProc&& proc)
   {
      return query_explicit(query_text, detail::make_values(proc),  std::forward<ValueProc>(proc));
   }
   template<typename ValueProc>
   base_database& query(const std::string& query_text, ValueProc&& proc)
   {
      return query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
   }
   template<typename Params, typename... ValueProc>
   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>
   base_database& query_multi_with_params(const char* query_text, const Params& params, ValueProc&&... proc)
   {
      return query_multi_with_params(query_text, strlen(query_text), params, std::forward<ValueProc>(proc)...);
   }
   template<typename Params, typename... ValueProc>
   base_database& query_multi_with_params(const std::string& query_text, const Params& params, ValueProc&&... proc)
   {
      return query_multi_with_params(query_text.data(), query_text.size(), params, std::forward<ValueProc>(proc)...);
   }
   template<typename... ValueProc>
   base_database& query_multi(const char* query_text, size_t text_length, ValueProc&&... proc)
   {
      return query_multi_with_params<std::tuple<>, ValueProc...>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
   }
   template<typename... ValueProc>
   base_database& query_multi(const char* query_text, 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>
   base_database& query_multi(const std::string& query_text, 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>
   bool query_first(const char* query_text, size_t text_length, const Params& params, Values&& values)
   {
      first_record fetcher;
      query_explicit(query_text, text_length, params, std::forward<Values>(values), std::ref(fetcher));
      return fetcher;
   }
   template<typename Params, typename Values>
   bool query_first(const char* query_text, const Params& params, Values&& values)
   {
      first_record fetcher;
      query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), std::ref(fetcher));
      return fetcher;
   }
   template<typename Params, typename Values>
   bool query_first(const std::string& query_text, const Params& params, Values&& values)
   {
      first_record fetcher;
      return query_explicit(query_text, params, values, std::ref(fetcher));
      return fetcher;
   }
   template<typename Values>
   bool query_first(const char* query_text, size_t text_length, Values&& values)
   {
      first_record fetcher;
      return query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
      return fetcher;
   }
   template<typename Values>
   bool query_first(const char* query_text, Values&& values)
   {
      first_record fetcher;
      query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
      return fetcher;
   }
   template<typename Values>
   bool query_first(const std::string& query_text, Values&& values)
   {
      first_record fetcher;
      return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
      return fetcher;
   }
   template<typename... Values>
   bool query_first_direct(const char* query_text, size_t text_length, Values&... values)
   {
      return query_first(query_text, text_length, std::tie(values...));
   }
   template<typename... Values>
   bool query_first_direct(const char* query_text, Values&... values)
   {
      return query_first(query_text, std::tie(values...));
   }
   template<typename... Values>
   bool query_first_direct(const std::string& query_text, Values&... values)
   {
      return query_first(query_text, std::tie(values...));
   }
protected:
   struct nothing
   {
      template<typename... Values> bool operator()(Values&&...) const {  return true; }
      enum
      {
         size = 1
      };
      inline void operator()(Command &command, const T &param) const
      {
         qtl::bind_param(command, 0, param);
      }
   };
   struct first_record
   template <typename Command, typename... Types>
   struct params_binder<Command, std::tuple<Types...>>
   {
      first_record() : _found(false) { }
      template<typename... Values> bool operator()(Values&&...) { _found = true; return false; }
      operator bool() const { return _found; }
      enum
      {
         size = sizeof...(Types)
      };
      void operator()(Command &command, const std::tuple<Types...> &params) const
      {
         (detail::bind_helper<Command, std::tuple_size<std::tuple<Types...>>::value, Types...>(command))(params);
      }
   };
   template <typename Command, typename Type1, typename Type2>
   struct params_binder<Command, std::pair<Type1, Type2>>
   {
      enum
      {
         size = 2
      };
      void operator()(Command &command, std::pair<Type1, Type2> &&values) const
      {
         qtl::bind_param(command, 0, std::forward<Type1>(values.first));
         qtl::bind_param(command, 1, std::forward<Type2>(values.second));
      }
   };
   template <typename Command, typename T>
   inline void bind_params(Command &command, const T &param)
   {
      params_binder<Command, T> binder;
      binder(command, param);
   }
   template <typename Command, typename T>
   struct record_binder
   {
      inline void operator()(Command &command, T &&value) const
      {
         bind_field(command, static_cast<size_t>(0), std::forward<typename std::remove_reference<T>::type>(value));
      }
   };
   template <typename Command, typename T>
   struct record_binder<Command, std::reference_wrapper<T>>
   {
      inline void operator()(Command &command, std::reference_wrapper<T> &&value) const
      {
         bind_field(command, static_cast<size_t>(0), std::forward<typename std::remove_reference<T>::type>(value.get()));
      }
   };
   template <typename Command, typename... Types>
   struct record_binder<Command, std::tuple<Types...>>
   {
      void operator()(Command &command, std::tuple<Types...> &&values) const
      {
         (detail::bind_helper<Command, std::tuple_size<std::tuple<Types...>>::value, Types...>(command))(std::forward<std::tuple<Types...>>(values));
      }
   };
   template <typename Command, typename Type1, typename Type2>
   struct record_binder<Command, std::pair<Type1, Type2>>
   {
      void operator()(Command &command, std::pair<Type1, Type2> &&values) const
      {
         bind_field(command, static_cast<size_t>(0), std::forward<Type1>(values.first));
         bind_field(command, static_cast<size_t>(1), std::forward<Type2>(values.second));
      }
   };
   template <typename T, typename Tag>
   struct record_with_tag : public T
   {
   };
   template <typename T, typename Pred>
   struct custom_binder_type : public T
   {
      typedef T value_type;
      explicit custom_binder_type(Pred pred) : m_pred(pred) {}
      custom_binder_type(value_type &&v, Pred pred)
         : value_type(std::forward<value_type>(v)), m_pred(pred)
      {
      }
      template <typename... Args>
      custom_binder_type(Pred pred, Args &&...args)
         : value_type(std::forward<Args>(args)...), m_pred(pred)
      {
      }
      template <typename Command>
      void bind(Command &command)
      {
         m_pred(std::forward<T>(*this), command); // Pred maybe member function
      }
   private:
      bool _found;
      Pred m_pred;
   };
};
class blobbuf : public std::streambuf
{
public:
   blobbuf() = default;
   blobbuf(const blobbuf&) = default;
   blobbuf& operator=(const blobbuf&) = default;
   virtual ~blobbuf()
   template <typename T, typename Pred>
   struct custom_binder_type<std::reference_wrapper<T>, Pred> : public std::reference_wrapper<T>
   {
      overflow();
   }
      typedef std::reference_wrapper<T> value_type;
   void swap(blobbuf& other)
   {
      std::swap(m_buf, other.m_buf);
      std::swap(m_size, other.m_size);
      std::swap(m_pos, other.m_pos);
      std::streambuf::swap(other);
   }
protected:
   virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
      std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
   {
      if (which&std::ios_base::in)
      explicit custom_binder_type(Pred pred) : m_pred(pred) {}
      custom_binder_type(value_type &&v, Pred pred)
         : value_type(std::forward<value_type>(v)), m_pred(pred)
      {
         pos_type pos = 0;
         pos = seekoff(m_pos, off, dir);
         return seekpos(pos, which);
      }
      return std::streambuf::seekoff(off, dir, which);
      template <typename... Args>
      custom_binder_type(Pred pred, Args &&...args)
         : T(std::forward<Args>(args)...), m_pred(pred)
      {
      }
      template <typename Command>
      void bind(Command &command)
      {
         m_pred(std::forward<T>(*this), command); // Pred maybe member function
      }
   private:
      Pred m_pred;
   };
   template <typename T, typename Pred>
   inline custom_binder_type<T, Pred> custom_bind(T &&v, Pred pred)
   {
      return custom_binder_type<T, Pred>(std::forward<T>(v), pred);
   }
   virtual pos_type seekpos(pos_type pos,
      std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
   template <typename Command, typename T, typename Pred>
   struct record_binder<Command, custom_binder_type<T, Pred>>
   {
      if (pos >= m_size)
         return pos_type(off_type(-1));
      if (which&std::ios_base::out)
      void operator()(Command &command, custom_binder_type<T, Pred> &&values) const
      {
         if (pos < m_pos || pos >= m_pos + off_type(egptr() - pbase()))
         values.bind(command);
      }
   };
   template <typename Command, typename T>
   inline void bind_record(Command &command, T &&value)
   {
      record_binder<Command, T> binder;
      binder(command, std::forward<T>(value));
   }
   template <typename Command, typename Record>
   class query_iterator final
   {
   public:
      using iterator_category = std::forward_iterator_tag;
      using value_type = Record;
      using difference_type = ptrdiff_t;
      using pointer = Record *;
      using reference = Record &;
      explicit query_iterator(Command &command)
         : m_command(command) {}
      Record *operator->() const { return m_record.get(); }
      Record &operator*() const { return *m_record; }
      query_iterator &operator++()
      {
         if (!m_record)
            m_record = std::make_shared<Record>();
         if (m_record.use_count() == 1)
         {
            overflow();
            m_pos = pos;
            setp(m_buf.data(), m_buf.data() + m_buf.size());
            if (!m_command.fetch(std::forward<Record>(*m_record)))
               m_record.reset();
         }
         else
         {
            pbump(off_type(pos - pabs()));
            std::shared_ptr<Record> record = std::make_shared<Record>();
            if (m_command.fetch(std::forward<Record>(*record)))
               m_record = record;
            else
               m_record.reset();
         }
         return *this;
      }
      query_iterator operator++(int)
      {
         query_iterator temp = *this;
         m_record = std::make_shared<Record>();
         if (!m_command.fetch(std::forward<Record>(*m_record)))
            m_record.reset();
         return temp;
      }
      bool operator==(const query_iterator &rhs)
      {
         return &this->m_command == &rhs.m_command &&
               this->m_record == rhs.m_record;
      }
      bool operator!=(const query_iterator &rhs)
      {
         return !(*this == rhs);
      }
   private:
      Command &m_command;
      std::shared_ptr<Record> m_record;
   };
   template <typename Command, typename Record>
   class query_result final
   {
   public:
      typedef typename query_iterator<Command, Record>::value_type value_type;
      typedef typename query_iterator<Command, Record>::pointer pointer;
      typedef typename query_iterator<Command, Record>::reference reference;
      typedef query_iterator<Command, Record> iterator;
      explicit query_result(Command &&command) : m_command(std::move(command)) {}
      query_result(query_result &&src) : m_command(std::move(src.m_command)) {}
      query_result &operator=(query_result &&src)
      {
         if (this != &src)
            m_command = std::move(src.m_command);
         return *this;
      }
      template <typename Params>
      iterator begin(const Params &params)
      {
         query_iterator<Command, Record> it(m_command);
         ++it;
         return it;
      }
      iterator begin()
      {
         return begin(std::make_tuple());
      }
      iterator end()
      {
         return query_iterator<Command, Record>(m_command);
      }
   private:
      Command m_command;
   };
   template <typename T, class Command>
   class base_database
   {
   public:
      template <typename Params>
      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>
      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>
      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>
      base_database &execute_direct(const char *query_text, size_t text_length, uint64_t *affected, const Params &...params)
      {
         return execute(query_text, text_length, std::forward_as_tuple(params...), affected);
      }
      template <typename... Params>
      base_database &execute_direct(const char *query_text, uint64_t *affected, const Params &...params)
      {
         return execute(query_text, std::forward_as_tuple(params...), affected);
      }
      template <typename... Params>
      base_database &execute_direct(const std::string &query_text, uint64_t *affected, const Params &...params)
      {
         return execute(query_text, std::forward_as_tuple(params...), affected);
      }
      template <typename Params>
      uint64_t insert(const char *query_text, size_t text_length, const Params &params)
      {
         uint64_t id = 0;
         T *pThis = static_cast<T *>(this);
         Command command = pThis->open_command(query_text, text_length);
         command.execute(params);
         if (command.affetced_rows() > 0)
            id = command.insert_id();
         return id;
      }
      template <typename Params>
      uint64_t insert(const char *query_text, const Params &params)
      {
         return insert(query_text, strlen(query_text), params);
      }
      template <typename Params>
      uint64_t insert(const std::string &query_text, const Params &params)
      {
         return insert(query_text.data(), query_text.length(), params);
      }
      template <typename... Params>
      uint64_t insert_direct(const char *query_text, size_t text_length, const Params &...params)
      {
         return insert(query_text, text_length, std::forward_as_tuple(params...));
      }
      template <typename... Params>
      uint64_t insert_direct(const char *query_text, const Params &...params)
      {
         return insert(query_text, strlen(query_text), std::forward_as_tuple(params...));
      }
      template <typename... Params>
      uint64_t insert_direct(const std::string &query_text, const Params &...params)
      {
         return insert(query_text.data(), query_text.length(), std::forward_as_tuple(params...));
      }
      template <typename Record, typename Params>
      query_result<Command, Record> result(const char *query_text, size_t text_length, const Params &params)
      {
         T *pThis = static_cast<T *>(this);
         Command command = pThis->open_command(query_text, text_length);
         command.execute(params);
         return query_result<Command, Record>(std::move(command));
      }
      template <typename Record, typename Params>
      query_result<Command, Record> result(const char *query_text, const Params &params)
      {
         return result<Record, Params>(query_text, strlen(query_text), params);
      }
      template <typename Record, typename Params>
      query_result<Command, Record> result(const std::string &query_text, const Params &params)
      {
         return result<Record, Params>(query_text.data(), query_text.length(), params);
      }
      template <typename Record>
      query_result<Command, Record> result(const char *query_text, size_t text_length)
      {
         return result<Record>(query_text, text_length, std::make_tuple());
      }
      template <typename Record>
      query_result<Command, Record> result(const char *query_text)
      {
         return result<Record>(query_text, strlen(query_text), std::make_tuple());
      }
      template <typename Record>
      query_result<Command, Record> result(const std::string &query_text)
      {
         return result<Record>(query_text.data(), query_text.length(), std::make_tuple());
      }
      template <typename Params, typename Values, typename ValueProc>
      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);
         command.execute(params);
         while (command.fetch(std::forward<Values>(values)))
         {
            if (!detail::apply(std::forward<ValueProc>(proc), std::forward<Values>(values)))
               break;
         }
         command.close();
         return *this;
      }
      template <typename Params, typename Values, typename ValueProc>
      base_database &query_explicit(const char *query_text, const Params &params, Values &&values, 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>
      base_database &query_explicit(const std::string &query_text, const Params &params, Values &&values, 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>
      base_database &query_explicit(const char *query_text, size_t text_length, Values &&values, 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>
      base_database &query_explicit(const char *query_text, Values &&values, 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>
      base_database &query_explicit(const std::string &query_text, Values &&values, ValueProc &&proc)
      {
         return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::forward<ValueProc>(proc));
      }
      template <typename Params, typename ValueProc>
      base_database &query(const char *query_text, size_t text_length, const Params &params, ValueProc &&proc)
      {
         return query_explicit(query_text, text_length, params, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename Params, typename ValueProc>
      base_database &query(const char *query_text, const Params &params, ValueProc &&proc)
      {
         return query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename Params, typename ValueProc>
      base_database &query(const std::string &query_text, const Params &params, ValueProc &&proc)
      {
         return query_explicit(query_text, params, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename ValueProc>
      base_database &query(const char *query_text, size_t text_length, ValueProc &&proc)
      {
         return query_explicit(query_text, text_length, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename ValueProc>
      base_database &query(const char *query_text, ValueProc &&proc)
      {
         return query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename ValueProc>
      base_database &query(const std::string &query_text, ValueProc &&proc)
      {
         return query_explicit(query_text, detail::make_values(proc), std::forward<ValueProc>(proc));
      }
      template <typename Params, typename... ValueProc>
      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>
      base_database &query_multi_with_params(const char *query_text, const Params &params, ValueProc &&...proc)
      {
         return query_multi_with_params(query_text, strlen(query_text), params, std::forward<ValueProc>(proc)...);
      }
      template <typename Params, typename... ValueProc>
      base_database &query_multi_with_params(const std::string &query_text, const Params &params, ValueProc &&...proc)
      {
         return query_multi_with_params(query_text.data(), query_text.size(), params, std::forward<ValueProc>(proc)...);
      }
      template <typename... ValueProc>
      base_database &query_multi(const char *query_text, size_t text_length, ValueProc &&...proc)
      {
         return query_multi_with_params<std::tuple<>, ValueProc...>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
      }
      template <typename... ValueProc>
      base_database &query_multi(const char *query_text, 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>
      base_database &query_multi(const std::string &query_text, 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>
      bool query_first(const char *query_text, size_t text_length, const Params &params, Values &&values)
      {
         first_record fetcher;
         query_explicit(query_text, text_length, params, std::forward<Values>(values), std::ref(fetcher));
         return fetcher;
      }
      template <typename Params, typename Values>
      bool query_first(const char *query_text, const Params &params, Values &&values)
      {
         first_record fetcher;
         query_explicit(query_text, strlen(query_text), params, std::forward<Values>(values), std::ref(fetcher));
         return fetcher;
      }
      template <typename Params, typename Values>
      bool query_first(const std::string &query_text, const Params &params, Values &&values)
      {
         first_record fetcher;
         return query_explicit(query_text, params, values, std::ref(fetcher));
         return fetcher;
      }
      template <typename Values>
      bool query_first(const char *query_text, size_t text_length, Values &&values)
      {
         first_record fetcher;
         return query_explicit(query_text, text_length, std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
         return fetcher;
      }
      template <typename Values>
      bool query_first(const char *query_text, Values &&values)
      {
         first_record fetcher;
         query_explicit(query_text, strlen(query_text), std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
         return fetcher;
      }
      template <typename Values>
      bool query_first(const std::string &query_text, Values &&values)
      {
         first_record fetcher;
         return query_explicit(query_text, std::make_tuple(), std::forward<Values>(values), std::ref(fetcher));
         return fetcher;
      }
      template <typename... Values>
      bool query_first_direct(const char *query_text, size_t text_length, Values &...values)
      {
         return query_first(query_text, text_length, std::tie(values...));
      }
      template <typename... Values>
      bool query_first_direct(const char *query_text, Values &...values)
      {
         return query_first(query_text, std::tie(values...));
      }
      template <typename... Values>
      bool query_first_direct(const std::string &query_text, Values &...values)
      {
         return query_first(query_text, std::tie(values...));
      }
   protected:
      struct nothing
      {
         template <typename... Values>
         bool operator()(Values &&...) const { return true; }
      };
      struct first_record
      {
         first_record() : _found(false) {}
         template <typename... Values>
         bool operator()(Values &&...)
         {
            _found = true;
            return false;
         }
         operator bool() const { return _found; }
      private:
         bool _found;
      };
   };
   class blobbuf : public std::streambuf
   {
   public:
      blobbuf() = default;
      blobbuf(const blobbuf &) = default;
      blobbuf &operator=(const blobbuf &) = default;
      virtual ~blobbuf()
      {
         overflow();
      }
      void swap(blobbuf &other)
      {
         std::swap(m_buf, other.m_buf);
         std::swap(m_size, other.m_size);
         std::swap(m_pos, other.m_pos);
         std::streambuf::swap(other);
      }
   protected:
      virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
                         std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
      {
         if (which & std::ios_base::in)
         {
            pos_type pos = 0;
            pos = seekoff(m_pos, off, dir);
            return seekpos(pos, which);
         }
         return std::streambuf::seekoff(off, dir, which);
      }
      virtual pos_type seekpos(pos_type pos,
                         std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
      {
         if (pos >= m_size)
            return pos_type(off_type(-1));
         if (which & std::ios_base::out)
         {
            if (pos < m_pos || pos >= m_pos + off_type(egptr() - pbase()))
            {
               overflow();
               m_pos = pos;
               setp(m_buf.data(), m_buf.data() + m_buf.size());
            }
            else
            {
               pbump(off_type(pos - pabs()));
            }
         }
         else if (which & std::ios_base::in)
         {
            if (pos < m_pos || pos >= m_pos + off_type(epptr() - eback()))
            {
               m_pos = pos;
               setg(m_buf.data(), m_buf.data(), m_buf.data());
            }
            else
            {
               gbump(off_type(pos - gabs()));
            }
         }
         return pos;
      }
      virtual std::streamsize showmanyc() override
      {
         return m_size - pabs();
      }
      virtual int_type underflow() override
      {
         if (pptr() > pbase())
            overflow();
         off_type count = egptr() - eback();
         pos_type next_pos = 0;
         if (count == 0 && eback() == m_buf.data())
         {
            setg(m_buf.data(), m_buf.data(), m_buf.data() + m_buf.size());
            count = m_buf.size();
         }
         else
         {
            next_pos = m_pos + pos_type(count);
         }
         if (next_pos >= m_size)
            return traits_type::eof();
         count = std::min(count, m_size - next_pos);
         m_pos = next_pos;
         if (read_blob(m_buf.data(), count, m_pos))
         {
            setg(eback(), eback(), eback() + count);
            return traits_type::to_int_type(*gptr());
         }
         else
         {
            return traits_type::eof();
         }
      }
      else if (which&std::ios_base::in)
      virtual int_type overflow(int_type ch = traits_type::eof()) override
      {
         if (pos < m_pos || pos >= m_pos + off_type(epptr() - eback()))
         if (pptr() != pbase())
         {
            m_pos = pos;
            size_t count = pptr() - pbase();
            write_blob(pbase(), count);
            // auto intersection = interval_intersection(m_pos, egptr() - eback(), m_pos, epptr() - pbase());
            // if (intersection.first != intersection.second)
            //{
            //   commit(intersection.first, intersection.second);
            // }
            m_pos += count;
            setp(pbase(), epptr());
         }
         if (!traits_type::eq_int_type(ch, traits_type::eof()))
         {
            char_type c = traits_type::to_char_type(ch);
            if (m_pos >= m_size)
               return traits_type::eof();
            write_blob(&c, 1);
            // auto intersection = interval_intersection(m_pos, egptr() - eback(), m_pos, 1);
            // if (intersection.first != intersection.second)
            //{
            //   eback()[intersection.first - m_pos] = c;
            // }
            m_pos += 1;
         }
         return ch;
      }
      virtual int_type pbackfail(int_type c = traits_type::eof()) override
      {
         if (gptr() == 0 || gptr() <= eback() || (!traits_type::eq_int_type(traits_type::eof(), c) && !traits_type::eq(traits_type::to_char_type(c), gptr()[-1])))
         {
            return (traits_type::eof()); // can't put back, fail
         }
         else
         { // back up one position and store put-back character
            gbump(-1);
            if (!traits_type::eq_int_type(traits_type::eof(), c))
               *gptr() = traits_type::to_char_type(c);
            return (traits_type::not_eof(c));
         }
      }
   private:
      off_type seekoff(off_type position, off_type off, std::ios_base::seekdir dir)
      {
         off_type result = 0;
         switch (dir)
         {
         case std::ios_base::beg:
            result = off;
            break;
         case std::ios_base::cur:
            result = position + off;
            break;
         case std::ios_base::end:
            result = m_size - off;
         }
         if (result > m_size)
            result = m_size;
         return result;
      }
      pos_type gabs() const // absolute offset of input pointer in blob field
      {
         return m_pos + off_type(gptr() - eback());
      }
      pos_type pabs() const // absolute offset of output pointer in blob field
      {
         return m_pos + off_type(pptr() - pbase());
      }
   protected:
      std::vector<char> m_buf;
      pos_type m_size;
      pos_type m_pos; // position in the input sequence
      virtual bool read_blob(char *buffer, off_type &count, pos_type position) = 0;
      virtual void write_blob(const char *buffer, size_t count) = 0;
      void init_buffer(std::ios_base::openmode mode)
      {
         size_t bufsize;
         if (m_size > 0)
            bufsize = std::min<size_t>(blob_buffer_size, m_size);
         else
            bufsize = blob_buffer_size;
         if (mode & std::ios_base::in)
         {
            m_buf.resize(bufsize);
            m_pos = 0;
            setg(m_buf.data(), m_buf.data(), m_buf.data());
         }
         else
         else if (mode & std::ios_base::out)
         {
            gbump(off_type(pos - gabs()));
            m_buf.resize(bufsize);
            m_pos = 0;
            setp(m_buf.data(), m_buf.data() + bufsize);
         }
      }
      return pos;
   }
   };
   virtual std::streamsize showmanyc() override
   typedef std::function<void(std::ostream &)> blob_writer;
   template <typename Database>
   struct transaction
   {
      return m_size - pabs();
   }
      transaction(Database &db) : m_db(db), m_commited(true)
      {
         begin();
      }
      ~transaction()
      {
         rollback();
      }
      void begin()
      {
         if (m_commited)
         {
            m_db.begin_transaction();
            m_commited = false;
         }
      }
      void rollback()
      {
         if (!m_commited)
         {
            m_db.rollback();
            m_commited = true;
         }
      }
      void commit()
      {
         if (!m_commited)
         {
            m_db.commit();
            m_commited = true;
         }
      }
   virtual int_type underflow() override
   private:
      bool m_commited;
      Database &m_db;
   };
   template <typename Command, typename Params, typename... Others>
   inline void execute(Command &command, uint64_t *affected, const Params &params)
   {
      if (pptr() > pbase())
         overflow();
      off_type count = egptr() - eback();
      pos_type next_pos = 0;
      if (count == 0 && eback() == m_buf.data())
      {
         setg(m_buf.data(), m_buf.data(), m_buf.data() + m_buf.size());
         count = m_buf.size();
      }
      else
      {
         next_pos = m_pos + pos_type(count);
      }
      if (next_pos >= m_size)
         return traits_type::eof();
      count = std::min(count, m_size - next_pos);
      m_pos = next_pos;
      if (read_blob(m_buf.data(), count, m_pos))
      {
         setg(eback(), eback(), eback() + count);
         return traits_type::to_int_type(*gptr());
      }
      else
      {
         return traits_type::eof();
      }
      command.reset();
      command.execute(params);
      if (affected)
         *affected += command.affetced_rows();
   }
   virtual int_type overflow(int_type ch = traits_type::eof()) override
   template <typename Command, typename Params, typename... Others>
   inline void execute(Command &command, uint64_t *affected, const Params &params, const Others &...others)
   {
      if (pptr() != pbase())
      {
         size_t count = pptr() - pbase();
         write_blob(pbase(), count);
         //auto intersection = interval_intersection(m_pos, egptr() - eback(), m_pos, epptr() - pbase());
         //if (intersection.first != intersection.second)
         //{
         //   commit(intersection.first, intersection.second);
         //}
         m_pos += count;
         setp(pbase(), epptr());
      }
      if (!traits_type::eq_int_type(ch, traits_type::eof()))
      {
         char_type c = traits_type::to_char_type(ch);
         if (m_pos >= m_size)
            return traits_type::eof();
         write_blob(&c, 1);
         //auto intersection = interval_intersection(m_pos, egptr() - eback(), m_pos, 1);
         //if (intersection.first != intersection.second)
         //{
         //   eback()[intersection.first - m_pos] = c;
         //}
         m_pos += 1;
      }
      return ch;
      execute(command, affected, params);
      execute(command, affected, others...);
   }
   virtual int_type pbackfail(int_type c = traits_type::eof()) override
   {
      if (gptr() == 0
         || gptr() <= eback()
         || (!traits_type::eq_int_type(traits_type::eof(), c)
            && !traits_type::eq(traits_type::to_char_type(c), gptr()[-1])))
      {
         return (traits_type::eof());   // can't put back, fail
      }
      else
      {   // back up one position and store put-back character
         gbump(-1);
         if (!traits_type::eq_int_type(traits_type::eof(), c))
            *gptr() = traits_type::to_char_type(c);
         return (traits_type::not_eof(c));
      }
   }
private:
   off_type seekoff(off_type position, off_type off, std::ios_base::seekdir dir)
   {
      off_type result = 0;
      switch (dir)
      {
      case std::ios_base::beg:
         result = off;
         break;
      case std::ios_base::cur:
         result = position + off;
         break;
      case std::ios_base::end:
         result = m_size - off;
      }
      if (result > m_size)
         result = m_size;
      return result;
   }
   pos_type gabs() const // absolute offset of input pointer in blob field
   {
      return m_pos + off_type(gptr() - eback());
   }
   pos_type pabs() const // absolute offset of output pointer in blob field
   {
      return m_pos + off_type(pptr() - pbase());
   }
protected:
   std::vector<char> m_buf;
   pos_type m_size;
   pos_type m_pos;   //position in the input sequence
   virtual bool read_blob(char* buffer, off_type& count, pos_type position) = 0;
   virtual void write_blob(const char* buffer, size_t count) = 0;
   void init_buffer(std::ios_base::openmode mode)
   {
      size_t bufsize;
      if (m_size > 0)
         bufsize = std::min<size_t>(blob_buffer_size, m_size);
      else
         bufsize = blob_buffer_size;
      if (mode&std::ios_base::in)
      {
         m_buf.resize(bufsize);
         m_pos = 0;
         setg(m_buf.data(), m_buf.data(), m_buf.data());
      }
      else if (mode&std::ios_base::out)
      {
         m_buf.resize(bufsize);
         m_pos = 0;
         setp(m_buf.data(), m_buf.data() + bufsize);
      }
   }
};
typedef std::function<void(std::ostream&)> blob_writer;
template<typename Database>
struct transaction
{
   transaction(Database& db) : m_db(db), m_commited(true)
   {
      begin();
   }
   ~transaction()
   {
      rollback();
   }
   void begin()
   {
      if(m_commited)
      {
         m_db.begin_transaction();
         m_commited=false;
      }
   }
   void rollback()
   {
      if(!m_commited)
      {
         m_db.rollback();
         m_commited=true;
      }
   }
   void commit()
   {
      if(!m_commited)
      {
         m_db.commit();
         m_commited=true;
      }
   }
private:
   bool m_commited;
   Database& m_db;
};
template<typename Command, typename Params, typename... Others>
inline void execute(Command& command, uint64_t* affected, const Params& params)
{
   command.reset();
   command.execute(params);
   if(affected) *affected+=command.affetced_rows();
}
template<typename Command, typename Params, typename... Others>
inline void execute(Command& command, uint64_t* affected, const Params& params, const Others&... others)
{
   execute(command, affected, params);
   execute(command, affected, others...);
}
}