You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.0 KiB
130 lines
3.0 KiB
#include "infrastructure/repositories/FileUserRepository.h" |
|
#include "nlohmann/json.hpp" |
|
#include <fstream> |
|
#include <algorithm> |
|
|
|
namespace nxl::autostore::infrastructure { |
|
|
|
namespace { |
|
|
|
// Helper functions for JSON serialization |
|
inline void userToJson(nlohmann::json& j, const domain::User& u) |
|
{ |
|
j = nlohmann::json{ |
|
{"id", u.id}, {"username", u.username}, {"passwordHash", u.passwordHash}}; |
|
} |
|
|
|
inline void jsonToUser(const nlohmann::json& j, domain::User& u) |
|
{ |
|
j.at("id").get_to(u.id); |
|
j.at("username").get_to(u.username); |
|
j.at("passwordHash").get_to(u.passwordHash); |
|
} |
|
|
|
// Helper functions for vector serialization |
|
inline nlohmann::json usersToJson(const std::vector<domain::User>& users) |
|
{ |
|
nlohmann::json j = nlohmann::json::array(); |
|
for (const auto& user : users) { |
|
nlohmann::json userJson; |
|
userToJson(userJson, user); |
|
j.push_back(userJson); |
|
} |
|
return j; |
|
} |
|
|
|
inline std::vector<domain::User> jsonToUsers(const nlohmann::json& j) |
|
{ |
|
std::vector<domain::User> users; |
|
for (const auto& userJson : j) { |
|
domain::User user; |
|
jsonToUser(userJson, user); |
|
users.push_back(user); |
|
} |
|
return users; |
|
} |
|
|
|
} // namespace |
|
|
|
FileUserRepository::FileUserRepository(std::string_view dbPath) : dbPath(dbPath) |
|
{ |
|
load(); |
|
} |
|
|
|
void FileUserRepository::save(const domain::User& user) |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
auto it = |
|
std::find_if(users.begin(), users.end(), |
|
[&](const domain::User& u) { return u.id == user.id; }); |
|
|
|
if (it != users.end()) { |
|
*it = user; |
|
} else { |
|
users.push_back(user); |
|
} |
|
persist(); |
|
} |
|
|
|
std::optional<domain::User> FileUserRepository::findById(std::string_view id) |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
auto it = std::find_if(users.begin(), users.end(), |
|
[&](const domain::User& u) { return u.id == id; }); |
|
|
|
if (it != users.end()) { |
|
return *it; |
|
} |
|
return std::nullopt; |
|
} |
|
|
|
std::optional<domain::User> |
|
FileUserRepository::findByUsername(std::string_view username) |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
auto it = |
|
std::find_if(users.begin(), users.end(), |
|
[&](const domain::User& u) { return u.username == username; }); |
|
|
|
if (it != users.end()) { |
|
return *it; |
|
} |
|
return std::nullopt; |
|
} |
|
|
|
std::vector<domain::User> FileUserRepository::findAll() |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
return users; |
|
} |
|
|
|
void FileUserRepository::remove(std::string_view id) |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
users.erase(std::remove_if(users.begin(), users.end(), |
|
[&](const domain::User& u) { return u.id == id; }), |
|
users.end()); |
|
persist(); |
|
} |
|
|
|
void FileUserRepository::load() |
|
{ |
|
std::lock_guard<std::mutex> lock(mtx); |
|
std::ifstream file(dbPath); |
|
if (file.is_open()) { |
|
nlohmann::json j; |
|
file >> j; |
|
users = jsonToUsers(j); |
|
} |
|
} |
|
|
|
void FileUserRepository::persist() |
|
{ |
|
std::ofstream file(dbPath); |
|
if (file.is_open()) { |
|
nlohmann::json j = usersToJson(users); |
|
file << j.dump(4); |
|
} |
|
} |
|
|
|
} // namespace nxl::autostore::infrastructure
|