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
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
|