Multiple implementations of the same back-end application. The aim is to provide quick, side-by-side comparisons of different technologies (languages, frameworks, libraries) while preserving consistent business logic across all implementations.
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.
 
 
 
 
 
 

123 lines
3.1 KiB

#include "infrastructure/repositories/FileItemRepository.h"
#include "infrastructure/helpers/JsonItem.h"
#include <fstream>
#include <algorithm>
#include <chrono>
#include <ctime>
#include <iterator>
namespace nxl::autostore::infrastructure {
namespace {
// Helper functions for vector serialization
inline nlohmann::json itemsToJson(const std::vector<domain::Item>& items)
{
nlohmann::json j = nlohmann::json::array();
for (const auto& item : items) {
j.push_back(infrastructure::JsonItem::toJsonObj(item));
}
return j;
}
inline std::vector<domain::Item> jsonToItems(const nlohmann::json& j)
{
std::vector<domain::Item> items;
for (const auto& itemJson : j) {
items.push_back(infrastructure::JsonItem::fromJsonObj(itemJson));
}
return items;
}
} // namespace
FileItemRepository::FileItemRepository(std::string_view dbPath) : dbPath(dbPath)
{
load();
}
domain::Item::Id_t FileItemRepository::save(const domain::Item& item)
{
std::lock_guard<std::mutex> lock(mtx);
domain::Item::Id_t id = item.id;
auto it =
std::find_if(items.begin(), items.end(),
[&](const domain::Item& i) { return i.id == item.id; });
if (it != items.end()) {
*it = item;
} else {
domain::Item newItem{item};
newItem.id = "item-"
+ std::to_string(
std::chrono::system_clock::now().time_since_epoch().count());
items.push_back(newItem);
id = newItem.id;
}
persist();
return id;
}
std::optional<domain::Item> FileItemRepository::findById(domain::Item::Id_t id)
{
std::lock_guard<std::mutex> lock(mtx);
auto it = std::find_if(items.begin(), items.end(),
[&](const domain::Item& i) { return i.id == id; });
if (it != items.end()) {
return *it;
}
return std::nullopt;
}
std::vector<domain::Item>
FileItemRepository::findByOwner(domain::User::Id_t userId)
{
std::lock_guard<std::mutex> lock(mtx);
std::vector<domain::Item> userItems;
std::copy_if(items.begin(), items.end(), std::back_inserter(userItems),
[&](const domain::Item& i) { return i.userId == userId; });
return userItems;
}
std::vector<domain::Item> FileItemRepository::findWhere(
std::function<bool(const domain::Item&)> predicate)
{
std::lock_guard<std::mutex> lock(mtx);
std::vector<domain::Item> matchedItems;
std::copy_if(items.begin(), items.end(), std::back_inserter(matchedItems),
predicate);
return matchedItems;
}
void FileItemRepository::remove(domain::Item::Id_t id)
{
std::lock_guard<std::mutex> lock(mtx);
items.erase(std::remove_if(items.begin(), items.end(),
[&](const domain::Item& i) { return i.id == id; }),
items.end());
persist();
}
void FileItemRepository::load()
{
std::lock_guard<std::mutex> lock(mtx);
std::ifstream file(dbPath);
if (file.is_open()) {
nlohmann::json j;
file >> j;
items = jsonToItems(j);
}
}
void FileItemRepository::persist()
{
std::ofstream file(dbPath);
if (file.is_open()) {
nlohmann::json j = itemsToJson(items);
file << j.dump(4);
}
}
} // namespace nxl::autostore::infrastructure