#include "utils.h" #include #include #include int Utils::optionalStoiOrDefault(const std::unordered_map& 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& 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 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 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& 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 Utils::optionalUid(const std::string& val) { if (isNullOrEmpty(val)) return std::nullopt; try { return std::stoi(val); } catch (...) { return std::nullopt; } }