95 lines
2.8 KiB
C++
95 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include <boost/asio.hpp>
|
|
#include <boost/asio/awaitable.hpp>
|
|
#include <boost/asio/ssl.hpp>
|
|
#include <boost/mysql.hpp>
|
|
#include <deque>
|
|
#include <memory>
|
|
#include <queue>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
class DatabaseManager {
|
|
public:
|
|
static DatabaseManager &GetInstance();
|
|
|
|
bool Init(boost::asio::io_context &io_context, const std::string &host,
|
|
uint16_t port, const std::string &user, const std::string &password,
|
|
const std::string &db);
|
|
|
|
struct UserData {
|
|
std::string nickname;
|
|
uint64_t gold;
|
|
uint32_t swordLevel;
|
|
uint32_t maxSwordLevel;
|
|
};
|
|
|
|
struct RankingResult {
|
|
struct Entry {
|
|
uint32_t rank;
|
|
std::string nickname;
|
|
uint64_t value;
|
|
};
|
|
std::vector<Entry> topEntries;
|
|
int32_t myRank;
|
|
uint64_t myValue;
|
|
};
|
|
|
|
class ConnectionProxy {
|
|
public:
|
|
ConnectionProxy(std::unique_ptr<boost::mysql::tcp_ssl_connection> conn,
|
|
DatabaseManager &owner)
|
|
: conn_(std::move(conn)), owner_(owner) {}
|
|
~ConnectionProxy();
|
|
|
|
// Move only
|
|
ConnectionProxy(ConnectionProxy &&other) noexcept
|
|
: conn_(std::move(other.conn_)), owner_(other.owner_) {}
|
|
ConnectionProxy &operator=(ConnectionProxy &&other) noexcept {
|
|
if (this != &other) {
|
|
conn_ = std::move(other.conn_);
|
|
}
|
|
return *this;
|
|
}
|
|
ConnectionProxy(const ConnectionProxy &) = delete;
|
|
ConnectionProxy &operator=(const ConnectionProxy &) = delete;
|
|
|
|
boost::mysql::tcp_ssl_connection *operator->() { return conn_.get(); }
|
|
boost::mysql::tcp_ssl_connection &operator*() { return *conn_; }
|
|
|
|
private:
|
|
std::unique_ptr<boost::mysql::tcp_ssl_connection> conn_;
|
|
DatabaseManager &owner_;
|
|
};
|
|
|
|
boost::asio::awaitable<UserData> LoadUser(std::string nickname);
|
|
boost::asio::awaitable<void> SaveUser(std::string nickname, uint64_t gold,
|
|
uint32_t swordLevel);
|
|
boost::asio::awaitable<RankingResult> GetRanking(int type,
|
|
std::string nickname);
|
|
|
|
boost::asio::awaitable<ConnectionProxy> GetConnection();
|
|
|
|
private:
|
|
DatabaseManager() = default;
|
|
|
|
void ReturnConnection(std::unique_ptr<boost::mysql::tcp_ssl_connection> conn);
|
|
boost::asio::awaitable<std::unique_ptr<boost::mysql::tcp_ssl_connection>>
|
|
CreateNewConnection();
|
|
|
|
std::deque<std::unique_ptr<boost::mysql::tcp_ssl_connection>> pool_;
|
|
std::queue<std::shared_ptr<boost::asio::steady_timer>> waiting_queue_;
|
|
|
|
boost::asio::io_context *io_context_ = nullptr;
|
|
std::unique_ptr<boost::asio::strand<boost::asio::io_context::executor_type>>
|
|
strand_;
|
|
|
|
boost::asio::ssl::context ssl_ctx_{boost::asio::ssl::context::tlsv12_client};
|
|
|
|
std::string host_, user_, password_, db_;
|
|
uint16_t port_;
|
|
|
|
uint32_t max_connections_ = 10;
|
|
uint32_t current_total_connections_ = 0;
|
|
};
|