diff --git a/src/libsql/Statement.cpp b/src/libsql/Statement.cpp index 3863c51..a1776b1 100644 --- a/src/libsql/Statement.cpp +++ b/src/libsql/Statement.cpp @@ -30,6 +30,12 @@ void CStmt::Destroy() free(m_puiParamLen); m_puiParamLen = NULL; } + + m_vec_param.clear(); + m_vec_result.clear(); + m_vec_result_len.clear(); + m_uiParamCount = 0; + m_uiResultCount = 0; } void CStmt::Error(const char * c_pszMsg) @@ -41,6 +47,8 @@ bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery) { m_pkStmt = mysql_stmt_init(sql->GetSQLHandle()); m_stQuery = c_pszQuery; + m_uiParamCount = 0; + m_uiResultCount = 0; if (mysql_stmt_prepare(m_pkStmt, m_stQuery.c_str(), m_stQuery.length())) { @@ -48,11 +56,7 @@ bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery) return false; } - int iParamCount = 0; - - for (unsigned int i = 0; i < m_stQuery.length(); ++i) - if (c_pszQuery[i] == '?') - ++iParamCount; + const auto iParamCount = mysql_stmt_param_count(m_pkStmt); if (iParamCount) { @@ -62,13 +66,12 @@ bool CStmt::Prepare(CAsyncSQL * sql, const char * c_pszQuery) m_puiParamLen = (long unsigned int *) calloc(iParamCount, sizeof(long unsigned int)); } - m_vec_result.resize(48); - memset(&m_vec_result[0], 0, sizeof(MYSQL_BIND) * 48); - - if (mysql_stmt_bind_result(m_pkStmt, &m_vec_result[0])) + const auto iFieldCount = mysql_stmt_field_count(m_pkStmt); + if (iFieldCount) { - Error("mysql_stmt_bind_result"); - return 0; + m_vec_result.resize(iFieldCount); + memset(&m_vec_result[0], 0, sizeof(MYSQL_BIND) * iFieldCount); + m_vec_result_len.resize(iFieldCount, 0); } return true; @@ -114,6 +117,7 @@ bool CStmt::BindResult(enum_field_types type, void * p, int iMaxLen) bind->buffer_type = type; bind->buffer = (void *) p; bind->buffer_length = iMaxLen; + bind->length = &m_vec_result_len[m_uiResultCount - 1]; return true; } @@ -130,9 +134,21 @@ int CStmt::Execute() MYSQL_BIND * bind = &m_vec_param[i]; if (bind->buffer_type == MYSQL_TYPE_STRING) - { *(m_puiParamLen + i) = strlen((const char *) bind->buffer); - sys_log(0, "param %d len %d buf %s", i, *m_puiParamLen, (const char *) bind->buffer); + } + + if (!m_vec_result.empty()) + { + if (m_uiResultCount != m_vec_result.size()) + { + sys_log(0, "Result binding not enough %d, expected %d query: %s", m_uiResultCount, m_vec_result.size(), m_stQuery.c_str()); + return 0; + } + + if (mysql_stmt_bind_result(m_pkStmt, &m_vec_result[0])) + { + Error("mysql_stmt_bind_result"); + return 0; } } @@ -157,3 +173,10 @@ bool CStmt::Fetch() return !mysql_stmt_fetch(m_pkStmt); } +unsigned long CStmt::GetResultLength(unsigned int index) const +{ + if (index >= m_vec_result_len.size()) + return 0; + + return m_vec_result_len[index]; +} diff --git a/src/libsql/Statement.h b/src/libsql/Statement.h index 681fdfb..1871512 100644 --- a/src/libsql/Statement.h +++ b/src/libsql/Statement.h @@ -17,6 +17,7 @@ class CStmt bool BindResult(enum_field_types type, void * p, int iMaxLen=0); int Execute(); bool Fetch(); + unsigned long GetResultLength(unsigned int index) const; void Error(const char * c_pszMsg); @@ -35,6 +36,7 @@ class CStmt long unsigned int * m_puiParamLen; std::vector m_vec_result; + std::vector m_vec_result_len; unsigned int m_uiResultCount; };