Merge pull request #168 from addtheice/mysql_fetch_lengths_interface

Mysql fetch lengths interface
This commit is contained in:
Alex 2014-07-07 19:36:08 -07:00
commit 0e0dee3d3d
4 changed files with 57 additions and 1 deletions

View File

@ -32,6 +32,11 @@ MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, u
m_RowsAffected = rowsAffected;
m_RowCount = rowCount;
m_ColumnCount = columnCount;
// If we actually need the column length / fields it will be
// requested at that time, no need to pull it in just to cache it.
// Normal usage would have it as nullptr most likely anyways.
m_ColumnLengths = nullptr;
m_Fields = nullptr;
m_LastInsertedID = lastInsertedID;
m_ErrorNumber = errorNumber;
}
@ -51,6 +56,8 @@ void MySQLRequestResult::ZeroOut()
m_Success = false;
m_Result = nullptr;
m_ErrorBuffer = nullptr;
m_ColumnLengths = nullptr;
m_Fields = nullptr;
m_RowCount = 0;
m_RowsAffected = 0;
m_LastInsertedID = 0;
@ -61,6 +68,39 @@ MySQLRequestResult::~MySQLRequestResult()
FreeInternals();
}
uint32 MySQLRequestResult::LengthOfColumn(int columnIndex)
{
if (m_ColumnLengths == nullptr && m_Result != nullptr)
m_ColumnLengths = mysql_fetch_lengths(m_Result);
// If someone screws up and tries to get the length of a
// column when no result occured (check Success! argh!)
// then we always return 0. Also applies if mysql screws
// up and can't get the column lengths for whatever reason.
if (m_ColumnLengths == nullptr)
return 0;
// Want to index check to be sure we don't read passed
// the end of the array. Just default to 0 in that case.
// We *shouldn't* need this or the previous checks if all
// interface code is correctly written.
if (columnIndex >= m_ColumnCount)
return 0;
return m_ColumnLengths[columnIndex];
}
const std::string MySQLRequestResult::FieldName(int columnIndex)
{
if (columnIndex >= m_ColumnCount || m_Result == nullptr)
return std::string();
if (m_Fields == nullptr)
m_Fields = mysql_fetch_fields(m_Result);
return std::string(m_Fields[columnIndex].name);
}
MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem)
: m_CurrentRow(moveItem.m_CurrentRow), m_OneBeyondRow()
{
@ -70,6 +110,8 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem)
m_RowCount = moveItem.m_RowCount;
m_RowsAffected = moveItem.m_RowsAffected;
m_LastInsertedID = moveItem.m_LastInsertedID;
m_ColumnLengths = moveItem.m_ColumnLengths;
m_Fields = moveItem.m_Fields;
// Keeps deconstructor from double freeing
// pre move instance.
@ -95,7 +137,9 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
m_LastInsertedID = other.m_LastInsertedID;
m_CurrentRow = other.m_CurrentRow;
m_OneBeyondRow = other.m_OneBeyondRow;
m_ColumnLengths = other.m_ColumnLengths;
m_Fields = other.m_Fields;
// Keeps deconstructor from double freeing
// pre move instance.
other.ZeroOut();

View File

@ -16,7 +16,9 @@
class MySQLRequestResult {
private:
MYSQL_RES* m_Result;
MYSQL_FIELD* m_Fields;
char* m_ErrorBuffer;
unsigned long* m_ColumnLengths;
MySQLRequestRow m_CurrentRow;
MySQLRequestRow m_OneBeyondRow;
@ -44,6 +46,9 @@ public:
uint32 RowCount() const {return m_RowCount;}
uint32 ColumnCount() const {return m_ColumnCount;}
uint32 LastInsertedID() const {return m_LastInsertedID;}
// default to 0 index since we mostly use it that way anyways.
uint32 LengthOfColumn(int columnIndex = 0);
const std::string FieldName(int columnIndex);
MySQLRequestRow& begin() { return m_CurrentRow; }
MySQLRequestRow& end() { return m_OneBeyondRow;}

View File

@ -58,6 +58,11 @@ void DBcore::ping() {
MDatabase.unlock();
}
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
{
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
}
MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce)
{
LockMutex lock(&MDatabase);

View File

@ -7,6 +7,7 @@
#endif
#include <mysql.h>
#include <string.h>
#include "../common/types.h"
#include "../common/Mutex.h"
#include "../common/linked_list.h"
@ -24,6 +25,7 @@ public:
eStatus GetStatus() { return pStatus; }
bool RunQuery(const char* query, uint32 querylen, char* errbuf = 0, MYSQL_RES** result = 0, uint32* affected_rows = 0, uint32* last_insert_id = 0, uint32* errnum = 0, bool retry = true);
MySQLRequestResult QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
uint32 DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen);
void ping();
MYSQL* getMySQL(){ return &mysql; }