From 3e2cc0ded7fed0948ef4d3a94390b916bbb23550 Mon Sep 17 00:00:00 2001 From: Intel Date: Sun, 29 Dec 2013 19:59:39 +0200 Subject: [PATCH] MySQL updates --- .../poolserver/Database/ServerDatabaseEnv.h | 8 ++-- src/server/poolserver/Server/Server.cpp | 38 +++++++++++++--- src/server/shared/Logging/Log.cpp | 2 +- .../shared/MySQL/DatabaseConnection.cpp | 12 +++-- src/server/shared/MySQL/DatabaseConnection.h | 2 +- src/server/shared/MySQL/DatabaseWorkerPool.h | 2 + src/server/shared/MySQL/Field.h | 45 ++++++++++--------- src/server/shared/MySQL/PreparedStatement.cpp | 2 +- src/server/shared/MySQL/QueryResult.cpp | 20 ++++++--- src/server/shared/MySQL/QueryResult.h | 2 +- src/server/shared/Util.h | 5 +++ 11 files changed, 91 insertions(+), 47 deletions(-) diff --git a/src/server/poolserver/Database/ServerDatabaseEnv.h b/src/server/poolserver/Database/ServerDatabaseEnv.h index a2abb9a..851771c 100644 --- a/src/server/poolserver/Database/ServerDatabaseEnv.h +++ b/src/server/poolserver/Database/ServerDatabaseEnv.h @@ -6,15 +6,17 @@ enum ServerSTMT { STMT_QUERY_TEST_TABLE, - STMT_INSERT_SHIT + STMT_INSERT_SHIT, + STMT_QUERY_SHARES }; class ServerDatabaseWorkerPoolMySQL : public MySQL::DatabaseWorkerPool { void LoadSTMT() { - PrepareStatement(STMT_QUERY_TEST_TABLE, "SELECT * FROM `test_table`", MySQL::STMT_BOTH); - PrepareStatement(STMT_INSERT_SHIT, "INSERT INTO `test_table` VALUES (?, ?, ?)", MySQL::STMT_BOTH); + //PrepareStatement(STMT_QUERY_TEST_TABLE, "SELECT * FROM `test_table`", MySQL::STMT_BOTH); + //PrepareStatement(STMT_INSERT_SHIT, "INSERT INTO `test_table` VALUES (?, ?, ?)", MySQL::STMT_BOTH); + PrepareStatement(STMT_QUERY_SHARES, "SELECT `id`, `difficulty`, UNIX_TIMESTAMP(`time`) FROM `shares` WHERE `id` > ? ORDER BY `id` ASC LIMIT 500000;", MySQL::STMT_BOTH); } }; diff --git a/src/server/poolserver/Server/Server.cpp b/src/server/poolserver/Server/Server.cpp index d006f56..3e57925 100644 --- a/src/server/poolserver/Server/Server.cpp +++ b/src/server/poolserver/Server/Server.cpp @@ -11,6 +11,15 @@ #include #include #include +struct Share +{ + Share(uint64 _id, uint32 _diff, uint32 _workerid, uint32 _timestamp) : + id(_id), diff(_diff), workerid(_workerid), timestamp(_timestamp) {} + uint64 id; + uint32 diff; + uint32 workerid; + uint32 timestamp; +}; Server::Server() : serverLoops(0) { @@ -23,17 +32,36 @@ Server::~Server() void AsyncQueryCallback(MySQL::QueryResult result) { - sLog.Info(LOG_SERVER, "Metadata: F: %u R: %u", result->GetFieldCount(), result->GetRowCount()); - while (MySQL::Field* fields = result->FetchRow()) { - sLog.Info(LOG_SERVER, "Row: %i %s", fields[0].GetUInt32(), fields[1].GetString().c_str()); - } } int Server::Run() { sLog.Info(LOG_SERVER, "Server is starting..."); - //InitDatabase(); + InitDatabase(); + + std::vector shares; + + sLog.Info(LOG_SERVER, "Loading shares..."); + + MySQL::QueryResult result = sDatabase.Query("SELECT MIN(`id`), MAX(`id`) FROM `shares`"); + MySQL::Field* fields = result->FetchRow(); + uint32 min = fields[0].Get(); + uint32 max = fields[1].Get(); + sLog.Info(LOG_SERVER, "Min: %u Max: %u", min, max); + + MySQL::PreparedStatement* stmt = sDatabase.GetPreparedStatement(STMT_QUERY_SHARES); + for (uint32 i = min; i < max; i += 500000) + { + stmt->SetUInt32(0, i); + MySQL::QueryResult result2 = sDatabase.Query(stmt); + while (MySQL::Field* fields2 = result2->FetchRow()) { + shares.push_back(Share(fields2[0].Get(), fields2[1].Get(), 2981, fields2[2].Get())); + } + sLog.Info(LOG_SERVER, "Shares: %u", shares.size()); + } + + sLog.Info(LOG_SERVER, "Loaded %u shares", shares.size()); JSON node = JSON::FromString("{\"test\":{\"omg\":\"smth\"},\"other\":[\"smth2\", \"smth3\"] }"); sLog.Info(LOG_SERVER, "Something2: %s", node["other"][0].GetString().c_str()); diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 6396432..7cc0c1c 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -4,7 +4,7 @@ Log sLog; -Log::Log(): logfile(NULL) +Log::Log() { } diff --git a/src/server/shared/MySQL/DatabaseConnection.cpp b/src/server/shared/MySQL/DatabaseConnection.cpp index a2bb4b5..49678b1 100644 --- a/src/server/shared/MySQL/DatabaseConnection.cpp +++ b/src/server/shared/MySQL/DatabaseConnection.cpp @@ -123,7 +123,7 @@ namespace MySQL rowCount = mysql_affected_rows(_mysql); fieldCount = mysql_field_count(_mysql); - if (!result) + if (!*result) return false; if (!rowCount) { @@ -136,7 +136,7 @@ namespace MySQL return true; } - bool DatabaseConnection::_Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint64& rowCount, uint32& fieldCount) + bool DatabaseConnection::_Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint32& fieldCount) { if (!_mysql) return false; @@ -171,7 +171,7 @@ namespace MySQL sLog.Error(LOG_DATABASE, "STMT Execute Error[%u]: %s", lErrno, mysql_stmt_error(mSTMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(stmt, result, resultSTMT, rowCount, fieldCount); // Try again + return _Query(stmt, result, resultSTMT, fieldCount); // Try again cstmt->ClearParameters(); return false; @@ -180,7 +180,6 @@ namespace MySQL cstmt->ClearParameters(); *result = mysql_stmt_result_metadata(mSTMT); - rowCount = mysql_stmt_num_rows(mSTMT); fieldCount = mysql_stmt_field_count(mSTMT); *resultSTMT = mSTMT; @@ -237,16 +236,15 @@ namespace MySQL { MYSQL_RES* result = NULL; MYSQL_STMT* resultSTMT = NULL; - uint64 rowCount = 0; uint32 fieldCount = 0; - if (!_Query(stmt, &result, &resultSTMT, rowCount, fieldCount)) + if (!_Query(stmt, &result, &resultSTMT, fieldCount)) return NULL; if (mysql_more_results(_mysql)) mysql_next_result(_mysql); - return new ResultSet(result, resultSTMT, rowCount, fieldCount); + return new ResultSet(result, resultSTMT, fieldCount); } bool DatabaseConnection::PrepareStatement(uint32 index, const char* sql) diff --git a/src/server/shared/MySQL/DatabaseConnection.h b/src/server/shared/MySQL/DatabaseConnection.h index 04844b5..3bec214 100644 --- a/src/server/shared/MySQL/DatabaseConnection.h +++ b/src/server/shared/MySQL/DatabaseConnection.h @@ -75,7 +75,7 @@ namespace MySQL private: bool _Query(const char *sql, MYSQL_RES** result, MYSQL_FIELD** fields, uint64& rowCount, uint32& fieldCount); - bool _Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint64& rowCount, uint32& fieldCount); + bool _Query(PreparedStatement* stmt, MYSQL_RES** result, MYSQL_STMT** resultSTMT, uint32& fieldCount); bool _HandleMySQLErrno(uint32_t lErrno); diff --git a/src/server/shared/MySQL/DatabaseWorkerPool.h b/src/server/shared/MySQL/DatabaseWorkerPool.h index 584bc78..b096043 100644 --- a/src/server/shared/MySQL/DatabaseWorkerPool.h +++ b/src/server/shared/MySQL/DatabaseWorkerPool.h @@ -17,6 +17,8 @@ namespace MySQL DatabaseWorkerPool() : _asyncQueue(new DatabaseWorkQueue()) { } ~DatabaseWorkerPool() { + Close(); + mysql_library_end(); delete _asyncQueue; } diff --git a/src/server/shared/MySQL/Field.h b/src/server/shared/MySQL/Field.h index b0a91df..9a43d30 100644 --- a/src/server/shared/MySQL/Field.h +++ b/src/server/shared/MySQL/Field.h @@ -17,6 +17,11 @@ namespace MySQL data.length = 0; } + ~Field() + { + CleanUp(); + } + void SetValue(char* value, enum_field_types type) { if (data.value) @@ -51,30 +56,12 @@ namespace MySQL data.raw = true; } - uint32_t GetUInt32() - { - if (data.raw) - return *reinterpret_cast(data.value); - return boost::lexical_cast(data.value); - } - - char const* GetCString() - { - return static_cast(data.value); - } - - std::string GetString() - { - if (data.raw) - return std::string(GetCString(), data.length); - return boost::lexical_cast(data.value); - } - - double GetDouble() + template + T Get() { if (data.raw) - return *reinterpret_cast(data.value); - return boost::lexical_cast(data.value); + return *reinterpret_cast(data.value); + return boost::lexical_cast(data.value); } static size_t SizeForType(MYSQL_FIELD* field) @@ -131,6 +118,20 @@ namespace MySQL data.value = NULL; } }; + + template<> + inline const char* Field::Get() + { + return static_cast(data.value); + } + + template<> + inline std::string Field::Get() + { + if (data.raw) + return std::string(Get(), data.length); + return boost::lexical_cast(data.value); + } } #endif diff --git a/src/server/shared/MySQL/PreparedStatement.cpp b/src/server/shared/MySQL/PreparedStatement.cpp index ff757c7..87bed08 100644 --- a/src/server/shared/MySQL/PreparedStatement.cpp +++ b/src/server/shared/MySQL/PreparedStatement.cpp @@ -77,7 +77,7 @@ namespace MySQL MYSQL_BIND* param = &_bind[index]; param->buffer_type = type; - delete [] static_cast(param->buffer); + delete[] (char *)param->buffer; param->buffer = new char[len]; param->buffer_length = 0; param->is_null_value = 0; diff --git a/src/server/shared/MySQL/QueryResult.cpp b/src/server/shared/MySQL/QueryResult.cpp index 371610d..96375b1 100644 --- a/src/server/shared/MySQL/QueryResult.cpp +++ b/src/server/shared/MySQL/QueryResult.cpp @@ -24,13 +24,11 @@ namespace MySQL } // Prepared statement query - ResultSet::ResultSet(MYSQL_RES* result, MYSQL_STMT* stmt, uint64 rowCount, uint32 fieldCount) : - _rowCount(rowCount), _fieldCount(fieldCount), _currentRow(0) + ResultSet::ResultSet(MYSQL_RES* result, MYSQL_STMT* stmt, uint32 fieldCount) : + _fieldCount(fieldCount), _currentRow(0) { - if (stmt->bind_result_done) { - delete[] stmt->bind->length; - delete[] stmt->bind->is_null; - } + if (!result) + return; // Store entire result set locally from server if (mysql_stmt_store_result(stmt)) { @@ -104,7 +102,17 @@ namespace MySQL _rows.push_back(fields); } + // Free everything mysql_free_result(result); + + for (uint32 i = 0; i < fieldCount; ++i) + delete (char *)bind[i].buffer; + + mysql_stmt_free_result(stmt); + + delete[] bind; + delete[] isNull; + delete[] length; } bool ResultSet::_NextSTMTRow(MYSQL_STMT* stmt) diff --git a/src/server/shared/MySQL/QueryResult.h b/src/server/shared/MySQL/QueryResult.h index 4599a92..c89addf 100644 --- a/src/server/shared/MySQL/QueryResult.h +++ b/src/server/shared/MySQL/QueryResult.h @@ -18,7 +18,7 @@ namespace MySQL // Normal query ResultSet(MYSQL_RES* result, MYSQL_FIELD* resultFields, uint64 rowCount, uint32 fieldCount); // Prepared statement query - ResultSet(MYSQL_RES* result, MYSQL_STMT* stmt, uint64 rowCount, uint32 fieldCount); + ResultSet(MYSQL_RES* result, MYSQL_STMT* stmt, uint32 fieldCount); ~ResultSet(); // Metadata diff --git a/src/server/shared/Util.h b/src/server/shared/Util.h index 5163b2b..06e58be 100644 --- a/src/server/shared/Util.h +++ b/src/server/shared/Util.h @@ -73,6 +73,11 @@ namespace Util class GenericWorker { public: + ~GenericWorker() + { + delete _thread; + } + void Activate() { _thread = new boost::thread(boost::bind(&GenericWorker::Work, this));