diff --git a/common/MySQLRequestResult.cpp b/common/MySQLRequestResult.cpp index 16d7fe9a0..8fc47cfca 100644 --- a/common/MySQLRequestResult.cpp +++ b/common/MySQLRequestResult.cpp @@ -32,6 +32,10 @@ MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, u m_RowsAffected = rowsAffected; m_RowCount = rowCount; m_ColumnCount = columnCount; + // If we actually need the column length 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_LastInsertedID = lastInsertedID; m_ErrorNumber = errorNumber; } @@ -51,6 +55,7 @@ void MySQLRequestResult::ZeroOut() m_Success = false; m_Result = nullptr; m_ErrorBuffer = nullptr; + m_ColumnLengths = nullptr; m_RowCount = 0; m_RowsAffected = 0; m_LastInsertedID = 0; @@ -61,6 +66,28 @@ 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]; +} + MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem) : m_CurrentRow(moveItem.m_CurrentRow), m_OneBeyondRow() { @@ -70,6 +97,7 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem) m_RowCount = moveItem.m_RowCount; m_RowsAffected = moveItem.m_RowsAffected; m_LastInsertedID = moveItem.m_LastInsertedID; + m_ColumnLengths = moveItem.m_ColumnLengths; // Keeps deconstructor from double freeing // pre move instance. @@ -95,6 +123,7 @@ 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; // Keeps deconstructor from double freeing // pre move instance. diff --git a/common/MySQLRequestResult.h b/common/MySQLRequestResult.h index 05f363722..4859a625f 100644 --- a/common/MySQLRequestResult.h +++ b/common/MySQLRequestResult.h @@ -17,6 +17,7 @@ class MySQLRequestResult { private: MYSQL_RES* m_Result; char* m_ErrorBuffer; + unsigned long* m_ColumnLengths; MySQLRequestRow m_CurrentRow; MySQLRequestRow m_OneBeyondRow; @@ -44,6 +45,8 @@ 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); MySQLRequestRow& begin() { return m_CurrentRow; } MySQLRequestRow& end() { return m_OneBeyondRow;}