#include "MyStatement.h" #include "MyBoundResults.h" MyStatement::MyStatement(MyDatabase *db, MYSQL_STMT *stmt) : m_mysql(db->m_mysql), m_pParent(db), m_stmt(stmt), m_rs(NULL), m_Results(false) { m_Params = (unsigned int)mysql_stmt_param_count(m_stmt); if (m_Params) { m_pushinfo = (ParamBind *)malloc(sizeof(ParamBind) * m_Params); memset(m_pushinfo, 0, sizeof(ParamBind) * m_Params); m_bind = (MYSQL_BIND *)malloc(sizeof(MYSQL_BIND) * m_Params); memset(m_bind, 0, sizeof(MYSQL_BIND) * m_Params); } else { m_pushinfo = NULL; m_bind = NULL; } m_pParent->IncRefCount(); m_pRes = mysql_stmt_result_metadata(stmt); m_Results = false; } MyStatement::~MyStatement() { /* Free result set structures */ delete m_rs; /* Free old blobs */ for (unsigned int i=0; iClose(); } void MyStatement::Destroy() { delete this; } bool MyStatement::FetchMoreResults() { /* Multiple result sets are not supported by statements, * thank god. */ return false; } void *MyStatement::CopyBlob(unsigned int param, const void *blobptr, size_t length) { void *copy_ptr = NULL; if (m_pushinfo[param].blob != NULL) { if (m_pushinfo[param].length < length) { free(m_pushinfo[param].blob); } else { copy_ptr = m_pushinfo[param].blob; } } if (copy_ptr == NULL) { copy_ptr = malloc(length); m_pushinfo[param].blob = copy_ptr; m_pushinfo[param].length = length; } memcpy(copy_ptr, blobptr, length); return copy_ptr; } bool MyStatement::BindParamInt(unsigned int param, int num, bool signd) { if (param >= m_Params) { return false; } m_pushinfo[param].data.ival = num; m_bind[param].buffer_type = MYSQL_TYPE_LONG; m_bind[param].buffer = &(m_pushinfo[param].data.ival); m_bind[param].is_unsigned = signd ? 0 : 1; m_bind[param].length = NULL; return true; } bool MyStatement::BindParamFloat(unsigned int param, float f) { if (param >= m_Params) { return false; } m_pushinfo[param].data.fval = f; m_bind[param].buffer_type = MYSQL_TYPE_FLOAT; m_bind[param].buffer = &(m_pushinfo[param].data.fval); m_bind[param].length = NULL; return true; } bool MyStatement::BindParamString(unsigned int param, const char *text, bool copy) { if (param >= m_Params) { return false; } const void *final_ptr; size_t len; if (copy) { len = strlen(text); final_ptr = CopyBlob(param, text, len+1); } else { len = strlen(text); final_ptr = text; } m_bind[param].buffer_type = MYSQL_TYPE_STRING; m_bind[param].buffer = (void *)final_ptr; m_bind[param].buffer_length = (unsigned long)len; m_bind[param].length = &(m_bind[param].buffer_length); return true; } bool MyStatement::BindParamBlob(unsigned int param, const void *data, size_t length, bool copy) { if (param >= m_Params) { return false; } const void *final_ptr; if (copy) { final_ptr = CopyBlob(param, data, length); } else { final_ptr = data; } m_bind[param].buffer_type = MYSQL_TYPE_BLOB; m_bind[param].buffer = (void *)final_ptr; m_bind[param].buffer_length = (unsigned long)length; m_bind[param].length = &(m_bind[param].buffer_length); return true; } bool MyStatement::BindParamNull(unsigned int param) { if (param >= m_Params) { return false; } m_bind[param].buffer_type = MYSQL_TYPE_NULL; return true; } bool MyStatement::Execute() { /* Clear any past result first! */ m_Results = false; /* Bind the parameters */ if (m_Params) { if (mysql_stmt_bind_param(m_stmt, m_bind) != 0) { return false; } } if (mysql_stmt_execute(m_stmt) != 0) { return false; } /* Skip away if we don't have data */ if (!m_pRes) { return true; } /* If we don't have a result manager, create one. */ if (!m_rs) { m_rs = new MyBoundResults(m_stmt, m_pRes); } /* Tell the result set to update its bind info, * and initialize itself if necessary. */ if (!(m_Results = m_rs->Initialize())) { return false; } /* Try precaching the results. */ m_Results = (mysql_stmt_store_result(m_stmt) == 0); /* Update now that the data is known. */ m_rs->Update(); /* Return indicator */ return m_Results; } const char *MyStatement::GetError(int *errCode/* =NULL */) { if (errCode) { *errCode = mysql_stmt_errno(m_stmt); } return mysql_stmt_error(m_stmt); } unsigned int MyStatement::GetAffectedRows() { return (unsigned int)mysql_stmt_affected_rows(m_stmt); } unsigned int MyStatement::GetInsertID() { return (unsigned int)mysql_stmt_insert_id(m_stmt); } IResultSet *MyStatement::GetResultSet() { return (m_Results ? m_rs : NULL); }