From 1dce5b78d52de94ecd840f2d7f5bae0c0ad0b467 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Sat, 11 Sep 2010 09:17:14 +0200 Subject: Core/DBLayer: Implement lower level classes for prepared statements with resultsets. (Implementation in upper level code not yet possible) --HG-- branch : trunk --- src/server/shared/Database/QueryResult.cpp | 139 +++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) (limited to 'src/server/shared/Database/QueryResult.cpp') diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp index dfcb3a94acd..c5a081a514e 100644 --- a/src/server/shared/Database/QueryResult.cpp +++ b/src/server/shared/Database/QueryResult.cpp @@ -103,3 +103,142 @@ enum Field::DataTypes QueryResult::ConvertNativeType(enum_field_types mysqlType) return Field::DB_TYPE_UNKNOWN; } } + +void ResultBind::BindResult(uint32& num_rows) +{ + FreeBindBuffer(); + m_fieldCount = mysql_stmt_field_count(m_stmt); + if (!m_fieldCount) + return; + + m_rBind = new MYSQL_BIND[m_fieldCount]; + memset(m_rBind, 0, sizeof(MYSQL_BIND) * m_fieldCount); + + m_isNull = new my_bool[m_fieldCount]; + memset(m_isNull, 0, sizeof(my_bool) * m_fieldCount); + + m_length = new unsigned long[m_fieldCount]; + memset(m_length, 0, sizeof(unsigned long) * m_fieldCount); + + m_res = mysql_stmt_result_metadata(m_stmt); + + //- This is where we store the (entire) resultset + if (mysql_stmt_store_result(m_stmt)) + { + sLog.outSQLDriver("%s:mysql_stmt_store_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); + return; + } + + //- This is where we prepare the buffer based on metadata + uint32 i = 0; + MYSQL_FIELD* field; + while (field = mysql_fetch_field(m_res)) + { + size_t size = SizeForType(field); + if (size == 0) + size = field->max_length + 1; + + m_rBind[i].buffer_type = field->type; + m_rBind[i].buffer = new char[size]; + memset(m_rBind[i].buffer, 0, size); + m_rBind[i].buffer_length = size; + m_rBind[i].length = &m_length[i]; + m_rBind[i].is_null = &m_isNull[i]; + m_rBind[i].error = NULL;//&m_error[i]; + m_rBind[i].is_unsigned = field->flags & UNSIGNED_FLAG; + + ++i; + } + + //- This is where we bind the bind the buffer to the statement + if (mysql_stmt_bind_result(m_stmt, m_rBind)) + { + sLog.outSQLDriver("%s:mysql_stmt_bind_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); + return; + } + + num_rows = mysql_stmt_num_rows(m_stmt); +} + +void ResultBind::FreeBindBuffer() +{ + for (uint32 i = 0; i < m_fieldCount; ++i) + { + delete[] (char *) m_rBind[i].buffer; + m_rBind[i].buffer = NULL; + } + m_rBind = NULL; +} + +void ResultBind::CleanUp() +{ + FreeBindBuffer(); + delete[] m_isNull; + delete[] m_length; +} + +uint8 PreparedResultSet::GetUInt8(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +int8 PreparedResultSet::GetInt8(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +uint16 PreparedResultSet::GetUInt16(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +int16 PreparedResultSet::GetInt16(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +uint32 PreparedResultSet::GetUInt32(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +int32 PreparedResultSet::GetInt32(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +float PreparedResultSet::GetFloat(uint32 index) +{ + if (!CheckFieldIndex(index)) + return 0; + + return *reinterpret_cast(rbind->m_rBind[index].buffer); +} + +std::string PreparedResultSet::GetString(uint32 index) +{ + if (!CheckFieldIndex(index)) + return std::string(""); + + const char* temp = static_cast(rbind->m_rBind[index].buffer); + size_t len = *rbind->m_rBind[index].length; + return std::string(temp, len ); +} \ No newline at end of file -- cgit v1.2.3