18 changed files with 624 additions and 74 deletions
@ -0,0 +1,83 @@ |
|||||||
|
--- |
||||||
|
Language: Cpp |
||||||
|
AccessModifierOffset: -2 |
||||||
|
AlignAfterOpenBracket: Align |
||||||
|
AlignConsecutiveAssignments: false |
||||||
|
AlignConsecutiveDeclarations: false |
||||||
|
AlignEscapedNewlines: Right |
||||||
|
AlignOperands: true |
||||||
|
AlignTrailingComments: true |
||||||
|
AllowAllArgumentsOnNextLine: true |
||||||
|
AllowAllConstructorInitializersOnNextLine: true |
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true |
||||||
|
AllowShortBlocksOnASingleLine: false |
||||||
|
AllowShortCaseLabelsOnASingleLine: false |
||||||
|
AllowShortFunctionsOnASingleLine: Inline |
||||||
|
AllowShortIfStatementsOnASingleLine: false |
||||||
|
AllowShortLoopsOnASingleLine: false |
||||||
|
AlwaysBreakAfterDefinitionReturnType: None |
||||||
|
AlwaysBreakAfterReturnType: None |
||||||
|
AlwaysBreakBeforeMultilineStrings: false |
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine |
||||||
|
BinPackArguments: true |
||||||
|
BinPackParameters: true |
||||||
|
BreakBeforeBinaryOperators: NonAssignment |
||||||
|
BreakBeforeBraces: Custom |
||||||
|
BraceWrapping: |
||||||
|
AfterClass: true |
||||||
|
AfterControlStatement: false |
||||||
|
AfterEnum: false |
||||||
|
AfterFunction: true |
||||||
|
AfterNamespace: false |
||||||
|
AfterStruct: true |
||||||
|
AfterUnion: false |
||||||
|
AfterExternBlock: false |
||||||
|
BeforeCatch: false |
||||||
|
BeforeElse: false |
||||||
|
IndentBraces: false |
||||||
|
SplitEmptyFunction: false |
||||||
|
SplitEmptyRecord: false |
||||||
|
SplitEmptyNamespace: false |
||||||
|
BreakBeforeInheritanceComma: false |
||||||
|
BreakInheritanceList: BeforeColon |
||||||
|
ColumnLimit: 80 |
||||||
|
CompactNamespaces: false |
||||||
|
ConstructorInitializerIndentWidth: 2 |
||||||
|
ContinuationIndentWidth: 2 |
||||||
|
Cpp11BracedListStyle: true |
||||||
|
DerivePointerAlignment: false |
||||||
|
DisableFormat: false |
||||||
|
ExperimentalAutoDetectBinPacking: false |
||||||
|
FixNamespaceComments: true |
||||||
|
IndentCaseLabels: true |
||||||
|
IndentPPDirectives: None |
||||||
|
IndentWidth: 2 |
||||||
|
IndentWrappedFunctionNames: false |
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false |
||||||
|
# LambdaBodyIndentation: Signature |
||||||
|
MaxEmptyLinesToKeep: 1 |
||||||
|
NamespaceIndentation: None |
||||||
|
PointerAlignment: Left |
||||||
|
ReflowComments: true |
||||||
|
SortIncludes: false |
||||||
|
SortUsingDeclarations: false |
||||||
|
SpaceAfterCStyleCast: false |
||||||
|
SpaceAfterLogicalNot: false |
||||||
|
SpaceAfterTemplateKeyword: true |
||||||
|
# SpaceAroundPointerQualifiers: Default |
||||||
|
SpaceBeforeAssignmentOperators: true |
||||||
|
SpaceBeforeCpp11BracedList: false |
||||||
|
SpaceBeforeCtorInitializerColon: true |
||||||
|
SpaceBeforeInheritanceColon: true |
||||||
|
SpaceBeforeParens: ControlStatements |
||||||
|
SpaceBeforeRangeBasedForLoopColon: true |
||||||
|
SpaceInEmptyParentheses: false |
||||||
|
SpacesBeforeTrailingComments: 1 |
||||||
|
SpacesInAngles: false |
||||||
|
SpacesInCStyleCastParentheses: false |
||||||
|
SpacesInConditionalStatement: false |
||||||
|
SpacesInContainerLiterals: true |
||||||
|
SpacesInParentheses: false |
||||||
|
SpacesInSquareBrackets: false |
||||||
|
TabWidth: 8 |
||||||
|
UseTab: Never |
||||||
@ -1,25 +1,37 @@ |
|||||||
#include "App.h" |
#include "App.h" |
||||||
#include "autostore/AutoStore.h" |
|
||||||
#include <iostream> |
#include <iostream> |
||||||
|
|
||||||
namespace nxl |
namespace nxl { |
||||||
|
|
||||||
|
std::condition_variable App::exitCv; |
||||||
|
std::mutex App::mtx; |
||||||
|
bool App::shouldExit = false; |
||||||
|
|
||||||
|
App::App(int argc, char** argv) |
||||||
{ |
{ |
||||||
App::App(int argc, char **argv) |
signal(SIGINT, App::handleSignal); |
||||||
{ |
signal(SIGTERM, App::handleSignal); |
||||||
signal(SIGINT, App::handle_signal); |
} |
||||||
signal(SIGTERM, App::handle_signal); |
|
||||||
} |
int App::exec() |
||||||
|
{ |
||||||
int App::exec() |
// TODO: start application services when implemented
|
||||||
{ |
|
||||||
nxl::AutoStore autostore; |
std::unique_lock<std::mutex> lock(mtx); |
||||||
autostore.run(); |
exitCv.wait(lock, [] { return shouldExit; }); |
||||||
return 0; |
|
||||||
} |
return 0; |
||||||
|
} |
||||||
void App::handle_signal(int signum) |
|
||||||
{ |
void App::handleSignal(int signum) |
||||||
std::cout << "\nCaught signal " << signum << ". Graceful shutdown." << std::endl; |
{ |
||||||
exit(signum); |
std::cout << "\nCaught signal " << signum << ". Graceful shutdown." |
||||||
} |
<< std::endl; |
||||||
} |
{ |
||||||
|
std::lock_guard<std::mutex> lock(mtx); |
||||||
|
shouldExit = true; |
||||||
|
} |
||||||
|
exitCv.notify_one(); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace nxl
|
||||||
@ -1,16 +1,24 @@ |
|||||||
#pragma once |
#pragma once |
||||||
|
|
||||||
|
#include <atomic> |
||||||
|
#include <condition_variable> |
||||||
#include <csignal> |
#include <csignal> |
||||||
|
#include <mutex> |
||||||
|
#include <thread> |
||||||
|
|
||||||
namespace nxl |
namespace nxl { |
||||||
|
|
||||||
|
class App |
||||||
{ |
{ |
||||||
class App |
public: |
||||||
{ |
App(int argc, char** argv); |
||||||
public: |
int exec(); |
||||||
App(int argc, char **argv); |
|
||||||
int exec(); |
private: |
||||||
|
static void handleSignal(int signum); |
||||||
|
static std::condition_variable exitCv; |
||||||
|
static std::mutex mtx; |
||||||
|
static bool shouldExit; |
||||||
|
}; |
||||||
|
|
||||||
private: |
} // namespace nxl
|
||||||
static void handle_signal(int signum); |
|
||||||
}; |
|
||||||
} |
|
||||||
@ -1,11 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
namespace nxl |
|
||||||
{ |
|
||||||
class AutoStore |
|
||||||
{ |
|
||||||
public: |
|
||||||
AutoStore(); |
|
||||||
void run(); |
|
||||||
}; |
|
||||||
} // namespace nxl
|
|
||||||
@ -0,0 +1,21 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include <string_view> |
||||||
|
#include <optional> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace application { |
||||||
|
|
||||||
|
class IAuthService |
||||||
|
{ |
||||||
|
public: |
||||||
|
virtual ~IAuthService() = default; |
||||||
|
virtual std::string generateToken(std::string_view userId) = 0; |
||||||
|
virtual std::optional<std::string> validateToken(std::string_view token) = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace application
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,26 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "domain/entities/Item.h" |
||||||
|
#include <optional> |
||||||
|
#include <string> |
||||||
|
#include <string_view> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace application { |
||||||
|
|
||||||
|
class IItemRepository |
||||||
|
{ |
||||||
|
public: |
||||||
|
virtual ~IItemRepository() = default; |
||||||
|
virtual void save(const domain::Item& item) = 0; |
||||||
|
virtual std::optional<domain::Item> findById(std::string_view id) = 0; |
||||||
|
virtual std::vector<domain::Item> findByUser(std::string_view userId) = 0; |
||||||
|
virtual std::vector<domain::Item> findAll() = 0; |
||||||
|
virtual void remove(std::string_view id) = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace application
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,27 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "domain/entities/User.h" |
||||||
|
#include <optional> |
||||||
|
#include <string> |
||||||
|
#include <string_view> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace application { |
||||||
|
|
||||||
|
class IUserRepository |
||||||
|
{ |
||||||
|
public: |
||||||
|
virtual ~IUserRepository() = default; |
||||||
|
virtual void save(const domain::User& user) = 0; |
||||||
|
virtual std::optional<domain::User> findById(std::string_view id) = 0; |
||||||
|
virtual std::optional<domain::User> |
||||||
|
findByUsername(std::string_view username) = 0; |
||||||
|
virtual std::vector<domain::User> findAll() = 0; |
||||||
|
virtual void remove(std::string_view id) = 0; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace application
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,21 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
#include <chrono> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace domain { |
||||||
|
|
||||||
|
struct Item |
||||||
|
{ |
||||||
|
std::string id; |
||||||
|
std::string name; |
||||||
|
std::chrono::system_clock::time_point expirationDate; |
||||||
|
std::string orderUrl; |
||||||
|
std::string userId; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,18 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <string> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace domain { |
||||||
|
|
||||||
|
struct User |
||||||
|
{ |
||||||
|
std::string id; |
||||||
|
std::string username; |
||||||
|
std::string passwordHash; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace domain
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,33 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "application/interfaces/IItemRepository.h" |
||||||
|
#include <string> |
||||||
|
#include <vector> |
||||||
|
#include <mutex> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace infrastructure { |
||||||
|
|
||||||
|
class FileItemRepository : public application::IItemRepository |
||||||
|
{ |
||||||
|
public: |
||||||
|
explicit FileItemRepository(std::string_view dbPath); |
||||||
|
void save(const domain::Item& item) override; |
||||||
|
std::optional<domain::Item> findById(std::string_view id) override; |
||||||
|
std::vector<domain::Item> findByUser(std::string_view userId) override; |
||||||
|
std::vector<domain::Item> findAll() override; |
||||||
|
void remove(std::string_view id) override; |
||||||
|
|
||||||
|
private: |
||||||
|
void load(); |
||||||
|
void persist(); |
||||||
|
|
||||||
|
std::string dbPath; |
||||||
|
std::vector<domain::Item> items; |
||||||
|
std::mutex mtx; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace infrastructure
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,34 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include "application/interfaces/IUserRepository.h" |
||||||
|
#include <string> |
||||||
|
#include <vector> |
||||||
|
#include <mutex> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace infrastructure { |
||||||
|
|
||||||
|
class FileUserRepository : public application::IUserRepository |
||||||
|
{ |
||||||
|
public: |
||||||
|
explicit FileUserRepository(std::string_view dbPath); |
||||||
|
void save(const domain::User& user) override; |
||||||
|
std::optional<domain::User> findById(std::string_view id) override; |
||||||
|
std::optional<domain::User> |
||||||
|
findByUsername(std::string_view username) override; |
||||||
|
std::vector<domain::User> findAll() override; |
||||||
|
void remove(std::string_view id) override; |
||||||
|
|
||||||
|
private: |
||||||
|
void load(); |
||||||
|
void persist(); |
||||||
|
|
||||||
|
std::string dbPath; |
||||||
|
std::vector<domain::User> users; |
||||||
|
std::mutex mtx; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace infrastructure
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -1,15 +0,0 @@ |
|||||||
#include "autostore/AutoStore.h" |
|
||||||
#include <iostream> |
|
||||||
|
|
||||||
namespace nxl |
|
||||||
{ |
|
||||||
AutoStore::AutoStore() |
|
||||||
{ |
|
||||||
std::cout << "AutoStore library initialized." << std::endl; |
|
||||||
} |
|
||||||
|
|
||||||
void AutoStore::run() |
|
||||||
{ |
|
||||||
std::cout << "AutoStore library is running." << std::endl; |
|
||||||
} |
|
||||||
} // namespace nxl
|
|
||||||
@ -0,0 +1,142 @@ |
|||||||
|
#include "infrastructure/repositories/FileItemRepository.h" |
||||||
|
#include "nlohmann/json.hpp" |
||||||
|
#include <fstream> |
||||||
|
#include <algorithm> |
||||||
|
#include <chrono> |
||||||
|
#include <ctime> |
||||||
|
#include <iterator> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace infrastructure { |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
// Helper functions for JSON serialization
|
||||||
|
inline void itemToJson(nlohmann::json& j, const domain::Item& item) |
||||||
|
{ |
||||||
|
j = |
||||||
|
nlohmann::json{{"id", item.id}, |
||||||
|
{"name", item.name}, |
||||||
|
{"expirationDate", |
||||||
|
std::chrono::system_clock::to_time_t(item.expirationDate)}, |
||||||
|
{"orderUrl", item.orderUrl}, |
||||||
|
{"userId", item.userId}}; |
||||||
|
} |
||||||
|
|
||||||
|
inline void jsonToItem(const nlohmann::json& j, domain::Item& item) |
||||||
|
{ |
||||||
|
j.at("id").get_to(item.id); |
||||||
|
j.at("name").get_to(item.name); |
||||||
|
std::time_t expirationTime; |
||||||
|
j.at("expirationDate").get_to(expirationTime); |
||||||
|
item.expirationDate = std::chrono::system_clock::from_time_t(expirationTime); |
||||||
|
j.at("orderUrl").get_to(item.orderUrl); |
||||||
|
j.at("userId").get_to(item.userId); |
||||||
|
} |
||||||
|
|
||||||
|
// 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) { |
||||||
|
nlohmann::json itemJson; |
||||||
|
itemToJson(itemJson, item); |
||||||
|
j.push_back(itemJson); |
||||||
|
} |
||||||
|
return j; |
||||||
|
} |
||||||
|
|
||||||
|
inline std::vector<domain::Item> jsonToItems(const nlohmann::json& j) |
||||||
|
{ |
||||||
|
std::vector<domain::Item> items; |
||||||
|
for (const auto& itemJson : j) { |
||||||
|
domain::Item item; |
||||||
|
jsonToItem(itemJson, item); |
||||||
|
items.push_back(item); |
||||||
|
} |
||||||
|
return items; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
FileItemRepository::FileItemRepository(std::string_view dbPath) : dbPath(dbPath) |
||||||
|
{ |
||||||
|
load(); |
||||||
|
} |
||||||
|
|
||||||
|
void FileItemRepository::save(const domain::Item& item) |
||||||
|
{ |
||||||
|
std::lock_guard<std::mutex> lock(mtx); |
||||||
|
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 { |
||||||
|
items.push_back(item); |
||||||
|
} |
||||||
|
persist(); |
||||||
|
} |
||||||
|
|
||||||
|
std::optional<domain::Item> FileItemRepository::findById(std::string_view 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::findByUser(std::string_view 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::findAll() |
||||||
|
{ |
||||||
|
std::lock_guard<std::mutex> lock(mtx); |
||||||
|
return items; |
||||||
|
} |
||||||
|
|
||||||
|
void FileItemRepository::remove(std::string_view 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 infrastructure
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
@ -0,0 +1,134 @@ |
|||||||
|
#include "infrastructure/repositories/FileUserRepository.h" |
||||||
|
#include "nlohmann/json.hpp" |
||||||
|
#include <fstream> |
||||||
|
#include <algorithm> |
||||||
|
|
||||||
|
namespace nxl { |
||||||
|
namespace autostore { |
||||||
|
namespace 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 infrastructure
|
||||||
|
} // namespace autostore
|
||||||
|
} // namespace nxl
|
||||||
Loading…
Reference in new issue