From 08d6a0c93bac2210011e3e604fab1df9ec7c7733 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 4 Sep 2025 16:43:33 +0200 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20Unterst=C3=BCtzung=20f=C3=BCr=20das?= =?UTF-8?q?=20Neuladen=20von=20R=C3=A4umen=20aus=20der=20Datenbank=20hinzu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implementiere die Methode `reloadRooms` in den Klassen `Server` und `SSLServer`, um Räume aus der Datenbank neu zu laden. - Ergänze einen Signalhandler in `main.cpp`, um das Neuladen der Räume bei Empfang von SIGUSR1 zu ermöglichen. - Füge die Methode `getRooms` in der `Database`-Klasse hinzu, um Räume aus der Datenbank abzurufen. - Aktualisiere die Header-Dateien entsprechend, um die neuen Methoden zu berücksichtigen. --- src/core/server.cpp | 13 +++++++++++++ src/core/server.h | 1 + src/core/ssl_server.cpp | 26 ++++++++++++++++++++++++++ src/core/ssl_server.h | 1 + src/lib/database.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/lib/database.h | 1 + src/main.cpp | 15 +++++++++++++++ 7 files changed, 97 insertions(+) diff --git a/src/core/server.cpp b/src/core/server.cpp index 07f0b43..c2d6119 100755 --- a/src/core/server.cpp +++ b/src/core/server.cpp @@ -307,6 +307,19 @@ namespace Yc { return true; } + void Server::reloadRooms() { + std::cout << "[YourChat] Reloading rooms from database..." << std::endl; + + // Clear existing rooms + _rooms.clear(); + + // Reload from database + Json::Value emptyRoomList; + createRooms(emptyRoomList); + + std::cout << "[YourChat] Reloaded " << _rooms.size() << " rooms from database" << std::endl; + } + void Server::createRooms(Json::Value roomList) { auto self = shared_from_this(); bool created = false; diff --git a/src/core/server.h b/src/core/server.h index 89a1618..e28e825 100755 --- a/src/core/server.h +++ b/src/core/server.h @@ -18,6 +18,7 @@ namespace Yc { ~Server(); void run(); void stop(); + void reloadRooms(); std::vector roomList(); Json::Value jsonRoomList(); bool roomAllowed(std::string roomName, std::string userName, std::string password); diff --git a/src/core/ssl_server.cpp b/src/core/ssl_server.cpp index 6e11aa8..e3c0f6b 100644 --- a/src/core/ssl_server.cpp +++ b/src/core/ssl_server.cpp @@ -435,6 +435,32 @@ void SSLServer::createRooms() { } } +void SSLServer::reloadRooms() { + std::cout << "[YourChat] Reloading rooms from database..." << std::endl; + + // Clear existing rooms + _rooms.clear(); + + // Try to load rooms from database first + try { + Json::Value dbRooms = _database->getRooms(); + if (dbRooms.isArray() && dbRooms.size() > 0) { + for (const auto& room : dbRooms) { + auto newRoom = std::make_shared(nullptr, room); + _rooms.push_back(newRoom); + } + std::cout << "[YourChat] Loaded " << _rooms.size() << " rooms from database" << std::endl; + return; + } + } catch (const std::exception& e) { + std::cerr << "[YourChat] Failed to load rooms from database: " << e.what() << std::endl; + } + + // Fallback to config or default rooms + createRooms(); + std::cout << "[YourChat] Fallback to config/default rooms: " << _rooms.size() << " rooms loaded" << std::endl; +} + std::vector SSLServer::roomList() { std::vector list; for (const auto &room: _rooms) { diff --git a/src/core/ssl_server.h b/src/core/ssl_server.h index 2e6fd9e..3c9757c 100644 --- a/src/core/ssl_server.h +++ b/src/core/ssl_server.h @@ -39,6 +39,7 @@ public: void run(); void stop(); void createRooms(); + void reloadRooms(); // Room management std::vector roomList(); diff --git a/src/lib/database.cpp b/src/lib/database.cpp index 7fb4beb..31f2040 100644 --- a/src/lib/database.cpp +++ b/src/lib/database.cpp @@ -1,6 +1,8 @@ #include "database.h" #include #include +#include +#include namespace Yc { namespace Lib { @@ -40,5 +42,43 @@ pqxx::result Database::exec(const std::string& query) return r; } +Json::Value Database::getRooms() +{ + Json::Value rooms = Json::arrayValue; + + try { + std::string query = R"( + SELECT r.id, r.title, r.password_hash, r.room_type_id, r.is_public, r.owner_id, r.min_age, r.max_age, r.created_at, r.updated_at, rt.tr as room_type + FROM chat.room r + LEFT JOIN chat.room_type rt ON r.room_type_id = rt.id + ORDER BY r.title + )"; + + auto result = exec(query); + + for (const auto& row : result) { + Json::Value room; + room["id"] = row["id"].as(); + room["name"] = row["title"].c_str(); + room["password"] = row["password_hash"].is_null() ? "" : row["password_hash"].c_str(); + room["type"] = row["room_type_id"].is_null() ? 0 : row["room_type_id"].as(); + room["is_public"] = row["is_public"].as(); + room["owner_id"] = row["owner_id"].is_null() ? 0 : row["owner_id"].as(); + room["min_age"] = row["min_age"].is_null() ? 0 : row["min_age"].as(); + room["max_age"] = row["max_age"].is_null() ? 0 : row["max_age"].as(); + room["created_at"] = row["created_at"].c_str(); + room["updated_at"] = row["updated_at"].c_str(); + room["room_type"] = row["room_type"].is_null() ? "" : row["room_type"].c_str(); + room["allowed"] = Json::arrayValue; + room["roundlength"] = 60; + rooms.append(room); + } + } catch (const std::exception& e) { + std::cerr << "[YourChat] Database error in getRooms: " << e.what() << std::endl; + } + + return rooms; +} + } // namespace Lib } // namespace Yc diff --git a/src/lib/database.h b/src/lib/database.h index 949413e..2d21e73 100644 --- a/src/lib/database.h +++ b/src/lib/database.h @@ -13,6 +13,7 @@ public: Database(std::shared_ptr config); ~Database() = default; pqxx::result exec(const std::string& query); + Json::Value getRooms(); private: std::unique_ptr _connection; }; diff --git a/src/main.cpp b/src/main.cpp index da3c51f..9fa4e34 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ std::atomic g_running{true}; std::shared_ptr g_sslServer = nullptr; std::shared_ptr g_server = nullptr; +std::shared_ptr g_database = nullptr; // Signal handler for graceful shutdown void signalHandler(int signal) { @@ -27,14 +28,28 @@ void signalHandler(int signal) { } } +// Signal handler for room reload +void reloadHandler(int signal) { + std::cout << "\n[YourChat] Received SIGUSR1, reloading rooms from database..." << std::endl; + + if (g_sslServer) { + g_sslServer->reloadRooms(); + } + if (g_server) { + g_server->reloadRooms(); + } +} + // main function int main(int, char **) { // Set up signal handlers std::signal(SIGINT, signalHandler); std::signal(SIGTERM, signalHandler); + std::signal(SIGUSR1, reloadHandler); // Room reload signal auto config = std::make_shared(); auto database = std::make_shared(config); + g_database = database; // Store global reference for reload // Check if SSL is enabled bool sslEnabled = config->value("server", "ssl_enabled").asBool();