Füge UndergroundWorker hinzu und implementiere Logik für unterirdische Aufgaben. Aktualisiere CMakeLists.txt, um neue Quell- und Header-Dateien einzuschließen. Verbessere die Fehlerbehandlung in der Datenbank und sende Benachrichtigungen nach bestimmten Ereignissen. Integriere Hilfsfunktionen zur sicheren Verarbeitung von Daten.

This commit is contained in:
Torsten Schulz (local)
2025-08-31 23:11:09 +02:00
committed by Torsten (PC)
parent 1451225978
commit 23c07a3570
18 changed files with 1255 additions and 88 deletions

94
src/utils.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include "utils.h"
#include <sstream>
#include <iomanip>
#include <ctime>
int Utils::optionalStoiOrDefault(const std::unordered_map<std::string, std::string>& row,
const std::string& key, int def) {
auto it = row.find(key);
if (it == row.end()) return def;
const std::string& val = it->second;
if (isNullOrEmpty(val)) return def;
try {
return std::stoi(val);
} catch (...) {
return def;
}
}
double Utils::optionalStodOrDefault(const std::unordered_map<std::string, std::string>& row,
const std::string& key, double def) {
auto it = row.find(key);
if (it == row.end()) return def;
const std::string& val = it->second;
if (isNullOrEmpty(val)) return def;
try {
return std::stod(val);
} catch (...) {
return def;
}
}
bool Utils::isNullOrEmpty(const std::string& s) {
return s.empty() || s == "NULL";
}
std::optional<std::chrono::system_clock::time_point> Utils::parseTimestamp(const std::string& iso) {
std::istringstream ss(iso);
std::tm tm = {};
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
if (ss.fail()) {
ss.clear();
ss.str(iso);
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
if (ss.fail()) return std::nullopt;
}
std::time_t time_c = std::mktime(&tm);
if (time_c == -1) return std::nullopt;
return std::chrono::system_clock::from_time_t(time_c);
}
std::optional<int> Utils::computeAgeYears(const std::string& birthdate_iso) {
auto birth_tp = parseTimestamp(birthdate_iso);
if (!birth_tp) return std::nullopt;
auto now = std::chrono::system_clock::now();
std::time_t birth_time = std::chrono::system_clock::to_time_t(*birth_tp);
std::time_t now_time = std::chrono::system_clock::to_time_t(now);
std::tm birth_tm;
std::tm now_tm;
#if defined(_WIN32) || defined(_WIN64)
localtime_s(&birth_tm, &birth_time);
localtime_s(&now_tm, &now_time);
#else
localtime_r(&birth_time, &birth_tm);
localtime_r(&now_time, &now_tm);
#endif
int years = now_tm.tm_year - birth_tm.tm_year;
if (now_tm.tm_mon < birth_tm.tm_mon ||
(now_tm.tm_mon == birth_tm.tm_mon && now_tm.tm_mday < birth_tm.tm_mday)) {
years--;
}
return years;
}
std::string Utils::buildPgIntArrayLiteral(const std::vector<int>& elems) {
std::string res = "{";
for (size_t i = 0; i < elems.size(); ++i) {
res += std::to_string(elems[i]);
if (i + 1 < elems.size()) res += ",";
}
res += "}";
return res;
}
std::optional<int> Utils::optionalUid(const std::string& val) {
if (isNullOrEmpty(val)) return std::nullopt;
try {
return std::stoi(val);
} catch (...) {
return std::nullopt;
}
}