Browse Source

WIP: cpp17

cpp17-init-dingo-fail
chodak166 5 months ago
parent
commit
bf0634ae52
  1. 83
      cpp17/.clang-format
  2. 54
      cpp17/app/src/App.cpp
  3. 28
      cpp17/app/src/App.h
  4. 8
      cpp17/app/src/Main.cpp
  5. 21
      cpp17/app/src/Version.h.in
  6. 19
      cpp17/lib/CMakeLists.txt
  7. 11
      cpp17/lib/include/autostore/AutoStore.h
  8. 21
      cpp17/lib/include/autostore/application/interfaces/IAuthService.h
  9. 26
      cpp17/lib/include/autostore/application/interfaces/IItemRepository.h
  10. 27
      cpp17/lib/include/autostore/application/interfaces/IUserRepository.h
  11. 21
      cpp17/lib/include/autostore/domain/entities/Item.h
  12. 18
      cpp17/lib/include/autostore/domain/entities/User.h
  13. 33
      cpp17/lib/include/autostore/infrastructure/repositories/FileItemRepository.h
  14. 34
      cpp17/lib/include/autostore/infrastructure/repositories/FileUserRepository.h
  15. 15
      cpp17/lib/src/AutoStore.cpp
  16. 142
      cpp17/lib/src/infrastructure/repositories/FileItemRepository.cpp
  17. 134
      cpp17/lib/src/infrastructure/repositories/FileUserRepository.cpp
  18. 3
      cpp17/vcpkg.json

83
cpp17/.clang-format

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

54
cpp17/app/src/App.cpp

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

28
cpp17/app/src/App.h

@ -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);
};
}

8
cpp17/app/src/Main.cpp

@ -2,9 +2,9 @@
#include "Version.h" #include "Version.h"
#include <iostream> #include <iostream>
int main(int argc, char **argv) int main(int argc, char** argv)
{ {
std::cout << "AutoStore v" << nxl::getVersionString() << std::endl; std::cout << "AutoStore v" << nxl::getVersionString() << std::endl;
nxl::App app(argc, argv); nxl::App app(argc, argv);
return app.exec(); return app.exec();
} }

21
cpp17/app/src/Version.h.in

@ -3,17 +3,18 @@
#include <string> #include <string>
namespace nxl namespace nxl {
{
static constexpr int VERSION_MAJOR = ${PROJECT_VERSION_MAJOR}; static constexpr int VERSION_MAJOR = ${PROJECT_VERSION_MAJOR};
static constexpr int VERSION_MINOR = ${PROJECT_VERSION_MINOR}; static constexpr int VERSION_MINOR = ${PROJECT_VERSION_MINOR};
static constexpr int VERSION_PATCH = ${PROJECT_VERSION_PATCH}; static constexpr int VERSION_PATCH = ${PROJECT_VERSION_PATCH};
static constexpr char VERSION_SUFFIX[] = "${PROJECT_VERSION_SUFFIX}"; static constexpr char VERSION_SUFFIX[] = "${PROJECT_VERSION_SUFFIX}";
inline std::string getVersionString() inline std::string getVersionString()
{ {
return std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + "." + std::to_string(VERSION_PATCH) + VERSION_SUFFIX; return std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR)
} + "." + std::to_string(VERSION_PATCH) + VERSION_SUFFIX;
}
} // namespace nxl } // namespace nxl

19
cpp17/lib/CMakeLists.txt

@ -7,20 +7,35 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(${TARGET_NAME} STATIC add_library(${TARGET_NAME} STATIC
src/AutoStore.cpp src/infrastructure/repositories/FileUserRepository.cpp
src/infrastructure/repositories/FileItemRepository.cpp
) )
target_include_directories(${TARGET_NAME} target_include_directories(${TARGET_NAME}
PUBLIC PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include/autostore
)
target_sources(${TARGET_NAME}
PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include
FILES
include/autostore/domain/entities/User.h
include/autostore/domain/entities/Item.h
include/autostore/application/interfaces/IUserRepository.h
include/autostore/application/interfaces/IItemRepository.h
include/autostore/application/interfaces/IAuthService.h
) )
# Find dependencies # Find dependencies
find_package(httplib CONFIG REQUIRED) find_package(httplib CONFIG REQUIRED)
find_package(Catch2 CONFIG REQUIRED) find_package(Catch2 CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
target_link_libraries(${TARGET_NAME} target_link_libraries(${TARGET_NAME}
PUBLIC PUBLIC
httplib::httplib httplib::httplib
Catch2::Catch2WithMain Catch2::Catch2WithMain
nlohmann_json::nlohmann_json
) )

11
cpp17/lib/include/autostore/AutoStore.h

@ -1,11 +0,0 @@
#pragma once
namespace nxl
{
class AutoStore
{
public:
AutoStore();
void run();
};
} // namespace nxl

21
cpp17/lib/include/autostore/application/interfaces/IAuthService.h

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

26
cpp17/lib/include/autostore/application/interfaces/IItemRepository.h

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

27
cpp17/lib/include/autostore/application/interfaces/IUserRepository.h

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

21
cpp17/lib/include/autostore/domain/entities/Item.h

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

18
cpp17/lib/include/autostore/domain/entities/User.h

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

33
cpp17/lib/include/autostore/infrastructure/repositories/FileItemRepository.h

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

34
cpp17/lib/include/autostore/infrastructure/repositories/FileUserRepository.h

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

15
cpp17/lib/src/AutoStore.cpp

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

142
cpp17/lib/src/infrastructure/repositories/FileItemRepository.cpp

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

134
cpp17/lib/src/infrastructure/repositories/FileUserRepository.cpp

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

3
cpp17/vcpkg.json

@ -3,6 +3,7 @@
"version-string": "1.0.0", "version-string": "1.0.0",
"dependencies": [ "dependencies": [
"cpp-httplib", "cpp-httplib",
"catch2" "catch2",
"nlohmann-json"
] ]
} }

Loading…
Cancel
Save