diff --git a/CMakeLists.txt b/CMakeLists.txt index 8deff64..0112358 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ add_executable(App ./src/main.cpp src/endpoints_handlers/GetUserTreatmentSchemeExecutor.h src/endpoints_handlers/GetDiariesExecutor.h src/endpoints_handlers/PostDiaryExecutor.h + src/endpoints_handlers/PutDiaryExecutor.h src/DAO/IDiariesDAO.h src/dtos/diary_dto.h src/DAO/MySQLDiariesDao.cpp diff --git a/src/DAO/IDiariesDAO.h b/src/DAO/IDiariesDAO.h index d68a6ca..8c27c8d 100644 --- a/src/DAO/IDiariesDAO.h +++ b/src/DAO/IDiariesDAO.h @@ -17,6 +17,12 @@ public: const diary_dto& dto ) const = 0; + virtual void UpdateDiary( + const std::string& user_uuid, + const std::string& diary_uuid, + const diary_dto& dto + ) const = 0; + virtual ~IDiariesDAO() = default; }; } diff --git a/src/DAO/MySQLDiariesDAO.cpp b/src/DAO/MySQLDiariesDAO.cpp index a489c76..c935411 100644 --- a/src/DAO/MySQLDiariesDAO.cpp +++ b/src/DAO/MySQLDiariesDAO.cpp @@ -1,5 +1,7 @@ #include "MySQLDiariesDAO.h" +#include "../exceptions/session_exception.h" + namespace uad { MySqlDiariesDAO::MySqlDiariesDAO(mysqlx::Session& session) : session_(session) @@ -107,4 +109,44 @@ void MySqlDiariesDAO::СreateDiary(const std::string& user_uuid, const diary_dto stmt.execute(); } + +void MySqlDiariesDAO::UpdateDiary( + const std::string& user_uuid, + const std::string& diary_uuid, + const diary_dto& dto) const +{ + auto stmt = session_.sql(R"( + UPDATE `up_and_down`.`diaries` + SET + mania_level = ?, + depression_level = ?, + mood_level = ?, + activity_level = ?, + appetite_level = ?, + dream_level = ?, + anxiety_level = ?, + comment = ?, + user_treatment_schemes_uuid = ? + WHERE uuid = ? + )"); + + stmt.bind( + dto.mania_level, + dto.depression_level, + dto.mood_level, + dto.activity_level, + dto.appetite_level, + dto.dream_level, + dto.anxiety_level, + dto.comment, + dto.user_treatment_scheme_uuid, + dto.uuid + ); + + auto res = stmt.execute(); + + if (res.getAffectedItemsCount() == 0) { + throw session_exception(boost::beast::http::status::not_found, "Diary not found"); + } +} } diff --git a/src/DAO/MySQLDiariesDAO.h b/src/DAO/MySQLDiariesDAO.h index 6097898..660712f 100644 --- a/src/DAO/MySQLDiariesDAO.h +++ b/src/DAO/MySQLDiariesDAO.h @@ -21,5 +21,11 @@ public: const std::string& user_uuid, const diary_dto& dto ) const override; + + void UpdateDiary( + const std::string& user_uuid, + const std::string& diary_uuid, + const diary_dto& dto + ) const override; }; } diff --git a/src/endpoints_handlers/PostDiaryExecutor.h b/src/endpoints_handlers/PostDiaryExecutor.h index c4b9080..bc6d9f7 100644 --- a/src/endpoints_handlers/PostDiaryExecutor.h +++ b/src/endpoints_handlers/PostDiaryExecutor.h @@ -71,7 +71,7 @@ public: diary_dto dto; - dto.uuid = obj["uuid"].as_string().c_str(); + dto.uuid = GenerateUUID(); dto.time_ms = obj["time_ms"].as_int64(); dto.mania_level = obj["mania_level"].as_int64(); dto.depression_level = obj["depression_level"].as_int64(); @@ -80,13 +80,9 @@ public: dto.appetite_level = obj["appetite_level"].as_int64(); dto.dream_level = obj["dream_level"].as_int64(); dto.anxiety_level = obj["anxiety_level"].as_int64(); - - if (obj.contains("comment")) - dto.comment = obj["comment"].as_string().c_str(); - - if (obj.contains("user_treatment_scheme_uuid")) - dto.user_treatment_scheme_uuid = - obj["user_treatment_scheme_uuid"].as_string().c_str(); + dto.comment = obj["comment"].as_string().c_str(); + dto.user_treatment_scheme_uuid = + obj["user_treatment_scheme_uuid"].as_string().c_str(); try { diff --git a/src/endpoints_handlers/PutDiaryExecutor.h b/src/endpoints_handlers/PutDiaryExecutor.h new file mode 100644 index 0000000..068c8d3 --- /dev/null +++ b/src/endpoints_handlers/PutDiaryExecutor.h @@ -0,0 +1,119 @@ +#pragma once +#include + +#include +#include +#include +#include + +#include "IExecutor.h" +#include "../DAO/IAuthDAO.h" +#include "../DAO/IDiariesDAO.h" +#include "../DAO/IUserTreatmentSchemesDAO.h" +#include "../exceptions/session_exception.h" + +namespace uad +{ +template +class PutDiaryExecutor +{ + mysqlx::Session& session_; + const std::shared_ptr& auth_dao_; + const std::shared_ptr& diaries_dao_; + +public: + PutDiaryExecutor( + mysqlx::Session& session, + const std::shared_ptr& auth_dao, + const std::shared_ptr& diaries_dao + ) : session_(session), auth_dao_(auth_dao), diaries_dao_(diaries_dao) + { + } + + [[nodiscard]] boost::beast::http::response operator ()( + boost::beast::http::request>&& req, + std::string diary_uuid + ) + { + using namespace boost; + using namespace boost::json; + using namespace boost::beast; + using namespace std::string_literals; + using namespace std::string_view_literals; + + constexpr std::string_view auth_prefix = "Bearer "sv; + static const std::string invalid_token_message = + "PUT /api/v1/Diary - Response 401: Unauthorized"s; + + BOOST_LOG_TRIVIAL(info) << "PUT /api/v1/Diary - Request"; + + if (req[http::field::authorization].size() <= auth_prefix.size()) + { + BOOST_LOG_TRIVIAL(error) << invalid_token_message; + throw session_exception(http::status::unauthorized, "Unauthorized"); + } + + const std::string auth_token = { + req[http::field::authorization].begin() + auth_prefix.size(), + req[http::field::authorization].end() + }; + + if (!auth_dao_->HasAuthorized(auth_token)) + { + BOOST_LOG_TRIVIAL(error) << invalid_token_message; + throw session_exception(http::status::unauthorized, "Unauthorized"); + } + + std::string_view user_uuid_ref = auth_dao_->GetUUID(auth_token); + const std::string user_uuid{user_uuid_ref.begin(), user_uuid_ref.end()}; + + value val = json::parse(req.body()); + object& obj = val.as_object(); + + diary_dto dto; + + dto.uuid = diary_uuid; + dto.mania_level = obj["mania_level"].as_int64(); + dto.depression_level = obj["depression_level"].as_int64(); + dto.mood_level = obj["mood_level"].as_int64(); + dto.activity_level = obj["activity_level"].as_int64(); + dto.appetite_level = obj["appetite_level"].as_int64(); + dto.dream_level = obj["dream_level"].as_int64(); + dto.anxiety_level = obj["anxiety_level"].as_int64(); + dto.comment = obj["comment"].as_string().c_str(); + dto.user_treatment_scheme_uuid = obj["user_treatment_scheme_uuid"].as_string().c_str(); + + diaries_dao_->UpdateDiary(user_uuid, diary_uuid, dto); + + http::response res{http::status::ok, req.version()}; + value response_body = ToJSON(dto); + + res.body() = serialize(response_body); + res.set(http::field::content_type, "application/json"); + res.content_length(res.body().size()); + + return res; + } + +private: + boost::json::object ToJSON(const diary_dto& diary) + { + boost::json::object diary_json; + + diary_json["uuid"] = diary.uuid; + diary_json["time"] = diary.time_ms; + diary_json["mania_level"] = diary.mania_level; + diary_json["depression_level"] = diary.depression_level; + diary_json["mood_level"] = diary.mood_level; + diary_json["activity_level"] = diary.activity_level; + diary_json["appetite_level"] = diary.appetite_level; + diary_json["dream_level"] = diary.dream_level; + diary_json["anxiety_level"] = diary.anxiety_level; + diary_json["comment"] = diary.comment; + diary_json["user_treatment_scheme_uuid"] = + diary.user_treatment_scheme_uuid; + + return diary_json; + } +}; +} diff --git a/src/endpoints_handlers/RootExecutor.h b/src/endpoints_handlers/RootExecutor.h index 6710075..7ad6db7 100644 --- a/src/endpoints_handlers/RootExecutor.h +++ b/src/endpoints_handlers/RootExecutor.h @@ -16,6 +16,7 @@ #include "PostUserMedicationsExecutor.h" #include "GetDiariesExecutor.h" #include "PostDiaryExecutor.h" +#include "PutDiaryExecutor.h" #include "../DAO/IUserDAO.h" #include "../DAO/IAuthDAO.h" #include "../DAO/IDiariesDAO.h" @@ -48,6 +49,8 @@ class RootExecutor Body, Allocator, boost::beast::http::string_body>; using RoutePostDiaryExecutor = PostDiaryExecutor< Body, Allocator, boost::beast::http::string_body>; + using RoutePutDiaryExecutor = PutDiaryExecutor< + Body, Allocator, boost::beast::http::string_body>; using IRouteController = IController; using RouteController = Controller; using RoutesPathes = std::unordered_map>; @@ -203,7 +206,11 @@ public: if (req.method() == boost::beast::http::verb::put) { - + return send(PutDiaryExecutor( + session_, + auth_dao_, + diaries_dao_ + )(std::move(req), uuid)); } }