Ergänze Unterstützung für Datenbankintegration in ChatRoom und ChatUser

- Implementiere einen neuen Konstruktor in der Klasse `ChatUser`, der eine Datenbankverbindung akzeptiert, um Benutzerinformationen zu laden.
- Füge eine Methode `setDatabase` in der Klasse `ChatRoom` hinzu, um die Datenbankverbindung zu setzen.
- Aktualisiere die Logik in `ChatRoom`, um den neuen Konstruktor zu verwenden, wenn eine Datenbankverbindung vorhanden ist, andernfalls wird der alte Konstruktor verwendet.
- Stelle sicher, dass die Datenbankverbindung in den Server- und SSLServer-Klassen beim Erstellen neuer Räume gesetzt wird.
This commit is contained in:
Torsten Schulz (local)
2025-09-05 09:56:14 +02:00
parent e38cd6ef9d
commit dce5a56316
6 changed files with 110 additions and 2 deletions

View File

@@ -45,6 +45,13 @@ namespace Yc
return;
}
auto server = _parent->getServer();
if (!server) {
// Fallback wenn Server nicht verfügbar
_user = Yc::Object::User(Json::Value());
_token = Yc::Lib::Tools::generateRandomString(32);
sendMsg(token, _token, _name, _color);
return;
}
auto db = server->_database;
// Suche Community-User
std::string query = "SELECT * FROM community.\"user\" WHERE username = '" + name + "' LIMIT 1;";
@@ -107,6 +114,83 @@ namespace Yc
// Thread-Start erfolgt jetzt explizit per start(), nicht im Konstruktor
}
ChatUser::ChatUser(std::shared_ptr<ChatRoom> parent, std::string name, std::string color, int socket, std::shared_ptr<Database> database)
: _parent(std::move(parent)),
_name(name),
_color(color),
_socket(socket),
_stop(false)
{
// Verwende die direkt übergebene Datenbank
if (!database) {
// Fallback wenn keine Datenbank verfügbar
_user = Yc::Object::User(Json::Value());
_token = Yc::Lib::Tools::generateRandomString(32);
sendMsg(token, _token, _name, _color);
return;
}
auto db = database;
// Suche Community-User
std::string query = "SELECT * FROM community.\"user\" WHERE username = '" + name + "' LIMIT 1;";
auto result = db->exec(query);
Json::Value userJson;
if (result.empty()) {
// Kein Community-User, lege Dummy an
userJson["display_name"] = name;
userJson["color"] = "#000000";
} else {
const auto& row = result[0];
int falukant_user_id = row["id"].as<int>();
// Suche Chat-User
std::string chatUserQuery = "SELECT * FROM chat.\"user\" WHERE falukant_user_id = " + std::to_string(falukant_user_id) + " LIMIT 1;";
auto chatUserResult = db->exec(chatUserQuery);
if (chatUserResult.empty()) {
// Chat-User anlegen
std::string insert = "INSERT INTO chat.\"user\" (falukant_user_id, display_name, color, show_gender, show_age, created_at, updated_at) VALUES (" +
std::to_string(falukant_user_id) + ", '" + name + "', '#000000', true, true, NOW(), NOW()) RETURNING *;";
auto newUser = db->exec(insert);
if (!newUser.empty()) {
const auto& u = newUser[0];
userJson["id"] = u["id"].as<int>();
userJson["falukant_user_id"] = u["falukant_user_id"].as<int>();
userJson["display_name"] = u["display_name"].c_str();
userJson["color"] = u["color"].c_str();
userJson["show_gender"] = u["show_gender"].as<bool>();
userJson["show_age"] = u["show_age"].as<bool>();
userJson["created_at"] = u["created_at"].c_str();
userJson["updated_at"] = u["updated_at"].c_str();
}
} else {
const auto& u = chatUserResult[0];
userJson["id"] = u["id"].as<int>();
userJson["falukant_user_id"] = u["falukant_user_id"].as<int>();
userJson["display_name"] = u["display_name"].c_str();
userJson["color"] = u["color"].c_str();
userJson["show_gender"] = u["show_gender"].as<bool>();
userJson["show_age"] = u["show_age"].as<bool>();
userJson["created_at"] = u["created_at"].c_str();
userJson["updated_at"] = u["updated_at"].c_str();
}
// Rechte laden
std::string rightsQuery = "SELECT r.tr FROM chat.user_rights ur JOIN chat.rights r ON ur.chat_right_id = r.id WHERE ur.chat_user_id = " + std::to_string(userJson["id"].asInt()) + ";";
auto rightsResult = db->exec(rightsQuery);
Json::Value rights(Json::arrayValue);
for (const auto& r : rightsResult) {
rights.append(r["tr"].c_str());
}
userJson["rights"] = rights;
}
_user = Yc::Object::User(userJson);
// Prefer DB color if available
if (_user.id() != 0 && !_user.color().empty()) {
_color = _user.color();
}
_token = Yc::Lib::Tools::generateRandomString(32);
// Beim Initial-Token direkt Name und aktuelle Farbe mitsenden, damit der Client "ich" korrekt färben kann
sendMsg(token, _token, _name, _color);
// Thread-Start erfolgt jetzt explizit per start(), nicht im Konstruktor
}
ChatUser::~ChatUser()
{
// Hinweis: Thread wird nicht im Destruktor gejoint, um Deadlocks zu vermeiden!