mirror of
https://github.com/GOSTSec/poolserver
synced 2025-01-29 16:04:14 +00:00
MySQL updates
This commit is contained in:
parent
ddd5fdeb2d
commit
3e2cc0ded7
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,6 +11,15 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
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<Share> 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>();
|
||||
uint32 max = fields[1].Get<uint32>();
|
||||
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<uint64>(), fields2[1].Get<uint32>(), 2981, fields2[2].Get<uint32>()));
|
||||
}
|
||||
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());
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Log sLog;
|
||||
|
||||
Log::Log(): logfile(NULL)
|
||||
Log::Log()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -17,6 +17,8 @@ namespace MySQL
|
||||
DatabaseWorkerPool() : _asyncQueue(new DatabaseWorkQueue()) { }
|
||||
~DatabaseWorkerPool()
|
||||
{
|
||||
Close();
|
||||
mysql_library_end();
|
||||
delete _asyncQueue;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
template<typename T>
|
||||
T Get()
|
||||
{
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<uint32*>(data.value);
|
||||
return boost::lexical_cast<uint32_t>(data.value);
|
||||
}
|
||||
|
||||
char const* GetCString()
|
||||
{
|
||||
return static_cast<char const*>(data.value);
|
||||
}
|
||||
|
||||
std::string GetString()
|
||||
{
|
||||
if (data.raw)
|
||||
return std::string(GetCString(), data.length);
|
||||
return boost::lexical_cast<std::string>(data.value);
|
||||
}
|
||||
|
||||
double GetDouble()
|
||||
{
|
||||
if (data.raw)
|
||||
return *reinterpret_cast<double*>(data.value);
|
||||
return boost::lexical_cast<double>(data.value);
|
||||
return *reinterpret_cast<T*>(data.value);
|
||||
return boost::lexical_cast<T>(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<const char*>(data.value);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string Field::Get()
|
||||
{
|
||||
if (data.raw)
|
||||
return std::string(Get<const char*>(), data.length);
|
||||
return boost::lexical_cast<std::string>(data.value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -77,7 +77,7 @@ namespace MySQL
|
||||
MYSQL_BIND* param = &_bind[index];
|
||||
|
||||
param->buffer_type = type;
|
||||
delete [] static_cast<char *>(param->buffer);
|
||||
delete[] (char *)param->buffer;
|
||||
param->buffer = new char[len];
|
||||
param->buffer_length = 0;
|
||||
param->is_null_value = 0;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -73,6 +73,11 @@ namespace Util
|
||||
class GenericWorker
|
||||
{
|
||||
public:
|
||||
~GenericWorker()
|
||||
{
|
||||
delete _thread;
|
||||
}
|
||||
|
||||
void Activate()
|
||||
{
|
||||
_thread = new boost::thread(boost::bind(&GenericWorker::Work, this));
|
||||
|
Loading…
x
Reference in New Issue
Block a user