znone
2018-06-06 9bd42502f62125906706b49178e471ceb36db4c9
修正在处理MySQL结果集时,移动字符串时的问题。
3 files modified
65 ■■■■■ changed files
include/qtl_common.hpp 31 ●●●●● patch | view | raw | blame | history
include/qtl_database_pool.hpp 7 ●●●●● patch | view | raw | blame | history
include/qtl_mysql.hpp 27 ●●●●● patch | view | raw | blame | history
include/qtl_common.hpp
@@ -79,6 +79,31 @@
    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<std::string>(src.m_value))
    {
    }
    bind_string_helper(bind_string_helper&& src)
        : m_value(std::forward<std::string>(src.m_value))
    {
    }
    bind_string_helper& operator=(const bind_string_helper& src)
    {
        if (this != &src)
        {
            m_value = std::forward<std::string>(src.m_value);
        }
        return *this;
    }
    bind_string_helper& operator=(bind_string_helper&& src)
    {
        if (this != &src)
        {
            m_value = std::forward<std::string>(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); }
@@ -859,17 +884,17 @@
    template<typename... ValueProc>
    void query_multi(const char* query_text, size_t text_length, ValueProc&&... proc)
    {
        query_multi_with_params<std::tuple<>>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
        query_multi_with_params<std::tuple<>, ValueProc...>(query_text, text_length, std::make_tuple(), std::forward<ValueProc>(proc)...);
    }
    template<typename... ValueProc>
    void query_multi(const char* query_text, ValueProc&&... proc)
    {
        query_multi_with_params<std::tuple<>>(query_text, strlen(query_text), std::make_tuple(), std::forward<ValueProc>(proc)...);
        query_multi_with_params<std::tuple<>, ValueProc...>(query_text, strlen(query_text), std::make_tuple(), std::forward<ValueProc>(proc)...);
    }
    template<typename... ValueProc>
    void query_multi(const std::string& query_text, ValueProc&&... proc)
    {
        query_multi_with_params<std::tuple<>>(query_text.data(), query_text.size(), std::make_tuple(), std::forward<ValueProc>(proc)...);
        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>
include/qtl_database_pool.hpp
@@ -29,8 +29,15 @@
        if(m_background_thread.joinable())
        {
            m_stop_thread=true;
            try
            {
            m_background_thread.join();
        }
            catch (std::system_error&)
            {
                //igore the error
            }
        }
        clear();
    }
include/qtl_mysql.hpp
@@ -70,6 +70,12 @@
    {
        bind();
    }
    void bind(bool& v)
    {
        init();
        buffer_type = MYSQL_TYPE_TINY;
        buffer = &v;
    }
    void bind(int8_t& v)
    {
        init();
@@ -188,7 +194,9 @@
class error : public std::exception
{
public:
    error() : m_error(0) { }
    error(int err, const char* errmsg) : m_error(err), m_errmsg(errmsg) { }
    explicit error(int err) : m_error(err), m_errmsg(ER(err)) { }
    explicit error(statement& stmt);
    explicit error(database& db);
    error(const error& src) = default;
@@ -363,6 +371,17 @@
            if(field==NULL) throw_exception();
            value.clear();
            typename bind_string_helper<T>::char_type* data=value.alloc(field->length);
            m_binderAddins[index].m_before_fetch = [this, value](binder& b) mutable {
                if (value.size() < b.buffer_length)
                {
                    value.alloc(b.buffer_length);
                    if (b.buffer != value.data())
                    {
                        b.buffer = const_cast<char*>(value.data());
                        mysql_stmt_bind_result(m_stmt, &m_binders.front());
                    }
                }
            };
            m_binderAddins[index].m_after_fetch= [value](const binder& b) mutable {
                if(*b.is_null) value.clear();
                else value.truncate(*b.length);
@@ -441,6 +460,11 @@
    bool fetch()
    {
        for (size_t i = 0; i != m_binders.size(); i++)
        {
            if (m_binderAddins[i].m_before_fetch)
                m_binderAddins[i].m_before_fetch(m_binders[i]);
        }
        int err=mysql_stmt_fetch(m_stmt);
        if(err==0 || err==MYSQL_DATA_TRUNCATED)
        {
@@ -511,6 +535,7 @@
        my_bool m_isNull;
        my_bool m_error;
        bool is_truncated;
        std::function<void(binder&)> m_before_fetch;
        std::function<void(const binder&)> m_after_fetch;
    };
    std::vector<binder_addin> m_binderAddins;
@@ -552,6 +577,8 @@
class database final : public qtl::base_database<database, statement>
{
public:
    typedef error exception_type;
    database()
    {
        m_mysql=mysql_init(NULL);