| | |
| | | return bind_string_helper<string_type>(std::forward<string_type>(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 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_field(Command& command, size_t index, T& value) |
| | | { |
| | | bind_field(command, index, std::forward<T>(value)); |
| | | } |
| | | |
| | | template<typename Command, typename T> |
| | | inline void bind_field(Command& command, size_t index, T&& value) |
| | | { |
| | | command.bind_field(index, std::forward<typename std::remove_reference<T>::type>(value)); |
| | | } |
| | | // 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]) |
| | |
| | | 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 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); |
| | | } |
| | | |
| | | namespace detail |
| | |
| | | explicit bind_helper(Command& command) : m_command(command) { } |
| | | void operator()(const std::tuple<Types...>& params) const |
| | | { |
| | | m_command.bind_param(N-1, std::get<N-1>(params)); |
| | | 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 |
| | |
| | | explicit bind_helper(Command& command) : m_command(command) { } |
| | | void operator()(const std::tuple<Types...>& params) const |
| | | { |
| | | m_command.bind_param(0, std::get<0>(params)); |
| | | bind_param(m_command, 0, std::get<0>(params)); |
| | | } |
| | | void operator()(std::tuple<Types...>&& params) const |
| | | { |
| | |
| | | binder.bind(v); |
| | | } |
| | | |
| | | inline void bind(binder& binder, const char* str) |
| | | inline void bind(binder& binder, const char* str, size_t length=0) |
| | | { |
| | | binder.bind((char*)str, (unsigned long)strlen(str)); |
| | | if(length==0) length=strlen(str); |
| | | binder.bind(const_cast<char*>(str), static_cast<unsigned long>(length), MYSQL_TYPE_VAR_STRING); |
| | | } |
| | | |
| | | class statement; |
| | |
| | | return fetch(); |
| | | } |
| | | |
| | | void bind_param(size_t index, const char* param, size_t length) |
| | | { |
| | | bind(m_binders[index], param, length); |
| | | } |
| | | |
| | | void bind_param(size_t index, const std::nullptr_t&) |
| | | { |
| | | m_binders[index].bind(); |
| | | } |
| | | |
| | | void bind_param(size_t index, std::istream& param) |
| | | { |
| | | m_binders[index].bind(NULL, 0, MYSQL_TYPE_LONG_BLOB); |
| | | m_binderAddins[index].m_after_fetch=[this, index, ¶m](const binder&) { |
| | | std::array<char, blob_buffer_size> buffer; |
| | | unsigned long readed=0; |
| | | while(!param.eof() && !param.fail()) |
| | | { |
| | | param.read(buffer.data(), buffer.size()); |
| | | readed=(unsigned long)param.gcount(); |
| | | if(readed>0) |
| | | { |
| | | if(mysql_stmt_send_long_data(m_stmt, index, buffer.data(), readed)!=0) |
| | | throw_exception(); |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | |
| | | template<class Param> |
| | | void bind_param(size_t index, const Param& param) |
| | | { |
| | |
| | | bind(m_binders[index], std::forward<Type>(value)); |
| | | m_binderAddins[index].m_after_fetch=if_null<typename std::remove_reference<Type>::type>(value); |
| | | } |
| | | } |
| | | |
| | | void bind_param(size_t index, const std::nullptr_t&) |
| | | { |
| | | m_binders[index].bind(); |
| | | } |
| | | |
| | | void bind_field(size_t index, char* value, size_t length) |
| | |
| | | m_binders[index].bind(data, field->length, field->type); |
| | | } |
| | | } |
| | | void bind_param(size_t index, std::istream& param) |
| | | { |
| | | m_binders[index].bind(NULL, 0, MYSQL_TYPE_LONG_BLOB); |
| | | m_binderAddins[index].m_after_fetch=[this, index, ¶m](const binder&) { |
| | | std::array<char, blob_buffer_size> buffer; |
| | | unsigned long readed=0; |
| | | while(!param.eof() && !param.fail()) |
| | | { |
| | | param.read(buffer.data(), buffer.size()); |
| | | readed=(unsigned long)param.gcount(); |
| | | if(readed>0) |
| | | { |
| | | if(mysql_stmt_send_long_data(m_stmt, index, buffer.data(), readed)!=0) |
| | | throw_exception(); |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | |
| | | void bind_field(size_t index, std::ostream&& value) |
| | | { |
| | | if(m_result) |
| | |
| | | m_mysql=src.m_mysql; |
| | | src.m_mysql=NULL; |
| | | } |
| | | database& operator=(const database&) = delete; |
| | | database& operator=(database&& src) |
| | | database& operator==(const database&) = delete; |
| | | database& operator==(database&& src) |
| | | { |
| | | if(this!=&src) |
| | | { |
| | |
| | | m_mysql=src.m_mysql; |
| | | src.m_mysql=NULL; |
| | | } |
| | | return *this; |
| | | } |
| | | |
| | | MYSQL* handle() { return m_mysql; } |
| | |
| | | m_db=src.m_db; |
| | | src.m_db=NULL; |
| | | } |
| | | return *this; |
| | | } |
| | | |
| | | void open(const char *filename, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) |