From 49b133d59f846f0c90a30645567d1cd98f2a9f28 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Fri, 28 Apr 2023 21:18:42 +0300 Subject: [PATCH 01/12] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D1=81=D1=83=D1=89=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B5=D0=B9,=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B7=D0=B0?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=20=D0=B1=D0=B4,=20=D0=B8=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D1=83=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 9 +- conanfile.txt | 2 +- include/dataBase/config.json | 6 + include/dataBase/conn.hpp | 33 +++++ include/entity/Solution.hpp | 60 ++++++++ include/entity/Task.hpp | 23 +++ include/entity/User.hpp | 51 +++++++ include/repository/ISolutionRepository.hpp | 26 ++++ include/repository/ITaskRepository.hpp | 21 +++ include/repository/IUserRepository.hpp | 23 +++ include/repository/UserRepository.hpp | 157 +++++++++++++++++++++ 11 files changed, 406 insertions(+), 5 deletions(-) create mode 100644 include/dataBase/config.json create mode 100644 include/dataBase/conn.hpp create mode 100644 include/entity/Solution.hpp create mode 100644 include/entity/Task.hpp create mode 100644 include/entity/User.hpp create mode 100644 include/repository/ISolutionRepository.hpp create mode 100644 include/repository/ITaskRepository.hpp create mode 100644 include/repository/IUserRepository.hpp create mode 100644 include/repository/UserRepository.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bdb1810..d5cb5a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) cmake_minimum_required(VERSION 3.19) set(CMAKE_PREFIX_PATH build) project(SourcedOut CXX) @@ -6,7 +6,8 @@ find_package(antlr4-runtime REQUIRED) find_package(Boost 1.8.1 REQUIRED) find_package(libpqxx REQUIRED) find_package(GTest REQUIRED) -message(STATUS ${Boost_LIBRARIES}) -add_executable(${PROJECT_NAME} src/main.cpp) +find_package(nlohmann_json REQUIRED) +message(STATUS ${nlohmann_json_LIBRARIES}) +add_executable(${PROJECT_NAME} src/main.cpp include/entity/User.hpp include/repository/UserRepository.hpp include/dataBase/conn.hpp include/repository/IUserRepository.hpp include/entity/Solution.hpp include/entity/Task.hpp include/repository/ISolutionRepository.hpp include/repository/ISolutionRepository.hpp include/repository/ITaskRepository.hpp include/repository/ITaskRepository.hpp) #add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES}) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} nlohmann_json::nlohmann_json) \ No newline at end of file diff --git a/conanfile.txt b/conanfile.txt index 18ee8ce..e4b350b 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -3,7 +3,7 @@ boost/1.81.0 antlr4-cppruntime/4.12.0 libpqxx/7.7.5 gtest/cci.20210126 - +nlohmann_json/3.11.2 [generators] CMakeDeps diff --git a/include/dataBase/config.json b/include/dataBase/config.json new file mode 100644 index 0000000..eee75d5 --- /dev/null +++ b/include/dataBase/config.json @@ -0,0 +1,6 @@ +{"dbname":"mydb", + "user":"postgres", + "password": "root", + "hostaddr": "127.0.0.1", + "port": "5432" +} \ No newline at end of file diff --git a/include/dataBase/conn.hpp b/include/dataBase/conn.hpp new file mode 100644 index 0000000..91dbd55 --- /dev/null +++ b/include/dataBase/conn.hpp @@ -0,0 +1,33 @@ +#ifndef SOURCEDOUT_CONN_HPP +#define SOURCEDOUT_CONN_HPP + +#include +#include +#include + +using json = nlohmann::json; + +struct conn { + std::string dbname; + std::string user; + std::string password; + std::string hostaddr; + std::string port; + + conn() { + std::ifstream f("config.json"); + json data = json::parse(f); + data.at("dbname").get_to(dbname); + data.at("user").get_to(user); + data.at("password").get_to(password); + data.at("hostaddr").get_to(hostaddr); + data.at("port").get_to(port); + } + + [[nodiscard]] std::string getData() const { + return "dbname = " + dbname + " user = " + user + " password = " + password + + " hostaddr = " + hostaddr + " port = " + port; + } +}; + +#endif //SOURCEDOUT_CONN_HPP diff --git a/include/entity/Solution.hpp b/include/entity/Solution.hpp new file mode 100644 index 0000000..8bd04ea --- /dev/null +++ b/include/entity/Solution.hpp @@ -0,0 +1,60 @@ +#ifndef SOURCEDOUT_SOLUTION_HPP +#define SOURCEDOUT_SOLUTION_HPP +#include +#include + +class Solution{ +private: + size_t id; + std::string send_date; + size_t sender_id; + std::string source; + size_t task_id; + std::string result; +public: + [[nodiscard]] size_t getId() const { + return id; + } + + + [[nodiscard]] const std::string &getSendDate() const { + return send_date; + } + + void setSendDate(const std::string &sendDate) { + send_date = sendDate; + } + + [[nodiscard]] size_t getSenderId() const { + return sender_id; + } + + void setSenderId(size_t senderId) { + sender_id = senderId; + } + + [[nodiscard]] const std::string &getSource() const { + return source; + } + + void setSource(const std::string &source_) { + Solution::source = source_; + } + + [[nodiscard]] size_t getTaskId() const { + return task_id; + } + + void setTaskId(size_t taskId) { + task_id = taskId; + } + + [[nodiscard]] const std::string &getResult() const { + return result; + } + + void setResult(const std::string &result_) { + Solution::result = result_; + } +}; +#endif //SOURCEDOUT_SOLUTION_HPP diff --git a/include/entity/Task.hpp b/include/entity/Task.hpp new file mode 100644 index 0000000..b252c26 --- /dev/null +++ b/include/entity/Task.hpp @@ -0,0 +1,23 @@ +#ifndef SOURCEDOUT_TASK_HPP +#define SOURCEDOUT_TASK_HPP +#include +class Task{ +private: + size_t id; + std::string description; +public: + [[nodiscard]] size_t getId() const { + return id; + } + + [[nodiscard]] const std::string &getDescription() const { + return description; + } + + void setDescription(const std::string &description_) { + Task::description = description_; + } + +public: +}; +#endif //SOURCEDOUT_TASK_HPP diff --git a/include/entity/User.hpp b/include/entity/User.hpp new file mode 100644 index 0000000..3c0e24e --- /dev/null +++ b/include/entity/User.hpp @@ -0,0 +1,51 @@ +#ifndef SOURCEDOUT_USER_HPP + +#include +#include + +#define SOURCEDOUT_USER_HPP + +class User { +private: + size_t id; + std::string login; + std::string password; + std::string username; + +public: + User(size_t id_, std::string login_, std::string password_, std::string username_) : + id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { + } + + User(std::string login_, std::string password_, std::string username_) : + id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { + } + + [[nodiscard]] size_t getId() const { + return id; + } + + + [[nodiscard]] const std::string &getLogin() const { + return login; + } + + + [[nodiscard]] const std::string &getPassword() const { + return password; + } + + void setPassword(const std::string &password_) { + User::password = password_; + } + + [[nodiscard]] const std::string &getUsername() const { + return username; + } + + void setUsername(const std::string &username_) { + User::username = username_; + } +}; + +#endif //SOURCEDOUT_USER_HPP diff --git a/include/repository/ISolutionRepository.hpp b/include/repository/ISolutionRepository.hpp new file mode 100644 index 0000000..7099c47 --- /dev/null +++ b/include/repository/ISolutionRepository.hpp @@ -0,0 +1,26 @@ +#ifndef SOURCEDOUT_ISOLUTIONREPOSITORY_HPP +#define SOURCEDOUT_ISOLUTIONREPOSITORY_HPP + +#include +#include +#include "../entity/Solution.hpp" + +class ISolutionRepository { + virtual Solution getSolutionById(size_t id) = 0; + + virtual std::vector getSolutionsBySenderId(size_t sender_id) = 0; + + virtual std::vector getSolutionsByTaskId(size_t task_id) = 0; + + virtual void makeSolution(Solution solution) = 0; + + virtual void updateSolution(Solution solution) = 0; + + virtual void deleteSolutionById(size_t id) = 0; + + virtual void deleteSolution(Solution solution) = 0; + + +}; + +#endif //SOURCEDOUT_ISOLUTIONREPOSITORY_HPP diff --git a/include/repository/ITaskRepository.hpp b/include/repository/ITaskRepository.hpp new file mode 100644 index 0000000..81ef63a --- /dev/null +++ b/include/repository/ITaskRepository.hpp @@ -0,0 +1,21 @@ +#ifndef SOURCEDOUT_ITASKREPOSITORY_HPP +#define SOURCEDOUT_ITASKREPOSITORY_HPP + +#include +#include "../entity/Task.hpp" + +class ITaskRepository { + virtual Task getTaskById(size_t id) = 0; + + virtual Task updateTask(size_t id) = 0; + + virtual Task updateTask(Task task) = 0; + + virtual void makeTask(Task task) = 0; + + virtual void deleteTask(Task task) = 0; + + virtual void deleteTaskById(size_t task_id) = 0; +}; + +#endif //SOURCEDOUT_ITASKREPOSITORY_HPP diff --git a/include/repository/IUserRepository.hpp b/include/repository/IUserRepository.hpp new file mode 100644 index 0000000..0647432 --- /dev/null +++ b/include/repository/IUserRepository.hpp @@ -0,0 +1,23 @@ +#ifndef SOURCEDOUT_IUSERREPOSITORY_HPP +#define SOURCEDOUT_IUSERREPOSITORY_HPP + +#include +#include "../entity/User.hpp" +class IUserRepository { +public: + virtual User getUserById(size_t id) = 0; + + virtual User getUserByLogin(std::string login) = 0; + + virtual size_t makeUser(User user) = 0; + + virtual void deleteUser(User user) = 0; + + virtual void deleteByUserId(size_t user_id) = 0; + + virtual std::vector getAllUsers() = 0; + + virtual void getUsersByTaskId(size_t id) = 0; +}; + +#endif //SOURCEDOUT_IUSERREPOSITORY_HPP diff --git a/include/repository/UserRepository.hpp b/include/repository/UserRepository.hpp new file mode 100644 index 0000000..64bda8f --- /dev/null +++ b/include/repository/UserRepository.hpp @@ -0,0 +1,157 @@ +#ifndef SOURCEDOUT_USERREPOSITORY_HPP +#define SOURCEDOUT_USERREPOSITORY_HPP + +#include +#include "IUserRepository.hpp" +#include "../entity/User.hpp" +#include "../dataBase/conn.hpp" +#include +#include + +using namespace pqxx; + +class UserRepository : IUserRepository { +public: + explicit UserRepository(conn conn_) { + conn = std::move(conn_); + } + + User getUserById(size_t id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeUser(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + User getUserByLogin(std::string login) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users WHERE login=" + login; + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeUser(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + size_t makeUser(User user) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO Users (login,password,username) " \ + "VALUES (%s, %s, %s); ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + return getUserByLogin(user.getLogin()).getId(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void deleteUser(User user) override { + deleteByUserId(user.getId()); + } + + void deleteByUserId(size_t user_id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM Users WHERE id=" + std::to_string(user_id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + std::vector getAllUsers() override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users"; + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector users; + for(result::const_iterator k = r.begin(); k != r.end(); ++k) + users.push_back(makeUser(k)); + return users; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void getUsersByTaskId(size_t id) override { + + } + +private: + static User makeUser(const result::const_iterator& c) { + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("login")).as(), + c.at(c.column_number("password")).as(), + c.at(c.column_number("username")).as()}; + } + + static conn conn; +}; + +#endif //SOURCEDOUT_USERREPOSITORY_HPP -- GitLab From 9d6453c91835c45b50877d7b3c5cbbabe6996f66 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Sun, 30 Apr 2023 01:55:07 +0300 Subject: [PATCH 02/12] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D1=81=D1=83=D1=89=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B5=D0=B9,=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B7=D0=B0?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=20=D0=B1=D0=B4,=20=D0=B8=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D1=83=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- include/entity/Solution.hpp | 5 + include/entity/Task.hpp | 3 + include/repository/ISolutionRepository.hpp | 2 +- include/repository/ITaskRepository.hpp | 6 +- include/repository/SolutionRepository.hpp | 173 +++++++++++++++++++++ include/repository/TaskRepository.hpp | 113 ++++++++++++++ 7 files changed, 298 insertions(+), 6 deletions(-) create mode 100644 include/repository/SolutionRepository.hpp create mode 100644 include/repository/TaskRepository.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d5cb5a4..395d0b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,6 @@ find_package(libpqxx REQUIRED) find_package(GTest REQUIRED) find_package(nlohmann_json REQUIRED) message(STATUS ${nlohmann_json_LIBRARIES}) -add_executable(${PROJECT_NAME} src/main.cpp include/entity/User.hpp include/repository/UserRepository.hpp include/dataBase/conn.hpp include/repository/IUserRepository.hpp include/entity/Solution.hpp include/entity/Task.hpp include/repository/ISolutionRepository.hpp include/repository/ISolutionRepository.hpp include/repository/ITaskRepository.hpp include/repository/ITaskRepository.hpp) +add_executable(${PROJECT_NAME} src/main.cpp include/entity/User.hpp include/repository/UserRepository.hpp include/dataBase/conn.hpp include/repository/IUserRepository.hpp include/entity/Solution.hpp include/entity/Task.hpp include/repository/ISolutionRepository.hpp include/repository/ISolutionRepository.hpp include/repository/ITaskRepository.hpp include/repository/ITaskRepository.hpp include/repository/TaskRepository.hpp include/repository/TaskRepository.hpp include/repository/SolutionRepository.hpp include/repository/SolutionRepository.hpp) #add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} nlohmann_json::nlohmann_json) \ No newline at end of file diff --git a/include/entity/Solution.hpp b/include/entity/Solution.hpp index 8bd04ea..ed4b1e5 100644 --- a/include/entity/Solution.hpp +++ b/include/entity/Solution.hpp @@ -2,6 +2,7 @@ #define SOURCEDOUT_SOLUTION_HPP #include #include +#include class Solution{ private: @@ -12,6 +13,10 @@ private: size_t task_id; std::string result; public: + Solution(size_t id, std::string sendDate, size_t senderId, std::string source, size_t taskId, + std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), source(std::move(source)), + task_id(taskId), result(std::move(result)) {} + [[nodiscard]] size_t getId() const { return id; } diff --git a/include/entity/Task.hpp b/include/entity/Task.hpp index b252c26..a9f2ad1 100644 --- a/include/entity/Task.hpp +++ b/include/entity/Task.hpp @@ -1,11 +1,14 @@ #ifndef SOURCEDOUT_TASK_HPP #define SOURCEDOUT_TASK_HPP #include +#include class Task{ private: size_t id; std::string description; + public: + Task(size_t id, std::string description) : id(id), description(std::move(description)) {} [[nodiscard]] size_t getId() const { return id; } diff --git a/include/repository/ISolutionRepository.hpp b/include/repository/ISolutionRepository.hpp index 7099c47..286e432 100644 --- a/include/repository/ISolutionRepository.hpp +++ b/include/repository/ISolutionRepository.hpp @@ -12,7 +12,7 @@ class ISolutionRepository { virtual std::vector getSolutionsByTaskId(size_t task_id) = 0; - virtual void makeSolution(Solution solution) = 0; + virtual void storeSolution(Solution solution) = 0; virtual void updateSolution(Solution solution) = 0; diff --git a/include/repository/ITaskRepository.hpp b/include/repository/ITaskRepository.hpp index 81ef63a..740e2de 100644 --- a/include/repository/ITaskRepository.hpp +++ b/include/repository/ITaskRepository.hpp @@ -7,11 +7,9 @@ class ITaskRepository { virtual Task getTaskById(size_t id) = 0; - virtual Task updateTask(size_t id) = 0; + virtual void updateTask(Task task) = 0; - virtual Task updateTask(Task task) = 0; - - virtual void makeTask(Task task) = 0; + virtual void storeTask(Task task) = 0; virtual void deleteTask(Task task) = 0; diff --git a/include/repository/SolutionRepository.hpp b/include/repository/SolutionRepository.hpp new file mode 100644 index 0000000..5671b33 --- /dev/null +++ b/include/repository/SolutionRepository.hpp @@ -0,0 +1,173 @@ +#ifndef SOURCEDOUT_SOLUTIONREPOSITORY_HPP +#define SOURCEDOUT_SOLUTIONREPOSITORY_HPP + +#include +#include +#include +#include "ISolutionRepository.hpp" +#include "../entity/Solution.hpp" +#include "../dataBase/conn.hpp" +using namespace pqxx; + +class SolutionRepository : ISolutionRepository { + Solution getSolutionById(size_t id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeSolution(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + std::vector getSolutionsBySenderId(size_t sender_id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM solutions WHERE sender_id=" + std::to_string(sender_id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector solutions; + for(result::const_iterator k = r.begin(); k != r.end(); ++k) + solutions.push_back(makeSolution(k)); + return solutions; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + std::vector getSolutionsByTaskId(size_t task_id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM solutions WHERE task_id=" + std::to_string(task_id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector solutions; + for(result::const_iterator k = r.begin(); k != r.end(); ++k) + solutions.push_back(makeSolution(k)); + return solutions; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void storeSolution(Solution solution) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result) " \ + "VALUES (%s, %s, %s, %s, %s); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void updateSolution(Solution solution) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("UPDATE solutions SET send_date = %s, sender_id = %s, source = %s, task_id = %s, resulr = %s ;") + % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult()).str(); + work w(c); + w.exec(sql); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void deleteSolutionById(size_t id) override { + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void deleteSolution(Solution solution) override { + deleteSolutionById(solution.getId()); + } + +private: + conn conn; + static Solution makeSolution(const result::const_iterator& c){ + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("send_date")).as(), + c.at(c.column_number("sender_id")).as(), + c.at(c.column_number("source")).as(), + c.at(c.column_number("task_id")).as(), + c.at(c.column_number("result")).as()}; + } +}; + +#endif //SOURCEDOUT_SOLUTIONREPOSITORY_HPP diff --git a/include/repository/TaskRepository.hpp b/include/repository/TaskRepository.hpp new file mode 100644 index 0000000..2a4c778 --- /dev/null +++ b/include/repository/TaskRepository.hpp @@ -0,0 +1,113 @@ +#ifndef SOURCEDOUT_TASKREPOSITORY_HPP +#define SOURCEDOUT_TASKREPOSITORY_HPP + +#include +#include "ITaskRepository.hpp" +#include "pqxx/pqxx" +#include "../dataBase/conn.hpp" +using namespace pqxx; +class TaskRepository:ITaskRepository{ +public: + Task getTaskById(size_t id) override{ + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM tasks WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeTask(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void updateTask(Task task) override{ + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("UPDATE tasks SET description = %s ;") % task.getDescription()).str(); + work w(c); + w.exec(sql); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void storeTask(Task task) override{ + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO tasks (description) " \ + "VALUES (%s); ") % task.getDescription()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } + + void deleteTask(Task task) override{ + deleteTaskById(task.getId()); + } + + void deleteTaskById(size_t task_id) override{ + try { + connection c(conn.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM tasks WHERE id=" + std::to_string(task_id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } + } +private: + static Task makeTask(const result::const_iterator& c){ + return{c.at(c.column_number("id")).as(), + c.at(c.column_number("description")).as()}; + } + static conn conn; +}; + +#endif //SOURCEDOUT_TASKREPOSITORY_HPP -- GitLab From a524400ddacaf2a56252fbd91f4dae2762b908ae Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Mon, 1 May 2023 11:03:01 +0300 Subject: [PATCH 03/12] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D1=81=D1=83=D1=89=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B5=D0=B9,=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B7=D0=B0?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=20=D0=B1=D0=B4,=20=D0=B8=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D1=83=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 5 + CMakeLists.txt | 13 - conanfile.txt | 10 - config.sh | 8 - include/dataBase/config.json | 6 - include/dataBase/conn.hpp | 33 -- include/entity/Solution.hpp | 65 ---- include/entity/Task.hpp | 26 -- include/entity/User.hpp | 51 --- include/repository/ISolutionRepository.hpp | 26 -- include/repository/ITaskRepository.hpp | 19 -- include/repository/IUserRepository.hpp | 23 -- include/repository/SolutionRepository.hpp | 173 ---------- include/repository/TaskRepository.hpp | 113 ------ include/repository/UserRepository.hpp | 157 --------- server/cmd/CMakeLists.txt | 14 + server/cmd/main.cpp | 11 + server/internal/CMakeLists.txt | 11 + server/internal/solutions/CMakeLists.txt | 20 ++ server/internal/tasks/CMakeLists.txt | 20 ++ server/internal/users/CMakeLists.txt | 28 ++ server/internal/users/tests/CMakeLists.txt | 0 .../internal/users/tests/users_repo_test.cpp | 0 src/main.cpp | 321 ------------------ text-basic-metrics/code1.txt | 29 -- text-basic-metrics/code2.txt | 29 -- text-basic-metrics/tbm_main.cpp | 153 --------- 27 files changed, 109 insertions(+), 1255 deletions(-) create mode 100644 .env delete mode 100644 CMakeLists.txt delete mode 100644 conanfile.txt delete mode 100644 config.sh delete mode 100644 include/dataBase/config.json delete mode 100644 include/dataBase/conn.hpp delete mode 100644 include/entity/Solution.hpp delete mode 100644 include/entity/Task.hpp delete mode 100644 include/entity/User.hpp delete mode 100644 include/repository/ISolutionRepository.hpp delete mode 100644 include/repository/ITaskRepository.hpp delete mode 100644 include/repository/IUserRepository.hpp delete mode 100644 include/repository/SolutionRepository.hpp delete mode 100644 include/repository/TaskRepository.hpp delete mode 100644 include/repository/UserRepository.hpp create mode 100644 server/cmd/CMakeLists.txt create mode 100644 server/cmd/main.cpp create mode 100644 server/internal/CMakeLists.txt create mode 100644 server/internal/solutions/CMakeLists.txt create mode 100644 server/internal/tasks/CMakeLists.txt create mode 100644 server/internal/users/CMakeLists.txt create mode 100644 server/internal/users/tests/CMakeLists.txt create mode 100644 server/internal/users/tests/users_repo_test.cpp delete mode 100644 src/main.cpp delete mode 100644 text-basic-metrics/code1.txt delete mode 100644 text-basic-metrics/code2.txt delete mode 100644 text-basic-metrics/tbm_main.cpp diff --git a/.env b/.env new file mode 100644 index 0000000..0804779 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +PGHOSTADDR=0.0.0.0 +PGPORT=5432 +PGDATABASE=mydb +PGUSER=postgres +PGPASSWORD=root diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 395d0b7..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) -cmake_minimum_required(VERSION 3.19) -set(CMAKE_PREFIX_PATH build) -project(SourcedOut CXX) -find_package(antlr4-runtime REQUIRED) -find_package(Boost 1.8.1 REQUIRED) -find_package(libpqxx REQUIRED) -find_package(GTest REQUIRED) -find_package(nlohmann_json REQUIRED) -message(STATUS ${nlohmann_json_LIBRARIES}) -add_executable(${PROJECT_NAME} src/main.cpp include/entity/User.hpp include/repository/UserRepository.hpp include/dataBase/conn.hpp include/repository/IUserRepository.hpp include/entity/Solution.hpp include/entity/Task.hpp include/repository/ISolutionRepository.hpp include/repository/ISolutionRepository.hpp include/repository/ITaskRepository.hpp include/repository/ITaskRepository.hpp include/repository/TaskRepository.hpp include/repository/TaskRepository.hpp include/repository/SolutionRepository.hpp include/repository/SolutionRepository.hpp) -#add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} nlohmann_json::nlohmann_json) \ No newline at end of file diff --git a/conanfile.txt b/conanfile.txt deleted file mode 100644 index e4b350b..0000000 --- a/conanfile.txt +++ /dev/null @@ -1,10 +0,0 @@ -[requires] -boost/1.81.0 -antlr4-cppruntime/4.12.0 -libpqxx/7.7.5 -gtest/cci.20210126 -nlohmann_json/3.11.2 - -[generators] -CMakeDeps -CMakeToolchain \ No newline at end of file diff --git a/config.sh b/config.sh deleted file mode 100644 index b05efd5..0000000 --- a/config.sh +++ /dev/null @@ -1,8 +0,0 @@ -pip install conan -conan profile detect --force -#------------- -mkdir "build" -cd build/ -#------------ -conan install . --build=missing -s build_type=Debug -cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug diff --git a/include/dataBase/config.json b/include/dataBase/config.json deleted file mode 100644 index eee75d5..0000000 --- a/include/dataBase/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{"dbname":"mydb", - "user":"postgres", - "password": "root", - "hostaddr": "127.0.0.1", - "port": "5432" -} \ No newline at end of file diff --git a/include/dataBase/conn.hpp b/include/dataBase/conn.hpp deleted file mode 100644 index 91dbd55..0000000 --- a/include/dataBase/conn.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef SOURCEDOUT_CONN_HPP -#define SOURCEDOUT_CONN_HPP - -#include -#include -#include - -using json = nlohmann::json; - -struct conn { - std::string dbname; - std::string user; - std::string password; - std::string hostaddr; - std::string port; - - conn() { - std::ifstream f("config.json"); - json data = json::parse(f); - data.at("dbname").get_to(dbname); - data.at("user").get_to(user); - data.at("password").get_to(password); - data.at("hostaddr").get_to(hostaddr); - data.at("port").get_to(port); - } - - [[nodiscard]] std::string getData() const { - return "dbname = " + dbname + " user = " + user + " password = " + password + - " hostaddr = " + hostaddr + " port = " + port; - } -}; - -#endif //SOURCEDOUT_CONN_HPP diff --git a/include/entity/Solution.hpp b/include/entity/Solution.hpp deleted file mode 100644 index ed4b1e5..0000000 --- a/include/entity/Solution.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef SOURCEDOUT_SOLUTION_HPP -#define SOURCEDOUT_SOLUTION_HPP -#include -#include -#include - -class Solution{ -private: - size_t id; - std::string send_date; - size_t sender_id; - std::string source; - size_t task_id; - std::string result; -public: - Solution(size_t id, std::string sendDate, size_t senderId, std::string source, size_t taskId, - std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), source(std::move(source)), - task_id(taskId), result(std::move(result)) {} - - [[nodiscard]] size_t getId() const { - return id; - } - - - [[nodiscard]] const std::string &getSendDate() const { - return send_date; - } - - void setSendDate(const std::string &sendDate) { - send_date = sendDate; - } - - [[nodiscard]] size_t getSenderId() const { - return sender_id; - } - - void setSenderId(size_t senderId) { - sender_id = senderId; - } - - [[nodiscard]] const std::string &getSource() const { - return source; - } - - void setSource(const std::string &source_) { - Solution::source = source_; - } - - [[nodiscard]] size_t getTaskId() const { - return task_id; - } - - void setTaskId(size_t taskId) { - task_id = taskId; - } - - [[nodiscard]] const std::string &getResult() const { - return result; - } - - void setResult(const std::string &result_) { - Solution::result = result_; - } -}; -#endif //SOURCEDOUT_SOLUTION_HPP diff --git a/include/entity/Task.hpp b/include/entity/Task.hpp deleted file mode 100644 index a9f2ad1..0000000 --- a/include/entity/Task.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SOURCEDOUT_TASK_HPP -#define SOURCEDOUT_TASK_HPP -#include -#include -class Task{ -private: - size_t id; - std::string description; - -public: - Task(size_t id, std::string description) : id(id), description(std::move(description)) {} - [[nodiscard]] size_t getId() const { - return id; - } - - [[nodiscard]] const std::string &getDescription() const { - return description; - } - - void setDescription(const std::string &description_) { - Task::description = description_; - } - -public: -}; -#endif //SOURCEDOUT_TASK_HPP diff --git a/include/entity/User.hpp b/include/entity/User.hpp deleted file mode 100644 index 3c0e24e..0000000 --- a/include/entity/User.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef SOURCEDOUT_USER_HPP - -#include -#include - -#define SOURCEDOUT_USER_HPP - -class User { -private: - size_t id; - std::string login; - std::string password; - std::string username; - -public: - User(size_t id_, std::string login_, std::string password_, std::string username_) : - id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { - } - - User(std::string login_, std::string password_, std::string username_) : - id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { - } - - [[nodiscard]] size_t getId() const { - return id; - } - - - [[nodiscard]] const std::string &getLogin() const { - return login; - } - - - [[nodiscard]] const std::string &getPassword() const { - return password; - } - - void setPassword(const std::string &password_) { - User::password = password_; - } - - [[nodiscard]] const std::string &getUsername() const { - return username; - } - - void setUsername(const std::string &username_) { - User::username = username_; - } -}; - -#endif //SOURCEDOUT_USER_HPP diff --git a/include/repository/ISolutionRepository.hpp b/include/repository/ISolutionRepository.hpp deleted file mode 100644 index 286e432..0000000 --- a/include/repository/ISolutionRepository.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef SOURCEDOUT_ISOLUTIONREPOSITORY_HPP -#define SOURCEDOUT_ISOLUTIONREPOSITORY_HPP - -#include -#include -#include "../entity/Solution.hpp" - -class ISolutionRepository { - virtual Solution getSolutionById(size_t id) = 0; - - virtual std::vector getSolutionsBySenderId(size_t sender_id) = 0; - - virtual std::vector getSolutionsByTaskId(size_t task_id) = 0; - - virtual void storeSolution(Solution solution) = 0; - - virtual void updateSolution(Solution solution) = 0; - - virtual void deleteSolutionById(size_t id) = 0; - - virtual void deleteSolution(Solution solution) = 0; - - -}; - -#endif //SOURCEDOUT_ISOLUTIONREPOSITORY_HPP diff --git a/include/repository/ITaskRepository.hpp b/include/repository/ITaskRepository.hpp deleted file mode 100644 index 740e2de..0000000 --- a/include/repository/ITaskRepository.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SOURCEDOUT_ITASKREPOSITORY_HPP -#define SOURCEDOUT_ITASKREPOSITORY_HPP - -#include -#include "../entity/Task.hpp" - -class ITaskRepository { - virtual Task getTaskById(size_t id) = 0; - - virtual void updateTask(Task task) = 0; - - virtual void storeTask(Task task) = 0; - - virtual void deleteTask(Task task) = 0; - - virtual void deleteTaskById(size_t task_id) = 0; -}; - -#endif //SOURCEDOUT_ITASKREPOSITORY_HPP diff --git a/include/repository/IUserRepository.hpp b/include/repository/IUserRepository.hpp deleted file mode 100644 index 0647432..0000000 --- a/include/repository/IUserRepository.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SOURCEDOUT_IUSERREPOSITORY_HPP -#define SOURCEDOUT_IUSERREPOSITORY_HPP - -#include -#include "../entity/User.hpp" -class IUserRepository { -public: - virtual User getUserById(size_t id) = 0; - - virtual User getUserByLogin(std::string login) = 0; - - virtual size_t makeUser(User user) = 0; - - virtual void deleteUser(User user) = 0; - - virtual void deleteByUserId(size_t user_id) = 0; - - virtual std::vector getAllUsers() = 0; - - virtual void getUsersByTaskId(size_t id) = 0; -}; - -#endif //SOURCEDOUT_IUSERREPOSITORY_HPP diff --git a/include/repository/SolutionRepository.hpp b/include/repository/SolutionRepository.hpp deleted file mode 100644 index 5671b33..0000000 --- a/include/repository/SolutionRepository.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef SOURCEDOUT_SOLUTIONREPOSITORY_HPP -#define SOURCEDOUT_SOLUTIONREPOSITORY_HPP - -#include -#include -#include -#include "ISolutionRepository.hpp" -#include "../entity/Solution.hpp" -#include "../dataBase/conn.hpp" -using namespace pqxx; - -class SolutionRepository : ISolutionRepository { - Solution getSolutionById(size_t id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - return makeSolution(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - std::vector getSolutionsBySenderId(size_t sender_id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM solutions WHERE sender_id=" + std::to_string(sender_id); - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - std::vector solutions; - for(result::const_iterator k = r.begin(); k != r.end(); ++k) - solutions.push_back(makeSolution(k)); - return solutions; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - std::vector getSolutionsByTaskId(size_t task_id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM solutions WHERE task_id=" + std::to_string(task_id); - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - std::vector solutions; - for(result::const_iterator k = r.begin(); k != r.end(); ++k) - solutions.push_back(makeSolution(k)); - return solutions; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void storeSolution(Solution solution) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result) " \ - "VALUES (%s, %s, %s, %s, %s); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult()).str(); - work w(c); - w.exec(sql); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void updateSolution(Solution solution) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("UPDATE solutions SET send_date = %s, sender_id = %s, source = %s, task_id = %s, resulr = %s ;") - % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult()).str(); - work w(c); - w.exec(sql); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void deleteSolutionById(size_t id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); - work w(c); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void deleteSolution(Solution solution) override { - deleteSolutionById(solution.getId()); - } - -private: - conn conn; - static Solution makeSolution(const result::const_iterator& c){ - return {c.at(c.column_number("id")).as(), - c.at(c.column_number("send_date")).as(), - c.at(c.column_number("sender_id")).as(), - c.at(c.column_number("source")).as(), - c.at(c.column_number("task_id")).as(), - c.at(c.column_number("result")).as()}; - } -}; - -#endif //SOURCEDOUT_SOLUTIONREPOSITORY_HPP diff --git a/include/repository/TaskRepository.hpp b/include/repository/TaskRepository.hpp deleted file mode 100644 index 2a4c778..0000000 --- a/include/repository/TaskRepository.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef SOURCEDOUT_TASKREPOSITORY_HPP -#define SOURCEDOUT_TASKREPOSITORY_HPP - -#include -#include "ITaskRepository.hpp" -#include "pqxx/pqxx" -#include "../dataBase/conn.hpp" -using namespace pqxx; -class TaskRepository:ITaskRepository{ -public: - Task getTaskById(size_t id) override{ - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM tasks WHERE id=" + std::to_string(id); - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - return makeTask(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void updateTask(Task task) override{ - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("UPDATE tasks SET description = %s ;") % task.getDescription()).str(); - work w(c); - w.exec(sql); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void storeTask(Task task) override{ - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("INSERT INTO tasks (description) " \ - "VALUES (%s); ") % task.getDescription()).str(); - work w(c); - w.exec(sql); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void deleteTask(Task task) override{ - deleteTaskById(task.getId()); - } - - void deleteTaskById(size_t task_id) override{ - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "DELETE FROM tasks WHERE id=" + std::to_string(task_id); - work w(c); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } -private: - static Task makeTask(const result::const_iterator& c){ - return{c.at(c.column_number("id")).as(), - c.at(c.column_number("description")).as()}; - } - static conn conn; -}; - -#endif //SOURCEDOUT_TASKREPOSITORY_HPP diff --git a/include/repository/UserRepository.hpp b/include/repository/UserRepository.hpp deleted file mode 100644 index 64bda8f..0000000 --- a/include/repository/UserRepository.hpp +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef SOURCEDOUT_USERREPOSITORY_HPP -#define SOURCEDOUT_USERREPOSITORY_HPP - -#include -#include "IUserRepository.hpp" -#include "../entity/User.hpp" -#include "../dataBase/conn.hpp" -#include -#include - -using namespace pqxx; - -class UserRepository : IUserRepository { -public: - explicit UserRepository(conn conn_) { - conn = std::move(conn_); - } - - User getUserById(size_t id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - return makeUser(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - User getUserByLogin(std::string login) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM Users WHERE login=" + login; - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - return makeUser(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - size_t makeUser(User user) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("INSERT INTO Users (login,password,username) " \ - "VALUES (%s, %s, %s); ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); - work w(c); - w.exec(sql); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - return getUserByLogin(user.getLogin()).getId(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void deleteUser(User user) override { - deleteByUserId(user.getId()); - } - - void deleteByUserId(size_t user_id) override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "DELETE FROM Users WHERE id=" + std::to_string(user_id); - work w(c); - w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - std::vector getAllUsers() override { - try { - connection c(conn.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "SELECT * FROM Users"; - nontransaction n(c); - result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); - std::vector users; - for(result::const_iterator k = r.begin(); k != r.end(); ++k) - users.push_back(makeUser(k)); - return users; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; - } - } - - void getUsersByTaskId(size_t id) override { - - } - -private: - static User makeUser(const result::const_iterator& c) { - return {c.at(c.column_number("id")).as(), - c.at(c.column_number("login")).as(), - c.at(c.column_number("password")).as(), - c.at(c.column_number("username")).as()}; - } - - static conn conn; -}; - -#endif //SOURCEDOUT_USERREPOSITORY_HPP diff --git a/server/cmd/CMakeLists.txt b/server/cmd/CMakeLists.txt new file mode 100644 index 0000000..4829fdd --- /dev/null +++ b/server/cmd/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.19) + +set(CMAKE_CXX_STANDARD 20) + +set(PROJECT_NAME "Server") + +project(${PROJECT_NAME}) + +add_executable(Server main.cpp) +message(STATUS ${libusers}) +target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} ${libusers_LIB}) +target_include_directories(Server PUBLIC ${libusers_INCLUDE_DIRS}) +message("Built server") + diff --git a/server/cmd/main.cpp b/server/cmd/main.cpp new file mode 100644 index 0000000..83f740d --- /dev/null +++ b/server/cmd/main.cpp @@ -0,0 +1,11 @@ + + +#include "../internal/users/include/UserRepository.hpp" + +int main(){ + User user{"qwerty200468@gmail.com", "123", "tolik"}; + conn conn; + UserRepository repo(conn); + std::cout< -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace beast = boost::beast; // from -namespace http = beast::http; // from -namespace net = boost::asio; // from -using tcp = boost::asio::ip::tcp; // from - -//------------------------------------------------------------------------------ - -// Return a reasonable mime type based on the extension of a file. -beast::string_view -mime_type(beast::string_view path) -{ - using beast::iequals; - auto const ext = [&path] - { - auto const pos = path.rfind("."); - if(pos == beast::string_view::npos) - return beast::string_view{}; - return path.substr(pos); - }(); - if(iequals(ext, ".htm")) return "text/html"; - if(iequals(ext, ".html")) return "text/html"; - if(iequals(ext, ".php")) return "text/html"; - if(iequals(ext, ".css")) return "text/css"; - if(iequals(ext, ".txt")) return "text/plain"; - if(iequals(ext, ".js")) return "application/javascript"; - if(iequals(ext, ".json")) return "application/json"; - if(iequals(ext, ".xml")) return "application/xml"; - if(iequals(ext, ".swf")) return "application/x-shockwave-flash"; - if(iequals(ext, ".flv")) return "video/x-flv"; - if(iequals(ext, ".png")) return "image/png"; - if(iequals(ext, ".jpe")) return "image/jpeg"; - if(iequals(ext, ".jpeg")) return "image/jpeg"; - if(iequals(ext, ".jpg")) return "image/jpeg"; - if(iequals(ext, ".gif")) return "image/gif"; - if(iequals(ext, ".bmp")) return "image/bmp"; - if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon"; - if(iequals(ext, ".tiff")) return "image/tiff"; - if(iequals(ext, ".tif")) return "image/tiff"; - if(iequals(ext, ".svg")) return "image/svg+xml"; - if(iequals(ext, ".svgz")) return "image/svg+xml"; - return "application/text"; -} - -// Append an HTTP rel-path to a local filesystem path. -// The returned path is normalized for the platform. -std::string -path_cat( - beast::string_view base, - beast::string_view path) -{ - if (base.empty()) - return std::string(path); - std::string result(base); -#ifdef BOOST_MSVC - char constexpr path_separator = '\\'; - if(result.back() == path_separator) - result.resize(result.size() - 1); - result.append(path.data(), path.size()); - for(auto& c : result) - if(c == '/') - c = path_separator; -#else - char constexpr path_separator = '/'; - if(result.back() == path_separator) - result.resize(result.size() - 1); - result.append(path.data(), path.size()); -#endif - return result; -} - -// This function produces an HTTP response for the given -// request. The type of the response object depends on the -// contents of the request, so the interface requires the -// caller to pass a generic lambda for receiving the response. -template< - class Body, class Allocator, - class Send> -void -handle_request( - beast::string_view doc_root, - http::request>&& req, - Send&& send) -{ - // Returns a bad request response - auto const bad_request = - [&req](beast::string_view why) - { - http::response res{http::status::bad_request, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = std::string(why); - res.prepare_payload(); - return res; - }; - - // Returns a not found response - auto const not_found = - [&req](beast::string_view target) - { - http::response res{http::status::not_found, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "The resource '" + std::string(target) + "' was not found."; - res.prepare_payload(); - return res; - }; - - // Returns a server error response - auto const server_error = - [&req](beast::string_view what) - { - http::response res{http::status::internal_server_error, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, "text/html"); - res.keep_alive(req.keep_alive()); - res.body() = "An error occurred: '" + std::string(what) + "'"; - res.prepare_payload(); - return res; - }; - - // Make sure we can handle the method - if( req.method() != http::verb::get && - req.method() != http::verb::head) - return send(bad_request("Unknown HTTP-method")); - - // Request path must be absolute and not contain "..". - if( req.target().empty() || - req.target()[0] != '/' || - req.target().find("..") != beast::string_view::npos) - return send(bad_request("Illegal request-target")); - - // Build the path to the requested file - std::string path = path_cat(doc_root, req.target()); - if(req.target().back() == '/') - path.append("index.html"); - - // Attempt to open the file - beast::error_code ec; - http::file_body::value_type body; - body.open(path.c_str(), beast::file_mode::scan, ec); - - // Handle the case where the file doesn't exist - if(ec == beast::errc::no_such_file_or_directory) - return send(not_found(req.target())); - - // Handle an unknown error - if(ec) - return send(server_error(ec.message())); - - // Cache the size since we need it after the move - auto const size = body.size(); - - // Respond to HEAD request - if(req.method() == http::verb::head) - { - http::response res{http::status::ok, req.version()}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, mime_type(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return send(std::move(res)); - } - - // Respond to GET request - http::response res{ - std::piecewise_construct, - std::make_tuple(std::move(body)), - std::make_tuple(http::status::ok, req.version())}; - res.set(http::field::server, BOOST_BEAST_VERSION_STRING); - res.set(http::field::content_type, mime_type(path)); - res.content_length(size); - res.keep_alive(req.keep_alive()); - return send(std::move(res)); -} - -//------------------------------------------------------------------------------ - -// Report a failure -void -fail(beast::error_code ec, char const* what) -{ - std::cerr << what << ": " << ec.message() << "\n"; -} - -// This is the C++11 equivalent of a generic lambda. -// The function object is used to send an HTTP message. -template -struct send_lambda -{ - Stream& stream_; - bool& close_; - beast::error_code& ec_; - - explicit - send_lambda( - Stream& stream, - bool& close, - beast::error_code& ec) - : stream_(stream) - , close_(close) - , ec_(ec) - { - } - - template - void - operator()(http::message&& msg) const - { - // Determine if we should close the connection after - close_ = msg.need_eof(); - - // We need the serializer here because the serializer requires - // a non-const file_body, and the message oriented version of - // http::write only works with const messages. - http::serializer sr{msg}; - http::write(stream_, sr, ec_); - } -}; - -// Handles an HTTP server connection -void -do_session( - tcp::socket& socket, - std::shared_ptr const& doc_root) -{ - bool close = false; - beast::error_code ec; - - // This buffer is required to persist across reads - beast::flat_buffer buffer; - - // This lambda is used to send messages - send_lambda lambda{socket, close, ec}; - - for(;;) - { - // Read a request - http::request req; - http::read(socket, buffer, req, ec); - if(ec == http::error::end_of_stream) - break; - if(ec) - return fail(ec, "read"); - - // Send the response - handle_request(*doc_root, std::move(req), lambda); - if(ec) - return fail(ec, "write"); - if(close) - { - // This means we should close the connection, usually because - // the response indicated the "Connection: close" semantic. - break; - } - } - - // Send a TCP shutdown - socket.shutdown(tcp::socket::shutdown_send, ec); - - // At this point the connection is closed gracefully -} - -//------------------------------------------------------------------------------ - -int main(int argc, char* argv[]) -{ - try - { - // Check command line arguments. - if (argc != 4) - { - std::cerr << - "Usage: http-server-sync
\n" << - "Example:\n" << - " http-server-sync 0.0.0.0 8080 .\n"; - return EXIT_FAILURE; - } - auto const address = net::ip::make_address(argv[1]); - auto const port = static_cast(std::atoi(argv[2])); - auto const doc_root = std::make_shared(argv[3]); - - // The io_context is required for all I/O - net::io_context ioc{1}; - - // The acceptor receives incoming connections - tcp::acceptor acceptor{ioc, {address, port}}; - for(;;) - { - // This will receive the new connection - tcp::socket socket{ioc}; - - // Block until we get a connection - acceptor.accept(socket); - - // Launch the session, transferring ownership of the socket - std::thread{std::bind( - &do_session, - std::move(socket), - doc_root)}.detach(); - } - } - catch (const std::exception& e) - { - std::cerr << "Error: " << e.what() << std::endl; - return EXIT_FAILURE; - } -} \ No newline at end of file diff --git a/text-basic-metrics/code1.txt b/text-basic-metrics/code1.txt deleted file mode 100644 index 5fa95b8..0000000 --- a/text-basic-metrics/code1.txt +++ /dev/null @@ -1,29 +0,0 @@ -// однострочный комментарий -// еще один -// вау еще один - -#include -#include -#include - -using namespace std; - -/* многострочный комм - * // внутри него однострочный - * - */ - - -int main() { - stringstream ss; - string res; - // ещё в код напихаю комментов - ss << "a bwfw ce "; - while(getline(ss, res, ' ')){ //комментарий после строки с кодом - /* - * летс гоу - * худшее место для многострочного коммента - */ - cout << res << endl; /* многострочный однострочно */ - } -} diff --git a/text-basic-metrics/code2.txt b/text-basic-metrics/code2.txt deleted file mode 100644 index 2115b76..0000000 --- a/text-basic-metrics/code2.txt +++ /dev/null @@ -1,29 +0,0 @@ -// однострочный комментарий -// еще один -// вау еще один - -#include -#include -#include - -using namespace std; - -/* многострочный комм - * // внутри него однострочный - * - */ - - -int main() { - stringstream ss1; - string res1; - // ещё в код напихаю комментов - ss1 << "a bwfw ce "; - while(getline(ss, res1, ' ')){ //комментарий после строки с кодом - /* - * летс гоу - * худшее место для многострочного коммента - */ - cout << res1 << endl; /* многострочный однострочно */ - } -} \ No newline at end of file diff --git a/text-basic-metrics/tbm_main.cpp b/text-basic-metrics/tbm_main.cpp deleted file mode 100644 index fdd4253..0000000 --- a/text-basic-metrics/tbm_main.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// Created by march on 21.04.2023. -// - -#include -#include -#include -#include -#include -#include -#include - -#include - - -std::string deleteComms(const std::string& text){ - std::string modif; - std::string res; - - std::stringstream ss; - std::string line; - - ss << text; - - while(getline(ss, line)){ - line.pop_back(); - line.push_back('\0'); - modif += line; - } - - bool s_comm = false; - bool m_comm = false; - - for (int i = 0; i < modif.size(); i++){ - if (s_comm && modif[i] == '\0') - s_comm = false; - else if (m_comm && modif[i] == '*' && modif[i + 1] == '/') - m_comm = false, i++; - else if (s_comm || m_comm) - continue; - else if (modif[i] == '/' && modif[i+1] == '/') - s_comm = true, i++; - else if (modif[i] == '/' && modif[i+1] == '*') - m_comm = true, i++; - - else if (modif[i] != '\0') - res += modif[i]; - else{ - res += '\n'; - } - } - return res; -} - -std::vector tbm_tokenizer(const std::string &text){ - boost::char_separator sep(" {}();,\"\0\'"); - std::vector res; - boost::tokenizer < boost::char_separator > tokens(text, sep); - - for (const std::string &s: tokens) { - if (!s.empty() && s[0] != '\n' && s[0] != '\0'){ - res.push_back(s); - } - } - return res; -} - -// % = intersection(A, B) / union(A, B) -double Jaccard_metric(const std::vector & tokens1, const std::vector & tokens2){ - std::set s1; - std::set s2; - - for (auto &i : tokens1) s1.insert(i); - for (auto &i : tokens2) s2.insert(i); - - - std::set intersect_sets; - set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), - std::inserter(intersect_sets, intersect_sets.begin())); - - std::set union_sets; - set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), - std::inserter(union_sets, union_sets.begin())); - - std::cout << intersect_sets.size() << " " << union_sets.size() << std::endl; - - return static_cast (intersect_sets.size()) / static_cast (union_sets.size()); -} - -double Livenstain_dist(std::vector tokens1, std::vector tokens2){ - unsigned long n = tokens1.size(); - unsigned long m = tokens2.size(); - int x, y, z; - - std::vector > lev (n, std::vector (m, 0)); - - for (int i = 0; i < n; i++){ - for (int j = 0; j < m; j++){ - if (std::min(i, j) == 0){ - lev[i][j] = std::max(i, j); - } - else{ - x = lev[i-1][j]; - y = lev[i][j-1]; - z = lev[i-1][j-1]; - lev[i][j] = std::min(x, std::min(y, z)); - if (tokens1[i] != tokens2[j]){ - lev[i][j]++; - } - } - } - } - - return lev[n-1][m-1]; -} - -std::pair textCompare(std::istream& fin1, std::istream& fin2){ - std::string line; - - std::string text1( (std::istreambuf_iterator(fin1) ), - (std::istreambuf_iterator() ) ); - - std::string text2( (std::istreambuf_iterator(fin2) ), - (std::istreambuf_iterator() ) ); - - std::string non_comm_text1 = deleteComms(text1); - std::string non_comm_text2 = deleteComms(text2); - - std::vector tokens1 = tbm_tokenizer(non_comm_text1); - std::vector tokens2 = tbm_tokenizer(non_comm_text2); - - double res1 = Jaccard_metric(tokens1, tokens2); - double res2 = 1 - Livenstain_dist(tokens1, tokens2) / std::max(tokens1.size(), tokens2.size()); - - return {res1, res2}; -} - -int main(){ - - std::ifstream fin1; - fin1.open("text-basic-metrics/code1.txt"); - assert(fin1.is_open()); - - std::ifstream fin2; - fin2.open("text-basic-metrics/code2.txt"); - assert(fin2.is_open()); - - std::pair metrics_res = textCompare(fin1, fin2); - - std::cout << "Jaccard metric "<< metrics_res.first << "\nLivenstein distance: " << metrics_res.second; - fin1.close(); - fin2.close(); -} \ No newline at end of file -- GitLab From 9295e895979b85fde141d87dbe6b82dd19fc5896 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Mon, 1 May 2023 11:10:35 +0300 Subject: [PATCH 04/12] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D1=81=D1=83=D1=89=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B5=D0=B9,=20=D0=BD=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D0=B7=D0=B0?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=20=D0=B1=D0=B4,=20=D0=B8=20=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D1=83=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 40 +++++ log.txt | 13 ++ server/cmd/.env | 5 + server/internal/solutions/Solution.hpp | 57 ++++++ .../solutions/include/SolutionRepository.hpp | 30 ++++ server/internal/solutions/src/Solution.cpp | 73 ++++++++ .../solutions/src/SolutionRepository.cpp | 169 ++++++++++++++++++ .../solutions/virtual/ISolutionRepository.hpp | 26 +++ server/internal/src/CMakeLists.txt | 5 + server/internal/src/db/CMakeLists.txt | 29 +++ server/internal/src/db/config.json | 7 + server/internal/src/db/include/conn.hpp | 22 +++ server/internal/src/db/src/conn.cpp | 27 +++ server/internal/tasks/Task.hpp | 21 +++ .../internal/tasks/include/TaskRepository.hpp | 27 +++ server/internal/tasks/src/Task.cpp | 21 +++ server/internal/tasks/src/TaskRepository.cpp | 106 +++++++++++ .../tasks/virtual/ITaskRepository.hpp | 19 ++ server/internal/users/User.hpp | 35 ++++ .../internal/users/include/UserRepository.hpp | 35 ++++ server/internal/users/src/User.cpp | 37 ++++ server/internal/users/src/UserRepository.cpp | 145 +++++++++++++++ .../users/virtual/IUserRepository.hpp | 22 +++ 23 files changed, 971 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 log.txt create mode 100644 server/cmd/.env create mode 100644 server/internal/solutions/Solution.hpp create mode 100644 server/internal/solutions/include/SolutionRepository.hpp create mode 100644 server/internal/solutions/src/Solution.cpp create mode 100644 server/internal/solutions/src/SolutionRepository.cpp create mode 100644 server/internal/solutions/virtual/ISolutionRepository.hpp create mode 100644 server/internal/src/CMakeLists.txt create mode 100644 server/internal/src/db/CMakeLists.txt create mode 100644 server/internal/src/db/config.json create mode 100644 server/internal/src/db/include/conn.hpp create mode 100644 server/internal/src/db/src/conn.cpp create mode 100644 server/internal/tasks/Task.hpp create mode 100644 server/internal/tasks/include/TaskRepository.hpp create mode 100644 server/internal/tasks/src/Task.cpp create mode 100644 server/internal/tasks/src/TaskRepository.cpp create mode 100644 server/internal/tasks/virtual/ITaskRepository.hpp create mode 100644 server/internal/users/User.hpp create mode 100644 server/internal/users/include/UserRepository.hpp create mode 100644 server/internal/users/src/User.cpp create mode 100644 server/internal/users/src/UserRepository.cpp create mode 100644 server/internal/users/virtual/IUserRepository.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..90ae8b6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +set(CMAKE_CXX_STANDARD 20) +cmake_minimum_required(VERSION 3.19) + +set(PROJECT_NAME "SourcedOut") + +project(${PROJECT_NAME}) + + +set(BUILD_DEV TRUE CACHE BOOL "build dev version") +set(SANITIZE_BUILD TRUE CACHE BOOL "build with sanitizers") + +if(BUILD_DEV) + enable_testing() + message("Building dev version") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0 -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ + -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage -lgcov") + + if(SANITIZE_BUILD) + message("Sanitizers ON") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") + endif(SANITIZE_BUILD) +endif(BUILD_DEV) + +set(BUILD_SERVER "BUILD_SERVER") +set(BUILD_CLIENT "BUILD_CLIENT") +set(BUILD_ALL "BUILD_ALL") + + +message("${BUILD_DEV} ${SANITIZE_BUILD} ${CMAKE_EXE_LINKER_FLAGS}") +set(BUILD_MODE ${BUILD_SERVER}) + +if((BUILD_MODE STREQUAL ${BUILD_CLIENT}) OR (BUILD_MODE STREQUAL ${BUILD_ALL})) + add_subdirectory(client) +endif() + +if((BUILD_MODE STREQUAL ${BUILD_SERVER}) OR (BUILD_MODE STREQUAL ${BUILD_ALL})) + add_subdirectory(server) +endif() diff --git a/log.txt b/log.txt new file mode 100644 index 0000000..836dc35 --- /dev/null +++ b/log.txt @@ -0,0 +1,13 @@ +Opened database successfully: mydb +Opened database successfully: mydb +Opened database successfully: mydb +Opened database successfully: mydb +OK +Opened database successfully: mydb +OK +Opened database successfully: mydb +Opened database successfully: mydb +OK +Opened database successfully: mydb +OK +Opened database successfully: mydb diff --git a/server/cmd/.env b/server/cmd/.env new file mode 100644 index 0000000..0804779 --- /dev/null +++ b/server/cmd/.env @@ -0,0 +1,5 @@ +PGHOSTADDR=0.0.0.0 +PGPORT=5432 +PGDATABASE=mydb +PGUSER=postgres +PGPASSWORD=root diff --git a/server/internal/solutions/Solution.hpp b/server/internal/solutions/Solution.hpp new file mode 100644 index 0000000..dcfa255 --- /dev/null +++ b/server/internal/solutions/Solution.hpp @@ -0,0 +1,57 @@ +#ifndef SOURCEDOUT_SOLUTION_HPP +#define SOURCEDOUT_SOLUTION_HPP + +#include +#include +#include + +class Solution { +public: + Solution(size_t id, std::string sendDate, size_t senderId, std::string source, + std::string tokens, std::string astTree, size_t taskId, std::string result); + + [[nodiscard]] size_t getId() const; + + + [[nodiscard]] const std::string &getSendDate() const; + + void setSendDate(const std::string &sendDate); + + [[nodiscard]] size_t getSenderId() const; + + void setSenderId(size_t senderId); + + [[nodiscard]] const std::string &getSource() const; + + void setSource(const std::string &source); + + [[nodiscard]] const std::string &getTokens() const; + + void setTokens(const std::string &tokens); + + [[nodiscard]] const std::string &getAstTree() const; + + void setAstTree(const std::string &astTree); + + [[nodiscard]] size_t getTaskId() const; + + void setTaskId(size_t taskId); + + [[nodiscard]] const std::string &getResult() const; + + void setResult(const std::string &result); + +private: + size_t id; + std::string send_date; + size_t sender_id; + std::string source; + std::string tokens; + std::string astTree; + size_t task_id; + std::string result; +public: + +}; + +#endif //SOURCEDOUT_SOLUTION_HPP diff --git a/server/internal/solutions/include/SolutionRepository.hpp b/server/internal/solutions/include/SolutionRepository.hpp new file mode 100644 index 0000000..4856b6d --- /dev/null +++ b/server/internal/solutions/include/SolutionRepository.hpp @@ -0,0 +1,30 @@ +#ifndef SOURCEDOUT_SOLUTIONREPOSITORY_HPP +#define SOURCEDOUT_SOLUTIONREPOSITORY_HPP + +#include +#include +#include +#include +#include "ISolutionRepository.hpp" +using namespace pqxx; + +class SolutionRepository : ISolutionRepository { + Solution getSolutionById(size_t id) override; + + std::vector getSolutionsBySenderId(size_t sender_id) override; + + std::vector getSolutionsByTaskId(size_t task_id) override; + + void storeSolution(Solution solution) override; + + void updateSolution(Solution solution) override; + + void deleteSolutionById(size_t id) override; + + void deleteSolution(Solution solution) override; + +private: + static Solution makeSolution(const result::const_iterator& c); +}; + +#endif //SOURCEDOUT_SOLUTIONREPOSITORY_HPP diff --git a/server/internal/solutions/src/Solution.cpp b/server/internal/solutions/src/Solution.cpp new file mode 100644 index 0000000..db3b2b9 --- /dev/null +++ b/server/internal/solutions/src/Solution.cpp @@ -0,0 +1,73 @@ + +#include +#include +#include "../Solution.hpp" + +Solution::Solution(unsigned long id, std::string sendDate, unsigned long senderId, + std::string source, std::string tokens, + std::string astTree, unsigned long taskId, + std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), + source(std::move(source)), tokens(std::move(tokens)), + astTree(std::move(astTree)), + task_id(taskId), result(std::move(result)) {} + +size_t Solution::getId() const { + return id; +} + + +const std::string &Solution::getSendDate() const { + return send_date; +} + +void Solution::setSendDate(const std::string &sendDate) { + send_date = sendDate; +} + +size_t Solution::getSenderId() const { + return sender_id; +} + +void Solution::setSenderId(size_t senderId) { + sender_id = senderId; +} + +const std::string &Solution::getSource() const { + return source; +} + +void Solution::setSource(const std::string &source_) { + Solution::source = source_; +} + +const std::string &Solution::getTokens() const { + return tokens; +} + +void Solution::setTokens(const std::string &tokens_) { + Solution::tokens = tokens_; +} + +const std::string &Solution::getAstTree() const { + return astTree; +} + +void Solution::setAstTree(const std::string &astTree_) { + Solution::astTree = astTree_; +} + +size_t Solution::getTaskId() const { + return task_id; +} + +void Solution::setTaskId(size_t taskId) { + task_id = taskId; +} + +const std::string &Solution::getResult() const { + return result; +} + +void Solution::setResult(const std::string &result_) { + Solution::result = result_; +} diff --git a/server/internal/solutions/src/SolutionRepository.cpp b/server/internal/solutions/src/SolutionRepository.cpp new file mode 100644 index 0000000..fdb9d3c --- /dev/null +++ b/server/internal/solutions/src/SolutionRepository.cpp @@ -0,0 +1,169 @@ +#pragma once + +#include +#include +#include +#include +#include "../Solution.hpp" +#include "SolutionRepository.hpp" +using namespace pqxx; + +Solution SolutionRepository::getSolutionById(size_t id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeSolution(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM solutions WHERE sender_id=" + std::to_string(sender_id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector solutions; + for(result::const_iterator k = r.begin(); k != r.end(); ++k) + solutions.push_back(makeSolution(k)); + return solutions; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM solutions WHERE task_id=" + std::to_string(task_id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector solutions; + for(result::const_iterator k = r.begin(); k != r.end(); ++k) + solutions.push_back(makeSolution(k)); + return solutions; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void SolutionRepository::storeSolution(Solution solution) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result, tokens, astTree) " \ + "VALUES (%s, %s, %s, %s, %s, %s, %s); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void SolutionRepository::updateSolution(Solution solution) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("UPDATE solutions SET send_date = %s, sender_id = %s, source = %s, task_id = %s, result = %s, tokens = %s, astTree = %s ;") + % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + work w(c); + w.exec(sql); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void SolutionRepository::deleteSolutionById(size_t id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void SolutionRepository::deleteSolution(Solution solution) { + deleteSolutionById(solution.getId()); +} + + +Solution SolutionRepository::makeSolution(const result::const_iterator& c){ + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("send_date")).as(), + c.at(c.column_number("sender_id")).as(), + c.at(c.column_number("source")).as(), + c.at(c.column_number("tokens")).as(), + c.at(c.column_number("astTree")).as(), + c.at(c.column_number("task_id")).as(), + c.at(c.column_number("result")).as()}; +} \ No newline at end of file diff --git a/server/internal/solutions/virtual/ISolutionRepository.hpp b/server/internal/solutions/virtual/ISolutionRepository.hpp new file mode 100644 index 0000000..902d0d5 --- /dev/null +++ b/server/internal/solutions/virtual/ISolutionRepository.hpp @@ -0,0 +1,26 @@ +#ifndef SOURCEDOUT_ISOLUTIONREPOSITORY_HPP +#define SOURCEDOUT_ISOLUTIONREPOSITORY_HPP + +#include +#include +#include "../Solution.hpp" + +class ISolutionRepository { + virtual Solution getSolutionById(size_t id) = 0; + + virtual std::vector getSolutionsBySenderId(size_t sender_id) = 0; + + virtual std::vector getSolutionsByTaskId(size_t task_id) = 0; + + virtual void storeSolution(Solution solution) = 0; + + virtual void updateSolution(Solution solution) = 0; + + virtual void deleteSolutionById(size_t id) = 0; + + virtual void deleteSolution(Solution solution) = 0; + + +}; + +#endif //SOURCEDOUT_ISOLUTIONREPOSITORY_HPP diff --git a/server/internal/src/CMakeLists.txt b/server/internal/src/CMakeLists.txt new file mode 100644 index 0000000..72e4c50 --- /dev/null +++ b/server/internal/src/CMakeLists.txt @@ -0,0 +1,5 @@ +set(CMAKE_CXX_STANDARD 20) +cmake_minimum_required(VERSION 3.19) +add_subdirectory(db) +set(DB_Lib_LIB ${DB_Lib_LIB} PARENT_SCOPE) +set(DB_Lib_INCLUDE_DIRS ${DB_Lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/server/internal/src/db/CMakeLists.txt b/server/internal/src/db/CMakeLists.txt new file mode 100644 index 0000000..df02471 --- /dev/null +++ b/server/internal/src/db/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.10) + +project("DBLib") + +set(LIB_NAME DB_Lib) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +message("SOURCES = ${SOURCES}") +message("HEADERS = ${HEADERS}") + + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + +add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) +target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_link_libraries(${LIB_NAME} ${libpqxx_LIBRARIES} nlohmann_json::nlohmann_json) + +set(DB_Lib_LIB ${LIB_NAME}) +set(DB_Lib_LIB ${DB_Lib_LIB} PARENT_SCOPE) +set(DB_Lib_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(DB_Lib_INCLUDE_DIRS ${DB_Lib_INCLUDE_DIRS} PARENT_SCOPE) + +message("DB_Lib_LIB = ${DB_Lib_LIB}") +message("DB_Lib_INCLUDE_DIRS = ${DB_Lib_INCLUDE_DIRS}") diff --git a/server/internal/src/db/config.json b/server/internal/src/db/config.json new file mode 100644 index 0000000..81007a5 --- /dev/null +++ b/server/internal/src/db/config.json @@ -0,0 +1,7 @@ +{ + "dbname": "mydb", + "user": "postgres", + "password": "root", + "hostaddr": "127.0.0.1", + "port": "5432" +} diff --git a/server/internal/src/db/include/conn.hpp b/server/internal/src/db/include/conn.hpp new file mode 100644 index 0000000..1468361 --- /dev/null +++ b/server/internal/src/db/include/conn.hpp @@ -0,0 +1,22 @@ +#ifndef SOURCEDOUT_CONN_HPP +#define SOURCEDOUT_CONN_HPP + +#include +#include +#include + +using json = nlohmann::json; + +struct conn { + std::string dbname; + std::string user; + std::string password; + std::string hostaddr; + std::string port; + + conn(); + + [[nodiscard]] std::string getData() const; +}; + +#endif //SOURCEDOUT_CONN_HPP diff --git a/server/internal/src/db/src/conn.cpp b/server/internal/src/db/src/conn.cpp new file mode 100644 index 0000000..9fe5074 --- /dev/null +++ b/server/internal/src/db/src/conn.cpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "conn.hpp" +#include +conn::conn() { + std::ifstream f("../config.json"); + json data = json::parse(R"( +{ + "dbname": "mydb", + "user": "postgres", + "password": "root", + "hostaddr": "172.28.224.1", + "port": "5432" +} +)"); + data.at("dbname").get_to(dbname); + data.at("user").get_to(user); + data.at("password").get_to(password); + data.at("hostaddr").get_to(hostaddr); + data.at("port").get_to(port); +} + +std::string conn::getData() const { + return "dbname = " + dbname + " user = " + user + " password = " + password + + " hostaddr = " + hostaddr + " port = " + port; +} \ No newline at end of file diff --git a/server/internal/tasks/Task.hpp b/server/internal/tasks/Task.hpp new file mode 100644 index 0000000..a9832ec --- /dev/null +++ b/server/internal/tasks/Task.hpp @@ -0,0 +1,21 @@ +#ifndef SOURCEDOUT_TASK_HPP +#define SOURCEDOUT_TASK_HPP +#include +#include +class Task{ +private: + size_t id; + std::string description; + +public: + Task(size_t id, std::string description); + + explicit Task(std::string description); + + [[nodiscard]] size_t getId() const; + + [[nodiscard]] const std::string &getDescription() const; + + void setDescription(const std::string &description); +}; +#endif //SOURCEDOUT_TASK_HPP diff --git a/server/internal/tasks/include/TaskRepository.hpp b/server/internal/tasks/include/TaskRepository.hpp new file mode 100644 index 0000000..342f64b --- /dev/null +++ b/server/internal/tasks/include/TaskRepository.hpp @@ -0,0 +1,27 @@ +#ifndef SOURCEDOUT_TASKREPOSITORY_HPP +#define SOURCEDOUT_TASKREPOSITORY_HPP + +#include +#include +#include "ITaskRepository.hpp" +#include "pqxx/pqxx" + +using namespace pqxx; + +class TaskRepository : ITaskRepository { +public: + Task getTaskById(size_t id) override; + + void updateTask(Task task) override; + + void storeTask(Task task) override; + + void deleteTask(Task task) override; + + void deleteTaskById(size_t task_id) override; + +private: + static Task makeTask(const result::const_iterator &c); +}; + +#endif //SOURCEDOUT_TASKREPOSITORY_HPP diff --git a/server/internal/tasks/src/Task.cpp b/server/internal/tasks/src/Task.cpp new file mode 100644 index 0000000..03629d8 --- /dev/null +++ b/server/internal/tasks/src/Task.cpp @@ -0,0 +1,21 @@ +#pragma once + +#include "../Task.hpp" +#include +#include + +unsigned long Task::getId() const { + return id; +} + +Task::Task(size_t id, std::string description) : id(id), description(std::move(description)) {} + +Task::Task(std::string description) : id(0), description(std::move(description)) {} + +const std::string &Task::getDescription() const { + return description; +} + +void Task::setDescription(const std::string &description_) { + Task::description = description_; +} diff --git a/server/internal/tasks/src/TaskRepository.cpp b/server/internal/tasks/src/TaskRepository.cpp new file mode 100644 index 0000000..655dd04 --- /dev/null +++ b/server/internal/tasks/src/TaskRepository.cpp @@ -0,0 +1,106 @@ +#pragma once +#include +#include +#include "../Task.hpp" +#include +#include "TaskRepository.hpp" + +Task TaskRepository::getTaskById(size_t id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM tasks WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeTask(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void TaskRepository::updateTask(Task task) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("UPDATE tasks SET description = %s ;") % task.getDescription()).str(); + work w(c); + w.exec(sql); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void TaskRepository::storeTask(Task task) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO tasks (description) " \ + "VALUES (%s); ") % task.getDescription()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void TaskRepository::deleteTask(Task task) { + deleteTaskById(task.getId()); +} + +void TaskRepository::deleteTaskById(size_t task_id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM tasks WHERE id=" + std::to_string(task_id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +Task TaskRepository::makeTask(const result::const_iterator &c) { + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("description")).as()}; +} \ No newline at end of file diff --git a/server/internal/tasks/virtual/ITaskRepository.hpp b/server/internal/tasks/virtual/ITaskRepository.hpp new file mode 100644 index 0000000..c788f94 --- /dev/null +++ b/server/internal/tasks/virtual/ITaskRepository.hpp @@ -0,0 +1,19 @@ +#ifndef SOURCEDOUT_ITASKREPOSITORY_HPP +#define SOURCEDOUT_ITASKREPOSITORY_HPP + +#include +#include "../Task.hpp" + +class ITaskRepository { + virtual Task getTaskById(size_t id) = 0; + + virtual void updateTask(Task task) = 0; + + virtual void storeTask(Task task) = 0; + + virtual void deleteTask(Task task) = 0; + + virtual void deleteTaskById(size_t task_id) = 0; +}; + +#endif //SOURCEDOUT_ITASKREPOSITORY_HPP diff --git a/server/internal/users/User.hpp b/server/internal/users/User.hpp new file mode 100644 index 0000000..b4dba92 --- /dev/null +++ b/server/internal/users/User.hpp @@ -0,0 +1,35 @@ +#ifndef SOURCEDOUT_USER_HPP + +#include +#include + +#define SOURCEDOUT_USER_HPP + +class User { +private: + size_t id; + std::string login; + std::string password; + std::string username; + +public: + User(size_t id_, std::string login_, std::string password_, std::string username_); + + User(std::string login_, std::string password_, std::string username_); + + [[nodiscard]] const std::string &getLogin() const; + + void setLogin(const std::string &login); + + [[nodiscard]] const std::string &getPassword() const; + + void setPassword(const std::string &password); + + [[nodiscard]] const std::string &getUsername() const; + + void setUsername(const std::string &username); + + [[nodiscard]] size_t getId() const; +}; + +#endif //SOURCEDOUT_USER_HPP diff --git a/server/internal/users/include/UserRepository.hpp b/server/internal/users/include/UserRepository.hpp new file mode 100644 index 0000000..3851cd7 --- /dev/null +++ b/server/internal/users/include/UserRepository.hpp @@ -0,0 +1,35 @@ +#ifndef SOURCEDOUT_USERREPOSITORY_HPP +#define SOURCEDOUT_USERREPOSITORY_HPP + +#include +#include "IUserRepository.hpp" +#include "../User.hpp" +#include +#include +#include +#include "conn.hpp" +using namespace pqxx; + +class UserRepository : IUserRepository { +public: + explicit UserRepository(conn connect); + + User getUserById(size_t id) override; + + User getUserByLogin(std::string login) override; + + size_t makeUser(User user) override; + + void deleteUser(User user) override; + + void deleteByUserId(size_t user_id) override; + + std::vector getAllUsers() override; + + +private: + static User makeUser(const result::const_iterator& c); + conn conn_; +}; + +#endif //SOURCEDOUT_USERREPOSITORY_HPP diff --git a/server/internal/users/src/User.cpp b/server/internal/users/src/User.cpp new file mode 100644 index 0000000..e32d7ae --- /dev/null +++ b/server/internal/users/src/User.cpp @@ -0,0 +1,37 @@ +#include +#include "../User.hpp" + +User::User(size_t id_, std::string login_, std::string password_, std::string username_) : + id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { +} +User::User(std::string login_, std::string password_, std::string username_) : +id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { +} + +const std::string &User::getLogin() const { + return login; +} + +void User::setLogin(const std::string &login_) { + User::login = login_; +} + +const std::string &User::getPassword() const { + return password; +} + +void User::setPassword(const std::string &password_) { + User::password = password_; +} + +const std::string &User::getUsername() const { + return username; +} + +void User::setUsername(const std::string &username_) { + User::username = username_; +} + +size_t User::getId() const { + return id; +} diff --git a/server/internal/users/src/UserRepository.cpp b/server/internal/users/src/UserRepository.cpp new file mode 100644 index 0000000..6b3207b --- /dev/null +++ b/server/internal/users/src/UserRepository.cpp @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include "../User.hpp" +#include "UserRepository.hpp" +#include +#include + +User UserRepository::getUserById(size_t id) { + try { + connection c(conn_.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeUser(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +User UserRepository::getUserByLogin(std::string login) { + try { + connection c(conn_.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("SELECT * FROM Users WHERE login= '%s'")% login).str(); + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + return makeUser(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +size_t UserRepository::makeUser(User user) { + try { + connection c(conn_.getData()); + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = (boost::format("INSERT INTO users (login,password,username) " \ + "VALUES ('%s', '%s', '%s'); ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); + work w(c); + w.exec(sql); + w.commit(); + log << "OK" << std::endl; + log.close(); + + c.close(); + + return getUserByLogin(user.getLogin()).getId(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void UserRepository::deleteByUserId(size_t user_id) { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "DELETE FROM Users WHERE id=" + std::to_string(user_id); + work w(c); + w.commit(); + log << "OK" << std::endl; + log.close(); + c.close(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + + +void UserRepository::deleteUser(User user) { + deleteByUserId(user.getId()); +} + +std::vector UserRepository::getAllUsers() { + try { + connection c; + std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); + if (c.is_open()) { + log << "Opened database successfully: " << c.dbname() << std::endl; + } else { + log << "Can't open database" << std::endl; + std::cerr << "Can't open database" << std::endl; + } + std::string sql = "SELECT * FROM Users"; + nontransaction n(c); + result r(n.exec(sql)); + log << "OK" << std::endl; + log.close(); + c.close(); + std::vector users; + for (result::const_iterator k = r.begin(); k != r.end(); ++k) + users.push_back(makeUser(k)); + return users; + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +User UserRepository::makeUser(const result::const_iterator &c) { + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("login")).as(), + c.at(c.column_number("password")).as(), + c.at(c.column_number("username")).as()}; +} + +UserRepository::UserRepository(conn connect) { + conn_ = std::move(connect); +} diff --git a/server/internal/users/virtual/IUserRepository.hpp b/server/internal/users/virtual/IUserRepository.hpp new file mode 100644 index 0000000..8f41eb3 --- /dev/null +++ b/server/internal/users/virtual/IUserRepository.hpp @@ -0,0 +1,22 @@ +#ifndef SOURCEDOUT_IUSERREPOSITORY_HPP +#define SOURCEDOUT_IUSERREPOSITORY_HPP + +#include +#include "../User.hpp" +class IUserRepository { +public: + virtual User getUserById(size_t id) = 0; + + virtual User getUserByLogin(std::string login) = 0; + + virtual size_t makeUser(User user) = 0; + + virtual void deleteUser(User user) = 0; + + virtual void deleteByUserId(size_t user_id) = 0; + + virtual std::vector getAllUsers() = 0; + +}; + +#endif //SOURCEDOUT_IUSERREPOSITORY_HPP -- GitLab From 18cb05a3c4350dd84f757a18a8c54319e5067009 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Mon, 1 May 2023 13:20:36 +0300 Subject: [PATCH 05/12] modify architecture --- .gitignore | 2 ++ .../users/tests => client}/CMakeLists.txt | 0 server/CMakeLists.txt | 14 ++++++++ server/cmd/main.cpp | 2 +- server/conanfile.txt | 10 ++++++ server/internal/CMakeLists.txt | 13 ++++--- .../internal/dbManager/include/dbManager.hpp | 14 ++++++++ server/internal/dbManager/src/dbManager.cpp | 5 +++ .../include}/Solution.hpp | 0 .../{tasks => entities/include}/Task.hpp | 0 .../{users => entities/include}/User.hpp | 0 .../{solutions => entities}/src/Solution.cpp | 2 +- .../internal/{tasks => entities}/src/Task.cpp | 2 +- .../internal/{users => entities}/src/User.cpp | 2 +- server/internal/entities/tests/CMakeLists.txt | 0 server/internal/repository/CMakeLists.txt | 34 +++++++++++++++++++ .../include/SolutionRepository.hpp | 3 +- .../include/TaskRepository.hpp | 2 +- .../include/UserRepository.hpp | 3 +- .../src/SolutionRepository.cpp | 2 +- .../src/TaskRepository.cpp | 2 +- .../src/UserRepository.cpp | 2 +- .../internal/repository/tests/CMakeLists.txt | 0 .../virtual/ISolutionRepository.hpp | 2 +- .../virtual/ITaskRepository.hpp | 2 +- .../virtual/IUserRepository.hpp | 2 +- server/internal/solutions/CMakeLists.txt | 20 ----------- server/internal/tasks/CMakeLists.txt | 20 ----------- server/internal/users/CMakeLists.txt | 28 --------------- 29 files changed, 101 insertions(+), 87 deletions(-) rename {server/internal/users/tests => client}/CMakeLists.txt (100%) create mode 100644 server/CMakeLists.txt create mode 100644 server/conanfile.txt create mode 100644 server/internal/dbManager/include/dbManager.hpp create mode 100644 server/internal/dbManager/src/dbManager.cpp rename server/internal/{solutions => entities/include}/Solution.hpp (100%) rename server/internal/{tasks => entities/include}/Task.hpp (100%) rename server/internal/{users => entities/include}/User.hpp (100%) rename server/internal/{solutions => entities}/src/Solution.cpp (98%) rename server/internal/{tasks => entities}/src/Task.cpp (93%) rename server/internal/{users => entities}/src/User.cpp (96%) create mode 100644 server/internal/entities/tests/CMakeLists.txt create mode 100644 server/internal/repository/CMakeLists.txt rename server/internal/{solutions => repository}/include/SolutionRepository.hpp (94%) rename server/internal/{tasks => repository}/include/TaskRepository.hpp (92%) rename server/internal/{users => repository}/include/UserRepository.hpp (92%) rename server/internal/{solutions => repository}/src/SolutionRepository.cpp (99%) rename server/internal/{tasks => repository}/src/TaskRepository.cpp (99%) rename server/internal/{users => repository}/src/UserRepository.cpp (99%) create mode 100644 server/internal/repository/tests/CMakeLists.txt rename server/internal/{solutions => repository}/virtual/ISolutionRepository.hpp (93%) rename server/internal/{tasks => repository}/virtual/ITaskRepository.hpp (90%) rename server/internal/{users => repository}/virtual/IUserRepository.hpp (91%) delete mode 100644 server/internal/solutions/CMakeLists.txt delete mode 100644 server/internal/tasks/CMakeLists.txt delete mode 100644 server/internal/users/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 29e77ea..ff16b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /cmake-build-debug/ /build/ .idea +server/build/ +log.txt CMakeUserPresets.json diff --git a/server/internal/users/tests/CMakeLists.txt b/client/CMakeLists.txt similarity index 100% rename from server/internal/users/tests/CMakeLists.txt rename to client/CMakeLists.txt diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..83d384f --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CMAKE_CXX_STANDARD 20) +cmake_minimum_required(VERSION 3.19) +set(CMAKE_PREFIX_PATH build) +project(SourcedOut CXX) +find_package(antlr4-runtime REQUIRED) +find_package(Boost 1.8.1 REQUIRED) +find_package(libpqxx REQUIRED) +find_package(GTest REQUIRED) +find_package(nlohmann_json REQUIRED) +message(STATUS ${nlohmann_json_LIBRARIES}) +add_subdirectory(internal) +add_subdirectory(cmd) +#add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics +#target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} nlohmann_json::nlohmann_json) diff --git a/server/cmd/main.cpp b/server/cmd/main.cpp index 83f740d..e494b5e 100644 --- a/server/cmd/main.cpp +++ b/server/cmd/main.cpp @@ -1,6 +1,6 @@ -#include "../internal/users/include/UserRepository.hpp" +#include "../internal/repository/include/UserRepository.hpp" int main(){ User user{"qwerty200468@gmail.com", "123", "tolik"}; diff --git a/server/conanfile.txt b/server/conanfile.txt new file mode 100644 index 0000000..e4b350b --- /dev/null +++ b/server/conanfile.txt @@ -0,0 +1,10 @@ +[requires] +boost/1.81.0 +antlr4-cppruntime/4.12.0 +libpqxx/7.7.5 +gtest/cci.20210126 +nlohmann_json/3.11.2 + +[generators] +CMakeDeps +CMakeToolchain \ No newline at end of file diff --git a/server/internal/CMakeLists.txt b/server/internal/CMakeLists.txt index d990989..87ba964 100644 --- a/server/internal/CMakeLists.txt +++ b/server/internal/CMakeLists.txt @@ -1,11 +1,14 @@ set(CMAKE_CXX_STANDARD 20) cmake_minimum_required(VERSION 3.19) add_subdirectory(src) -add_subdirectory(users) -add_subdirectory(solutions) -add_subdirectory(tasks) -set(libusers_LIB ${libusers_LIB} PARENT_SCOPE) -set(libusers_INCLUDE_DIRS ${libusers_INCLUDE_DIRS} PARENT_SCOPE) +add_subdirectory(entities) +add_subdirectory(repository) +add_subdirectory(dbManager) +set(libEntities_LIB ${libEntities_LIB} PARENT_SCOPE) +set(libEntities_INCLUDE_DIRS ${libEntities_INCLUDE_DIRS} PARENT_SCOPE) + +set(libRepository_LIB ${libRepository_LIB} PARENT_SCOPE) +set(libRepository_INCLUDE_DIRS ${libRepository_INCLUDE_DIRS} PARENT_SCOPE) set(DB_Lib_LIB ${DB_Lib_LIB} PARENT_SCOPE) set(DB_Lib_INCLUDE_DIRS ${DB_Lib_INCLUDE_DIRS} PARENT_SCOPE) \ No newline at end of file diff --git a/server/internal/dbManager/include/dbManager.hpp b/server/internal/dbManager/include/dbManager.hpp new file mode 100644 index 0000000..78bcc74 --- /dev/null +++ b/server/internal/dbManager/include/dbManager.hpp @@ -0,0 +1,14 @@ +// +// Created by qwert on 01.05.2023. +// + +#ifndef SOURCEDOUT_DBMANAGER_HPP +#define SOURCEDOUT_DBMANAGER_HPP + + +class dbManager { + +}; + + +#endif //SOURCEDOUT_DBMANAGER_HPP diff --git a/server/internal/dbManager/src/dbManager.cpp b/server/internal/dbManager/src/dbManager.cpp new file mode 100644 index 0000000..a778fc7 --- /dev/null +++ b/server/internal/dbManager/src/dbManager.cpp @@ -0,0 +1,5 @@ +// +// Created by qwert on 01.05.2023. +// + +#include "../include/dbManager.hpp" diff --git a/server/internal/solutions/Solution.hpp b/server/internal/entities/include/Solution.hpp similarity index 100% rename from server/internal/solutions/Solution.hpp rename to server/internal/entities/include/Solution.hpp diff --git a/server/internal/tasks/Task.hpp b/server/internal/entities/include/Task.hpp similarity index 100% rename from server/internal/tasks/Task.hpp rename to server/internal/entities/include/Task.hpp diff --git a/server/internal/users/User.hpp b/server/internal/entities/include/User.hpp similarity index 100% rename from server/internal/users/User.hpp rename to server/internal/entities/include/User.hpp diff --git a/server/internal/solutions/src/Solution.cpp b/server/internal/entities/src/Solution.cpp similarity index 98% rename from server/internal/solutions/src/Solution.cpp rename to server/internal/entities/src/Solution.cpp index db3b2b9..dd8a542 100644 --- a/server/internal/solutions/src/Solution.cpp +++ b/server/internal/entities/src/Solution.cpp @@ -1,7 +1,7 @@ #include #include -#include "../Solution.hpp" +#include "../include/Solution.hpp" Solution::Solution(unsigned long id, std::string sendDate, unsigned long senderId, std::string source, std::string tokens, diff --git a/server/internal/tasks/src/Task.cpp b/server/internal/entities/src/Task.cpp similarity index 93% rename from server/internal/tasks/src/Task.cpp rename to server/internal/entities/src/Task.cpp index 03629d8..99e0fe6 100644 --- a/server/internal/tasks/src/Task.cpp +++ b/server/internal/entities/src/Task.cpp @@ -1,6 +1,6 @@ #pragma once -#include "../Task.hpp" +#include "../include/Task.hpp" #include #include diff --git a/server/internal/users/src/User.cpp b/server/internal/entities/src/User.cpp similarity index 96% rename from server/internal/users/src/User.cpp rename to server/internal/entities/src/User.cpp index e32d7ae..d1ade4b 100644 --- a/server/internal/users/src/User.cpp +++ b/server/internal/entities/src/User.cpp @@ -1,5 +1,5 @@ #include -#include "../User.hpp" +#include "../include/User.hpp" User::User(size_t id_, std::string login_, std::string password_, std::string username_) : id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { diff --git a/server/internal/entities/tests/CMakeLists.txt b/server/internal/entities/tests/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/server/internal/repository/CMakeLists.txt b/server/internal/repository/CMakeLists.txt new file mode 100644 index 0000000..c51edf2 --- /dev/null +++ b/server/internal/repository/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.19) + +project("RepositoryLib") + +set(LIB_NAME libRepository) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +message("SOURCES = ${SOURCES}") +message("HEADERS = ${HEADERS}") + + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") + + +add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) +target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB}) + +set(libRepository_LIB ${LIB_NAME}) +set(libRepository_LIB ${libRepository_LIB} PARENT_SCOPE) +set(libRepository_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(libRepository_INCLUDE_DIRS ${libRepository_INCLUDE_DIRS} PARENT_SCOPE) + +message(Entities_LIB = "${libEntities_LIB}") +message("libRepository_LIB = ${libRepository_LIB}") +message("libRepository_INCLUDE_DIRS = ${libRepository_INCLUDE_DIRS}") + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/server/internal/solutions/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp similarity index 94% rename from server/internal/solutions/include/SolutionRepository.hpp rename to server/internal/repository/include/SolutionRepository.hpp index 4856b6d..2642624 100644 --- a/server/internal/solutions/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -5,7 +5,8 @@ #include #include #include -#include "ISolutionRepository.hpp" +#include "../virtual/ISolutionRepository.hpp" + using namespace pqxx; class SolutionRepository : ISolutionRepository { diff --git a/server/internal/tasks/include/TaskRepository.hpp b/server/internal/repository/include/TaskRepository.hpp similarity index 92% rename from server/internal/tasks/include/TaskRepository.hpp rename to server/internal/repository/include/TaskRepository.hpp index 342f64b..551efbe 100644 --- a/server/internal/tasks/include/TaskRepository.hpp +++ b/server/internal/repository/include/TaskRepository.hpp @@ -3,7 +3,7 @@ #include #include -#include "ITaskRepository.hpp" +#include "../virtual/ITaskRepository.hpp" #include "pqxx/pqxx" using namespace pqxx; diff --git a/server/internal/users/include/UserRepository.hpp b/server/internal/repository/include/UserRepository.hpp similarity index 92% rename from server/internal/users/include/UserRepository.hpp rename to server/internal/repository/include/UserRepository.hpp index 3851cd7..335dbd0 100644 --- a/server/internal/users/include/UserRepository.hpp +++ b/server/internal/repository/include/UserRepository.hpp @@ -2,8 +2,7 @@ #define SOURCEDOUT_USERREPOSITORY_HPP #include -#include "IUserRepository.hpp" -#include "../User.hpp" +#include "../virtual/IUserRepository.hpp" #include #include #include diff --git a/server/internal/solutions/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp similarity index 99% rename from server/internal/solutions/src/SolutionRepository.cpp rename to server/internal/repository/src/SolutionRepository.cpp index fdb9d3c..05e200f 100644 --- a/server/internal/solutions/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "../Solution.hpp" +#include "Solution.hpp" #include "SolutionRepository.hpp" using namespace pqxx; diff --git a/server/internal/tasks/src/TaskRepository.cpp b/server/internal/repository/src/TaskRepository.cpp similarity index 99% rename from server/internal/tasks/src/TaskRepository.cpp rename to server/internal/repository/src/TaskRepository.cpp index 655dd04..a90b3b6 100644 --- a/server/internal/tasks/src/TaskRepository.cpp +++ b/server/internal/repository/src/TaskRepository.cpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include "../Task.hpp" +#include "Task.hpp" #include #include "TaskRepository.hpp" diff --git a/server/internal/users/src/UserRepository.cpp b/server/internal/repository/src/UserRepository.cpp similarity index 99% rename from server/internal/users/src/UserRepository.cpp rename to server/internal/repository/src/UserRepository.cpp index 6b3207b..835402f 100644 --- a/server/internal/users/src/UserRepository.cpp +++ b/server/internal/repository/src/UserRepository.cpp @@ -2,7 +2,7 @@ #include #include -#include "../User.hpp" +#include "User.hpp" #include "UserRepository.hpp" #include #include diff --git a/server/internal/repository/tests/CMakeLists.txt b/server/internal/repository/tests/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/server/internal/solutions/virtual/ISolutionRepository.hpp b/server/internal/repository/virtual/ISolutionRepository.hpp similarity index 93% rename from server/internal/solutions/virtual/ISolutionRepository.hpp rename to server/internal/repository/virtual/ISolutionRepository.hpp index 902d0d5..c64a1b6 100644 --- a/server/internal/solutions/virtual/ISolutionRepository.hpp +++ b/server/internal/repository/virtual/ISolutionRepository.hpp @@ -3,7 +3,7 @@ #include #include -#include "../Solution.hpp" +#include "../../entities/include/Solution.hpp" class ISolutionRepository { virtual Solution getSolutionById(size_t id) = 0; diff --git a/server/internal/tasks/virtual/ITaskRepository.hpp b/server/internal/repository/virtual/ITaskRepository.hpp similarity index 90% rename from server/internal/tasks/virtual/ITaskRepository.hpp rename to server/internal/repository/virtual/ITaskRepository.hpp index c788f94..26d32d2 100644 --- a/server/internal/tasks/virtual/ITaskRepository.hpp +++ b/server/internal/repository/virtual/ITaskRepository.hpp @@ -2,7 +2,7 @@ #define SOURCEDOUT_ITASKREPOSITORY_HPP #include -#include "../Task.hpp" +#include "../../entities/include/Task.hpp" class ITaskRepository { virtual Task getTaskById(size_t id) = 0; diff --git a/server/internal/users/virtual/IUserRepository.hpp b/server/internal/repository/virtual/IUserRepository.hpp similarity index 91% rename from server/internal/users/virtual/IUserRepository.hpp rename to server/internal/repository/virtual/IUserRepository.hpp index 8f41eb3..8b3f7ab 100644 --- a/server/internal/users/virtual/IUserRepository.hpp +++ b/server/internal/repository/virtual/IUserRepository.hpp @@ -2,7 +2,7 @@ #define SOURCEDOUT_IUSERREPOSITORY_HPP #include -#include "../User.hpp" +#include "../../entities/include/User.hpp" class IUserRepository { public: virtual User getUserById(size_t id) = 0; diff --git a/server/internal/solutions/CMakeLists.txt b/server/internal/solutions/CMakeLists.txt deleted file mode 100644 index 48709e6..0000000 --- a/server/internal/solutions/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) -cmake_minimum_required(VERSION 3.19) -project(solutions) - -set(LIB_NAME libsolutions) - -file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) -file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) - -message("SOURCES = ${SOURCES}") -message("HEADERS = ${HEADERS}") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ --Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - -add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) -target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) -target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES}) \ No newline at end of file diff --git a/server/internal/tasks/CMakeLists.txt b/server/internal/tasks/CMakeLists.txt deleted file mode 100644 index b118f3d..0000000 --- a/server/internal/tasks/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) -cmake_minimum_required(VERSION 3.19) -project(tasks) - -set(LIB_NAME libtasks) - -file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) -file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) - -message("SOURCES = ${SOURCES}") -message("HEADERS = ${HEADERS}") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ --Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - -add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) -target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) -target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES}) \ No newline at end of file diff --git a/server/internal/users/CMakeLists.txt b/server/internal/users/CMakeLists.txt deleted file mode 100644 index 168866a..0000000 --- a/server/internal/users/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(CMAKE_CXX_STANDARD 20) -cmake_minimum_required(VERSION 3.19) -project(users) - -set(LIB_NAME libusers) - -file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) -file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) - -message("SOURCES = ${SOURCES}") -message("HEADERS = ${HEADERS}") - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ --Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") - -add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) -target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) -target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${DB_Lib_LIB}) - -set(libusers_LIB ${LIB_NAME}) -set(libusers_LIB ${libusers_LIB} PARENT_SCOPE) -set(libusers_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) -set(libusers_INCLUDE_DIRS ${libusers_INCLUDE_DIRS} PARENT_SCOPE) - -enable_testing() -add_subdirectory(tests) \ No newline at end of file -- GitLab From f580b22dff342375f22ff610912e262ec91d5c12 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Mon, 1 May 2023 16:18:48 +0300 Subject: [PATCH 06/12] add dbManager --- .env | 1 + log.txt | 8 ++ server/CMakeLists.txt | 1 + server/cmd/.env | 1 + server/cmd/CMakeLists.txt | 2 +- server/cmd/main.cpp | 13 ++- server/internal/CMakeLists.txt | 8 +- server/internal/dbManager/CMakeLists.txt | 32 ++++++ .../dbManager/include/dbConnection.hpp | 26 +++++ .../internal/dbManager/include/dbManager.hpp | 26 +++-- .../internal/dbManager/src/dbConnection.cpp | 20 ++++ server/internal/dbManager/src/dbManager.cpp | 48 ++++++++- server/internal/entities/CMakeLists.txt | 33 +++++++ server/internal/entities/include/User.hpp | 2 + server/internal/entities/src/User.cpp | 6 ++ server/internal/repository/CMakeLists.txt | 5 +- .../repository/include/SolutionRepository.hpp | 2 + .../repository/include/TaskRepository.hpp | 2 + .../repository/include/UserRepository.hpp | 6 +- .../repository/src/SolutionRepository.cpp | 99 +++++-------------- .../repository/src/TaskRepository.cpp | 67 +++---------- .../repository/src/UserRepository.cpp | 85 ++++------------ .../internal/users/tests/users_repo_test.cpp | 0 23 files changed, 273 insertions(+), 220 deletions(-) create mode 100644 server/internal/dbManager/CMakeLists.txt create mode 100644 server/internal/dbManager/include/dbConnection.hpp create mode 100644 server/internal/dbManager/src/dbConnection.cpp create mode 100644 server/internal/entities/CMakeLists.txt delete mode 100644 server/internal/users/tests/users_repo_test.cpp diff --git a/.env b/.env index 0804779..3281990 100644 --- a/.env +++ b/.env @@ -3,3 +3,4 @@ PGPORT=5432 PGDATABASE=mydb PGUSER=postgres PGPASSWORD=root +POOLSIZE=10 \ No newline at end of file diff --git a/log.txt b/log.txt index 836dc35..d72fd29 100644 --- a/log.txt +++ b/log.txt @@ -11,3 +11,11 @@ OK Opened database successfully: mydb OK Opened database successfully: mydb +Opened database successfully: mydb +OK +Opened database successfully: mydb +OK +Opened database successfully: mydb +OK +Opened database successfully: mydb +OK diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 83d384f..e7bc4e0 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -10,5 +10,6 @@ find_package(nlohmann_json REQUIRED) message(STATUS ${nlohmann_json_LIBRARIES}) add_subdirectory(internal) add_subdirectory(cmd) +#add_subdirectory(cpp-dotenv) #add_executable(${PROJECT_NAME} text-basic-metrics/tbm_main.cpp text-basic-metrics/tbm_main.cpp) строка для запуска моей части в text-basic-metrics #target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} nlohmann_json::nlohmann_json) diff --git a/server/cmd/.env b/server/cmd/.env index 0804779..7cac90d 100644 --- a/server/cmd/.env +++ b/server/cmd/.env @@ -3,3 +3,4 @@ PGPORT=5432 PGDATABASE=mydb PGUSER=postgres PGPASSWORD=root +POOL_SIZE=10 \ No newline at end of file diff --git a/server/cmd/CMakeLists.txt b/server/cmd/CMakeLists.txt index 4829fdd..7b7c468 100644 --- a/server/cmd/CMakeLists.txt +++ b/server/cmd/CMakeLists.txt @@ -8,7 +8,7 @@ project(${PROJECT_NAME}) add_executable(Server main.cpp) message(STATUS ${libusers}) -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${GTest_LIBRARIES} ${libusers_LIB}) +target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${antlr4-runtime_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libRepository_LIB}) target_include_directories(Server PUBLIC ${libusers_INCLUDE_DIRS}) message("Built server") diff --git a/server/cmd/main.cpp b/server/cmd/main.cpp index e494b5e..177490d 100644 --- a/server/cmd/main.cpp +++ b/server/cmd/main.cpp @@ -1,11 +1,10 @@ +//#include "dotenv.h" +#include "UserRepository.hpp" +#include "User.hpp" - -#include "../internal/repository/include/UserRepository.hpp" - +//using namespace dotenv; int main(){ User user{"qwerty200468@gmail.com", "123", "tolik"}; - conn conn; - UserRepository repo(conn); - std::cout< +//#include "dotenv.h" +//using namespace dotenv; +class dbConnection { +public: + dbConnection(); + [[nodiscard]] std::shared_ptr connection() const; +private: + void establish_connection(); + + std::string m_dbhost = "localhost"; + int m_dbport = 5432; + std::string m_dbname = "demo"; + std::string m_dbuser = "postgres"; + std::string m_dbpass = "postgres"; + + std::shared_ptr m_connection; + +}; + + +#endif //SOURCEDOUT_DBCONNECTION_HPP diff --git a/server/internal/dbManager/include/dbManager.hpp b/server/internal/dbManager/include/dbManager.hpp index 78bcc74..deeeba2 100644 --- a/server/internal/dbManager/include/dbManager.hpp +++ b/server/internal/dbManager/include/dbManager.hpp @@ -1,13 +1,27 @@ -// -// Created by qwert on 01.05.2023. -// - #ifndef SOURCEDOUT_DBMANAGER_HPP #define SOURCEDOUT_DBMANAGER_HPP - +#include +#include +#include +#include +#include +#include +#include +#include +//#include "dotenv.h" +//using namespace dotenv; class dbManager { - +public: + dbManager(); + std::shared_ptr connection(); + void freeConnection(const std::shared_ptr&); +private: + const int POOL_SIZE = 10; + std::condition_variable m_condition; + void createPool(); + std::queue> connection_pool; + std::mutex m_mutex; }; diff --git a/server/internal/dbManager/src/dbConnection.cpp b/server/internal/dbManager/src/dbConnection.cpp new file mode 100644 index 0000000..6ad134a --- /dev/null +++ b/server/internal/dbManager/src/dbConnection.cpp @@ -0,0 +1,20 @@ +// +// Created by qwert on 01.05.2023. +// + +#include +#include "../include/dbConnection.hpp" + +dbConnection::dbConnection() { + +} + +std::shared_ptr dbConnection::connection() const { + return m_connection; +} + +void dbConnection::establish_connection() { + pqxx::connection c( "dbname =mydb" "user = postgres password =root hostaddr =172.28.224.1 port = 5432"); + m_connection.reset(&c); + +} diff --git a/server/internal/dbManager/src/dbManager.cpp b/server/internal/dbManager/src/dbManager.cpp index a778fc7..1c4f71f 100644 --- a/server/internal/dbManager/src/dbManager.cpp +++ b/server/internal/dbManager/src/dbManager.cpp @@ -1,5 +1,45 @@ -// -// Created by qwert on 01.05.2023. -// -#include "../include/dbManager.hpp" +#include "dbManager.hpp" + + +dbManager::dbManager() { + createPool(); +} + +void dbManager::createPool() { + std::lock_guard locker_(m_mutex); + + for (auto i = 0; i < POOL_SIZE; i++) { + connection_pool.emplace(std::make_shared( + "dbname =mydb user = postgres password =root hostaddr =172.28.224.1 port = 5432")); + } +} + +std::shared_ptr dbManager::connection() { + std::unique_lock lock_(m_mutex); + + // if pool is empty, then wait until it notifies back + while (connection_pool.empty()) { + m_condition.wait(lock_); + } + + // get new connection in queue + auto conn_ = connection_pool.front(); + // immediately pop as we will use it now + connection_pool.pop(); + + return conn_; +} + +void dbManager::freeConnection(const std::shared_ptr &conn_) { + std::unique_lock lock_(m_mutex); + + // push a new connection into a pool + connection_pool.push(conn_); + + // unlock mutex + lock_.unlock(); + + // notify one of thread that is waiting + m_condition.notify_one(); +} diff --git a/server/internal/entities/CMakeLists.txt b/server/internal/entities/CMakeLists.txt new file mode 100644 index 0000000..08858c7 --- /dev/null +++ b/server/internal/entities/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.19) + +project("EntitiesLib") + +set(LIB_NAME libEntities) + +file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) + +message("SOURCES = ${SOURCES}") +message("HEADERS = ${HEADERS}") + + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") + + +add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) +target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +#target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} nlohmann_json::nlohmann_json) + +set(libEntities_LIB ${LIB_NAME}) +set(libEntities_LIB ${libEntities_LIB} PARENT_SCOPE) +set(libEntities_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(libEntities_INCLUDE_DIRS ${libEntities_INCLUDE_DIRS} PARENT_SCOPE) + +message("libEntities_LIB = ${libEntities_LIB}") +message("libEntities_INCLUDE_DIRS = ${libEntities_INCLUDE_DIRS}") + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/server/internal/entities/include/User.hpp b/server/internal/entities/include/User.hpp index b4dba92..23a2f13 100644 --- a/server/internal/entities/include/User.hpp +++ b/server/internal/entities/include/User.hpp @@ -30,6 +30,8 @@ public: void setUsername(const std::string &username); [[nodiscard]] size_t getId() const; + + friend std::ostream &operator<<(std::ostream &os, const User &user); }; #endif //SOURCEDOUT_USER_HPP diff --git a/server/internal/entities/src/User.cpp b/server/internal/entities/src/User.cpp index d1ade4b..c048f8f 100644 --- a/server/internal/entities/src/User.cpp +++ b/server/internal/entities/src/User.cpp @@ -35,3 +35,9 @@ void User::setUsername(const std::string &username_) { size_t User::getId() const { return id; } + +std::ostream &operator<<(std::ostream &os, const User &user) { + os << "id: " << user.id << " login: " << user.login << " password: " << user.password << " username: " + << user.username; + return os; +} diff --git a/server/internal/repository/CMakeLists.txt b/server/internal/repository/CMakeLists.txt index c51edf2..c3eeeee 100644 --- a/server/internal/repository/CMakeLists.txt +++ b/server/internal/repository/CMakeLists.txt @@ -19,14 +19,17 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB}) +target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libDbManager_LIB}) set(libRepository_LIB ${LIB_NAME}) set(libRepository_LIB ${libRepository_LIB} PARENT_SCOPE) + set(libRepository_INCLUDE_DIRS ${LIB_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/include) set(libRepository_INCLUDE_DIRS ${libRepository_INCLUDE_DIRS} PARENT_SCOPE) + message(Entities_LIB = "${libEntities_LIB}") +message(dbManager = "${libDbManager_LIB}") message("libRepository_LIB = ${libRepository_LIB}") message("libRepository_INCLUDE_DIRS = ${libRepository_INCLUDE_DIRS}") diff --git a/server/internal/repository/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp index 2642624..04034d5 100644 --- a/server/internal/repository/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -6,6 +6,7 @@ #include #include #include "../virtual/ISolutionRepository.hpp" +#include "dbManager.hpp" using namespace pqxx; @@ -26,6 +27,7 @@ class SolutionRepository : ISolutionRepository { private: static Solution makeSolution(const result::const_iterator& c); + std::shared_ptr manager; }; #endif //SOURCEDOUT_SOLUTIONREPOSITORY_HPP diff --git a/server/internal/repository/include/TaskRepository.hpp b/server/internal/repository/include/TaskRepository.hpp index 551efbe..793ea2f 100644 --- a/server/internal/repository/include/TaskRepository.hpp +++ b/server/internal/repository/include/TaskRepository.hpp @@ -5,6 +5,7 @@ #include #include "../virtual/ITaskRepository.hpp" #include "pqxx/pqxx" +#include "dbManager.hpp" using namespace pqxx; @@ -22,6 +23,7 @@ public: private: static Task makeTask(const result::const_iterator &c); + std::shared_ptr manager; }; #endif //SOURCEDOUT_TASKREPOSITORY_HPP diff --git a/server/internal/repository/include/UserRepository.hpp b/server/internal/repository/include/UserRepository.hpp index 335dbd0..a8bd86d 100644 --- a/server/internal/repository/include/UserRepository.hpp +++ b/server/internal/repository/include/UserRepository.hpp @@ -3,15 +3,15 @@ #include #include "../virtual/IUserRepository.hpp" +#include "dbManager.hpp" #include #include #include -#include "conn.hpp" using namespace pqxx; class UserRepository : IUserRepository { public: - explicit UserRepository(conn connect); + explicit UserRepository(); User getUserById(size_t id) override; @@ -28,7 +28,7 @@ public: private: static User makeUser(const result::const_iterator& c); - conn conn_; + std::shared_ptr manager; }; #endif //SOURCEDOUT_USERREPOSITORY_HPP diff --git a/server/internal/repository/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp index 05e200f..4e21f05 100644 --- a/server/internal/repository/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -1,29 +1,17 @@ -#pragma once - #include #include #include -#include #include "Solution.hpp" #include "SolutionRepository.hpp" using namespace pqxx; Solution SolutionRepository::getSolutionById(size_t id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); return makeSolution(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -33,21 +21,12 @@ Solution SolutionRepository::getSolutionById(size_t id) { std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM solutions WHERE sender_id=" + std::to_string(sender_id); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); std::vector solutions; + manager->freeConnection(c); for(result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; @@ -59,21 +38,12 @@ std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_i std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM solutions WHERE task_id=" + std::to_string(task_id); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); std::vector solutions; + manager->freeConnection(c); for(result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; @@ -85,22 +55,14 @@ std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) void SolutionRepository::storeSolution(Solution solution) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); + std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result, tokens, astTree) " \ - "VALUES (%s, %s, %s, %s, %s, %s, %s); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); - work w(c); + "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s'); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + work w(*c); w.exec(sql); w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -109,21 +71,13 @@ void SolutionRepository::storeSolution(Solution solution) { void SolutionRepository::updateSolution(Solution solution) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("UPDATE solutions SET send_date = %s, sender_id = %s, source = %s, task_id = %s, result = %s, tokens = %s, astTree = %s ;") + auto c = manager->connection(); + + std::string sql = (boost::format("UPDATE solutions SET send_date = '%s', sender_id = '%s', source = '%s', task_id = '%s', result = '%s', tokens = '%s', astTree = '%s';") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); - work w(c); + work w(*c); w.exec(sql); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -132,20 +86,11 @@ void SolutionRepository::updateSolution(Solution solution) { void SolutionRepository::deleteSolutionById(size_t id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); - work w(c); + work w(*c); w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; diff --git a/server/internal/repository/src/TaskRepository.cpp b/server/internal/repository/src/TaskRepository.cpp index a90b3b6..58725b5 100644 --- a/server/internal/repository/src/TaskRepository.cpp +++ b/server/internal/repository/src/TaskRepository.cpp @@ -1,4 +1,4 @@ -#pragma once + #include #include #include "Task.hpp" @@ -7,20 +7,11 @@ Task TaskRepository::getTaskById(size_t id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM tasks WHERE id=" + std::to_string(id); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); return makeTask(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -30,20 +21,11 @@ Task TaskRepository::getTaskById(size_t id) { void TaskRepository::updateTask(Task task) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = (boost::format("UPDATE tasks SET description = %s ;") % task.getDescription()).str(); - work w(c); + auto c = manager->connection(); + std::string sql = (boost::format("UPDATE tasks SET description = '%s' ;") % task.getDescription()).str(); + work w(*c); w.exec(sql); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -52,22 +34,13 @@ void TaskRepository::updateTask(Task task) { void TaskRepository::storeTask(Task task) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = (boost::format("INSERT INTO tasks (description) " \ - "VALUES (%s); ") % task.getDescription()).str(); - work w(c); + "VALUES ('%s'); ") % task.getDescription()).str(); + work w(*c); w.exec(sql); w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -80,20 +53,10 @@ void TaskRepository::deleteTask(Task task) { void TaskRepository::deleteTaskById(size_t task_id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } - std::string sql = "DELETE FROM tasks WHERE id=" + std::to_string(task_id); - work w(c); + auto c = manager->connection(); + work w(*c); w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; diff --git a/server/internal/repository/src/UserRepository.cpp b/server/internal/repository/src/UserRepository.cpp index 835402f..b496286 100644 --- a/server/internal/repository/src/UserRepository.cpp +++ b/server/internal/repository/src/UserRepository.cpp @@ -1,28 +1,17 @@ -#pragma once #include -#include #include "User.hpp" #include "UserRepository.hpp" +#include "dbManager.hpp" #include -#include User UserRepository::getUserById(size_t id) { try { - connection c(conn_.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); return makeUser(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -32,20 +21,11 @@ User UserRepository::getUserById(size_t id) { User UserRepository::getUserByLogin(std::string login) { try { - connection c(conn_.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = (boost::format("SELECT * FROM Users WHERE login= '%s'")% login).str(); - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); return makeUser(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -55,23 +35,14 @@ User UserRepository::getUserByLogin(std::string login) { size_t UserRepository::makeUser(User user) { try { - connection c(conn_.getData()); - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); + std::string sql = (boost::format("INSERT INTO users (login,password,username) " \ "VALUES ('%s', '%s', '%s'); ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); - work w(c); + work w(*c); w.exec(sql); w.commit(); - log << "OK" << std::endl; - log.close(); - - c.close(); + manager->freeConnection(c); return getUserByLogin(user.getLogin()).getId(); } catch (const std::exception &e) { @@ -82,20 +53,11 @@ size_t UserRepository::makeUser(User user) { void UserRepository::deleteByUserId(size_t user_id) { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "DELETE FROM Users WHERE id=" + std::to_string(user_id); - work w(c); + work w(*c); w.commit(); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -109,20 +71,11 @@ void UserRepository::deleteUser(User user) { std::vector UserRepository::getAllUsers() { try { - connection c; - std::ofstream log("log.txt", std::ios_base::out | std::ios_base::app); - if (c.is_open()) { - log << "Opened database successfully: " << c.dbname() << std::endl; - } else { - log << "Can't open database" << std::endl; - std::cerr << "Can't open database" << std::endl; - } + auto c = manager->connection(); std::string sql = "SELECT * FROM Users"; - nontransaction n(c); + nontransaction n(*c); result r(n.exec(sql)); - log << "OK" << std::endl; - log.close(); - c.close(); + manager->freeConnection(c); std::vector users; for (result::const_iterator k = r.begin(); k != r.end(); ++k) users.push_back(makeUser(k)); @@ -140,6 +93,6 @@ User UserRepository::makeUser(const result::const_iterator &c) { c.at(c.column_number("username")).as()}; } -UserRepository::UserRepository(conn connect) { - conn_ = std::move(connect); +UserRepository::UserRepository() { + manager = std::make_shared(); } diff --git a/server/internal/users/tests/users_repo_test.cpp b/server/internal/users/tests/users_repo_test.cpp deleted file mode 100644 index e69de29..0000000 -- GitLab From 450ee048ac8b18c53a65bcf290f97b0e43bce027 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Wed, 3 May 2023 01:52:19 +0300 Subject: [PATCH 07/12] =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=B0=20=D0=B2=20?= =?UTF-8?q?=D0=B1=D0=B4=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0?= =?UTF-8?q?=D0=B5=D1=82=D1=81=D1=8F=20=D0=B5=D0=B3=D0=BE=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + server/cmd/main.cpp | 2 +- server/internal/entities/include/MetricStat.hpp | 8 ++++++++ server/internal/entities/src/MetricStat.cpp | 3 +++ server/internal/repository/include/MetricRepository.hpp | 8 ++++++++ .../internal/repository/include/SolutionRepository.hpp | 2 +- server/internal/repository/include/TaskRepository.hpp | 2 +- server/internal/repository/src/MetricRepository.cpp | 3 +++ server/internal/repository/src/SolutionRepository.cpp | 8 +++++--- server/internal/repository/src/TaskRepository.cpp | 9 ++++++--- server/internal/repository/src/UserRepository.cpp | 8 ++++---- server/internal/repository/virtual/IMetricRepository.hpp | 8 ++++++++ .../internal/repository/virtual/ISolutionRepository.hpp | 2 +- server/internal/repository/virtual/ITaskRepository.hpp | 2 +- 14 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 server/internal/entities/include/MetricStat.hpp create mode 100644 server/internal/entities/src/MetricStat.cpp create mode 100644 server/internal/repository/include/MetricRepository.hpp create mode 100644 server/internal/repository/src/MetricRepository.cpp create mode 100644 server/internal/repository/virtual/IMetricRepository.hpp diff --git a/.gitignore b/.gitignore index ff16b4f..6e8ea51 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ .idea server/build/ log.txt +/server/cpp-dotenv CMakeUserPresets.json diff --git a/server/cmd/main.cpp b/server/cmd/main.cpp index 177490d..10b8775 100644 --- a/server/cmd/main.cpp +++ b/server/cmd/main.cpp @@ -6,5 +6,5 @@ int main(){ User user{"qwerty200468@gmail.com", "123", "tolik"}; UserRepository repo; - std::cout< getSolutionsByTaskId(size_t task_id) override; - void storeSolution(Solution solution) override; + size_t storeSolution(Solution solution) override; void updateSolution(Solution solution) override; diff --git a/server/internal/repository/include/TaskRepository.hpp b/server/internal/repository/include/TaskRepository.hpp index 793ea2f..7ffae02 100644 --- a/server/internal/repository/include/TaskRepository.hpp +++ b/server/internal/repository/include/TaskRepository.hpp @@ -15,7 +15,7 @@ public: void updateTask(Task task) override; - void storeTask(Task task) override; + size_t storeTask(Task task) override; void deleteTask(Task task) override; diff --git a/server/internal/repository/src/MetricRepository.cpp b/server/internal/repository/src/MetricRepository.cpp new file mode 100644 index 0000000..6427df1 --- /dev/null +++ b/server/internal/repository/src/MetricRepository.cpp @@ -0,0 +1,3 @@ +// +// Created by qwert on 03.05.2023. +// diff --git a/server/internal/repository/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp index 4e21f05..3c7d0cd 100644 --- a/server/internal/repository/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -53,16 +53,17 @@ std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) } } -void SolutionRepository::storeSolution(Solution solution) { +size_t SolutionRepository::storeSolution(Solution solution) { try { auto c = manager->connection(); std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result, tokens, astTree) " \ - "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s'); ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s') RETURNING id; ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); work w(*c); - w.exec(sql); + row r = (w.exec1(sql)); w.commit(); manager->freeConnection(c); + return r["id"].as(); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -89,6 +90,7 @@ void SolutionRepository::deleteSolutionById(size_t id) { auto c = manager->connection(); std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); work w(*c); + w.exec(sql); w.commit(); manager->freeConnection(c); } catch (const std::exception &e) { diff --git a/server/internal/repository/src/TaskRepository.cpp b/server/internal/repository/src/TaskRepository.cpp index 58725b5..0f06026 100644 --- a/server/internal/repository/src/TaskRepository.cpp +++ b/server/internal/repository/src/TaskRepository.cpp @@ -32,15 +32,16 @@ void TaskRepository::updateTask(Task task) { } } -void TaskRepository::storeTask(Task task) { +size_t TaskRepository::storeTask(Task task) { try { auto c = manager->connection(); std::string sql = (boost::format("INSERT INTO tasks (description) " \ - "VALUES ('%s'); ") % task.getDescription()).str(); + "VALUES ('%s') RETURNING id; ") % task.getDescription()).str(); work w(*c); - w.exec(sql); + row r = w.exec1(sql); w.commit(); manager->freeConnection(c); + return r["id"].as(); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -54,7 +55,9 @@ void TaskRepository::deleteTask(Task task) { void TaskRepository::deleteTaskById(size_t task_id) { try { auto c = manager->connection(); + std::string sql = "DELETE FROM tasks WHERE id=" + std::to_string(task_id); work w(*c); + w.exec(sql); w.commit(); manager->freeConnection(c); } catch (const std::exception &e) { diff --git a/server/internal/repository/src/UserRepository.cpp b/server/internal/repository/src/UserRepository.cpp index b496286..df85bda 100644 --- a/server/internal/repository/src/UserRepository.cpp +++ b/server/internal/repository/src/UserRepository.cpp @@ -38,13 +38,12 @@ size_t UserRepository::makeUser(User user) { auto c = manager->connection(); std::string sql = (boost::format("INSERT INTO users (login,password,username) " \ - "VALUES ('%s', '%s', '%s'); ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); + "VALUES ('%s', '%s', '%s') RETURNING id; ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); work w(*c); - w.exec(sql); + row r = w.exec1(sql); w.commit(); manager->freeConnection(c); - - return getUserByLogin(user.getLogin()).getId(); + return r["id"].as(); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; throw e; @@ -56,6 +55,7 @@ void UserRepository::deleteByUserId(size_t user_id) { auto c = manager->connection(); std::string sql = "DELETE FROM Users WHERE id=" + std::to_string(user_id); work w(*c); + w.exec(sql); w.commit(); manager->freeConnection(c); } catch (const std::exception &e) { diff --git a/server/internal/repository/virtual/IMetricRepository.hpp b/server/internal/repository/virtual/IMetricRepository.hpp new file mode 100644 index 0000000..2c4fcff --- /dev/null +++ b/server/internal/repository/virtual/IMetricRepository.hpp @@ -0,0 +1,8 @@ +// +// Created by qwert on 03.05.2023. +// + +#ifndef SOURCEDOUT_IMETRICREPOSITORY_HPP +#define SOURCEDOUT_IMETRICREPOSITORY_HPP + +#endif //SOURCEDOUT_IMETRICREPOSITORY_HPP diff --git a/server/internal/repository/virtual/ISolutionRepository.hpp b/server/internal/repository/virtual/ISolutionRepository.hpp index c64a1b6..236f760 100644 --- a/server/internal/repository/virtual/ISolutionRepository.hpp +++ b/server/internal/repository/virtual/ISolutionRepository.hpp @@ -12,7 +12,7 @@ class ISolutionRepository { virtual std::vector getSolutionsByTaskId(size_t task_id) = 0; - virtual void storeSolution(Solution solution) = 0; + virtual size_t storeSolution(Solution solution) = 0; virtual void updateSolution(Solution solution) = 0; diff --git a/server/internal/repository/virtual/ITaskRepository.hpp b/server/internal/repository/virtual/ITaskRepository.hpp index 26d32d2..89962ff 100644 --- a/server/internal/repository/virtual/ITaskRepository.hpp +++ b/server/internal/repository/virtual/ITaskRepository.hpp @@ -9,7 +9,7 @@ class ITaskRepository { virtual void updateTask(Task task) = 0; - virtual void storeTask(Task task) = 0; + virtual size_t storeTask(Task task) = 0; virtual void deleteTask(Task task) = 0; -- GitLab From c6380f400d2ca11b312f42e0e8747783357331c3 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Wed, 3 May 2023 01:55:19 +0300 Subject: [PATCH 08/12] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=8E=20=D0=B2=20=D0=BB=D0=B8=D0=B1=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/internal/repository/CMakeLists.txt | 2 +- server/internal/repository/include/SolutionRepository.hpp | 2 +- server/internal/repository/include/TaskRepository.hpp | 2 +- server/internal/repository/include/UserRepository.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/internal/repository/CMakeLists.txt b/server/internal/repository/CMakeLists.txt index c3eeeee..2c08543 100644 --- a/server/internal/repository/CMakeLists.txt +++ b/server/internal/repository/CMakeLists.txt @@ -18,7 +18,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) -target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libDbManager_LIB}) set(libRepository_LIB ${LIB_NAME}) diff --git a/server/internal/repository/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp index 949edbf..5513cbc 100644 --- a/server/internal/repository/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -5,7 +5,7 @@ #include #include #include -#include "../virtual/ISolutionRepository.hpp" +#include "ISolutionRepository.hpp" #include "dbManager.hpp" using namespace pqxx; diff --git a/server/internal/repository/include/TaskRepository.hpp b/server/internal/repository/include/TaskRepository.hpp index 7ffae02..308a1a6 100644 --- a/server/internal/repository/include/TaskRepository.hpp +++ b/server/internal/repository/include/TaskRepository.hpp @@ -3,7 +3,7 @@ #include #include -#include "../virtual/ITaskRepository.hpp" +#include "ITaskRepository.hpp" #include "pqxx/pqxx" #include "dbManager.hpp" diff --git a/server/internal/repository/include/UserRepository.hpp b/server/internal/repository/include/UserRepository.hpp index a8bd86d..7a82f82 100644 --- a/server/internal/repository/include/UserRepository.hpp +++ b/server/internal/repository/include/UserRepository.hpp @@ -2,7 +2,7 @@ #define SOURCEDOUT_USERREPOSITORY_HPP #include -#include "../virtual/IUserRepository.hpp" +#include "IUserRepository.hpp" #include "dbManager.hpp" #include #include -- GitLab From 4b10027a3839192a8b4e89f605746a0745c1d591 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Wed, 3 May 2023 12:58:00 +0300 Subject: [PATCH 09/12] added new entity, small refactoring --- .../internal/entities/include/MetricStat.hpp | 52 ++++++++++- server/internal/entities/include/Solution.hpp | 6 ++ server/internal/entities/include/Task.hpp | 6 ++ server/internal/entities/include/User.hpp | 6 ++ server/internal/entities/src/MetricStat.cpp | 71 ++++++++++++++- server/internal/entities/src/Solution.cpp | 11 +++ server/internal/entities/src/Task.cpp | 12 +++ server/internal/entities/src/User.cpp | 12 +++ .../repository/include/MetricRepository.hpp | 29 +++++- .../repository/include/SolutionRepository.hpp | 3 +- .../repository/src/MetricRepository.cpp | 88 ++++++++++++++++++- .../repository/src/SolutionRepository.cpp | 37 ++++---- .../repository/virtual/IMetricRepository.hpp | 21 ++++- 13 files changed, 320 insertions(+), 34 deletions(-) diff --git a/server/internal/entities/include/MetricStat.hpp b/server/internal/entities/include/MetricStat.hpp index 8880d30..69ca521 100644 --- a/server/internal/entities/include/MetricStat.hpp +++ b/server/internal/entities/include/MetricStat.hpp @@ -1,8 +1,52 @@ -// -// Created by qwert on 03.05.2023. -// - #ifndef SOURCEDOUT_METRICSTAT_HPP #define SOURCEDOUT_METRICSTAT_HPP +#include + +class MetricStat { +public: + MetricStat(size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, bool verdict, + float meanRes); + + MetricStat(size_t id, size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, bool verdict, + float meanRes); + + [[nodiscard]] size_t getId() const; + + void setId(size_t id); + + [[nodiscard]] size_t getSolutionId() const; + + void setSolutionId(size_t solutionId); + + [[nodiscard]] float getTextBasedRes() const; + + void setTextBasedRes(float textBasedRes); + + [[nodiscard]] float getTokenBasedRes() const; + + void setTokenBasedRes(float tokenBasedRes); + + [[nodiscard]] float getTreeBasedRes() const; + + void setTreeBasedRes(float treeBasedRes); + + [[nodiscard]] bool isVerdict() const; + + void setVerdict(bool verdict); + + [[nodiscard]] float getMeanRes() const; + + void setMeanRes(float meanRes); + +private: + size_t id; + size_t solution_id; + float text_based_res; + float token_based_res; + float tree_based_res; + bool verdict; + float mean_res; +}; + #endif //SOURCEDOUT_METRICSTAT_HPP diff --git a/server/internal/entities/include/Solution.hpp b/server/internal/entities/include/Solution.hpp index dcfa255..5c3d313 100644 --- a/server/internal/entities/include/Solution.hpp +++ b/server/internal/entities/include/Solution.hpp @@ -41,6 +41,12 @@ public: void setResult(const std::string &result); + void setId(size_t id); + + bool operator==(const Solution &rhs) const; + + bool operator!=(const Solution &rhs) const; + private: size_t id; std::string send_date; diff --git a/server/internal/entities/include/Task.hpp b/server/internal/entities/include/Task.hpp index a9832ec..99d28e6 100644 --- a/server/internal/entities/include/Task.hpp +++ b/server/internal/entities/include/Task.hpp @@ -17,5 +17,11 @@ public: [[nodiscard]] const std::string &getDescription() const; void setDescription(const std::string &description); + + void setId(size_t id); + + bool operator==(const Task &rhs) const; + + bool operator!=(const Task &rhs) const; }; #endif //SOURCEDOUT_TASK_HPP diff --git a/server/internal/entities/include/User.hpp b/server/internal/entities/include/User.hpp index 23a2f13..d593cf9 100644 --- a/server/internal/entities/include/User.hpp +++ b/server/internal/entities/include/User.hpp @@ -32,6 +32,12 @@ public: [[nodiscard]] size_t getId() const; friend std::ostream &operator<<(std::ostream &os, const User &user); + + void setId(size_t id); + + bool operator==(const User &rhs) const; + + bool operator!=(const User &rhs) const; }; #endif //SOURCEDOUT_USER_HPP diff --git a/server/internal/entities/src/MetricStat.cpp b/server/internal/entities/src/MetricStat.cpp index 6427df1..268dde6 100644 --- a/server/internal/entities/src/MetricStat.cpp +++ b/server/internal/entities/src/MetricStat.cpp @@ -1,3 +1,68 @@ -// -// Created by qwert on 03.05.2023. -// + +#include "MetricStat.hpp" + +MetricStat::MetricStat(unsigned long solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, + bool verdict, float meanRes) : id(0), solution_id(solutionId), + text_based_res(textBasedRes), token_based_res(tokenBasedRes), + tree_based_res(treeBasedRes), verdict(verdict), mean_res(meanRes) {} + +MetricStat::MetricStat(size_t id, size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, + bool verdict, float meanRes) : id(id), solution_id(solutionId), text_based_res(textBasedRes), + token_based_res(tokenBasedRes), tree_based_res(treeBasedRes), + verdict(verdict), mean_res(meanRes) {} + +size_t MetricStat::getId() const { + return id; +} + +void MetricStat::setId(size_t id_) { + id = id_; +} + +size_t MetricStat::getSolutionId() const { + return solution_id; +} + +void MetricStat::setSolutionId(size_t solutionId) { + solution_id = solutionId; +} + +float MetricStat::getTextBasedRes() const { + return text_based_res; +} + +void MetricStat::setTextBasedRes(float textBasedRes) { + text_based_res = textBasedRes; +} + +float MetricStat::getTokenBasedRes() const { + return token_based_res; +} + +void MetricStat::setTokenBasedRes(float tokenBasedRes) { + token_based_res = tokenBasedRes; +} + +float MetricStat::getTreeBasedRes() const { + return tree_based_res; +} + +void MetricStat::setTreeBasedRes(float treeBasedRes) { + tree_based_res = treeBasedRes; +} + +bool MetricStat::isVerdict() const { + return verdict; +} + +void MetricStat::setVerdict(bool verdict_) { + verdict = verdict_; +} + +float MetricStat::getMeanRes() const { + return mean_res; +} + +void MetricStat::setMeanRes(float meanRes) { + mean_res = meanRes; +} diff --git a/server/internal/entities/src/Solution.cpp b/server/internal/entities/src/Solution.cpp index dd8a542..331f7e9 100644 --- a/server/internal/entities/src/Solution.cpp +++ b/server/internal/entities/src/Solution.cpp @@ -15,6 +15,9 @@ size_t Solution::getId() const { return id; } +void Solution::setId(size_t id_) { + id = id_; +} const std::string &Solution::getSendDate() const { return send_date; @@ -71,3 +74,11 @@ const std::string &Solution::getResult() const { void Solution::setResult(const std::string &result_) { Solution::result = result_; } + +bool Solution::operator==(const Solution &rhs) const { + return id == rhs.id; +} + +bool Solution::operator!=(const Solution &rhs) const { + return !(rhs == *this); +} diff --git a/server/internal/entities/src/Task.cpp b/server/internal/entities/src/Task.cpp index 99e0fe6..56de902 100644 --- a/server/internal/entities/src/Task.cpp +++ b/server/internal/entities/src/Task.cpp @@ -16,6 +16,18 @@ const std::string &Task::getDescription() const { return description; } +void Task::setId(size_t id_) { + id = id_; +} + void Task::setDescription(const std::string &description_) { Task::description = description_; } + +bool Task::operator==(const Task &rhs) const { + return id == rhs.id; +} + +bool Task::operator!=(const Task &rhs) const { + return !(rhs == *this); +} diff --git a/server/internal/entities/src/User.cpp b/server/internal/entities/src/User.cpp index c048f8f..b6f54d7 100644 --- a/server/internal/entities/src/User.cpp +++ b/server/internal/entities/src/User.cpp @@ -12,6 +12,10 @@ const std::string &User::getLogin() const { return login; } +void User::setId(size_t id_) { + id = id_; +} + void User::setLogin(const std::string &login_) { User::login = login_; } @@ -41,3 +45,11 @@ std::ostream &operator<<(std::ostream &os, const User &user) { << user.username; return os; } + +bool User::operator==(const User &rhs) const { + return id == rhs.id; +} + +bool User::operator!=(const User &rhs) const { + return !(rhs == *this); +} diff --git a/server/internal/repository/include/MetricRepository.hpp b/server/internal/repository/include/MetricRepository.hpp index ce611ba..4ece7fe 100644 --- a/server/internal/repository/include/MetricRepository.hpp +++ b/server/internal/repository/include/MetricRepository.hpp @@ -1,8 +1,29 @@ -// -// Created by qwert on 03.05.2023. -// - #ifndef SOURCEDOUT_METRICREPOSITORY_HPP #define SOURCEDOUT_METRICREPOSITORY_HPP +#include "IMetricRepository.hpp" +#include "dbManager.hpp" +#include + + +using namespace pqxx; + +class MetricRepository : IMetricRepository { +public: + MetricStat getById(size_t id) override; + + size_t storeMetric(MetricStat metric) override; + + void updateMetric(MetricStat metric) override; + + void deleteMetric(MetricStat metric) override; + + void deleteMetricById(size_t id) override; + +private: + std::shared_ptr manager; + + static MetricStat makeMetric(const result::const_iterator &c); +}; + #endif //SOURCEDOUT_METRICREPOSITORY_HPP diff --git a/server/internal/repository/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp index 5513cbc..f0b1c88 100644 --- a/server/internal/repository/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -11,6 +11,7 @@ using namespace pqxx; class SolutionRepository : ISolutionRepository { +public: Solution getSolutionById(size_t id) override; std::vector getSolutionsBySenderId(size_t sender_id) override; @@ -30,4 +31,4 @@ private: std::shared_ptr manager; }; -#endif //SOURCEDOUT_SOLUTIONREPOSITORY_HPP +#endif diff --git a/server/internal/repository/src/MetricRepository.cpp b/server/internal/repository/src/MetricRepository.cpp index 6427df1..0e72661 100644 --- a/server/internal/repository/src/MetricRepository.cpp +++ b/server/internal/repository/src/MetricRepository.cpp @@ -1,3 +1,85 @@ -// -// Created by qwert on 03.05.2023. -// +#include "MetricStat.hpp" +#include "MetricRepository.hpp" +#include + +MetricStat MetricRepository::getById(size_t id) { + try { + auto c = manager->connection(); + std::string sql = "SELECT * FROM metricStat WHERE id=" + std::to_string(id); + nontransaction n(*c); + result r(n.exec(sql)); + manager->freeConnection(c); + return makeMetric(r.begin()); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + + +size_t MetricRepository::storeMetric(MetricStat metric) { + try { + auto c = manager->connection(); + + std::string sql = ( + boost::format( + "INSERT INTO metricStat (solution_id, text_based_res, token_based_res, tree_based_res, verdict, mean_res) " \ + "VALUES ('%s', '%s', '%s', '%s', '%s', '%s') RETURNING id; ") % metric.getSolutionId() % + metric.getTextBasedRes() % metric.getTokenBasedRes() % metric.getTreeBasedRes() % metric.isVerdict() % + metric.getMeanRes()).str(); + work w(*c); + row r = (w.exec1(sql)); + w.commit(); + manager->freeConnection(c); + return r["id"].as(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void MetricRepository::updateMetric(MetricStat metric) { + try { + auto c = manager->connection(); + + std::string sql = (boost::format( + "UPDATE metricStat SET solution_id = '%s', text_based_res = '%s', token_based_res = '%s', tree_based_res = '%s', verdict = '%s', mean_res = '%s';") + % metric.getSolutionId() % metric.getTextBasedRes() % metric.getTokenBasedRes() % + metric.getTreeBasedRes() % metric.isVerdict() % metric.getMeanRes()).str(); + work w(*c); + w.exec(sql); + manager->freeConnection(c); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +void MetricRepository::deleteMetric(MetricStat metric) { + deleteMetricById(metric.getId()); +} + +void MetricRepository::deleteMetricById(size_t id) { + try { + auto c = manager->connection(); + std::string sql = "DELETE FROM metricStat WHERE id=" + std::to_string(id); + work w(*c); + w.exec(sql); + w.commit(); + manager->freeConnection(c); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} + +MetricStat MetricRepository::makeMetric(const result::const_iterator &c) { + return {c.at(c.column_number("id")).as(), + c.at(c.column_number("solution_id")).as(), + c.at(c.column_number("text_based_res")).as(), + c.at(c.column_number("token_based_res")).as(), + c.at(c.column_number("tree_based_res")).as(), + c.at(c.column_number("verdict")).as(), + c.at(c.column_number("mean_res")).as() + }; +} diff --git a/server/internal/repository/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp index 3c7d0cd..3288158 100644 --- a/server/internal/repository/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -3,12 +3,13 @@ #include #include "Solution.hpp" #include "SolutionRepository.hpp" + using namespace pqxx; -Solution SolutionRepository::getSolutionById(size_t id) { +Solution SolutionRepository::getSolutionById(size_t id) { try { auto c = manager->connection(); - std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); + std::string sql = "SELECT * FROM solutions WHERE id=" + std::to_string(id); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); @@ -19,7 +20,7 @@ Solution SolutionRepository::getSolutionById(size_t id) { } } -std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_id) { +std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM solutions WHERE sender_id=" + std::to_string(sender_id); @@ -27,7 +28,7 @@ std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_i result r(n.exec(sql)); std::vector solutions; manager->freeConnection(c); - for(result::const_iterator k = r.begin(); k != r.end(); ++k) + for (result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; } catch (const std::exception &e) { @@ -36,7 +37,7 @@ std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_i } } -std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) { +std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM solutions WHERE task_id=" + std::to_string(task_id); @@ -44,7 +45,7 @@ std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) result r(n.exec(sql)); std::vector solutions; manager->freeConnection(c); - for(result::const_iterator k = r.begin(); k != r.end(); ++k) + for (result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; } catch (const std::exception &e) { @@ -53,12 +54,15 @@ std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) } } -size_t SolutionRepository::storeSolution(Solution solution) { +size_t SolutionRepository::storeSolution(Solution solution) { try { auto c = manager->connection(); - std::string sql = (boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result, tokens, astTree) " \ - "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s') RETURNING id; ") % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + std::string sql = ( + boost::format("INSERT INTO solutions (send_date,sender_id, source, task_id, result, tokens, astTree) " \ + "VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s') RETURNING id; ") % solution.getSendDate() % + solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % + solution.getTokens() % solution.getAstTree()).str(); work w(*c); row r = (w.exec1(sql)); w.commit(); @@ -70,12 +74,15 @@ size_t SolutionRepository::storeSolution(Solution solution) { } } -void SolutionRepository::updateSolution(Solution solution) { +void SolutionRepository::updateSolution(Solution solution) { try { auto c = manager->connection(); - std::string sql = (boost::format("UPDATE solutions SET send_date = '%s', sender_id = '%s', source = '%s', task_id = '%s', result = '%s', tokens = '%s', astTree = '%s';") - % solution.getSendDate() % solution.getSenderId() % solution.getSource() % solution.getTaskId() % solution.getResult() % solution.getTokens() % solution.getAstTree()).str(); + std::string sql = (boost::format( + "UPDATE solutions SET send_date = '%s', sender_id = '%s', source = '%s', task_id = '%s', result = '%s', tokens = '%s', astTree = '%s';") + % solution.getSendDate() % solution.getSenderId() % solution.getSource() % + solution.getTaskId() % solution.getResult() % solution.getTokens() % + solution.getAstTree()).str(); work w(*c); w.exec(sql); manager->freeConnection(c); @@ -85,7 +92,7 @@ void SolutionRepository::updateSolution(Solution solution) { } } -void SolutionRepository::deleteSolutionById(size_t id) { +void SolutionRepository::deleteSolutionById(size_t id) { try { auto c = manager->connection(); std::string sql = "DELETE FROM solutions WHERE id=" + std::to_string(id); @@ -99,12 +106,12 @@ void SolutionRepository::deleteSolutionById(size_t id) { } } -void SolutionRepository::deleteSolution(Solution solution) { +void SolutionRepository::deleteSolution(Solution solution) { deleteSolutionById(solution.getId()); } -Solution SolutionRepository::makeSolution(const result::const_iterator& c){ +Solution SolutionRepository::makeSolution(const result::const_iterator &c) { return {c.at(c.column_number("id")).as(), c.at(c.column_number("send_date")).as(), c.at(c.column_number("sender_id")).as(), diff --git a/server/internal/repository/virtual/IMetricRepository.hpp b/server/internal/repository/virtual/IMetricRepository.hpp index 2c4fcff..f0911b9 100644 --- a/server/internal/repository/virtual/IMetricRepository.hpp +++ b/server/internal/repository/virtual/IMetricRepository.hpp @@ -1,8 +1,21 @@ -// -// Created by qwert on 03.05.2023. -// - #ifndef SOURCEDOUT_IMETRICREPOSITORY_HPP #define SOURCEDOUT_IMETRICREPOSITORY_HPP + +#include +#include "MetricStat.hpp" + +class IMetricRepository { +public: + virtual MetricStat getById(size_t id) = 0; + + virtual size_t storeMetric(MetricStat metric) = 0; + + virtual void updateMetric(MetricStat metric) = 0; + + virtual void deleteMetric(MetricStat metric) = 0; + + virtual void deleteMetricById(size_t id) = 0; +}; + #endif //SOURCEDOUT_IMETRICREPOSITORY_HPP -- GitLab From f04c90040855d37b072a5d29cc23334b65e1e419 Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Wed, 3 May 2023 13:00:32 +0300 Subject: [PATCH 10/12] add equality op --- server/internal/dbManager/include/dbManager.hpp | 8 +++++++- server/internal/dbManager/src/dbConnection.cpp | 2 +- server/internal/entities/include/MetricStat.hpp | 4 ++++ server/internal/entities/src/MetricStat.cpp | 8 ++++++++ .../internal/repository/virtual/ISolutionRepository.hpp | 1 + server/internal/repository/virtual/ITaskRepository.hpp | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/server/internal/dbManager/include/dbManager.hpp b/server/internal/dbManager/include/dbManager.hpp index deeeba2..a6d323d 100644 --- a/server/internal/dbManager/include/dbManager.hpp +++ b/server/internal/dbManager/include/dbManager.hpp @@ -9,17 +9,23 @@ #include #include #include + //#include "dotenv.h" //using namespace dotenv; class dbManager { public: dbManager(); + std::shared_ptr connection(); - void freeConnection(const std::shared_ptr&); + + void freeConnection(const std::shared_ptr &); + private: const int POOL_SIZE = 10; std::condition_variable m_condition; + void createPool(); + std::queue> connection_pool; std::mutex m_mutex; }; diff --git a/server/internal/dbManager/src/dbConnection.cpp b/server/internal/dbManager/src/dbConnection.cpp index 6ad134a..39fd7a6 100644 --- a/server/internal/dbManager/src/dbConnection.cpp +++ b/server/internal/dbManager/src/dbConnection.cpp @@ -14,7 +14,7 @@ std::shared_ptr dbConnection::connection() const { } void dbConnection::establish_connection() { - pqxx::connection c( "dbname =mydb" "user = postgres password =root hostaddr =172.28.224.1 port = 5432"); + pqxx::connection c("dbname =mydb" "user = postgres password =root hostaddr =172.28.224.1 port = 5432"); m_connection.reset(&c); } diff --git a/server/internal/entities/include/MetricStat.hpp b/server/internal/entities/include/MetricStat.hpp index 69ca521..4d5d338 100644 --- a/server/internal/entities/include/MetricStat.hpp +++ b/server/internal/entities/include/MetricStat.hpp @@ -39,6 +39,10 @@ public: void setMeanRes(float meanRes); + bool operator==(const MetricStat &rhs) const; + + bool operator!=(const MetricStat &rhs) const; + private: size_t id; size_t solution_id; diff --git a/server/internal/entities/src/MetricStat.cpp b/server/internal/entities/src/MetricStat.cpp index 268dde6..12fa3b4 100644 --- a/server/internal/entities/src/MetricStat.cpp +++ b/server/internal/entities/src/MetricStat.cpp @@ -66,3 +66,11 @@ float MetricStat::getMeanRes() const { void MetricStat::setMeanRes(float meanRes) { mean_res = meanRes; } + +bool MetricStat::operator==(const MetricStat &rhs) const { + return id == rhs.id; +} + +bool MetricStat::operator!=(const MetricStat &rhs) const { + return !(rhs == *this); +} diff --git a/server/internal/repository/virtual/ISolutionRepository.hpp b/server/internal/repository/virtual/ISolutionRepository.hpp index 236f760..4325a3f 100644 --- a/server/internal/repository/virtual/ISolutionRepository.hpp +++ b/server/internal/repository/virtual/ISolutionRepository.hpp @@ -6,6 +6,7 @@ #include "../../entities/include/Solution.hpp" class ISolutionRepository { +public: virtual Solution getSolutionById(size_t id) = 0; virtual std::vector getSolutionsBySenderId(size_t sender_id) = 0; diff --git a/server/internal/repository/virtual/ITaskRepository.hpp b/server/internal/repository/virtual/ITaskRepository.hpp index 89962ff..6e97d0b 100644 --- a/server/internal/repository/virtual/ITaskRepository.hpp +++ b/server/internal/repository/virtual/ITaskRepository.hpp @@ -5,6 +5,7 @@ #include "../../entities/include/Task.hpp" class ITaskRepository { +public: virtual Task getTaskById(size_t id) = 0; virtual void updateTask(Task task) = 0; -- GitLab From eb61846e105ff04d879c7e71e1a044325d80a36f Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Thu, 4 May 2023 01:46:45 +0300 Subject: [PATCH 11/12] add equality op --- server/internal/dbManager/src/dbManager.cpp | 6 - .../internal/entities/include/MetricStat.hpp | 36 ++--- server/internal/entities/include/Solution.hpp | 42 +++--- server/internal/entities/include/Task.hpp | 24 ++- server/internal/entities/include/User.hpp | 28 ++-- server/internal/entities/src/MetricStat.cpp | 41 +++--- server/internal/entities/src/Solution.cpp | 53 ++++--- server/internal/entities/src/Task.cpp | 34 +++-- server/internal/entities/src/User.cpp | 32 ++-- server/internal/repository/CMakeLists.txt | 3 +- .../repository/include/MetricRepository.hpp | 6 +- .../repository/include/SolutionRepository.hpp | 5 +- .../repository/include/TaskRepository.hpp | 4 +- .../repository/include/UserRepository.hpp | 11 +- .../repository/src/MetricRepository.cpp | 8 +- .../repository/src/SolutionRepository.cpp | 10 +- .../repository/src/TaskRepository.cpp | 21 ++- .../repository/src/UserRepository.cpp | 29 +++- .../internal/repository/tests/CMakeLists.txt | 50 +++++++ .../repository/tests/RepositoryTests.cpp | 138 ++++++++++++++++++ .../repository/virtual/IMetricRepository.hpp | 3 +- .../virtual/ISolutionRepository.hpp | 7 +- .../repository/virtual/ITaskRepository.hpp | 5 +- .../repository/virtual/IUserRepository.hpp | 10 +- 24 files changed, 448 insertions(+), 158 deletions(-) create mode 100644 server/internal/repository/tests/RepositoryTests.cpp diff --git a/server/internal/dbManager/src/dbManager.cpp b/server/internal/dbManager/src/dbManager.cpp index 1c4f71f..f1ff766 100644 --- a/server/internal/dbManager/src/dbManager.cpp +++ b/server/internal/dbManager/src/dbManager.cpp @@ -18,14 +18,11 @@ void dbManager::createPool() { std::shared_ptr dbManager::connection() { std::unique_lock lock_(m_mutex); - // if pool is empty, then wait until it notifies back while (connection_pool.empty()) { m_condition.wait(lock_); } - // get new connection in queue auto conn_ = connection_pool.front(); - // immediately pop as we will use it now connection_pool.pop(); return conn_; @@ -34,12 +31,9 @@ std::shared_ptr dbManager::connection() { void dbManager::freeConnection(const std::shared_ptr &conn_) { std::unique_lock lock_(m_mutex); - // push a new connection into a pool connection_pool.push(conn_); - // unlock mutex lock_.unlock(); - // notify one of thread that is waiting m_condition.notify_one(); } diff --git a/server/internal/entities/include/MetricStat.hpp b/server/internal/entities/include/MetricStat.hpp index 4d5d338..491abb7 100644 --- a/server/internal/entities/include/MetricStat.hpp +++ b/server/internal/entities/include/MetricStat.hpp @@ -5,43 +5,45 @@ class MetricStat { public: + MetricStat() noexcept; + MetricStat(size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, bool verdict, - float meanRes); + float meanRes) noexcept; MetricStat(size_t id, size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, bool verdict, - float meanRes); + float meanRes) noexcept; - [[nodiscard]] size_t getId() const; + [[nodiscard]] size_t getId() const noexcept; void setId(size_t id); - [[nodiscard]] size_t getSolutionId() const; + [[nodiscard]] size_t getSolutionId() const noexcept; - void setSolutionId(size_t solutionId); + void setSolutionId(size_t solutionId) noexcept; - [[nodiscard]] float getTextBasedRes() const; + [[nodiscard]] float getTextBasedRes() const noexcept; - void setTextBasedRes(float textBasedRes); + void setTextBasedRes(float textBasedRes) noexcept; - [[nodiscard]] float getTokenBasedRes() const; + [[nodiscard]] float getTokenBasedRes() const noexcept; - void setTokenBasedRes(float tokenBasedRes); + void setTokenBasedRes(float tokenBasedRes) noexcept; - [[nodiscard]] float getTreeBasedRes() const; + [[nodiscard]] float getTreeBasedRes() const noexcept; - void setTreeBasedRes(float treeBasedRes); + void setTreeBasedRes(float treeBasedRes) noexcept; - [[nodiscard]] bool isVerdict() const; + [[nodiscard]] bool isVerdict() const noexcept; - void setVerdict(bool verdict); + void setVerdict(bool verdict) noexcept; - [[nodiscard]] float getMeanRes() const; + [[nodiscard]] float getMeanRes() const noexcept; - void setMeanRes(float meanRes); + void setMeanRes(float meanRes) noexcept; - bool operator==(const MetricStat &rhs) const; + bool operator==(const MetricStat &rhs) const noexcept; - bool operator!=(const MetricStat &rhs) const; + bool operator!=(const MetricStat &rhs) const noexcept; private: size_t id; diff --git a/server/internal/entities/include/Solution.hpp b/server/internal/entities/include/Solution.hpp index 5c3d313..974a560 100644 --- a/server/internal/entities/include/Solution.hpp +++ b/server/internal/entities/include/Solution.hpp @@ -8,44 +8,48 @@ class Solution { public: Solution(size_t id, std::string sendDate, size_t senderId, std::string source, - std::string tokens, std::string astTree, size_t taskId, std::string result); + std::string tokens, std::string astTree, size_t taskId, std::string result) noexcept; - [[nodiscard]] size_t getId() const; + Solution(std::string sendDate, size_t senderId, std::string source, std::string tokens, std::string astTree, + size_t taskId, std::string result) noexcept; + Solution() noexcept; + [[nodiscard]] size_t getId() const noexcept; - [[nodiscard]] const std::string &getSendDate() const; - void setSendDate(const std::string &sendDate); + [[nodiscard]] const std::string &getSendDate() const noexcept; - [[nodiscard]] size_t getSenderId() const; + void setSendDate(const std::string &sendDate) noexcept; - void setSenderId(size_t senderId); + [[nodiscard]] size_t getSenderId() const noexcept; - [[nodiscard]] const std::string &getSource() const; + void setSenderId(size_t senderId) noexcept; - void setSource(const std::string &source); + [[nodiscard]] const std::string &getSource() const noexcept; - [[nodiscard]] const std::string &getTokens() const; + void setSource(const std::string &source) noexcept; - void setTokens(const std::string &tokens); + [[nodiscard]] const std::string &getTokens() const noexcept; - [[nodiscard]] const std::string &getAstTree() const; + void setTokens(const std::string &tokens) noexcept; - void setAstTree(const std::string &astTree); + [[nodiscard]] const std::string &getAstTree() const noexcept; - [[nodiscard]] size_t getTaskId() const; + void setAstTree(const std::string &astTree) noexcept; - void setTaskId(size_t taskId); + [[nodiscard]] size_t getTaskId() const noexcept; - [[nodiscard]] const std::string &getResult() const; + void setTaskId(size_t taskId) noexcept; - void setResult(const std::string &result); + [[nodiscard]] const std::string &getResult() const noexcept; - void setId(size_t id); + void setResult(const std::string &result) noexcept; - bool operator==(const Solution &rhs) const; + void setId(size_t id) noexcept; - bool operator!=(const Solution &rhs) const; + bool operator==(const Solution &rhs) const noexcept; + + bool operator!=(const Solution &rhs) const noexcept; private: size_t id; diff --git a/server/internal/entities/include/Task.hpp b/server/internal/entities/include/Task.hpp index 99d28e6..e551804 100644 --- a/server/internal/entities/include/Task.hpp +++ b/server/internal/entities/include/Task.hpp @@ -6,22 +6,30 @@ class Task{ private: size_t id; std::string description; + float treshhold; public: - Task(size_t id, std::string description); + Task(size_t id, std::string description_, float treshold_) noexcept; - explicit Task(std::string description); + Task(std::string description_, float treshold_) noexcept; - [[nodiscard]] size_t getId() const; + Task() noexcept; - [[nodiscard]] const std::string &getDescription() const; + [[nodiscard]] size_t getId() const noexcept; - void setDescription(const std::string &description); + [[nodiscard]] const std::string &getDescription() const noexcept; - void setId(size_t id); + float getTreshhold() const noexcept; - bool operator==(const Task &rhs) const; + void setTreshhold(float treshhold) noexcept; + + void setDescription(const std::string &description) noexcept; + + void setId(size_t id) noexcept; + + bool operator==(const Task &rhs) const noexcept; + + bool operator!=(const Task &rhs) const noexcept; - bool operator!=(const Task &rhs) const; }; #endif //SOURCEDOUT_TASK_HPP diff --git a/server/internal/entities/include/User.hpp b/server/internal/entities/include/User.hpp index d593cf9..82e659f 100644 --- a/server/internal/entities/include/User.hpp +++ b/server/internal/entities/include/User.hpp @@ -13,31 +13,33 @@ private: std::string username; public: - User(size_t id_, std::string login_, std::string password_, std::string username_); + User(size_t id_, std::string login_, std::string password_, std::string username_) noexcept; - User(std::string login_, std::string password_, std::string username_); + User(std::string login_, std::string password_, std::string username_) noexcept; - [[nodiscard]] const std::string &getLogin() const; + User() noexcept; - void setLogin(const std::string &login); + [[nodiscard]] const std::string &getLogin() const noexcept; - [[nodiscard]] const std::string &getPassword() const; + void setLogin(const std::string &login) noexcept; - void setPassword(const std::string &password); + [[nodiscard]] const std::string &getPassword() const noexcept; - [[nodiscard]] const std::string &getUsername() const; + void setPassword(const std::string &password) noexcept; - void setUsername(const std::string &username); + [[nodiscard]] const std::string &getUsername() const noexcept; - [[nodiscard]] size_t getId() const; + void setUsername(const std::string &username) noexcept; - friend std::ostream &operator<<(std::ostream &os, const User &user); + [[nodiscard]] size_t getId() const noexcept; - void setId(size_t id); + friend std::ostream &operator<<(std::ostream &os, const User &user) noexcept; - bool operator==(const User &rhs) const; + void setId(size_t id) noexcept; - bool operator!=(const User &rhs) const; + bool operator==(const User &rhs) const noexcept; + + bool operator!=(const User &rhs) const noexcept; }; #endif //SOURCEDOUT_USER_HPP diff --git a/server/internal/entities/src/MetricStat.cpp b/server/internal/entities/src/MetricStat.cpp index 12fa3b4..aa0befc 100644 --- a/server/internal/entities/src/MetricStat.cpp +++ b/server/internal/entities/src/MetricStat.cpp @@ -2,16 +2,21 @@ #include "MetricStat.hpp" MetricStat::MetricStat(unsigned long solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, - bool verdict, float meanRes) : id(0), solution_id(solutionId), + bool verdict, float meanRes) noexcept : id(0), solution_id(solutionId), text_based_res(textBasedRes), token_based_res(tokenBasedRes), - tree_based_res(treeBasedRes), verdict(verdict), mean_res(meanRes) {} + tree_based_res(treeBasedRes), verdict(verdict), + mean_res(meanRes) {} MetricStat::MetricStat(size_t id, size_t solutionId, float textBasedRes, float tokenBasedRes, float treeBasedRes, - bool verdict, float meanRes) : id(id), solution_id(solutionId), text_based_res(textBasedRes), + bool verdict, float meanRes) noexcept : id(id), solution_id(solutionId), text_based_res(textBasedRes), token_based_res(tokenBasedRes), tree_based_res(treeBasedRes), verdict(verdict), mean_res(meanRes) {} -size_t MetricStat::getId() const { +MetricStat::MetricStat() noexcept : id(0), solution_id(0), text_based_res(0), token_based_res(0), tree_based_res(), + verdict(true), mean_res(0) { +} + +size_t MetricStat::getId() const noexcept { return id; } @@ -19,58 +24,58 @@ void MetricStat::setId(size_t id_) { id = id_; } -size_t MetricStat::getSolutionId() const { +size_t MetricStat::getSolutionId() const noexcept { return solution_id; } -void MetricStat::setSolutionId(size_t solutionId) { +void MetricStat::setSolutionId(size_t solutionId) noexcept { solution_id = solutionId; } -float MetricStat::getTextBasedRes() const { +float MetricStat::getTextBasedRes() const noexcept { return text_based_res; } -void MetricStat::setTextBasedRes(float textBasedRes) { +void MetricStat::setTextBasedRes(float textBasedRes) noexcept { text_based_res = textBasedRes; } -float MetricStat::getTokenBasedRes() const { +float MetricStat::getTokenBasedRes() const noexcept { return token_based_res; } -void MetricStat::setTokenBasedRes(float tokenBasedRes) { +void MetricStat::setTokenBasedRes(float tokenBasedRes) noexcept { token_based_res = tokenBasedRes; } -float MetricStat::getTreeBasedRes() const { +float MetricStat::getTreeBasedRes() const noexcept { return tree_based_res; } -void MetricStat::setTreeBasedRes(float treeBasedRes) { +void MetricStat::setTreeBasedRes(float treeBasedRes) noexcept { tree_based_res = treeBasedRes; } -bool MetricStat::isVerdict() const { +bool MetricStat::isVerdict() const noexcept { return verdict; } -void MetricStat::setVerdict(bool verdict_) { +void MetricStat::setVerdict(bool verdict_) noexcept { verdict = verdict_; } -float MetricStat::getMeanRes() const { +float MetricStat::getMeanRes() const noexcept { return mean_res; } -void MetricStat::setMeanRes(float meanRes) { +void MetricStat::setMeanRes(float meanRes) noexcept { mean_res = meanRes; } -bool MetricStat::operator==(const MetricStat &rhs) const { +bool MetricStat::operator==(const MetricStat &rhs) const noexcept { return id == rhs.id; } -bool MetricStat::operator!=(const MetricStat &rhs) const { +bool MetricStat::operator!=(const MetricStat &rhs) const noexcept { return !(rhs == *this); } diff --git a/server/internal/entities/src/Solution.cpp b/server/internal/entities/src/Solution.cpp index 331f7e9..0603c00 100644 --- a/server/internal/entities/src/Solution.cpp +++ b/server/internal/entities/src/Solution.cpp @@ -1,84 +1,95 @@ #include #include -#include "../include/Solution.hpp" +#include "Solution.hpp" -Solution::Solution(unsigned long id, std::string sendDate, unsigned long senderId, +Solution::Solution(size_t id, std::string sendDate, unsigned long senderId, std::string source, std::string tokens, std::string astTree, unsigned long taskId, - std::string result) : id(id), send_date(std::move(sendDate)), sender_id(senderId), + std::string result) noexcept : id(id), send_date(std::move(sendDate)), sender_id(senderId), source(std::move(source)), tokens(std::move(tokens)), astTree(std::move(astTree)), task_id(taskId), result(std::move(result)) {} -size_t Solution::getId() const { +Solution::Solution(std::string sendDate, unsigned long senderId, + std::string source, std::string tokens, + std::string astTree, unsigned long taskId, + std::string result) noexcept : id(0), send_date(std::move(sendDate)), sender_id(senderId), + source(std::move(source)), tokens(std::move(tokens)), + astTree(std::move(astTree)), + task_id(taskId), result(std::move(result)) {} + +Solution::Solution() noexcept : id(0), sender_id(0), task_id(0) {} + +size_t Solution::getId() const noexcept { return id; } -void Solution::setId(size_t id_) { +void Solution::setId(size_t id_) noexcept { id = id_; } -const std::string &Solution::getSendDate() const { +const std::string &Solution::getSendDate() const noexcept { return send_date; } -void Solution::setSendDate(const std::string &sendDate) { +void Solution::setSendDate(const std::string &sendDate) noexcept { send_date = sendDate; } -size_t Solution::getSenderId() const { +size_t Solution::getSenderId() const noexcept { return sender_id; } -void Solution::setSenderId(size_t senderId) { +void Solution::setSenderId(size_t senderId) noexcept { sender_id = senderId; } -const std::string &Solution::getSource() const { +const std::string &Solution::getSource() const noexcept { return source; } -void Solution::setSource(const std::string &source_) { +void Solution::setSource(const std::string &source_) noexcept { Solution::source = source_; } -const std::string &Solution::getTokens() const { +const std::string &Solution::getTokens() const noexcept { return tokens; } -void Solution::setTokens(const std::string &tokens_) { +void Solution::setTokens(const std::string &tokens_) noexcept { Solution::tokens = tokens_; } -const std::string &Solution::getAstTree() const { +const std::string &Solution::getAstTree() const noexcept { return astTree; } -void Solution::setAstTree(const std::string &astTree_) { +void Solution::setAstTree(const std::string &astTree_) noexcept { Solution::astTree = astTree_; } -size_t Solution::getTaskId() const { +size_t Solution::getTaskId() const noexcept { return task_id; } -void Solution::setTaskId(size_t taskId) { +void Solution::setTaskId(size_t taskId) noexcept { task_id = taskId; } -const std::string &Solution::getResult() const { +const std::string &Solution::getResult() const noexcept { return result; } -void Solution::setResult(const std::string &result_) { +void Solution::setResult(const std::string &result_) noexcept { Solution::result = result_; } -bool Solution::operator==(const Solution &rhs) const { +bool Solution::operator==(const Solution &rhs) const noexcept { return id == rhs.id; } -bool Solution::operator!=(const Solution &rhs) const { +bool Solution::operator!=(const Solution &rhs) const noexcept { return !(rhs == *this); } + diff --git a/server/internal/entities/src/Task.cpp b/server/internal/entities/src/Task.cpp index 56de902..b830fe9 100644 --- a/server/internal/entities/src/Task.cpp +++ b/server/internal/entities/src/Task.cpp @@ -2,32 +2,44 @@ #include "../include/Task.hpp" #include -#include -unsigned long Task::getId() const { - return id; -} +Task::Task(std::string description_, float treshold_) noexcept : id(0), description(std::move(description_)), + treshhold(treshold_) {} -Task::Task(size_t id, std::string description) : id(id), description(std::move(description)) {} +Task::Task(size_t id, std::string description_, float treshold_) noexcept : id(id), description(std::move(description_)), + treshhold(treshold_) {} +Task::Task() noexcept:id(0), treshhold(0) { +} -Task::Task(std::string description) : id(0), description(std::move(description)) {} +unsigned long Task::getId() const noexcept { + return id; +} -const std::string &Task::getDescription() const { +const std::string &Task::getDescription() const noexcept { return description; } -void Task::setId(size_t id_) { +void Task::setId(size_t id_) noexcept { id = id_; } -void Task::setDescription(const std::string &description_) { +void Task::setDescription(const std::string &description_) noexcept { Task::description = description_; } -bool Task::operator==(const Task &rhs) const { +bool Task::operator==(const Task &rhs) const noexcept { return id == rhs.id; } -bool Task::operator!=(const Task &rhs) const { +bool Task::operator!=(const Task &rhs) const noexcept { return !(rhs == *this); } + +float Task::getTreshhold() const noexcept { + return treshhold; +} + +void Task::setTreshhold(float treshhold_) noexcept { + Task::treshhold = treshhold_; +} + diff --git a/server/internal/entities/src/User.cpp b/server/internal/entities/src/User.cpp index b6f54d7..67f2620 100644 --- a/server/internal/entities/src/User.cpp +++ b/server/internal/entities/src/User.cpp @@ -1,55 +1,59 @@ #include #include "../include/User.hpp" -User::User(size_t id_, std::string login_, std::string password_, std::string username_) : +User::User(size_t id_, std::string login_, std::string password_, std::string username_) noexcept : id(id_), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { } -User::User(std::string login_, std::string password_, std::string username_) : -id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { + +User::User(std::string login_, std::string password_, std::string username_) noexcept : + id(0), login(std::move(login_)), password(std::move(password_)), username(std::move(username_)) { +} + +User::User() noexcept : id(0) { } -const std::string &User::getLogin() const { +const std::string &User::getLogin() const noexcept { return login; } -void User::setId(size_t id_) { +void User::setId(size_t id_) noexcept { id = id_; } -void User::setLogin(const std::string &login_) { +void User::setLogin(const std::string &login_) noexcept { User::login = login_; } -const std::string &User::getPassword() const { +const std::string &User::getPassword() const noexcept { return password; } -void User::setPassword(const std::string &password_) { +void User::setPassword(const std::string &password_) noexcept { User::password = password_; } -const std::string &User::getUsername() const { +const std::string &User::getUsername() const noexcept { return username; } -void User::setUsername(const std::string &username_) { +void User::setUsername(const std::string &username_) noexcept { User::username = username_; } -size_t User::getId() const { +size_t User::getId() const noexcept { return id; } -std::ostream &operator<<(std::ostream &os, const User &user) { +std::ostream &operator<<(std::ostream &os, const User &user) noexcept { os << "id: " << user.id << " login: " << user.login << " password: " << user.password << " username: " << user.username; return os; } -bool User::operator==(const User &rhs) const { +bool User::operator==(const User &rhs) const noexcept { return id == rhs.id; } -bool User::operator!=(const User &rhs) const { +bool User::operator!=(const User &rhs) const noexcept { return !(rhs == *this); } diff --git a/server/internal/repository/CMakeLists.txt b/server/internal/repository/CMakeLists.txt index 2c08543..a8c0efe 100644 --- a/server/internal/repository/CMakeLists.txt +++ b/server/internal/repository/CMakeLists.txt @@ -12,11 +12,12 @@ message("HEADERS = ${HEADERS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ --Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align") +-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -ftest-coverage") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") + add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libDbManager_LIB}) diff --git a/server/internal/repository/include/MetricRepository.hpp b/server/internal/repository/include/MetricRepository.hpp index 4ece7fe..5d9bf96 100644 --- a/server/internal/repository/include/MetricRepository.hpp +++ b/server/internal/repository/include/MetricRepository.hpp @@ -4,13 +4,15 @@ #include "IMetricRepository.hpp" #include "dbManager.hpp" #include - +#include using namespace pqxx; class MetricRepository : IMetricRepository { public: - MetricStat getById(size_t id) override; + explicit MetricRepository(); + + std::optional getById(size_t id) override; size_t storeMetric(MetricStat metric) override; diff --git a/server/internal/repository/include/SolutionRepository.hpp b/server/internal/repository/include/SolutionRepository.hpp index f0b1c88..2760959 100644 --- a/server/internal/repository/include/SolutionRepository.hpp +++ b/server/internal/repository/include/SolutionRepository.hpp @@ -7,12 +7,15 @@ #include #include "ISolutionRepository.hpp" #include "dbManager.hpp" +#include + using namespace pqxx; class SolutionRepository : ISolutionRepository { public: - Solution getSolutionById(size_t id) override; + explicit SolutionRepository(); + std::optional getSolutionById(size_t id) override; std::vector getSolutionsBySenderId(size_t sender_id) override; diff --git a/server/internal/repository/include/TaskRepository.hpp b/server/internal/repository/include/TaskRepository.hpp index 308a1a6..d907481 100644 --- a/server/internal/repository/include/TaskRepository.hpp +++ b/server/internal/repository/include/TaskRepository.hpp @@ -6,12 +6,14 @@ #include "ITaskRepository.hpp" #include "pqxx/pqxx" #include "dbManager.hpp" +#include using namespace pqxx; class TaskRepository : ITaskRepository { public: - Task getTaskById(size_t id) override; + explicit TaskRepository(); + std::optional getTaskById(size_t id) override; void updateTask(Task task) override; diff --git a/server/internal/repository/include/UserRepository.hpp b/server/internal/repository/include/UserRepository.hpp index 7a82f82..b5a52f3 100644 --- a/server/internal/repository/include/UserRepository.hpp +++ b/server/internal/repository/include/UserRepository.hpp @@ -7,15 +7,17 @@ #include #include #include +#include + using namespace pqxx; class UserRepository : IUserRepository { public: explicit UserRepository(); - User getUserById(size_t id) override; + std::optional getUserById(size_t id) override; - User getUserByLogin(std::string login) override; + std::optional getUserByLogin(std::string login) override; size_t makeUser(User user) override; @@ -25,9 +27,12 @@ public: std::vector getAllUsers() override; + void update(User user) override; + private: - static User makeUser(const result::const_iterator& c); + static User makeUser(const result::const_iterator &c); + std::shared_ptr manager; }; diff --git a/server/internal/repository/src/MetricRepository.cpp b/server/internal/repository/src/MetricRepository.cpp index 0e72661..b5e17fd 100644 --- a/server/internal/repository/src/MetricRepository.cpp +++ b/server/internal/repository/src/MetricRepository.cpp @@ -2,13 +2,15 @@ #include "MetricRepository.hpp" #include -MetricStat MetricRepository::getById(size_t id) { +std::optional MetricRepository::getById(size_t id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM metricStat WHERE id=" + std::to_string(id); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); + if(r.empty()) + return std::nullopt; return makeMetric(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -83,3 +85,7 @@ MetricStat MetricRepository::makeMetric(const result::const_iterator &c) { c.at(c.column_number("mean_res")).as() }; } + +MetricRepository::MetricRepository() { + manager = std::make_shared(); +} diff --git a/server/internal/repository/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp index 3288158..4b112b3 100644 --- a/server/internal/repository/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -6,13 +6,15 @@ using namespace pqxx; -Solution SolutionRepository::getSolutionById(size_t id) { +std::optional SolutionRepository::getSolutionById(size_t id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM solutions WHERE id=" + std::to_string(id); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); + if(r.empty()) + return std::nullopt; return makeSolution(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -120,4 +122,8 @@ Solution SolutionRepository::makeSolution(const result::const_iterator &c) { c.at(c.column_number("astTree")).as(), c.at(c.column_number("task_id")).as(), c.at(c.column_number("result")).as()}; -} \ No newline at end of file +} + +SolutionRepository::SolutionRepository() { + manager = std::make_shared(); +} diff --git a/server/internal/repository/src/TaskRepository.cpp b/server/internal/repository/src/TaskRepository.cpp index 0f06026..7b92d31 100644 --- a/server/internal/repository/src/TaskRepository.cpp +++ b/server/internal/repository/src/TaskRepository.cpp @@ -5,13 +5,16 @@ #include #include "TaskRepository.hpp" -Task TaskRepository::getTaskById(size_t id) { +std::optional TaskRepository::getTaskById(size_t id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM tasks WHERE id=" + std::to_string(id); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); + if (r.empty()){ + return std::nullopt; + } return makeTask(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -22,7 +25,8 @@ Task TaskRepository::getTaskById(size_t id) { void TaskRepository::updateTask(Task task) { try { auto c = manager->connection(); - std::string sql = (boost::format("UPDATE tasks SET description = '%s' ;") % task.getDescription()).str(); + std::string sql = (boost::format("UPDATE tasks SET description = '%s', treshold = '%s';") % + task.getDescription() % task.getTreshhold()).str(); work w(*c); w.exec(sql); manager->freeConnection(c); @@ -35,8 +39,8 @@ void TaskRepository::updateTask(Task task) { size_t TaskRepository::storeTask(Task task) { try { auto c = manager->connection(); - std::string sql = (boost::format("INSERT INTO tasks (description) " \ - "VALUES ('%s') RETURNING id; ") % task.getDescription()).str(); + std::string sql = (boost::format("INSERT INTO tasks (description, treshold) " \ + "VALUES ('%s', '%s') RETURNING id; ") % task.getDescription() % task.getTreshhold()).str(); work w(*c); row r = w.exec1(sql); w.commit(); @@ -68,5 +72,10 @@ void TaskRepository::deleteTaskById(size_t task_id) { Task TaskRepository::makeTask(const result::const_iterator &c) { return {c.at(c.column_number("id")).as(), - c.at(c.column_number("description")).as()}; -} \ No newline at end of file + c.at(c.column_number("description")).as(), + c.at(c.column_number("treshold")).as()}; +} + +TaskRepository::TaskRepository() { + manager = std::make_shared(); +} diff --git a/server/internal/repository/src/UserRepository.cpp b/server/internal/repository/src/UserRepository.cpp index df85bda..51f23c5 100644 --- a/server/internal/repository/src/UserRepository.cpp +++ b/server/internal/repository/src/UserRepository.cpp @@ -5,13 +5,15 @@ #include "dbManager.hpp" #include -User UserRepository::getUserById(size_t id) { +std::optional UserRepository::getUserById(size_t id) { try { auto c = manager->connection(); std::string sql = "SELECT * FROM Users WHERE id=" + std::to_string(id); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); + if (r.empty()) + return std::nullopt; return makeUser(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -19,13 +21,15 @@ User UserRepository::getUserById(size_t id) { } } -User UserRepository::getUserByLogin(std::string login) { +std::optional UserRepository::getUserByLogin(std::string login) { try { auto c = manager->connection(); - std::string sql = (boost::format("SELECT * FROM Users WHERE login= '%s'")% login).str(); + std::string sql = (boost::format("SELECT * FROM Users WHERE login= '%s'") % login).str(); nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); + if(r.empty()) + return std::nullopt; return makeUser(r.begin()); } catch (const std::exception &e) { std::cerr << e.what() << std::endl; @@ -38,7 +42,8 @@ size_t UserRepository::makeUser(User user) { auto c = manager->connection(); std::string sql = (boost::format("INSERT INTO users (login,password,username) " \ - "VALUES ('%s', '%s', '%s') RETURNING id; ") % user.getLogin() % user.getPassword() % user.getUsername()).str(); + "VALUES ('%s', '%s', '%s') RETURNING id; ") % user.getLogin() % user.getPassword() % + user.getUsername()).str(); work w(*c); row r = w.exec1(sql); w.commit(); @@ -96,3 +101,19 @@ User UserRepository::makeUser(const result::const_iterator &c) { UserRepository::UserRepository() { manager = std::make_shared(); } + +void UserRepository::update(User user) { + try { + auto c = manager->connection(); + + std::string sql = (boost::format( + "UPDATE Users SET login = '%s', password = '%s', username = '%s';") + % user.getLogin() % user.getPassword() % user.getUsername()).str(); + work w(*c); + w.exec(sql); + manager->freeConnection(c); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + throw e; + } +} diff --git a/server/internal/repository/tests/CMakeLists.txt b/server/internal/repository/tests/CMakeLists.txt index e69de29..ad20fc9 100644 --- a/server/internal/repository/tests/CMakeLists.txt +++ b/server/internal/repository/tests/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.19) + +project("RepositoryTests") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES *.cpp) + +if(BUILD_TYPE) + set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-fprofile-arcs -ftest-coverage -O0 -g") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage -lgcov" ) +endif(BUILD_TYPE) + + +file(GLOB TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +message("${TEST_SOURCES}") +add_executable(${PROJECT_NAME} ${TEST_SOURCES}) + +target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libDbManager_LIB} ${GTest_LIBRARIES} ${libRepository_LIB}) +target_include_directories(${PROJECT_NAME} PUBLIC ${libRepository_INCLUDE_DIRS}) + +target_compile_options(${PROJECT_NAME} PUBLIC --coverage) +target_link_options(${PROJECT_NAME} PUBLIC --coverage) + +gtest_discover_tests(${PROJECT_NAME}) + +add_custom_target( + ${PROJECT_NAME}_TEST + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME} +) + +add_custom_target( + ${PROJECT_NAME}_COVERAGE + COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_custom_target( + ${PROJECT_NAME}_COVERAGE_FILE + COMMAND rm -r ${CMAKE_CURRENT_BINARY_DIR}/report || echo "There are no reports" + COMMAND mkdir ${CMAKE_CURRENT_BINARY_DIR}/report + COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} --html-details report/report.html +) + +add_custom_target( + ${PROJECT_NAME}_VALGRIND + COMMAND valgrind -s --leak-check=full --show-leak-kinds=all ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME} +) + + + diff --git a/server/internal/repository/tests/RepositoryTests.cpp b/server/internal/repository/tests/RepositoryTests.cpp new file mode 100644 index 0000000..4af0790 --- /dev/null +++ b/server/internal/repository/tests/RepositoryTests.cpp @@ -0,0 +1,138 @@ +#include +#include +#include "MetricRepository.hpp" +#include "UserRepository.hpp" +#include "SolutionRepository.hpp" +#include "TaskRepository.hpp" +#include +TEST(UserRepository_CRUD_Test, CRUD) { + UserRepository rep; + + EXPECT_NO_FATAL_FAILURE(rep.getUserById(1)); + + User user("test@test.com", "test", "testuser"); + size_t id = rep.makeUser(user); + user.setId(id); + std::optional new_user_opt = rep.getUserById(id); + User new_user; + if (new_user_opt) { + new_user = new_user_opt.value(); + } + EXPECT_EQ(user, new_user); + new_user.setUsername("new_test_user"); + EXPECT_NO_FATAL_FAILURE(rep.update(new_user)); + + EXPECT_NO_FATAL_FAILURE(rep.deleteUser(new_user)); +} + +TEST(TaskRepository_CRUD_Test, CRUD) { + TaskRepository rep; + + Task task("test task", 0.5); + size_t id = rep.storeTask(task); + EXPECT_NO_FATAL_FAILURE(rep.getTaskById(1)); + task.setId(id); + std::optional new_task_opt = rep.getTaskById(id); + Task new_task; + if (new_task_opt) + new_task = new_task_opt.value(); + EXPECT_EQ(task, new_task); + new_task.setDescription("new_test_description"); + EXPECT_NO_FATAL_FAILURE(rep.updateTask(new_task)); + EXPECT_NO_FATAL_FAILURE(rep.deleteTask(new_task)); +} + +TEST(SolutionRepository_CRUD_Test, CRUD) { + SolutionRepository rep; + + Solution solution("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); + size_t id = rep.storeSolution(solution); + EXPECT_NO_FATAL_FAILURE(rep.getSolutionById(1)); + solution.setId(id); + std::optional new_solution_opt = rep.getSolutionById(id); + Solution new_solution; + if (new_solution_opt) + new_solution = new_solution_opt.value(); + EXPECT_EQ(solution, new_solution); + new_solution.setSource(":/D"); + EXPECT_NO_FATAL_FAILURE(rep.updateSolution(new_solution)); + EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(new_solution)); +} + +TEST(MetricRepository_CRUD_Test, CRUD){ + MetricRepository rep; + MetricStat metricStat(1, 0.8f, 0.9f, 0.89f, true, 0.85f); + size_t id = rep.storeMetric(metricStat); + EXPECT_NO_FATAL_FAILURE(rep.getById(1)); + metricStat.setId(id); + std::optional new_stat_opt = rep.getById(id); + MetricStat new_stat; + if (new_stat_opt) + new_stat = new_stat_opt.value(); + EXPECT_EQ(metricStat, new_stat); + new_stat.setMeanRes(1); + EXPECT_NO_FATAL_FAILURE(rep.updateMetric(new_stat)); + EXPECT_NO_FATAL_FAILURE(rep.deleteMetric(new_stat)); +} + +TEST(UserRepository_CRUD_Test, CRUD_many) { + UserRepository rep; + std::vector v = {{"test@test.com", "test", "testuser"}, {"test2@test.com", "test2", "testuser2"}}; + EXPECT_NO_FATAL_FAILURE(rep.getAllUsers()); + std::vector new_v = rep.getAllUsers(); + EXPECT_EQ(v, new_v); +} + +TEST(UserRepository_CRUD_Test, loginLikeId) { + UserRepository rep; + User user("test@test.com", "test", "testuser"); + size_t id = rep.makeUser(user); + user.setId(id); + std::optional new_user_id = rep.getUserById(id); + std::optional new_user_login = rep.getUserByLogin(user.getLogin()); + User new_user; + EXPECT_EQ(new_user_id, new_user_login); + EXPECT_NO_FATAL_FAILURE(rep.deleteUser(user)); + +} + +TEST(SolutionRepository_CRUD_Test, CRUD_getSolutionsBySenderId) { + SolutionRepository rep; + + Solution solution1("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); + Solution solution2("01.01.1970", 1, "/home/usr","tokens.txt","tree.txt", 1, "result"); + + size_t id1 = rep.storeSolution(solution1); + solution1.setId(id1); + size_t id2 = rep.storeSolution(solution2); + solution2.setId(id2); + std::vector v = {solution1, solution2}; + std::vector new_v = rep.getSolutionsBySenderId(solution1.getId()); + EXPECT_EQ(v, new_v); + EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution1)); + EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution2)); + +} + +TEST(SolutionRepository_CRUD_Test, CRUD_getSolutionsByTaskId) { + SolutionRepository rep; + + Solution solution1("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); + Solution solution2("01.01.1970", 1, "/home/usr","tokens.txt","tree.txt", 1, "result"); + + size_t id1 = rep.storeSolution(solution1); + solution1.setId(id1); + size_t id2 = rep.storeSolution(solution2); + solution2.setId(id2); + std::vector v = {solution1, solution2}; + std::vector new_v = rep.getSolutionsByTaskId(solution1.getId()); + EXPECT_EQ(v, new_v); + EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution1)); + EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution2)); + +} + +int main(int argc, char **argv) { + ::testing::InitGoogleMock(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/server/internal/repository/virtual/IMetricRepository.hpp b/server/internal/repository/virtual/IMetricRepository.hpp index f0911b9..fcd92fe 100644 --- a/server/internal/repository/virtual/IMetricRepository.hpp +++ b/server/internal/repository/virtual/IMetricRepository.hpp @@ -3,11 +3,12 @@ #include +#include #include "MetricStat.hpp" class IMetricRepository { public: - virtual MetricStat getById(size_t id) = 0; + virtual std::optional getById(size_t id) = 0; virtual size_t storeMetric(MetricStat metric) = 0; diff --git a/server/internal/repository/virtual/ISolutionRepository.hpp b/server/internal/repository/virtual/ISolutionRepository.hpp index 4325a3f..d8e3b80 100644 --- a/server/internal/repository/virtual/ISolutionRepository.hpp +++ b/server/internal/repository/virtual/ISolutionRepository.hpp @@ -3,11 +3,12 @@ #include #include -#include "../../entities/include/Solution.hpp" +#include "Solution.hpp" +#include class ISolutionRepository { public: - virtual Solution getSolutionById(size_t id) = 0; + virtual std::optional getSolutionById(size_t id) = 0; virtual std::vector getSolutionsBySenderId(size_t sender_id) = 0; @@ -20,8 +21,6 @@ public: virtual void deleteSolutionById(size_t id) = 0; virtual void deleteSolution(Solution solution) = 0; - - }; #endif //SOURCEDOUT_ISOLUTIONREPOSITORY_HPP diff --git a/server/internal/repository/virtual/ITaskRepository.hpp b/server/internal/repository/virtual/ITaskRepository.hpp index 6e97d0b..6f201ca 100644 --- a/server/internal/repository/virtual/ITaskRepository.hpp +++ b/server/internal/repository/virtual/ITaskRepository.hpp @@ -2,11 +2,12 @@ #define SOURCEDOUT_ITASKREPOSITORY_HPP #include -#include "../../entities/include/Task.hpp" +#include "Task.hpp" +#include class ITaskRepository { public: - virtual Task getTaskById(size_t id) = 0; + virtual std::optional getTaskById(size_t id) = 0; virtual void updateTask(Task task) = 0; diff --git a/server/internal/repository/virtual/IUserRepository.hpp b/server/internal/repository/virtual/IUserRepository.hpp index 8b3f7ab..6212721 100644 --- a/server/internal/repository/virtual/IUserRepository.hpp +++ b/server/internal/repository/virtual/IUserRepository.hpp @@ -2,17 +2,21 @@ #define SOURCEDOUT_IUSERREPOSITORY_HPP #include -#include "../../entities/include/User.hpp" +#include "User.hpp" +#include + class IUserRepository { public: - virtual User getUserById(size_t id) = 0; + virtual std::optional getUserById(size_t id) = 0; - virtual User getUserByLogin(std::string login) = 0; + virtual std::optional getUserByLogin(std::string login) = 0; virtual size_t makeUser(User user) = 0; virtual void deleteUser(User user) = 0; + virtual void update(User user) = 0; + virtual void deleteByUserId(size_t user_id) = 0; virtual std::vector getAllUsers() = 0; -- GitLab From 4be443fc2b39d3c5b071148130bf92f5e3e117ed Mon Sep 17 00:00:00 2001 From: Sarah_deep <91503476+Sarahdeep@users.noreply.github.com> Date: Thu, 4 May 2023 16:57:18 +0300 Subject: [PATCH 12/12] test improvement --- .../internal/dbManager/include/dbManager.hpp | 2 +- .../internal/dbManager/src/dbConnection.cpp | 2 +- server/internal/entities/src/Task.cpp | 4 +- server/internal/repository/CMakeLists.txt | 12 +++- .../repository/src/MetricRepository.cpp | 23 ++++---- .../repository/src/SolutionRepository.cpp | 37 ++++++------ .../repository/src/TaskRepository.cpp | 24 +++----- .../repository/src/UserRepository.cpp | 36 ++++++------ .../internal/repository/tests/CMakeLists.txt | 11 ---- .../repository/tests/RepositoryTests.cpp | 56 +++++++++++++++---- 10 files changed, 114 insertions(+), 93 deletions(-) diff --git a/server/internal/dbManager/include/dbManager.hpp b/server/internal/dbManager/include/dbManager.hpp index a6d323d..d17e9ab 100644 --- a/server/internal/dbManager/include/dbManager.hpp +++ b/server/internal/dbManager/include/dbManager.hpp @@ -21,7 +21,7 @@ public: void freeConnection(const std::shared_ptr &); private: - const int POOL_SIZE = 10; + const size_t POOL_SIZE = 10; std::condition_variable m_condition; void createPool(); diff --git a/server/internal/dbManager/src/dbConnection.cpp b/server/internal/dbManager/src/dbConnection.cpp index 39fd7a6..fe9c04d 100644 --- a/server/internal/dbManager/src/dbConnection.cpp +++ b/server/internal/dbManager/src/dbConnection.cpp @@ -6,7 +6,7 @@ #include "../include/dbConnection.hpp" dbConnection::dbConnection() { - + establish_connection(); } std::shared_ptr dbConnection::connection() const { diff --git a/server/internal/entities/src/Task.cpp b/server/internal/entities/src/Task.cpp index b830fe9..e0fc107 100644 --- a/server/internal/entities/src/Task.cpp +++ b/server/internal/entities/src/Task.cpp @@ -1,6 +1,4 @@ -#pragma once - -#include "../include/Task.hpp" +#include "Task.hpp" #include Task::Task(std::string description_, float treshold_) noexcept : id(0), description(std::move(description_)), diff --git a/server/internal/repository/CMakeLists.txt b/server/internal/repository/CMakeLists.txt index a8c0efe..d7309fa 100644 --- a/server/internal/repository/CMakeLists.txt +++ b/server/internal/repository/CMakeLists.txt @@ -16,8 +16,16 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -O2 -pedantic -Wformat set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lboost_filesystem") - - +add_custom_target( + ${PROJECT_NAME}_COVERAGE + COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} +) +add_custom_target( + ${PROJECT_NAME}_COVERAGE_FILE + COMMAND rm -r ${CMAKE_CURRENT_BINARY_DIR}/report || echo "There are no reports" + COMMAND mkdir ${CMAKE_CURRENT_BINARY_DIR}/report + COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} --html-details report/report.html +) add_library(${LIB_NAME} ${SOURCES} ${HEADERS}) target_include_directories(${LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) target_link_libraries(${LIB_NAME} ${Boost_LIBRARIES} ${libpqxx_LIBRARIES} ${libEntities_LIB} ${libDbManager_LIB}) diff --git a/server/internal/repository/src/MetricRepository.cpp b/server/internal/repository/src/MetricRepository.cpp index b5e17fd..d6d265a 100644 --- a/server/internal/repository/src/MetricRepository.cpp +++ b/server/internal/repository/src/MetricRepository.cpp @@ -12,9 +12,9 @@ std::optional MetricRepository::getById(size_t id) { if(r.empty()) return std::nullopt; return makeMetric(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -34,9 +34,9 @@ size_t MetricRepository::storeMetric(MetricStat metric) { w.commit(); manager->freeConnection(c); return r["id"].as(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -51,9 +51,9 @@ void MetricRepository::updateMetric(MetricStat metric) { work w(*c); w.exec(sql); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -69,9 +69,8 @@ void MetricRepository::deleteMetricById(size_t id) { w.exec(sql); w.commit(); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } diff --git a/server/internal/repository/src/SolutionRepository.cpp b/server/internal/repository/src/SolutionRepository.cpp index 4b112b3..91ef68e 100644 --- a/server/internal/repository/src/SolutionRepository.cpp +++ b/server/internal/repository/src/SolutionRepository.cpp @@ -13,12 +13,12 @@ std::optional SolutionRepository::getSolutionById(size_t id) { nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); - if(r.empty()) + if (r.empty()) return std::nullopt; return makeSolution(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -33,9 +33,9 @@ std::vector SolutionRepository::getSolutionsBySenderId(size_t sender_i for (result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -50,9 +50,9 @@ std::vector SolutionRepository::getSolutionsByTaskId(size_t task_id) { for (result::const_iterator k = r.begin(); k != r.end(); ++k) solutions.push_back(makeSolution(k)); return solutions; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -70,9 +70,8 @@ size_t SolutionRepository::storeSolution(Solution solution) { w.commit(); manager->freeConnection(c); return r["id"].as(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } @@ -88,9 +87,9 @@ void SolutionRepository::updateSolution(Solution solution) { work w(*c); w.exec(sql); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -102,9 +101,9 @@ void SolutionRepository::deleteSolutionById(size_t id) { w.exec(sql); w.commit(); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } diff --git a/server/internal/repository/src/TaskRepository.cpp b/server/internal/repository/src/TaskRepository.cpp index 7b92d31..9974dc5 100644 --- a/server/internal/repository/src/TaskRepository.cpp +++ b/server/internal/repository/src/TaskRepository.cpp @@ -1,6 +1,4 @@ - #include -#include #include "Task.hpp" #include #include "TaskRepository.hpp" @@ -12,13 +10,12 @@ std::optional TaskRepository::getTaskById(size_t id) { nontransaction n(*c); result r(n.exec(sql)); manager->freeConnection(c); - if (r.empty()){ + if (r.empty()) { return std::nullopt; } return makeTask(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } @@ -30,9 +27,8 @@ void TaskRepository::updateTask(Task task) { work w(*c); w.exec(sql); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } @@ -46,9 +42,8 @@ size_t TaskRepository::storeTask(Task task) { w.commit(); manager->freeConnection(c); return r["id"].as(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } @@ -64,9 +59,8 @@ void TaskRepository::deleteTaskById(size_t task_id) { w.exec(sql); w.commit(); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + throw; } } diff --git a/server/internal/repository/src/UserRepository.cpp b/server/internal/repository/src/UserRepository.cpp index 51f23c5..216baef 100644 --- a/server/internal/repository/src/UserRepository.cpp +++ b/server/internal/repository/src/UserRepository.cpp @@ -15,9 +15,9 @@ std::optional UserRepository::getUserById(size_t id) { if (r.empty()) return std::nullopt; return makeUser(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -31,9 +31,9 @@ std::optional UserRepository::getUserByLogin(std::string login) { if(r.empty()) return std::nullopt; return makeUser(r.begin()); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -49,9 +49,9 @@ size_t UserRepository::makeUser(User user) { w.commit(); manager->freeConnection(c); return r["id"].as(); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -63,9 +63,9 @@ void UserRepository::deleteByUserId(size_t user_id) { w.exec(sql); w.commit(); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -85,9 +85,9 @@ std::vector UserRepository::getAllUsers() { for (result::const_iterator k = r.begin(); k != r.end(); ++k) users.push_back(makeUser(k)); return users; - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } @@ -112,8 +112,8 @@ void UserRepository::update(User user) { work w(*c); w.exec(sql); manager->freeConnection(c); - } catch (const std::exception &e) { - std::cerr << e.what() << std::endl; - throw e; + } catch (...) { + + throw; } } diff --git a/server/internal/repository/tests/CMakeLists.txt b/server/internal/repository/tests/CMakeLists.txt index ad20fc9..23379e5 100644 --- a/server/internal/repository/tests/CMakeLists.txt +++ b/server/internal/repository/tests/CMakeLists.txt @@ -29,17 +29,6 @@ add_custom_target( COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME} ) -add_custom_target( - ${PROJECT_NAME}_COVERAGE - COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} -) - -add_custom_target( - ${PROJECT_NAME}_COVERAGE_FILE - COMMAND rm -r ${CMAKE_CURRENT_BINARY_DIR}/report || echo "There are no reports" - COMMAND mkdir ${CMAKE_CURRENT_BINARY_DIR}/report - COMMAND gcovr ${CMAKE_CURRENT_BINARY_DIR} -r ${CMAKE_CURRENT_SOURCE_DIR} --html-details report/report.html -) add_custom_target( ${PROJECT_NAME}_VALGRIND diff --git a/server/internal/repository/tests/RepositoryTests.cpp b/server/internal/repository/tests/RepositoryTests.cpp index 4af0790..b78c57c 100644 --- a/server/internal/repository/tests/RepositoryTests.cpp +++ b/server/internal/repository/tests/RepositoryTests.cpp @@ -5,6 +5,7 @@ #include "SolutionRepository.hpp" #include "TaskRepository.hpp" #include + TEST(UserRepository_CRUD_Test, CRUD) { UserRepository rep; @@ -45,7 +46,7 @@ TEST(TaskRepository_CRUD_Test, CRUD) { TEST(SolutionRepository_CRUD_Test, CRUD) { SolutionRepository rep; - Solution solution("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); + Solution solution("01.01.1970", 1, ":/C/Users", "tokens.txt", "tree.txt", 1, "result"); size_t id = rep.storeSolution(solution); EXPECT_NO_FATAL_FAILURE(rep.getSolutionById(1)); solution.setId(id); @@ -59,7 +60,7 @@ TEST(SolutionRepository_CRUD_Test, CRUD) { EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(new_solution)); } -TEST(MetricRepository_CRUD_Test, CRUD){ +TEST(MetricRepository_CRUD_Test, CRUD) { MetricRepository rep; MetricStat metricStat(1, 0.8f, 0.9f, 0.89f, true, 0.85f); size_t id = rep.storeMetric(metricStat); @@ -75,9 +76,10 @@ TEST(MetricRepository_CRUD_Test, CRUD){ EXPECT_NO_FATAL_FAILURE(rep.deleteMetric(new_stat)); } -TEST(UserRepository_CRUD_Test, CRUD_many) { +TEST(UserRepository_CRUD_Test, getAllUsers) { UserRepository rep; - std::vector v = {{"test@test.com", "test", "testuser"}, {"test2@test.com", "test2", "testuser2"}}; + std::vector v = {{"test@test.com", "test", "testuser"}, + {"test2@test.com", "test2", "testuser2"}}; EXPECT_NO_FATAL_FAILURE(rep.getAllUsers()); std::vector new_v = rep.getAllUsers(); EXPECT_EQ(v, new_v); @@ -99,15 +101,18 @@ TEST(UserRepository_CRUD_Test, loginLikeId) { TEST(SolutionRepository_CRUD_Test, CRUD_getSolutionsBySenderId) { SolutionRepository rep; - Solution solution1("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); - Solution solution2("01.01.1970", 1, "/home/usr","tokens.txt","tree.txt", 1, "result"); + Solution solution1("01.01.1970", 1, ":/C/Users", "tokens.txt", "tree.txt", 1, "result"); + Solution solution2("01.01.1970", 1, "/home/usr", "tokens.txt", "tree.txt", 1, "result"); size_t id1 = rep.storeSolution(solution1); solution1.setId(id1); + EXPECT_EQ(solution1, rep.getSolutionById(id1)); size_t id2 = rep.storeSolution(solution2); solution2.setId(id2); - std::vector v = {solution1, solution2}; - std::vector new_v = rep.getSolutionsBySenderId(solution1.getId()); + EXPECT_EQ(solution2, rep.getSolutionById(id2)); + std::vector v = {{id1, "01.01.1970", 1, ":/C/Users", "tokens.txt", "tree.txt", 1, "result"}, + {id2, "01.01.1970", 1, "/home/usr", "tokens.txt", "tree.txt", 1, "result"}}; + std::vector new_v = rep.getSolutionsBySenderId(solution1.getSenderId()); EXPECT_EQ(v, new_v); EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution1)); EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution2)); @@ -117,21 +122,50 @@ TEST(SolutionRepository_CRUD_Test, CRUD_getSolutionsBySenderId) { TEST(SolutionRepository_CRUD_Test, CRUD_getSolutionsByTaskId) { SolutionRepository rep; - Solution solution1("01.01.1970", 1, ":/C/Users","tokens.txt","tree.txt", 1, "result"); - Solution solution2("01.01.1970", 1, "/home/usr","tokens.txt","tree.txt", 1, "result"); + Solution solution1("01.01.1970", 1, ":/C/Users", "tokens.txt", "tree.txt", 1, "result"); + Solution solution2("01.01.1970", 1, "/home/usr", "tokens.txt", "tree.txt", 1, "result"); size_t id1 = rep.storeSolution(solution1); solution1.setId(id1); size_t id2 = rep.storeSolution(solution2); solution2.setId(id2); std::vector v = {solution1, solution2}; - std::vector new_v = rep.getSolutionsByTaskId(solution1.getId()); + std::vector new_v = rep.getSolutionsByTaskId(solution1.getTaskId()); EXPECT_EQ(v, new_v); EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution1)); EXPECT_NO_FATAL_FAILURE(rep.deleteSolution(solution2)); } +TEST(SolutionRepository_CRUD_Test, tryToAddWithNotExistingTask){ + SolutionRepository rep; + Solution solution("01.01.1970", 1, ":/C/Users", "tokens.txt", "tree.txt", 100500, "result"); + try{ + rep.storeSolution(solution); + }catch(pqxx::foreign_key_violation &e){ + std::cout<