From 6adfd73a8acbb91e04ced07f28e22cf2dee9d374 Mon Sep 17 00:00:00 2001 From: Maksongold Date: Thu, 15 Apr 2021 17:06:13 +0300 Subject: [PATCH 1/6] "Added MainDb Interface and MainDb class using Cassandra cpp driver" --- .gitignore | 1 + CMakeLists.txt | 16 ++- project/include/IMainDb.hpp | 26 +++++ project/include/MainDb.hpp | 37 +++++++ project/include/Models.hpp | 197 +++++++++++++----------------------- project/src/MainDb.cpp | 57 +++++++++++ project/src/Models.cpp | 132 ++++++++++++++++++++++++ 7 files changed, 334 insertions(+), 132 deletions(-) create mode 100644 project/include/IMainDb.hpp create mode 100644 project/include/MainDb.hpp create mode 100644 project/src/MainDb.cpp create mode 100644 project/src/Models.cpp diff --git a/.gitignore b/.gitignore index d33340d..e5eb935 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ cmake-build-*/ .idea/ build/ +.vscode/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c615eb..ae195ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,8 @@ execute_process(COMMAND ${CMAKE_COMMAND} --build . add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src ${CMAKE_BINARY_DIR}/googletest-build) -set(CMAKE_C_FLAGS "-pedantic -fprofile-arcs -ftest-coverage -Wall -Werror -Wpedantic") -set(CMAKE_CXX_FLAGS "-pedantic -fprofile-arcs -ftest-coverage -Wall -Werror -Wpedantic") +set(CMAKE_C_FLAGS "-pedantic -Wall") +set(CMAKE_CXX_FLAGS "-pedantic -Wall") enable_testing() @@ -24,7 +24,14 @@ set(INCLUDE ${PROJECT_SOURCE_DIR}/project/include) set(SOURCE ${PROJECT_SOURCE_DIR}/project/src) # adding libs - +add_library(Models STATIC + ${INCLUDE}/Models.hpp + ${SOURCE}/Models.cpp) + +add_library(MainDb STATIC + ${INCLUDE}/MainDb.hpp + ${INCLUDE}/IMainDb.hpp + ${SOURCE}/MainDb.cpp) # end libs file(GLOB prod_sources @@ -32,6 +39,7 @@ file(GLOB prod_sources "${SOURCE}/main.cpp") add_executable(main.out ${SOURCE}/main.cpp) +target_link_libraries(main.out MainDb Models cassandra) file(GLOB tests "${PROJECT_SOURCE_DIR}/project/tests/*.cpp") list(REMOVE_ITEM tests "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") @@ -43,6 +51,6 @@ foreach(file ${tests}) ${SOURCE}/${name}.cpp ${file} "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") - target_link_libraries("${name}_tests" gtest_main) + target_link_libraries("${name}_tests" gtest_main gmock_main) add_test(NAME ${name} COMMAND "${name}_tests") endforeach() diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp new file mode 100644 index 0000000..784307c --- /dev/null +++ b/project/include/IMainDb.hpp @@ -0,0 +1,26 @@ +#ifndef PROJECT_INCLUDE_IMAINDB_HPP_ +#define PROJECT_INCLUDE_IMAINDB_HPP_ + +#include +#include "Models.hpp" + +class IMAinDb { + public: + virtual ~IMAinDb() = 0; + + virtual User* searchUserLogin(std::string login, std::string password) = 0; + virtual uint32_t writeUser (User& user) = 0; + virtual int updateUser (User& user) = 0; + + virtual std::string getCodeFromMessage(int messageId) = 0; + virtual void writeMessageToDialogue(Message message) = 0; + virtual std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, + uint32_t receiverId, long count) = 0; + + virtual std::vector * getDialoguessByUserId(int userId) = 0; + virtual uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) = 0; // return dialogId + virtual void deleteMessageFromDialogue(Message& message) = 0; + virtual void deleteDialogue(Dialogue& dialogue) = 0; +}; + +#endif // PROJECT_INCLUDE_IMAINDB_HPP_ diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp new file mode 100644 index 0000000..2debf37 --- /dev/null +++ b/project/include/MainDb.hpp @@ -0,0 +1,37 @@ +#ifndef PROJECT_INCLUDE_MAINDB_HPP_ +#define PROJECT_INCLUDE_MAINDB_HPP_ + +#include +#include +#include "IMainDb.hpp" +#include "Models.hpp" + +class MainDb : public IMAinDb { + public: + MainDb(); + ~MainDb(); + + User* searchUserLogin(std::string login, std::string password) override; + uint32_t writeUser (User& user) override; + int updateUser (User& user) override; + + std::string getCodeFromMessage(int messageId) override; + void writeMessageToDialogue(Message message) override; + std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, + uint32_t receiverId, long count) override; + + std::vector * getDialoguessByUserId(int userId) override; + uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) override; // return dialogId + void deleteMessageFromDialogue(Message& message) override; + void deleteDialogue(Dialogue& dialogue) override; + + void connectToDb(const char* contactPoints); + void disconnectFromDb(); + private: + CassFuture* connect_future_; + CassFuture* close_future_; + CassCluster* cluster_; + CassSession* session_; +}; + +#endif // PROJECT_INCLUDE_MAINDB_HPP_ diff --git a/project/include/Models.hpp b/project/include/Models.hpp index cdd9a5b..b28c9c3 100644 --- a/project/include/Models.hpp +++ b/project/include/Models.hpp @@ -9,10 +9,10 @@ class User { private: uint32_t userId_; - std::wstring userLogin_; - std::wstring userPassword_; + std::string userLogin_; + std::string userPassword_; std::vector userDialogueList_; - std::wstring userToken_; + std::string userToken_; int userStatus_; public: @@ -20,148 +20,101 @@ class User { ~User() = default; - User(uint32_t userId, std::wstring userLogin, std::wstring userPassword, + User(uint32_t userId, std::string userLogin, std::string userPassword, std::vector dialogueList, - std::wstring userToken, int userStatus) : + std::string userToken, int userStatus) : userLogin_(std::move(userLogin)), userPassword_(std::move(userPassword)), userDialogueList_(std::move(dialogueList)), userToken_(std::move(userToken)) { setUserId(userId); setStatus(userStatus); } - uint32_t getUserId() const { - return userId_; - } + uint32_t getUserId() const; - std::wstring getLogin() { - return userLogin_; - } + std::string getLogin(); - std::wstring getPassword() { - return userPassword_; - } + std::string getPassword(); - std::vector getDialogues() { - return userDialogueList_; - } + std::vector getDialogues(); - std::wstring getToken() { - return userToken_; - } + std::string getToken(); - int getStatus() const { - return userStatus_; - } + int getStatus() const; - void setUserId(uint32_t userId) { - userId_ = userId; - } + void setUserId(uint32_t userId); - void setLogin(const std::wstring &userLogin) { - userLogin_ = userLogin; - } + void setLogin(const std::string &userLogin); - void setPassword(const std::wstring &userPassword) { - userPassword_ = userPassword; - } + void setPassword(const std::string &userPassword); - void setDialogues(const std::vector &dialogueList) { - userDialogueList_ = dialogueList; - } + void setDialogues(const std::vector &dialogueList); - void setToken(const std::wstring &userToken) { - userToken_ = userToken; - } + void setToken(const std::string &userToken); - void setStatus(int userStatus) { - userStatus_ = userStatus; - } + void setStatus(int userStatus); }; class LoginData { public: LoginData() { - login_ = std::wstring(); - password_ = std::wstring(); + login_ = std::string(); + password_ = std::string(); loginType_ = -1; } - LoginData(const std::wstring &login, const std::wstring &password) { + LoginData(const std::string &login, const std::string &password) { login_ = login; password_ = password; loginType_ = 1; } - void setLogin(const std::wstring &login) { - login_ = login; - } + void setLogin(const std::string &login); - void setPassword(const std::wstring &password) { - password_ = password; - } + void setPassword(const std::string &password); - void setType(short type) { - loginType_ = type; - } + void setType(short type); - std::wstring getLogin() { - return login_; - } + std::string getLogin() const; - std::wstring getPassword() { - return password_; - } + std::string getPassword() const; - short get_type() const { - return loginType_; - } + short get_type() const; + bool operator== (const LoginData& ldt1) const; private: - std::wstring login_; - std::wstring password_; + std::string login_; + std::string password_; short loginType_; }; class Message { public: Message(uint32_t messageId, uint32_t dialogueParentId, uint32_t senderId, - std::wstring messageText, std::wstring messageCode, time_t timeSent) : + std::string messageText, std::string messageCode, time_t timeSent) : messageId_(messageId), dialogueParentId_(dialogueParentId), senderId_(senderId), messageText_(std::move(messageText)), messageCode_(std::move(messageCode)), timeSent_(timeSent) { } ~Message() = default; - uint32_t getMessageId() const { - return messageId_; - } + uint32_t getMessageId() const; - uint32_t getDialogueParentId() const { - return dialogueParentId_; - } + uint32_t getDialogueParentId() const; - uint32_t getSenderId() const { - return senderId_; - } + uint32_t getSenderId() const; - std::wstring getMessageText() { - return messageText_; - } + std::string getMessageText(); - std::wstring getMessageCode() { - return messageCode_; - } + std::string getMessageCode(); - time_t getTimeSent() const { - return timeSent_; - } + time_t getTimeSent() const; private: uint32_t messageId_; uint32_t dialogueParentId_; uint32_t senderId_; - std::wstring messageText_; - std::wstring messageCode_; + std::string messageText_; + std::string messageCode_; time_t timeSent_; }; @@ -172,29 +125,17 @@ class Dialogue { ~Dialogue() = default; - std::vector getParticipantsList() { - return participantsList_; - } + std::vector getParticipantsList(); - std::vector getDialogueMessageList() { - return dialogueMessageList_; - } + std::vector getDialogueMessageList(); - uint32_t getDialogueId() const { - return dialogueId_; - } + uint32_t getDialogueId() const; - void setDialogueId(uint32_t id) { - dialogueId_ = id; - } + void setDialogueId(uint32_t id); - void pushNewMessage(const Message& newMessage) { - dialogueMessageList_.push_back(newMessage); - } + void pushNewMessage(const Message& newMessage); - void pushNewParticipant(uint32_t newParticipantId) { - participantsList_.push_back(newParticipantId); - } + void pushNewParticipant(uint32_t newParticipantId); private: uint32_t dialogueId_; @@ -225,81 +166,81 @@ class Compilation { messageId_ = messageId; } - std::wstring getMessageCode() { + std::string getMessageCode() { return messageCode_; } - void setMessageCode(const std::wstring &messageCode) { + void setMessageCode(const std::string &messageCode) { messageCode_ = messageCode; } - std::wstring getCompilerStderr() { + std::string getCompilerStderr() { return compilerStderr_; } - void setCompilerStderr(const std::wstring &compilerStderr) { + void setCompilerStderr(const std::string &compilerStderr) { compilerStderr_ = compilerStderr; } - std::wstring getCompilerStdout() { + std::string getCompilerStdout() { return compilerStdout_; } - void setCompilerStdout(const std::wstring &compilerStdout) { + void setCompilerStdout(const std::string &compilerStdout) { compilerStdout_ = compilerStdout; } - std::wstring getExecutionStderr() { + std::string getExecutionStderr() { return executionStderr_; } - void setExecutionStderr(const std::wstring &executionStderr) { + void setExecutionStderr(const std::string &executionStderr) { executionStderr_ = executionStderr; } - std::wstring getExecutionStdin() { + std::string getExecutionStdin() { return executionStdin_; } - void setExecutionStdin(const std::wstring &executionStdin) { + void setExecutionStdin(const std::string &executionStdin) { executionStdin_ = executionStdin; } - std::wstring getExecutionStdout() { + std::string getExecutionStdout() { return executionStdout_; } - void setExecutionStdout(const std::wstring &executionStdout) { + void setExecutionStdout(const std::string &executionStdout) { executionStdout_ = executionStdout; } - std::wstring getExecutionUsedMemory() { + std::string getExecutionUsedMemory() { return executionUsedMemory_; } - void setExecutionUsedMemory(const std::wstring &executionUsedMemory) { + void setExecutionUsedMemory(const std::string &executionUsedMemory) { executionUsedMemory_ = executionUsedMemory; } - std::wstring getExecutionTime() { + std::string getExecutionTime() { return executionTime_; } - void setExecutionTime(const std::wstring &executionTime) { + void setExecutionTime(const std::string &executionTime) { executionTime_ = executionTime; } private: uint32_t compilationId_; uint32_t messageId_; - std::wstring messageCode_; - std::wstring compilerStderr_; - std::wstring compilerStdout_; - std::wstring executionStderr_; - std::wstring executionStdin_; - std::wstring executionStdout_; - std::wstring executionUsedMemory_; - std::wstring executionTime_; + std::string messageCode_; + std::string compilerStderr_; + std::string compilerStdout_; + std::string executionStderr_; + std::string executionStdin_; + std::string executionStdout_; + std::string executionUsedMemory_; + std::string executionTime_; }; -#endif // PROJECT_INCLUDE_MODELS_HPP_ +#endif // PROJECT_INCLUDE_MODELS_HPP_ \ No newline at end of file diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp new file mode 100644 index 0000000..43edd3e --- /dev/null +++ b/project/src/MainDb.cpp @@ -0,0 +1,57 @@ +#include "MainDb.hpp" + + MainDb::MainDb() { + CassFuture* connect_future_ = NULL; + CassFuture* close_future_ = NULL; + CassCluster* cluster_ = cass_cluster_new(); + CassSession* session_ = cass_session_new(); + } + MainDb::~MainDb() { + cass_future_free(connect_future_); + cass_future_free(close_future_); + cass_cluster_free(cluster_); + cass_session_free(session_); + } + + void MainDb::connectToDb(const char* contactPoints) { + cass_cluster_set_contact_points(cluster_, contactPoints); + connect_future_ = cass_session_connect(session_, cluster_); + } + void MainDb::disconnectFromDb() { + close_future_ = cass_session_close(session_); + cass_future_wait(close_future_); + cass_future_free(close_future_); + } + + User* MainDb::searchUserLogin(std::string login, std::string password) { + return new User; + } + uint32_t MainDb::writeUser(User& user) { + return rand(); + } + int MainDb::updateUser(User& user) { + return EXIT_SUCCESS; + } + + std::string MainDb::getCodeFromMessage(int messageId) { + return ""; + } + void MainDb::writeMessageToDialogue(Message message) { + } + std::vector * MainDb::getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, + uint32_t receiverId, long count) { + std::vector * messages = new std::vector ; + return messages; + } + + std::vector * MainDb::getDialoguessByUserId(int userId) { + std::vector * dialogues = new std::vector ; + return dialogues; + } + uint32_t MainDb::createDialogue(uint32_t senderId, uint32_t receiverId) { + return rand(); + } + void MainDb::deleteMessageFromDialogue(Message& message) { + } + void MainDb::deleteDialogue(Dialogue& dialogue) { + } diff --git a/project/src/Models.cpp b/project/src/Models.cpp new file mode 100644 index 0000000..132ff39 --- /dev/null +++ b/project/src/Models.cpp @@ -0,0 +1,132 @@ +#include "Models.hpp" + +uint32_t User::getUserId() const { + return userId_; +} + +std::string User::getLogin() { + return userLogin_; +} + +std::string User::getPassword() { + return userPassword_; +} + +std::vector User::getDialogues() { + return userDialogueList_; +} + +std::string User::getToken() { + return userToken_; +} + +int User::getStatus() const { + return userStatus_; +} + +void User::setUserId(uint32_t userId) { + userId_ = userId; +} + +void User::setLogin(const std::string &userLogin) { + userLogin_ = userLogin; +} + +void User::setPassword(const std::string &userPassword) { + userPassword_ = userPassword; +} + +void User::setDialogues(const std::vector &dialogueList) { + userDialogueList_ = dialogueList; +} + +void User::setToken(const std::string &userToken) { + userToken_ = userToken; +} + +void User::setStatus(int userStatus) { + userStatus_ = userStatus; +} + +void LoginData::setLogin(const std::string &login) { + login_ = login; +} + +void LoginData::setPassword(const std::string &password) { + password_ = password; +} + +void LoginData::setType(short type) { + loginType_ = type; +} + +std::string LoginData::getLogin() const { + return login_; +} + +std::string LoginData::getPassword() const { + return password_; +} + +short LoginData::get_type() const { + return loginType_; +} + +bool LoginData::operator==(const LoginData &ldt1) const { + if (login_ == ldt1.getLogin()) { + if (password_ == ldt1.getPassword()) { + if (loginType_ == ldt1.get_type()) { + return true; + } + } + } + return false; +} + +uint32_t Message::getMessageId() const { + return messageId_; +} + +uint32_t Message::getDialogueParentId() const { + return dialogueParentId_; +} + +uint32_t Message::getSenderId() const { + return senderId_; +} + +std::string Message::getMessageText() { + return messageText_; +} + +std::string Message::getMessageCode() { + return messageCode_; +} + +time_t Message::getTimeSent() const { + return timeSent_; +} + +std::vector Dialogue::getDialogueMessageList() { + return dialogueMessageList_; +} + +std::vector Dialogue::getParticipantsList() { + return participantsList_; +} + +uint32_t Dialogue::getDialogueId() const { + return dialogueId_; +} + +void Dialogue::setDialogueId(uint32_t id) { + dialogueId_ = id; +} + +void Dialogue::pushNewMessage(const Message &newMessage) { + dialogueMessageList_.push_back(newMessage); +} + +void Dialogue::pushNewParticipant(uint32_t newParticipantId) { + participantsList_.push_back(newParticipantId); +} \ No newline at end of file From 10a7aeda2a872c2cdb8629f64ec7a2eeee6b2b59 Mon Sep 17 00:00:00 2001 From: Maksongold Date: Thu, 15 Apr 2021 18:13:35 +0300 Subject: [PATCH 2/6] "Fixed smth and added 2 tests" --- CMakeLists.txt | 2 +- project/include/IMainDb.hpp | 6 ++--- project/include/MainDb.hpp | 4 +-- project/src/MainDb.cpp | 2 +- project/tests/MainDb.cpp | 49 +++++++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 project/tests/MainDb.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ae195ae..0519a92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,6 @@ foreach(file ${tests}) ${SOURCE}/${name}.cpp ${file} "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") - target_link_libraries("${name}_tests" gtest_main gmock_main) + target_link_libraries("${name}_tests" gtest_main gmock_main cassandra) add_test(NAME ${name} COMMAND "${name}_tests") endforeach() diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp index 784307c..bd21daa 100644 --- a/project/include/IMainDb.hpp +++ b/project/include/IMainDb.hpp @@ -4,15 +4,15 @@ #include #include "Models.hpp" -class IMAinDb { +class IMainDb { public: - virtual ~IMAinDb() = 0; + virtual ~IMainDb() = default; virtual User* searchUserLogin(std::string login, std::string password) = 0; virtual uint32_t writeUser (User& user) = 0; virtual int updateUser (User& user) = 0; - virtual std::string getCodeFromMessage(int messageId) = 0; + virtual std::string getCodeFromMessage(uint32_t messageId) = 0; virtual void writeMessageToDialogue(Message message) = 0; virtual std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, uint32_t receiverId, long count) = 0; diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp index 2debf37..e45f3a9 100644 --- a/project/include/MainDb.hpp +++ b/project/include/MainDb.hpp @@ -6,7 +6,7 @@ #include "IMainDb.hpp" #include "Models.hpp" -class MainDb : public IMAinDb { +class MainDb : public IMainDb { public: MainDb(); ~MainDb(); @@ -15,7 +15,7 @@ class MainDb : public IMAinDb { uint32_t writeUser (User& user) override; int updateUser (User& user) override; - std::string getCodeFromMessage(int messageId) override; + std::string getCodeFromMessage(uint32_t messageId) override; void writeMessageToDialogue(Message message) override; std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, uint32_t receiverId, long count) override; diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp index 43edd3e..c4c72d0 100644 --- a/project/src/MainDb.cpp +++ b/project/src/MainDb.cpp @@ -33,7 +33,7 @@ return EXIT_SUCCESS; } - std::string MainDb::getCodeFromMessage(int messageId) { + std::string MainDb::getCodeFromMessage(uint32_t messageId) { return ""; } void MainDb::writeMessageToDialogue(Message message) { diff --git a/project/tests/MainDb.cpp b/project/tests/MainDb.cpp new file mode 100644 index 0000000..9673846 --- /dev/null +++ b/project/tests/MainDb.cpp @@ -0,0 +1,49 @@ +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "../include/MainDb.hpp" +#include "../include/IMainDb.hpp" +#include +#include +#include +#include +using ::testing::Return; +class MockDb : public IMainDb { +public: + MOCK_METHOD(User*, searchUserLogin, (std::string login, std::string password), (override)); + MOCK_METHOD(uint32_t, writeUser, (User& user), (override)); + MOCK_METHOD(int, updateUser, (User& user), (override)); + MOCK_METHOD(std::string, getCodeFromMessage, (uint32_t messageId), (override)); + MOCK_METHOD(void, writeMessageToDialogue, (Message message), (override)); + MOCK_METHOD(std::vector *, getNMessagesFromDialogue, (uint32_t dialogueId, uint32_t senderId, + uint32_t receiverId, long count), (override)); + MOCK_METHOD(std::vector *, getDialoguessByUserId, (int userId), (override)); + MOCK_METHOD(uint32_t, createDialogue, (uint32_t senderId, uint32_t receiverId), (override)); + MOCK_METHOD(void, deleteMessageFromDialogue, (Message& message), (override)); + MOCK_METHOD(void, deleteDialogue, (Dialogue& dialogue), (override)); +}; + +TEST(searchUserLogin, InCorrectData) { + MockDb mock; + EXPECT_CALL(mock, searchUserLogin(std::string("log"), std::string("pas"))).WillOnce(Return(nullptr)); + EXPECT_EQ(mock.searchUserLogin(std::string("log"), std::string("pas")), nullptr); +} + +TEST(getCodeFromMessage, CorrectData) { + MockDb mock; + EXPECT_CALL(mock, getCodeFromMessage(23)).WillOnce(Return("")); + EXPECT_EQ(mock.getCodeFromMessage(23), ""); +} + +// TEST(writeUser, CorrectData) { +// MockDb mock; +// User user; +// EXPECT_CALL(mock, writeUser(user)).WillOnce(Return(921392)); +// EXPECT_EQ(mock.writeUser(user), 921392); +// } + +// TEST(updateUser, CorrectData) { +// MockDb mock; +// User user; +// EXPECT_CALL(mock, updateUser(user)).WillOnce(Return(0)); +// EXPECT_EQ(mock.updateUser(user), 0); +// } From cdf3f2b8a3f108ca3eaf2e5b10ebc17a94489924 Mon Sep 17 00:00:00 2001 From: Maksongold Date: Fri, 7 May 2021 19:01:04 +0300 Subject: [PATCH 3/6] "Wrote migration for cold start, wrote functions for User object, rewrite some models" --- CMakeLists.txt | 20 +-- project/include/IMainDb.hpp | 2 +- project/include/MainDb.hpp | 4 +- project/include/Models.hpp | 14 +- project/src/MainDb.cpp | 259 ++++++++++++++++++++++++++++++------ project/src/Models.cpp | 18 +-- project/src/main.cpp | 14 ++ project/tests/MainDb.cpp | 50 +++---- project/tests/main.cpp | 10 +- 9 files changed, 296 insertions(+), 95 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0519a92..a972816 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,13 +44,13 @@ target_link_libraries(main.out MainDb Models cassandra) file(GLOB tests "${PROJECT_SOURCE_DIR}/project/tests/*.cpp") list(REMOVE_ITEM tests "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") -foreach(file ${tests}) - set(name) - get_filename_component(name ${file} NAME_WE) - add_executable("${name}_tests" - ${SOURCE}/${name}.cpp - ${file} - "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") - target_link_libraries("${name}_tests" gtest_main gmock_main cassandra) - add_test(NAME ${name} COMMAND "${name}_tests") -endforeach() +# foreach(file ${tests}) +# set(name) +# get_filename_component(name ${file} NAME_WE) +# add_executable("${name}_tests" +# ${SOURCE}/${name}.cpp +# ${file} +# "${PROJECT_SOURCE_DIR}/project/tests/main.cpp") +# target_link_libraries("${name}_tests" gtest_main gmock_main cassandra) +# add_test(NAME ${name} COMMAND "${name}_tests") +# endforeach() diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp index bd21daa..a7addc2 100644 --- a/project/include/IMainDb.hpp +++ b/project/include/IMainDb.hpp @@ -9,7 +9,7 @@ class IMainDb { virtual ~IMainDb() = default; virtual User* searchUserLogin(std::string login, std::string password) = 0; - virtual uint32_t writeUser (User& user) = 0; + virtual void writeUser (User& user) = 0; virtual int updateUser (User& user) = 0; virtual std::string getCodeFromMessage(uint32_t messageId) = 0; diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp index e45f3a9..10821d6 100644 --- a/project/include/MainDb.hpp +++ b/project/include/MainDb.hpp @@ -12,7 +12,7 @@ class MainDb : public IMainDb { ~MainDb(); User* searchUserLogin(std::string login, std::string password) override; - uint32_t writeUser (User& user) override; + void writeUser (User& user) override; int updateUser (User& user) override; std::string getCodeFromMessage(uint32_t messageId) override; @@ -27,6 +27,8 @@ class MainDb : public IMainDb { void connectToDb(const char* contactPoints); void disconnectFromDb(); + + void migrate(); private: CassFuture* connect_future_; CassFuture* close_future_; diff --git a/project/include/Models.hpp b/project/include/Models.hpp index b28c9c3..d27aa0c 100644 --- a/project/include/Models.hpp +++ b/project/include/Models.hpp @@ -2,26 +2,28 @@ #define PROJECT_INCLUDE_MODELS_HPP_ #include +#include #include #include #include class User { private: - uint32_t userId_; std::string userLogin_; std::string userPassword_; - std::vector userDialogueList_; + std::vector userDialogueList_; std::string userToken_; int userStatus_; public: - User() = default; + User(std::string userLogin = std::string(), std::string userPassword = std::string(), + std::vector userDialogueList = {std::string()}, + std::string userToken = std::string(), int userStatus = 0); ~User() = default; User(uint32_t userId, std::string userLogin, std::string userPassword, - std::vector dialogueList, + std::vector dialogueList, std::string userToken, int userStatus) : userLogin_(std::move(userLogin)), userPassword_(std::move(userPassword)), userDialogueList_(std::move(dialogueList)), userToken_(std::move(userToken)) { @@ -35,7 +37,7 @@ class User { std::string getPassword(); - std::vector getDialogues(); + std::vector getDialogues(); std::string getToken(); @@ -47,7 +49,7 @@ class User { void setPassword(const std::string &userPassword); - void setDialogues(const std::vector &dialogueList); + void setDialogues(const std::vector &dialogueList); void setToken(const std::string &userToken); diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp index c4c72d0..aa5c7ac 100644 --- a/project/src/MainDb.cpp +++ b/project/src/MainDb.cpp @@ -1,57 +1,238 @@ +#include #include "MainDb.hpp" - MainDb::MainDb() { - CassFuture* connect_future_ = NULL; - CassFuture* close_future_ = NULL; - CassCluster* cluster_ = cass_cluster_new(); - CassSession* session_ = cass_session_new(); - } - MainDb::~MainDb() { +MainDb::MainDb() { + connect_future_ = NULL; + close_future_ = NULL; + cluster_ = cass_cluster_new(); + session_ = cass_session_new(); +} + +MainDb::~MainDb() { + if (connect_future_) { cass_future_free(connect_future_); + } + if (close_future_) { cass_future_free(close_future_); + } + if (cluster_) { cass_cluster_free(cluster_); + } + if (session_) { cass_session_free(session_); } +} - void MainDb::connectToDb(const char* contactPoints) { - cass_cluster_set_contact_points(cluster_, contactPoints); - connect_future_ = cass_session_connect(session_, cluster_); - } - void MainDb::disconnectFromDb() { - close_future_ = cass_session_close(session_); - cass_future_wait(close_future_); - cass_future_free(close_future_); - } - User* MainDb::searchUserLogin(std::string login, std::string password) { - return new User; - } - uint32_t MainDb::writeUser(User& user) { - return rand(); - } - int MainDb::updateUser(User& user) { - return EXIT_SUCCESS; - } +void MainDb::connectToDb(const char* contactPoints) { + cass_cluster_set_contact_points(cluster_, contactPoints); + connect_future_ = cass_session_connect(session_, cluster_); +// DEBUG + CassError rc = cass_future_error_code(connect_future_); - std::string MainDb::getCodeFromMessage(uint32_t messageId) { - return ""; + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(connect_future_, &message, &message_length); + fprintf(stderr, "Connect error: '%.*s'\n", (int)message_length, message); } - void MainDb::writeMessageToDialogue(Message message) { +// DEBUG + + migrate(); +} + +void MainDb::migrate() { + + const char* keyspaceQ = "CREATE KEYSPACE IF NOT EXISTS mainDB " // Keyspace and tables + "WITH REPLICATION = { 'class' : 'SimpleStrategy'," + "'replication_factor' : 1 };"; + const char* usersTQ = "CREATE TABLE IF NOT EXISTS mainDB.users_by_login (" + "login text PRIMARY KEY," + "password text," + "dialogues_id list" + ")" + ";"; + const char* dialoguesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.dialogues_by_id (" + "dialogue_id uuid PRIMARY KEY," + "participants_id list" + ")" + ";"; + const char* messagesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.messages_by_id (" + "message_id uuid PRIMARY KEY," + "dialogue_id int," + "sender_id int," + "message_text text," + "message_code text," + "time_sent timestamp," + "is_read boolean" + ")" + ";"; + + + CassStatement* keyspaceSt = cass_statement_new(keyspaceQ, 0); // made statement + CassFuture* ks_future = cass_session_execute(session_, keyspaceSt); + +// DEBUG + CassError rc = cass_future_error_code(ks_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(ks_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); } - std::vector * MainDb::getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, - uint32_t receiverId, long count) { - std::vector * messages = new std::vector ; - return messages; +// DEBUG + + CassStatement* usersByIdSt = cass_statement_new(usersTQ, 0); // made statement + CassFuture* user_by_id_future = cass_session_execute(session_, usersByIdSt); + + CassStatement* dialoguesByIdSt = cass_statement_new(dialoguesByIdTQ, 0); // made statement + CassFuture* dialogues_by_id_future = cass_session_execute(session_, dialoguesByIdSt); + + CassStatement* messagesByIdSt = cass_statement_new(messagesByIdTQ, 0); // made statement + CassFuture* messages_by_id_future = cass_session_execute(session_, messagesByIdSt); + + cass_statement_free(keyspaceSt); + cass_statement_free(messagesByIdSt); + cass_statement_free(dialoguesByIdSt); + cass_statement_free(usersByIdSt); + + cass_future_free(ks_future); + cass_future_free(messages_by_id_future); + cass_future_free(dialogues_by_id_future); + cass_future_free(user_by_id_future); +} + +void MainDb::disconnectFromDb() { + close_future_ = cass_session_close(session_); + cass_future_wait(close_future_); + cass_future_free(close_future_); +} + +User* MainDb::searchUserLogin(std::string login, std::string password) { // function pull dialogues_list + const char* searchUser = "SELECT dialogues_id FROM maindb.users_by_login " + "WHERE login = ? AND password = ? LIMIT 1 ALLOW FILTERING;"; + CassStatement* returnedUser = cass_statement_new(searchUser, 2); + cass_statement_bind_string(returnedUser, 0, login.data()); + cass_statement_bind_string(returnedUser, 1, password.data()); + CassFuture* returnedUser_future = cass_session_execute(session_, returnedUser); + + CassError rc = cass_future_error_code(returnedUser_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(returnedUser_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); } - std::vector * MainDb::getDialoguessByUserId(int userId) { - std::vector * dialogues = new std::vector ; - return dialogues; + const CassResult* result = cass_future_get_result(returnedUser_future); + + if (result == NULL) { // user doesn't exist or password is incorrect + return new User(); } - uint32_t MainDb::createDialogue(uint32_t senderId, uint32_t receiverId) { - return rand(); + + const CassRow* row = cass_result_first_row(result); + const CassValue* dialogues_column = cass_row_get_column_by_name(row, "dialogues_id"); + + std::vector dialogues_list; + CassIterator* dialogues_iterator = cass_iterator_from_collection(dialogues_column); + while (cass_iterator_next(dialogues_iterator)) { + const CassValue* current_dialogue = cass_iterator_get_value(dialogues_iterator); + + const char* dialogue_value; + size_t dialogue_value_length; + cass_value_get_string(current_dialogue, &dialogue_value, &dialogue_value_length); + + std::string temp_str = dialogue_value; + temp_str[dialogue_value_length] = '\0'; + + dialogues_list.push_back(temp_str); } - void MainDb::deleteMessageFromDialogue(Message& message) { + + cass_result_free(result); + cass_iterator_free(dialogues_iterator); + cass_statement_free(returnedUser); + cass_future_free(returnedUser_future); + + return new User(login, password, dialogues_list); +} + +void MainDb::writeUser(User& user) { + const char* insertUser = "INSERT INTO maindb.users_by_login " + "(login, password, dialogues_id) VALUES " + "(?, ?, ?)" + ";"; + + CassStatement* newUser = cass_statement_new(insertUser, 3); // made statement + + CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, user.getDialogues().size()); + for (int i = 0; i < user.getDialogues().size(); i++) { + cass_collection_append_string(list, user.getDialogues()[i].data()); } - void MainDb::deleteDialogue(Dialogue& dialogue) { + + cass_statement_bind_collection(newUser, 2, list); + cass_statement_bind_string(newUser, 1, user.getPassword().data()); + cass_statement_bind_string(newUser, 0, user.getLogin().data()); + + CassFuture* newUser_future = cass_session_execute(session_, newUser); + + cass_statement_free(newUser); + cass_future_free(newUser_future); +} + +int MainDb::updateUser(User& user) { + const char* updateUserQ = "UPDATE maindb.users_by_login " + "SET password = ?, " + "dialogues_id = ? " + "WHERE login = ?;"; + + CassStatement* newUser = cass_statement_new(updateUserQ, 3); // made statement + + CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, user.getDialogues().size()); + for (int i = 0; i < user.getDialogues().size(); i++) { + cass_collection_append_string(list, user.getDialogues()[i].data()); } + + cass_statement_bind_string(newUser, 2, user.getLogin().data()); + cass_statement_bind_collection(newUser, 1, list); + cass_statement_bind_string(newUser, 0, user.getPassword().data()); + + CassFuture* newUser_future = cass_session_execute(session_, newUser); + + cass_statement_free(newUser); + cass_future_free(newUser_future); + + return EXIT_SUCCESS; +} + +std::string MainDb::getCodeFromMessage(uint32_t messageId) { + return ""; +} + +void MainDb::writeMessageToDialogue(Message message) { +} + +std::vector * MainDb::getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, + uint32_t receiverId, long count) { + std::vector * messages = new std::vector ; + return messages; +} + +std::vector * MainDb::getDialoguessByUserId(int userId) { + std::vector * dialogues = new std::vector ; + return dialogues; +} + +uint32_t MainDb::createDialogue(uint32_t senderId, uint32_t receiverId) { + return rand(); +} + +void MainDb::deleteMessageFromDialogue(Message& message) { +} + +void MainDb::deleteDialogue(Dialogue& dialogue) { +} diff --git a/project/src/Models.cpp b/project/src/Models.cpp index 132ff39..fa544a4 100644 --- a/project/src/Models.cpp +++ b/project/src/Models.cpp @@ -1,7 +1,13 @@ #include "Models.hpp" -uint32_t User::getUserId() const { - return userId_; +User::User(std::string userLogin, std::string userPassword, + std::vector userDialogueList, + std::string userToken, int userStatus) : + userLogin_(userLogin), + userPassword_(userPassword), + userDialogueList_(userDialogueList), + userToken_(userToken), + userStatus_(userStatus) { } std::string User::getLogin() { @@ -12,7 +18,7 @@ std::string User::getPassword() { return userPassword_; } -std::vector User::getDialogues() { +std::vector User::getDialogues() { return userDialogueList_; } @@ -24,10 +30,6 @@ int User::getStatus() const { return userStatus_; } -void User::setUserId(uint32_t userId) { - userId_ = userId; -} - void User::setLogin(const std::string &userLogin) { userLogin_ = userLogin; } @@ -36,7 +38,7 @@ void User::setPassword(const std::string &userPassword) { userPassword_ = userPassword; } -void User::setDialogues(const std::vector &dialogueList) { +void User::setDialogues(const std::vector &dialogueList) { userDialogueList_ = dialogueList; } diff --git a/project/src/main.cpp b/project/src/main.cpp index 9a8a752..5d1a1cc 100644 --- a/project/src/main.cpp +++ b/project/src/main.cpp @@ -1,5 +1,19 @@ +#include #include "Models.hpp" +#include "MainDb.hpp" int main() { + // MainDb db; + // db.connectToDb("127.0.0.1"); + // User newUser("hui", "hui4", {"1", "huyy", "3"}, "online", 1); + // db.writeUser(newUser); + // User* result = db.searchUserLogin(newUser.getLogin(), newUser.getPassword()); + // std::cout << result->getLogin() << " " << result->getPassword() << std::endl; + // for (int i = 0; i < result->getDialogues().size(); i++) { + // std::cout << result->getDialogues()[i] << " "; + // } + // std::cout << std::endl; + // db.updateUser(newUser); + // db.disconnectFromDb(); return 0; } diff --git a/project/tests/MainDb.cpp b/project/tests/MainDb.cpp index 9673846..eeb8c7e 100644 --- a/project/tests/MainDb.cpp +++ b/project/tests/MainDb.cpp @@ -6,33 +6,33 @@ #include #include #include -using ::testing::Return; -class MockDb : public IMainDb { -public: - MOCK_METHOD(User*, searchUserLogin, (std::string login, std::string password), (override)); - MOCK_METHOD(uint32_t, writeUser, (User& user), (override)); - MOCK_METHOD(int, updateUser, (User& user), (override)); - MOCK_METHOD(std::string, getCodeFromMessage, (uint32_t messageId), (override)); - MOCK_METHOD(void, writeMessageToDialogue, (Message message), (override)); - MOCK_METHOD(std::vector *, getNMessagesFromDialogue, (uint32_t dialogueId, uint32_t senderId, - uint32_t receiverId, long count), (override)); - MOCK_METHOD(std::vector *, getDialoguessByUserId, (int userId), (override)); - MOCK_METHOD(uint32_t, createDialogue, (uint32_t senderId, uint32_t receiverId), (override)); - MOCK_METHOD(void, deleteMessageFromDialogue, (Message& message), (override)); - MOCK_METHOD(void, deleteDialogue, (Dialogue& dialogue), (override)); -}; +// using ::testing::Return; +// class MockDb : public IMainDb { +// public: +// MOCK_METHOD(User*, searchUserLogin, (std::string login, std::string password), (override)); +// MOCK_METHOD(void, writeUser, (User& user), (override)); +// MOCK_METHOD(int, updateUser, (User& user), (override)); +// MOCK_METHOD(std::string, getCodeFromMessage, (uint32_t messageId), (override)); +// MOCK_METHOD(void, writeMessageToDialogue, (Message message), (override)); +// MOCK_METHOD(std::vector *, getNMessagesFromDialogue, (uint32_t dialogueId, uint32_t senderId, +// uint32_t receiverId, long count), (override)); +// MOCK_METHOD(std::vector *, getDialoguessByUserId, (int userId), (override)); +// MOCK_METHOD(uint32_t, createDialogue, (uint32_t senderId, uint32_t receiverId), (override)); +// MOCK_METHOD(void, deleteMessageFromDialogue, (Message& message), (override)); +// MOCK_METHOD(void, deleteDialogue, (Dialogue& dialogue), (override)); +// }; -TEST(searchUserLogin, InCorrectData) { - MockDb mock; - EXPECT_CALL(mock, searchUserLogin(std::string("log"), std::string("pas"))).WillOnce(Return(nullptr)); - EXPECT_EQ(mock.searchUserLogin(std::string("log"), std::string("pas")), nullptr); -} +// TEST(searchUserLogin, InCorrectData) { +// MockDb mock; +// EXPECT_CALL(mock, searchUserLogin(std::string("log"), std::string("pas"))).WillOnce(Return(nullptr)); +// EXPECT_EQ(mock.searchUserLogin(std::string("log"), std::string("pas")), nullptr); +// } -TEST(getCodeFromMessage, CorrectData) { - MockDb mock; - EXPECT_CALL(mock, getCodeFromMessage(23)).WillOnce(Return("")); - EXPECT_EQ(mock.getCodeFromMessage(23), ""); -} +// TEST(getCodeFromMessage, CorrectData) { +// MockDb mock; +// EXPECT_CALL(mock, getCodeFromMessage(23)).WillOnce(Return("")); +// EXPECT_EQ(mock.getCodeFromMessage(23), ""); +// } // TEST(writeUser, CorrectData) { // MockDb mock; diff --git a/project/tests/main.cpp b/project/tests/main.cpp index dc42b1a..566168d 100644 --- a/project/tests/main.cpp +++ b/project/tests/main.cpp @@ -1,6 +1,6 @@ -#include "gtest/gtest.h" +// #include "gtest/gtest.h" -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} +// int main(int argc, char **argv) { +// ::testing::InitGoogleTest(&argc, argv); +// return RUN_ALL_TESTS(); +// } From a3417faca04ea2d9a01c54d691d5d8391b62b7b6 Mon Sep 17 00:00:00 2001 From: Maksongold Date: Fri, 14 May 2021 00:00:57 +0300 Subject: [PATCH 4/6] "Made fucntion with messages and dialogue, rewrite some models and types" --- project/include/IMainDb.hpp | 7 +- project/include/MainDb.hpp | 11 +- project/include/Models.hpp | 22 ++-- project/src/MainDb.cpp | 205 +++++++++++++++++++++++++++++++++--- project/src/Models.cpp | 10 +- project/src/main.cpp | 40 ++++--- 6 files changed, 248 insertions(+), 47 deletions(-) diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp index a7addc2..b894777 100644 --- a/project/include/IMainDb.hpp +++ b/project/include/IMainDb.hpp @@ -12,10 +12,9 @@ class IMainDb { virtual void writeUser (User& user) = 0; virtual int updateUser (User& user) = 0; - virtual std::string getCodeFromMessage(uint32_t messageId) = 0; - virtual void writeMessageToDialogue(Message message) = 0; - virtual std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, - uint32_t receiverId, long count) = 0; + virtual std::string getCodeFromMessage(std::string messageId) = 0; + virtual void writeMessage(Message& message) = 0; + virtual std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) = 0; virtual std::vector * getDialoguessByUserId(int userId) = 0; virtual uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) = 0; // return dialogId diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp index 10821d6..2798e0f 100644 --- a/project/include/MainDb.hpp +++ b/project/include/MainDb.hpp @@ -12,13 +12,12 @@ class MainDb : public IMainDb { ~MainDb(); User* searchUserLogin(std::string login, std::string password) override; - void writeUser (User& user) override; - int updateUser (User& user) override; + void writeUser(User& user) override; + int updateUser(User& user) override; - std::string getCodeFromMessage(uint32_t messageId) override; - void writeMessageToDialogue(Message message) override; - std::vector * getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, - uint32_t receiverId, long count) override; + std::string getCodeFromMessage(std::string messageId) override; + void writeMessage(Message& message) override; + std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) override; std::vector * getDialoguessByUserId(int userId) override; uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) override; // return dialogId diff --git a/project/include/Models.hpp b/project/include/Models.hpp index d27aa0c..775e5d7 100644 --- a/project/include/Models.hpp +++ b/project/include/Models.hpp @@ -91,19 +91,20 @@ class LoginData { class Message { public: - Message(uint32_t messageId, uint32_t dialogueParentId, uint32_t senderId, - std::string messageText, std::string messageCode, time_t timeSent) : + Message(std::string messageId, std::string dialogueParentId, std::string senderId, + std::string messageText, std::string messageCode, time_t timeSent, bool isRead) : messageId_(messageId), dialogueParentId_(dialogueParentId), senderId_(senderId), - messageText_(std::move(messageText)), messageCode_(std::move(messageCode)), timeSent_(timeSent) { + messageText_(std::move(messageText)), messageCode_(std::move(messageCode)), + timeSent_(timeSent), isRead_(isRead) { } ~Message() = default; - uint32_t getMessageId() const; + std::string getMessageId() const; - uint32_t getDialogueParentId() const; + std::string getDialogueParentId() const; - uint32_t getSenderId() const; + std::string getSenderId() const; std::string getMessageText(); @@ -111,13 +112,16 @@ class Message { time_t getTimeSent() const; + bool isRead(); + private: - uint32_t messageId_; - uint32_t dialogueParentId_; - uint32_t senderId_; + std::string messageId_; + std::string dialogueParentId_; + std::string senderId_; std::string messageText_; std::string messageCode_; time_t timeSent_; + bool isRead_; }; class Dialogue { diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp index aa5c7ac..5ab0676 100644 --- a/project/src/MainDb.cpp +++ b/project/src/MainDb.cpp @@ -1,4 +1,5 @@ #include +#include #include "MainDb.hpp" MainDb::MainDb() { @@ -55,19 +56,22 @@ void MainDb::migrate() { ";"; const char* dialoguesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.dialogues_by_id (" "dialogue_id uuid PRIMARY KEY," - "participants_id list" + "participants_logins list" ")" ";"; const char* messagesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.messages_by_id (" - "message_id uuid PRIMARY KEY," - "dialogue_id int," - "sender_id int," + "message_id uuid," + "dialogue_id uuid," + "sender_id uuid," "message_text text," "message_code text," "time_sent timestamp," - "is_read boolean" - ")" + "is_read boolean," + "PRIMARY KEY (message_id, dialogue_id, time_sent)" + ") " + "WITH CLUSTERING ORDER BY (dialogue_id ASC, time_sent DESC)" ";"; + const char* messageByIdIndForDialog = "CREATE INDEX IF NOT EXISTS ON mainDB.messages_by_id (dialogue_id);"; CassStatement* keyspaceSt = cass_statement_new(keyspaceQ, 0); // made statement @@ -94,6 +98,19 @@ void MainDb::migrate() { CassStatement* messagesByIdSt = cass_statement_new(messagesByIdTQ, 0); // made statement CassFuture* messages_by_id_future = cass_session_execute(session_, messagesByIdSt); + CassStatement* messagesByIdIndForDialogSt = cass_statement_new(messageByIdIndForDialog, 0); // made statement + CassFuture* messagesByIdIndForDialogSt_future = cass_session_execute(session_, messagesByIdIndForDialogSt); + + CassError rc1 = cass_future_error_code(messagesByIdIndForDialogSt_future); + + if (rc1 != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(messagesByIdIndForDialogSt_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } + cass_statement_free(keyspaceSt); cass_statement_free(messagesByIdSt); cass_statement_free(dialoguesByIdSt); @@ -130,12 +147,19 @@ User* MainDb::searchUserLogin(std::string login, std::string password) { // fun } const CassResult* result = cass_future_get_result(returnedUser_future); - - if (result == NULL) { // user doesn't exist or password is incorrect + if (result == NULL) { // throw exception + cass_statement_free(returnedUser); + cass_future_free(returnedUser_future); return new User(); } const CassRow* row = cass_result_first_row(result); + if (row == NULL) { // user doesn't exist or password is incorrect + cass_result_free(result); + cass_statement_free(returnedUser); + cass_future_free(returnedUser_future); + return new User(); + } const CassValue* dialogues_column = cass_row_get_column_by_name(row, "dialogues_id"); std::vector dialogues_list; @@ -209,16 +233,171 @@ int MainDb::updateUser(User& user) { return EXIT_SUCCESS; } -std::string MainDb::getCodeFromMessage(uint32_t messageId) { - return ""; +std::string MainDb::getCodeFromMessage(std::string messageId) { + const char* getCode = "SELECT message_code FROM maindb.messages_by_id " + "WHERE message_id = ?;"; + CassUuid uuid; + cass_uuid_from_string(messageId.data(), &uuid); + CassStatement* returnedCode = cass_statement_new(getCode, 1); + cass_statement_bind_uuid(returnedCode, 0, uuid); + CassFuture* returnedCode_future = cass_session_execute(session_, returnedCode); + + const CassResult* result = cass_future_get_result(returnedCode_future); + if (result == NULL) { // throw exception + cass_statement_free(returnedCode); + cass_future_free(returnedCode_future); + return ""; + } + const CassRow* row = cass_result_first_row(result); + + if (row == NULL) { // user doesn't exist or password is incorrect + cass_result_free(result); + cass_statement_free(returnedCode); + cass_future_free(returnedCode_future); + return ""; + } + + const CassValue* code_column = cass_row_get_column(row, 0); + + const char* code_value; + size_t code_value_length; + cass_value_get_string(code_column, &code_value, &code_value_length); + + std::string code = code_value; + + + cass_result_free(result); + cass_statement_free(returnedCode); + cass_future_free(returnedCode_future); + + return code; } -void MainDb::writeMessageToDialogue(Message message) { +void MainDb::writeMessage(Message& message) { + // exceptions if message is not full filled + if (message.getDialogueParentId() == "" || message.getMessageId() == "" + || message.getSenderId() == "" || message.getTimeSent() == 0) { + throw(-2); + } + const char* insertMessage = "INSERT INTO maindb.messages_by_id " + "(message_id, dialogue_id, sender_id, message_text, message_code, time_sent, is_read) VALUES " + "(?, ?, ?, ?, ?, ?, ?)" + ";"; + CassUuid uuid; + CassStatement* insertMessageSt = cass_statement_new(insertMessage, 7); + cass_uuid_from_string(message.getMessageId().data(), &uuid); + cass_statement_bind_uuid(insertMessageSt, 0, uuid); + + cass_uuid_from_string(message.getDialogueParentId().data(), &uuid); + cass_statement_bind_uuid(insertMessageSt, 1, uuid); + + cass_uuid_from_string(message.getSenderId().data(), &uuid); + cass_statement_bind_uuid(insertMessageSt, 2, uuid); + + cass_statement_bind_string(insertMessageSt, 3, message.getMessageText().data()); + cass_statement_bind_string(insertMessageSt, 4, message.getMessageCode().data()); + cass_statement_bind_int64(insertMessageSt, 5, message.getTimeSent()); + cass_statement_bind_bool(insertMessageSt, 6, (cass_bool_t)message.isRead()); + + CassFuture* insertMessageSt_future = cass_session_execute(session_, insertMessageSt); + + cass_statement_free(insertMessageSt); + cass_future_free(insertMessageSt_future); } -std::vector * MainDb::getNMessagesFromDialogue(uint32_t dialogueId, uint32_t senderId, - uint32_t receiverId, long count) { +std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, long count) { + char* getNMessagesQ = "SELECT * FROM maindb.messages_by_id " + "WHERE dialogue_id = ? LIMIT ?;"; + CassStatement* getNMessagesSt = cass_statement_new(getNMessagesQ, 2); + CassUuid uuid; + cass_uuid_from_string(dialogueId.data(), &uuid); + cass_statement_bind_uuid(getNMessagesSt, 0, uuid); + cass_statement_bind_int32(getNMessagesSt, 1, count); + CassFuture* getNMessagesSt_future = cass_session_execute(session_, getNMessagesSt); + + CassError rc = cass_future_error_code(getNMessagesSt_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(getNMessagesSt_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } + + const CassResult* result = cass_future_get_result(getNMessagesSt_future); + if (result == NULL) { // throw exception + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + return nullptr; + } + + if (cass_result_first_row(result) == NULL) { // user doesn't exist or password is incorrect + cass_result_free(result); + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + return nullptr; + } + + CassIterator* messages_iterator = cass_iterator_from_result(result); + std::vector * messages = new std::vector ; + + while (cass_iterator_next(messages_iterator)) { + const CassRow* row = cass_iterator_get_row(messages_iterator); + + CassUuid messageUuid; + char* messageUuidStr; + const CassValue* messageId = cass_row_get_column_by_name(row, "message_id"); + cass_value_get_uuid(messageId, &messageUuid); + cass_uuid_string(messageUuid, messageUuidStr); + + CassUuid dialogueUuid; + char* dialogueUuidStr; + const CassValue* dialogueId = cass_row_get_column_by_name(row, "dialogue_id"); + cass_value_get_uuid(dialogueId, &dialogueUuid); + cass_uuid_string(dialogueUuid, dialogueUuidStr); + + CassUuid senderUuid; + char* senderUuidStr; + const CassValue* senderId = cass_row_get_column_by_name(row, "sender_id"); + cass_value_get_uuid(senderId, &senderUuid); + cass_uuid_string(senderUuid, senderUuidStr); + + const char* messageTextStr; + size_t messageTextLength; + const CassValue* messageText = cass_row_get_column_by_name(row, "message_text"); + cass_value_get_string(messageText, &messageTextStr, &messageTextLength); + + const char* messageCodeStr; + size_t messageCodeLength; + const CassValue* messageCode = cass_row_get_column_by_name(row, "message_code"); + cass_value_get_string(messageCode, &messageCodeStr, &messageCodeLength); + + time_t messageTimeT; + const CassValue* messageTime = cass_row_get_column_by_name(row, "time_sent"); + cass_value_get_int64(messageTime, &messageTimeT); + + bool isReadB; + cass_bool_t cassBool; + const CassValue* isRead = cass_row_get_column_by_name(row, "is_read"); + cass_value_get_bool(isRead, &cassBool); + isReadB = cassBool; + + Message newMessage((std::string)messageUuidStr, (std::string)dialogueUuidStr, + (std::string)senderUuidStr, (std::string)messageTextStr, + (std::string)messageCodeStr, messageTimeT, isReadB); + + + messages->push_back(newMessage); + } + + + cass_result_free(result); + cass_iterator_free(messages_iterator); + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + return messages; } diff --git a/project/src/Models.cpp b/project/src/Models.cpp index fa544a4..f908517 100644 --- a/project/src/Models.cpp +++ b/project/src/Models.cpp @@ -85,15 +85,15 @@ bool LoginData::operator==(const LoginData &ldt1) const { return false; } -uint32_t Message::getMessageId() const { +std::string Message::getMessageId() const { return messageId_; } -uint32_t Message::getDialogueParentId() const { +std::string Message::getDialogueParentId() const { return dialogueParentId_; } -uint32_t Message::getSenderId() const { +std::string Message::getSenderId() const { return senderId_; } @@ -109,6 +109,10 @@ time_t Message::getTimeSent() const { return timeSent_; } +bool Message::isRead() { + return isRead_; +} + std::vector Dialogue::getDialogueMessageList() { return dialogueMessageList_; } diff --git a/project/src/main.cpp b/project/src/main.cpp index 5d1a1cc..8ffecdd 100644 --- a/project/src/main.cpp +++ b/project/src/main.cpp @@ -1,19 +1,35 @@ #include +#include #include "Models.hpp" #include "MainDb.hpp" int main() { - // MainDb db; - // db.connectToDb("127.0.0.1"); - // User newUser("hui", "hui4", {"1", "huyy", "3"}, "online", 1); - // db.writeUser(newUser); - // User* result = db.searchUserLogin(newUser.getLogin(), newUser.getPassword()); - // std::cout << result->getLogin() << " " << result->getPassword() << std::endl; - // for (int i = 0; i < result->getDialogues().size(); i++) { - // std::cout << result->getDialogues()[i] << " "; - // } - // std::cout << std::endl; - // db.updateUser(newUser); - // db.disconnectFromDb(); + MainDb db; + CassUuidGen* uuid_gen = cass_uuid_gen_new(); + CassUuid uuid, puuid, suuid; + char uuid_str[CASS_UUID_STRING_LENGTH]; + char puuid_str[CASS_UUID_STRING_LENGTH]; + char suuid_str[CASS_UUID_STRING_LENGTH]; + cass_uuid_gen_random(uuid_gen, &uuid); + cass_uuid_gen_random(uuid_gen, &puuid); + cass_uuid_gen_random(uuid_gen, &suuid); + cass_uuid_gen_free(uuid_gen); + cass_uuid_string(uuid, uuid_str); + cass_uuid_string(puuid, puuid_str); + cass_uuid_string(suuid, suuid_str); + + Message message(uuid_str, puuid_str, suuid_str, "ui12as3", "cout << trhrth", 333, false); + db.connectToDb("127.0.0.1"); + // std::string out = db.getCodeFromMessage("c033e0ba-aaaf-4ea1-94f7-301954e9d023"); + // db.writeMessage(message); + std::vector * messages = db.getNMessagesFromDialogue("25f9e3e6-e1ba-4ae2-b8d8-35b2617e5482", 1); + if (messages) { + for (const auto &message: *messages) { + std::cout << message.getMessageId() << std::endl; + } + } + + // std::cout << out << std::endl; + db.disconnectFromDb(); return 0; } From 8d97c401ec800221196ed75f428d8526b3b2b662 Mon Sep 17 00:00:00 2001 From: Maksongold Date: Sun, 16 May 2021 10:51:35 +0300 Subject: [PATCH 5/6] "Save unworked logic, before full refactoring database" --- project/include/IMainDb.hpp | 9 +- project/include/MainDb.hpp | 10 +- project/include/Models.hpp | 60 ++++----- project/src/MainDb.cpp | 250 +++++++++++++++++++++++++++++------- project/src/Models.cpp | 49 +++---- project/src/main.cpp | 10 +- 6 files changed, 270 insertions(+), 118 deletions(-) diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp index b894777..317015b 100644 --- a/project/include/IMainDb.hpp +++ b/project/include/IMainDb.hpp @@ -15,11 +15,14 @@ class IMainDb { virtual std::string getCodeFromMessage(std::string messageId) = 0; virtual void writeMessage(Message& message) = 0; virtual std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) = 0; + virtual DialogueList& getLastNDialoguesWithLastMessage(User user, long count) = 0; + - virtual std::vector * getDialoguessByUserId(int userId) = 0; - virtual uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) = 0; // return dialogId - virtual void deleteMessageFromDialogue(Message& message) = 0; + virtual std::vector * getDialogueListByLogin(std::string login) = 0; + virtual Dialogue createDialogue(std::string firstId, std::string secondId) = 0; + virtual void deleteMessage(Message& message) = 0; virtual void deleteDialogue(Dialogue& dialogue) = 0; + virtual std::vector getUsersByUserName(const User &findUser) const = 0; }; #endif // PROJECT_INCLUDE_IMAINDB_HPP_ diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp index 2798e0f..1c1b81a 100644 --- a/project/include/MainDb.hpp +++ b/project/include/MainDb.hpp @@ -16,12 +16,14 @@ class MainDb : public IMainDb { int updateUser(User& user) override; std::string getCodeFromMessage(std::string messageId) override; - void writeMessage(Message& message) override; + void writeMessage(Message& message) override; // проставить айдишник если не проставлен std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) override; + DialogueList& getLastNDialoguesWithLastMessage(User user, long count) override; - std::vector * getDialoguessByUserId(int userId) override; - uint32_t createDialogue(uint32_t senderId, uint32_t receiverId) override; // return dialogId - void deleteMessageFromDialogue(Message& message) override; + std::vector * getDialogueListByLogin(std::string login) override; + Dialogue createDialogue(std::string firstId, std::string secondId) override; + // std::string createDialogue(std::string senderId, std::string receiverId, std::string dialogueName) override; with yourself + void deleteMessage(Message& message) override; void deleteDialogue(Dialogue& dialogue) override; void connectToDb(const char* contactPoints); diff --git a/project/include/Models.hpp b/project/include/Models.hpp index 775e5d7..985c6bd 100644 --- a/project/include/Models.hpp +++ b/project/include/Models.hpp @@ -7,50 +7,45 @@ #include #include +struct ComparatorDialogue { + bool operator()(const Dialogue &lhs, const Dialogue &rhs) { + // return lhs.getMessage().getTimeSent() > rhs.getMessage().getTimeSent(); + } +}; +typedef std::multiset DialogueList; + class User { private: std::string userLogin_; std::string userPassword_; - std::vector userDialogueList_; std::string userToken_; + std::vector dialoguesList_; int userStatus_; public: - User(std::string userLogin = std::string(), std::string userPassword = std::string(), - std::vector userDialogueList = {std::string()}, - std::string userToken = std::string(), int userStatus = 0); - ~User() = default; - User(uint32_t userId, std::string userLogin, std::string userPassword, - std::vector dialogueList, - std::string userToken, int userStatus) : + User(std::string userLogin, std::string userPassword, + std::string userToken, std::vector dialoguesList_, int userStatus) : userLogin_(std::move(userLogin)), userPassword_(std::move(userPassword)), - userDialogueList_(std::move(dialogueList)), userToken_(std::move(userToken)) { - setUserId(userId); - setStatus(userStatus); + userToken_(std::move(userToken)), userStatus_(userStatus) { } - uint32_t getUserId() const; - - std::string getLogin(); - std::string getPassword(); + std::string getLogin() const; - std::vector getDialogues(); + std::string getPassword() const; - std::string getToken(); + std::string getToken() const; int getStatus() const; - void setUserId(uint32_t userId); + std::vector getDialoguesList() const; - void setLogin(const std::string &userLogin); + void addDialogueToList(std::string dialogueId); void setPassword(const std::string &userPassword); - void setDialogues(const std::vector &dialogueList); - void setToken(const std::string &userToken); void setStatus(int userStatus); @@ -126,27 +121,32 @@ class Message { class Dialogue { public: - explicit Dialogue(uint32_t dialogueId) : dialogueId_(dialogueId) { + Dialogue(std::string dialogueId, std::string dialogueName, + std::vector participantsList, + std::vector dialogueMessageList) : + dialogueId_(dialogueId), dialogueName_(dialogueName), + dialogueMessageList_(dialogueMessageList) { } ~Dialogue() = default; - std::vector getParticipantsList(); + std::vector getParticipantsList(); std::vector getDialogueMessageList(); - uint32_t getDialogueId() const; - - void setDialogueId(uint32_t id); + std::string getDialogueId() const; void pushNewMessage(const Message& newMessage); - void pushNewParticipant(uint32_t newParticipantId); + void pushNewParticipant(std::string newParticipantId); + + std::string getName(User& user) const; private: - uint32_t dialogueId_; + std::string dialogueId_; + std::string dialogueName_; std::vector dialogueMessageList_; - std::vector participantsList_; + std::vector participantsList_; }; @@ -249,4 +249,4 @@ class Compilation { std::string executionTime_; }; -#endif // PROJECT_INCLUDE_MODELS_HPP_ \ No newline at end of file +#endif // PROJECT_INCLUDE_MODELS_HPP_ diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp index 5ab0676..b229390 100644 --- a/project/src/MainDb.cpp +++ b/project/src/MainDb.cpp @@ -101,25 +101,18 @@ void MainDb::migrate() { CassStatement* messagesByIdIndForDialogSt = cass_statement_new(messageByIdIndForDialog, 0); // made statement CassFuture* messagesByIdIndForDialogSt_future = cass_session_execute(session_, messagesByIdIndForDialogSt); - CassError rc1 = cass_future_error_code(messagesByIdIndForDialogSt_future); - - if (rc1 != CASS_OK) { - /* Display connection error message */ - const char* message; - size_t message_length; - cass_future_error_message(messagesByIdIndForDialogSt_future, &message, &message_length); - fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); - } cass_statement_free(keyspaceSt); cass_statement_free(messagesByIdSt); cass_statement_free(dialoguesByIdSt); cass_statement_free(usersByIdSt); + cass_statement_free(messagesByIdIndForDialogSt); cass_future_free(ks_future); cass_future_free(messages_by_id_future); cass_future_free(dialogues_by_id_future); cass_future_free(user_by_id_future); + cass_future_free(messagesByIdIndForDialogSt_future); } void MainDb::disconnectFromDb() { @@ -129,11 +122,10 @@ void MainDb::disconnectFromDb() { } User* MainDb::searchUserLogin(std::string login, std::string password) { // function pull dialogues_list - const char* searchUser = "SELECT dialogues_id FROM maindb.users_by_login " - "WHERE login = ? AND password = ? LIMIT 1 ALLOW FILTERING;"; - CassStatement* returnedUser = cass_statement_new(searchUser, 2); + const char* searchUser = "SELECT * FROM maindb.users_by_login " + "WHERE login = ? LIMIT 1;"; + CassStatement* returnedUser = cass_statement_new(searchUser, 1); cass_statement_bind_string(returnedUser, 0, login.data()); - cass_statement_bind_string(returnedUser, 1, password.data()); CassFuture* returnedUser_future = cass_session_execute(session_, returnedUser); CassError rc = cass_future_error_code(returnedUser_future); @@ -150,7 +142,7 @@ User* MainDb::searchUserLogin(std::string login, std::string password) { // fun if (result == NULL) { // throw exception cass_statement_free(returnedUser); cass_future_free(returnedUser_future); - return new User(); + return nullptr; } const CassRow* row = cass_result_first_row(result); @@ -158,31 +150,36 @@ User* MainDb::searchUserLogin(std::string login, std::string password) { // fun cass_result_free(result); cass_statement_free(returnedUser); cass_future_free(returnedUser_future); - return new User(); + return nullptr; + } + const CassValue* passwordColumn = cass_row_get_column_by_name(row, "password"); + const char* passwordStr; + size_t passwordStrLength; + cass_value_get_string(passwordColumn, &passwordStr, &passwordStrLength); + if (passwordStr != login) { // password is incorrect + return nullptr; } - const CassValue* dialogues_column = cass_row_get_column_by_name(row, "dialogues_id"); - std::vector dialogues_list; - CassIterator* dialogues_iterator = cass_iterator_from_collection(dialogues_column); - while (cass_iterator_next(dialogues_iterator)) { - const CassValue* current_dialogue = cass_iterator_get_value(dialogues_iterator); + const CassValue* dialoguesColumn = cass_row_get_column_by_name(row, "dialogues_id"); - const char* dialogue_value; - size_t dialogue_value_length; - cass_value_get_string(current_dialogue, &dialogue_value, &dialogue_value_length); - - std::string temp_str = dialogue_value; - temp_str[dialogue_value_length] = '\0'; + std::vector dialoguesList; + CassIterator* dialoguesIterator = cass_iterator_from_collection(dialoguesColumn); + while (cass_iterator_next(dialoguesIterator)) { + const CassValue* currentDialogue = cass_iterator_get_value(dialoguesIterator); + + const char* dialogueStr; + size_t dialogueStrLength; + cass_value_get_string(currentDialogue, &dialogueStr, &dialogueStrLength); - dialogues_list.push_back(temp_str); + dialoguesList.push_back(dialogueStr); } cass_result_free(result); - cass_iterator_free(dialogues_iterator); + cass_iterator_free(dialoguesIterator); cass_statement_free(returnedUser); cass_future_free(returnedUser_future); - return new User(login, password, dialogues_list); + return new User(login, password, "", dialoguesList, 1); } void MainDb::writeUser(User& user) { @@ -193,9 +190,11 @@ void MainDb::writeUser(User& user) { CassStatement* newUser = cass_statement_new(insertUser, 3); // made statement - CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, user.getDialogues().size()); - for (int i = 0; i < user.getDialogues().size(); i++) { - cass_collection_append_string(list, user.getDialogues()[i].data()); + CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, + user.getDialoguesList().size()); + + for (int i = 0; i < user.getDialoguesList().size(); i++) { + cass_collection_append_string(list, user.getDialoguesList()[i].data()); } cass_statement_bind_collection(newUser, 2, list); @@ -216,9 +215,10 @@ int MainDb::updateUser(User& user) { CassStatement* newUser = cass_statement_new(updateUserQ, 3); // made statement - CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, user.getDialogues().size()); - for (int i = 0; i < user.getDialogues().size(); i++) { - cass_collection_append_string(list, user.getDialogues()[i].data()); + CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, + user.getDialoguesList().size()); + for (int i = 0; i < user.getDialoguesList().size(); i++) { + cass_collection_append_string(list, user.getDialoguesList()[i].data()); } cass_statement_bind_string(newUser, 2, user.getLogin().data()); @@ -262,7 +262,7 @@ std::string MainDb::getCodeFromMessage(std::string messageId) { const char* code_value; size_t code_value_length; cass_value_get_string(code_column, &code_value, &code_value_length); - + std::string code = code_value; @@ -307,7 +307,7 @@ void MainDb::writeMessage(Message& message) { std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, long count) { char* getNMessagesQ = "SELECT * FROM maindb.messages_by_id " - "WHERE dialogue_id = ? LIMIT ?;"; + "WHERE dialogue_id = ? LIMIT ?;"; CassStatement* getNMessagesSt = cass_statement_new(getNMessagesQ, 2); CassUuid uuid; cass_uuid_from_string(dialogueId.data(), &uuid); @@ -347,19 +347,19 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, const CassRow* row = cass_iterator_get_row(messages_iterator); CassUuid messageUuid; - char* messageUuidStr; + char messageUuidStr[CASS_UUID_STRING_LENGTH]; const CassValue* messageId = cass_row_get_column_by_name(row, "message_id"); cass_value_get_uuid(messageId, &messageUuid); cass_uuid_string(messageUuid, messageUuidStr); CassUuid dialogueUuid; - char* dialogueUuidStr; + char dialogueUuidStr[CASS_UUID_STRING_LENGTH]; const CassValue* dialogueId = cass_row_get_column_by_name(row, "dialogue_id"); cass_value_get_uuid(dialogueId, &dialogueUuid); cass_uuid_string(dialogueUuid, dialogueUuidStr); CassUuid senderUuid; - char* senderUuidStr; + char senderUuidStr[CASS_UUID_STRING_LENGTH]; const CassValue* senderId = cass_row_get_column_by_name(row, "sender_id"); cass_value_get_uuid(senderId, &senderUuid); cass_uuid_string(senderUuid, senderUuidStr); @@ -384,9 +384,9 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, cass_value_get_bool(isRead, &cassBool); isReadB = cassBool; - Message newMessage((std::string)messageUuidStr, (std::string)dialogueUuidStr, - (std::string)senderUuidStr, (std::string)messageTextStr, - (std::string)messageCodeStr, messageTimeT, isReadB); + Message newMessage(messageUuidStr, dialogueUuidStr, + senderUuidStr, messageTextStr, + messageCodeStr, messageTimeT, isReadB); messages->push_back(newMessage); @@ -401,16 +401,170 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, return messages; } -std::vector * MainDb::getDialoguessByUserId(int userId) { - std::vector * dialogues = new std::vector ; +std::vector * MainDb::getDialogueListByLogin(std::string login) { + const char* searchDialogues = "SELECT dialogues_id FROM maindb.users_by_login " + "WHERE login = ? LIMIT 1;"; + CassStatement* searchDialoguesSt = cass_statement_new(searchDialogues, 1); + cass_statement_bind_string(searchDialoguesSt, 0, login.data()); + CassFuture* searchDialoguesSt_future = cass_session_execute(session_, searchDialoguesSt); + + CassError rc = cass_future_error_code(searchDialoguesSt_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(searchDialoguesSt_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } + + const CassResult* result = cass_future_get_result(searchDialoguesSt_future); + if (result == NULL) { // throw exception + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); + return nullptr; + } + + const CassRow* row = cass_result_first_row(result); + if (row == NULL) { // user doesn't exist or password is incorrect + cass_result_free(result); + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); + return nullptr; + } + const CassValue* dialogues_column = cass_row_get_column(row, 0); + + std::vector * dialogues = new std::vector ; + + CassIterator* dialogues_iterator = cass_iterator_from_collection(dialogues_column); + while (cass_iterator_next(dialogues_iterator)) { + const CassValue* current_dialogue = cass_iterator_get_value(dialogues_iterator); + + const char* dialogue_value; + size_t dialogue_value_length; + cass_value_get_string(current_dialogue, &dialogue_value, &dialogue_value_length); + + std::string temp_str = dialogue_value; + temp_str[dialogue_value_length] = '\0'; + + dialogues->push_back(temp_str); + } + + cass_result_free(result); + cass_iterator_free(dialogues_iterator); + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); + return dialogues; } -uint32_t MainDb::createDialogue(uint32_t senderId, uint32_t receiverId) { - return rand(); +DialogueList& MainDb::getLastNDialoguesWithLastMessage(User user, long count) { + DialogueList returnedDialogues; + char* getNDialogues = "SELECT * FROM maindb.messages_by_id " + "WHERE dialogue_id = ? LIMIT ?;"; + CassStatement* getNMessagesSt = cass_statement_new(getNMessagesQ, 2); + CassUuid uuid; + cass_uuid_from_string(dialogueId.data(), &uuid); + cass_statement_bind_uuid(getNMessagesSt, 0, uuid); + cass_statement_bind_int32(getNMessagesSt, 1, count); + CassFuture* getNMessagesSt_future = cass_session_execute(session_, getNMessagesSt); + + CassError rc = cass_future_error_code(getNMessagesSt_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(getNMessagesSt_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } + + const CassResult* result = cass_future_get_result(getNMessagesSt_future); + if (result == NULL) { // throw exception + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + return nullptr; + } + + if (cass_result_first_row(result) == NULL) { // user doesn't exist or password is incorrect + cass_result_free(result); + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + return nullptr; + } + + CassIterator* messages_iterator = cass_iterator_from_result(result); + + std::vector * messages = new std::vector ; + + while (cass_iterator_next(messages_iterator)) { + const CassRow* row = cass_iterator_get_row(messages_iterator); + + CassUuid messageUuid; + char messageUuidStr[CASS_UUID_STRING_LENGTH]; + const CassValue* messageId = cass_row_get_column_by_name(row, "message_id"); + cass_value_get_uuid(messageId, &messageUuid); + cass_uuid_string(messageUuid, messageUuidStr); + + CassUuid dialogueUuid; + char dialogueUuidStr[CASS_UUID_STRING_LENGTH]; + const CassValue* dialogueId = cass_row_get_column_by_name(row, "dialogue_id"); + cass_value_get_uuid(dialogueId, &dialogueUuid); + cass_uuid_string(dialogueUuid, dialogueUuidStr); + + CassUuid senderUuid; + char senderUuidStr[CASS_UUID_STRING_LENGTH]; + const CassValue* senderId = cass_row_get_column_by_name(row, "sender_id"); + cass_value_get_uuid(senderId, &senderUuid); + cass_uuid_string(senderUuid, senderUuidStr); + + const char* messageTextStr; + size_t messageTextLength; + const CassValue* messageText = cass_row_get_column_by_name(row, "message_text"); + cass_value_get_string(messageText, &messageTextStr, &messageTextLength); + + const char* messageCodeStr; + size_t messageCodeLength; + const CassValue* messageCode = cass_row_get_column_by_name(row, "message_code"); + cass_value_get_string(messageCode, &messageCodeStr, &messageCodeLength); + + time_t messageTimeT; + const CassValue* messageTime = cass_row_get_column_by_name(row, "time_sent"); + cass_value_get_int64(messageTime, &messageTimeT); + + bool isReadB; + cass_bool_t cassBool; + const CassValue* isRead = cass_row_get_column_by_name(row, "is_read"); + cass_value_get_bool(isRead, &cassBool); + isReadB = cassBool; + + Message newMessage(messageUuidStr, dialogueUuidStr, + senderUuidStr, messageTextStr, + messageCodeStr, messageTimeT, isReadB); + + + messages->push_back(newMessage); + } + + + cass_result_free(result); + cass_iterator_free(messages_iterator); + cass_statement_free(getNMessagesSt); + cass_future_free(getNMessagesSt_future); + + return messages; +} + + + +Dialogue MainDb::createDialogue(std::string firstId, std::string secondId) { + std::vector a; + std::vector b; + + return Dialogue("", "", a, b); } -void MainDb::deleteMessageFromDialogue(Message& message) { +void MainDb::deleteMessage(Message& message) { } void MainDb::deleteDialogue(Dialogue& dialogue) { diff --git a/project/src/Models.cpp b/project/src/Models.cpp index f908517..5589cfc 100644 --- a/project/src/Models.cpp +++ b/project/src/Models.cpp @@ -1,28 +1,14 @@ #include "Models.hpp" -User::User(std::string userLogin, std::string userPassword, - std::vector userDialogueList, - std::string userToken, int userStatus) : - userLogin_(userLogin), - userPassword_(userPassword), - userDialogueList_(userDialogueList), - userToken_(userToken), - userStatus_(userStatus) { -} - -std::string User::getLogin() { +std::string User::getLogin() const { return userLogin_; } -std::string User::getPassword() { +std::string User::getPassword() const { return userPassword_; } -std::vector User::getDialogues() { - return userDialogueList_; -} - -std::string User::getToken() { +std::string User::getToken() const { return userToken_; } @@ -30,16 +16,16 @@ int User::getStatus() const { return userStatus_; } -void User::setLogin(const std::string &userLogin) { - userLogin_ = userLogin; +std::vector User::getDialoguesList() const { + return dialoguesList_; } -void User::setPassword(const std::string &userPassword) { - userPassword_ = userPassword; +void User::addDialogueToList(std::string dialogueId) { + dialoguesList_.push_back(dialogueId); } -void User::setDialogues(const std::vector &dialogueList) { - userDialogueList_ = dialogueList; +void User::setPassword(const std::string &userPassword) { + userPassword_ = userPassword; } void User::setToken(const std::string &userToken) { @@ -117,22 +103,27 @@ std::vector Dialogue::getDialogueMessageList() { return dialogueMessageList_; } -std::vector Dialogue::getParticipantsList() { +std::vector Dialogue::getParticipantsList() { return participantsList_; } -uint32_t Dialogue::getDialogueId() const { +std::string Dialogue::getDialogueId() const { return dialogueId_; } -void Dialogue::setDialogueId(uint32_t id) { - dialogueId_ = id; +std::string Dialogue::getName(User& user) const { + if (participantsList_[0] == user.getLogin()) { + return participantsList_[1]; + } else { + return participantsList_[0]; + } } + void Dialogue::pushNewMessage(const Message &newMessage) { dialogueMessageList_.push_back(newMessage); } -void Dialogue::pushNewParticipant(uint32_t newParticipantId) { +void Dialogue::pushNewParticipant(std::string newParticipantId) { participantsList_.push_back(newParticipantId); -} \ No newline at end of file +} diff --git a/project/src/main.cpp b/project/src/main.cpp index 8ffecdd..fd00f93 100644 --- a/project/src/main.cpp +++ b/project/src/main.cpp @@ -5,8 +5,8 @@ int main() { MainDb db; - CassUuidGen* uuid_gen = cass_uuid_gen_new(); - CassUuid uuid, puuid, suuid; + CassUuidGen* uuid_gen = cass_uuid_gen_new(); + CassUuid uuid, puuid, suuid; char uuid_str[CASS_UUID_STRING_LENGTH]; char puuid_str[CASS_UUID_STRING_LENGTH]; char suuid_str[CASS_UUID_STRING_LENGTH]; @@ -18,11 +18,13 @@ int main() { cass_uuid_string(puuid, puuid_str); cass_uuid_string(suuid, suuid_str); - Message message(uuid_str, puuid_str, suuid_str, "ui12as3", "cout << trhrth", 333, false); + Message message(uuid_str, "25f9e3e4-e1ba-4ae2-b8d8-35b2617e5482", suuid_str, "iuuas3", "cout << shhh", 323, false); db.connectToDb("127.0.0.1"); // std::string out = db.getCodeFromMessage("c033e0ba-aaaf-4ea1-94f7-301954e9d023"); // db.writeMessage(message); - std::vector * messages = db.getNMessagesFromDialogue("25f9e3e6-e1ba-4ae2-b8d8-35b2617e5482", 1); + // db.writeMessage(message); + // db.writeMessage(message); + std::vector * messages = db.getNMessagesFromDialogue("25f9e3e4-e1ba-4ae2-b8d8-35b2617e5482", 5); if (messages) { for (const auto &message: *messages) { std::cout << message.getMessageId() << std::endl; From 52ead84a10bff6c4bb8ae70cd7a8b4963388914e Mon Sep 17 00:00:00 2001 From: Maksongold Date: Sun, 16 May 2021 18:41:09 +0300 Subject: [PATCH 6/6] "Rewrite database, rewrite code, wrote necessary funcs for dialogues and messages" --- project/include/IMainDb.hpp | 16 +- project/include/MainDb.hpp | 16 +- project/include/Models.hpp | 29 ++- project/src/MainDb.cpp | 367 +++++++++++++++++++++--------------- project/src/Models.cpp | 6 +- project/src/main.cpp | 23 --- 6 files changed, 261 insertions(+), 196 deletions(-) diff --git a/project/include/IMainDb.hpp b/project/include/IMainDb.hpp index 317015b..0cdffcc 100644 --- a/project/include/IMainDb.hpp +++ b/project/include/IMainDb.hpp @@ -9,20 +9,22 @@ class IMainDb { virtual ~IMainDb() = default; virtual User* searchUserLogin(std::string login, std::string password) = 0; - virtual void writeUser (User& user) = 0; - virtual int updateUser (User& user) = 0; + virtual void writeUser(const User& user) = 0; + virtual void changePassword(const User& user) = 0; + virtual std::string getCodeFromMessage(std::string messageId) = 0; virtual void writeMessage(Message& message) = 0; - virtual std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) = 0; - virtual DialogueList& getLastNDialoguesWithLastMessage(User user, long count) = 0; - - virtual std::vector * getDialogueListByLogin(std::string login) = 0; + virtual std::vector getNLastMessagesFromDialogue(std::string dialogueId, long count) = 0; + virtual std::vector getParticipantsLoginsFromDialogue(std::string dialogueId) = 0; + virtual std::vector getAllDialoguesIdByLogin(std::string login) = 0; + virtual std::vector getLastNDialoguesIdByLogin(std::string login, long count) = 0; + virtual DialogueList getLastNDialoguesWithLastMessage(User user, long count) = 0; + virtual Dialogue createDialogue(std::string firstId, std::string secondId) = 0; virtual void deleteMessage(Message& message) = 0; virtual void deleteDialogue(Dialogue& dialogue) = 0; - virtual std::vector getUsersByUserName(const User &findUser) const = 0; }; #endif // PROJECT_INCLUDE_IMAINDB_HPP_ diff --git a/project/include/MainDb.hpp b/project/include/MainDb.hpp index 1c1b81a..aafb891 100644 --- a/project/include/MainDb.hpp +++ b/project/include/MainDb.hpp @@ -6,23 +6,27 @@ #include "IMainDb.hpp" #include "Models.hpp" +// getAllMessagesFromDialogue with PAGINATION +// updateMessageIsRead, messageText, messageCode class MainDb : public IMainDb { public: MainDb(); ~MainDb(); User* searchUserLogin(std::string login, std::string password) override; - void writeUser(User& user) override; - int updateUser(User& user) override; + void writeUser(const User& user) override; + void changePassword(const User& user) override; std::string getCodeFromMessage(std::string messageId) override; void writeMessage(Message& message) override; // проставить айдишник если не проставлен - std::vector * getNMessagesFromDialogue(std::string dialogueId, long count) override; - DialogueList& getLastNDialoguesWithLastMessage(User user, long count) override; + std::vector getNLastMessagesFromDialogue(std::string dialogueId, long count) override; + DialogueList getLastNDialoguesWithLastMessage(User user, long count) override; + std::vector getParticipantsLoginsFromDialogue(std::string dialogueId) override; - std::vector * getDialogueListByLogin(std::string login) override; + std::vector getAllDialoguesIdByLogin(std::string login) override; + std::vector getLastNDialoguesIdByLogin(std::string login, long count) override; Dialogue createDialogue(std::string firstId, std::string secondId) override; - // std::string createDialogue(std::string senderId, std::string receiverId, std::string dialogueName) override; with yourself + void deleteMessage(Message& message) override; void deleteDialogue(Dialogue& dialogue) override; diff --git a/project/include/Models.hpp b/project/include/Models.hpp index 985c6bd..5affcd6 100644 --- a/project/include/Models.hpp +++ b/project/include/Models.hpp @@ -7,19 +7,13 @@ #include #include -struct ComparatorDialogue { - bool operator()(const Dialogue &lhs, const Dialogue &rhs) { - // return lhs.getMessage().getTimeSent() > rhs.getMessage().getTimeSent(); - } -}; -typedef std::multiset DialogueList; class User { private: std::string userLogin_; std::string userPassword_; std::string userToken_; - std::vector dialoguesList_; + std::vector dialoguesList_; // do we need this?????? int userStatus_; public: @@ -31,6 +25,12 @@ class User { userToken_(std::move(userToken)), userStatus_(userStatus) { } + User(std::string userLogin, std::string userPassword, + std::string userToken, int userStatus) : + userLogin_(std::move(userLogin)), userPassword_(std::move(userPassword)), + userToken_(std::move(userToken)), userStatus_(userStatus) { + } + std::string getLogin() const; @@ -121,15 +121,17 @@ class Message { class Dialogue { public: - Dialogue(std::string dialogueId, std::string dialogueName, + Dialogue(std::string dialogueId, std::vector participantsList, std::vector dialogueMessageList) : - dialogueId_(dialogueId), dialogueName_(dialogueName), + dialogueId_(dialogueId), dialogueMessageList_(dialogueMessageList) { } ~Dialogue() = default; + Message getLastMessage() const; + std::vector getParticipantsList(); std::vector getDialogueMessageList(); @@ -144,7 +146,6 @@ class Dialogue { private: std::string dialogueId_; - std::string dialogueName_; std::vector dialogueMessageList_; std::vector participantsList_; }; @@ -249,4 +250,12 @@ class Compilation { std::string executionTime_; }; +struct ComparatorDialogue { + bool operator()(const Dialogue &lhs, const Dialogue &rhs) { + return lhs.getLastMessage().getTimeSent() > rhs.getLastMessage().getTimeSent(); + } +}; + +typedef std::multiset DialogueList; + #endif // PROJECT_INCLUDE_MODELS_HPP_ diff --git a/project/src/MainDb.cpp b/project/src/MainDb.cpp index b229390..09cc4f0 100644 --- a/project/src/MainDb.cpp +++ b/project/src/MainDb.cpp @@ -50,15 +50,22 @@ void MainDb::migrate() { "'replication_factor' : 1 };"; const char* usersTQ = "CREATE TABLE IF NOT EXISTS mainDB.users_by_login (" "login text PRIMARY KEY," - "password text," - "dialogues_id list" + "password text" ")" ";"; const char* dialoguesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.dialogues_by_id (" "dialogue_id uuid PRIMARY KEY," - "participants_logins list" + "participants_logins set" ")" ";"; + const char* userDialoguesTQ = "CREATE TABLE IF NOT EXISTS mainDB.user_dialogues (" + "login text," + "dialogue_id uuid," + "time_update timestamp," + "PRIMARY KEY(login, time_update)" + ") " + "WITH CLUSTERING ORDER BY (time_update DESC)" + ";"; const char* messagesByIdTQ = "CREATE TABLE IF NOT EXISTS mainDB.messages_by_id (" "message_id uuid," "dialogue_id uuid," @@ -90,13 +97,16 @@ void MainDb::migrate() { // DEBUG CassStatement* usersByIdSt = cass_statement_new(usersTQ, 0); // made statement - CassFuture* user_by_id_future = cass_session_execute(session_, usersByIdSt); + CassFuture* usersByIdSt_future = cass_session_execute(session_, usersByIdSt); CassStatement* dialoguesByIdSt = cass_statement_new(dialoguesByIdTQ, 0); // made statement - CassFuture* dialogues_by_id_future = cass_session_execute(session_, dialoguesByIdSt); + CassFuture* dialoguesByIdSt_future = cass_session_execute(session_, dialoguesByIdSt); + + CassStatement* userDialoguesSt = cass_statement_new(userDialoguesTQ, 0); // made statement + CassFuture* userDialoguesSt_future = cass_session_execute(session_, userDialoguesSt); CassStatement* messagesByIdSt = cass_statement_new(messagesByIdTQ, 0); // made statement - CassFuture* messages_by_id_future = cass_session_execute(session_, messagesByIdSt); + CassFuture* messagesByIdSt_future = cass_session_execute(session_, messagesByIdSt); CassStatement* messagesByIdIndForDialogSt = cass_statement_new(messageByIdIndForDialog, 0); // made statement CassFuture* messagesByIdIndForDialogSt_future = cass_session_execute(session_, messagesByIdIndForDialogSt); @@ -105,13 +115,15 @@ void MainDb::migrate() { cass_statement_free(keyspaceSt); cass_statement_free(messagesByIdSt); cass_statement_free(dialoguesByIdSt); + cass_statement_free(userDialoguesSt); cass_statement_free(usersByIdSt); cass_statement_free(messagesByIdIndForDialogSt); cass_future_free(ks_future); - cass_future_free(messages_by_id_future); - cass_future_free(dialogues_by_id_future); - cass_future_free(user_by_id_future); + cass_future_free(messagesByIdSt_future); + cass_future_free(dialoguesByIdSt_future); + cass_future_free(userDialoguesSt_future); + cass_future_free(usersByIdSt_future); cass_future_free(messagesByIdIndForDialogSt_future); } @@ -146,7 +158,7 @@ User* MainDb::searchUserLogin(std::string login, std::string password) { // fun } const CassRow* row = cass_result_first_row(result); - if (row == NULL) { // user doesn't exist or password is incorrect + if (row == NULL) { // user doesn't exist cass_result_free(result); cass_statement_free(returnedUser); cass_future_free(returnedUser_future); @@ -160,44 +172,21 @@ User* MainDb::searchUserLogin(std::string login, std::string password) { // fun return nullptr; } - const CassValue* dialoguesColumn = cass_row_get_column_by_name(row, "dialogues_id"); - - std::vector dialoguesList; - CassIterator* dialoguesIterator = cass_iterator_from_collection(dialoguesColumn); - while (cass_iterator_next(dialoguesIterator)) { - const CassValue* currentDialogue = cass_iterator_get_value(dialoguesIterator); - - const char* dialogueStr; - size_t dialogueStrLength; - cass_value_get_string(currentDialogue, &dialogueStr, &dialogueStrLength); - - dialoguesList.push_back(dialogueStr); - } - cass_result_free(result); - cass_iterator_free(dialoguesIterator); cass_statement_free(returnedUser); cass_future_free(returnedUser_future); - return new User(login, password, "", dialoguesList, 1); + return new User(login, password, "", 1); } -void MainDb::writeUser(User& user) { - const char* insertUser = "INSERT INTO maindb.users_by_login " - "(login, password, dialogues_id) VALUES " - "(?, ?, ?)" +void MainDb::writeUser(const User& user) { + const char* insertUser = "INSERT INTO maindb.users_by_login " + "(login, password) VALUES " + "(?, ?)" ";"; - CassStatement* newUser = cass_statement_new(insertUser, 3); // made statement - - CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, - user.getDialoguesList().size()); + CassStatement* newUser = cass_statement_new(insertUser, 2); // made statement - for (int i = 0; i < user.getDialoguesList().size(); i++) { - cass_collection_append_string(list, user.getDialoguesList()[i].data()); - } - - cass_statement_bind_collection(newUser, 2, list); cass_statement_bind_string(newUser, 1, user.getPassword().data()); cass_statement_bind_string(newUser, 0, user.getLogin().data()); @@ -207,30 +196,20 @@ void MainDb::writeUser(User& user) { cass_future_free(newUser_future); } -int MainDb::updateUser(User& user) { +void MainDb::changePassword(const User& user) { const char* updateUserQ = "UPDATE maindb.users_by_login " - "SET password = ?, " - "dialogues_id = ? " + "SET password = ? " "WHERE login = ?;"; - CassStatement* newUser = cass_statement_new(updateUserQ, 3); // made statement + CassStatement* newUser = cass_statement_new(updateUserQ, 2); // made statement - CassCollection* list = cass_collection_new(CASS_COLLECTION_TYPE_LIST, - user.getDialoguesList().size()); - for (int i = 0; i < user.getDialoguesList().size(); i++) { - cass_collection_append_string(list, user.getDialoguesList()[i].data()); - } - - cass_statement_bind_string(newUser, 2, user.getLogin().data()); - cass_statement_bind_collection(newUser, 1, list); + cass_statement_bind_string(newUser, 1, user.getLogin().data()); cass_statement_bind_string(newUser, 0, user.getPassword().data()); CassFuture* newUser_future = cass_session_execute(session_, newUser); cass_statement_free(newUser); cass_future_free(newUser_future); - - return EXIT_SUCCESS; } std::string MainDb::getCodeFromMessage(std::string messageId) { @@ -275,10 +254,10 @@ std::string MainDb::getCodeFromMessage(std::string messageId) { void MainDb::writeMessage(Message& message) { // exceptions if message is not full filled - if (message.getDialogueParentId() == "" || message.getMessageId() == "" - || message.getSenderId() == "" || message.getTimeSent() == 0) { - throw(-2); - } + // if (message.getDialogueParentId() == "" || message.getMessageId() == "" + // || message.getSenderLogin() == "" || message.getTimeSent() == 0) { + // throw(-2); + // } const char* insertMessage = "INSERT INTO maindb.messages_by_id " "(message_id, dialogue_id, sender_id, message_text, message_code, time_sent, is_read) VALUES " "(?, ?, ?, ?, ?, ?, ?)" @@ -291,7 +270,7 @@ void MainDb::writeMessage(Message& message) { cass_uuid_from_string(message.getDialogueParentId().data(), &uuid); cass_statement_bind_uuid(insertMessageSt, 1, uuid); - cass_uuid_from_string(message.getSenderId().data(), &uuid); + cass_uuid_from_string(message.getSenderLogin().data(), &uuid); cass_statement_bind_uuid(insertMessageSt, 2, uuid); cass_statement_bind_string(insertMessageSt, 3, message.getMessageText().data()); @@ -301,11 +280,52 @@ void MainDb::writeMessage(Message& message) { CassFuture* insertMessageSt_future = cass_session_execute(session_, insertMessageSt); + const char* getTimeUpdate = "SELECT time_update FROM mainDB.user_dialogues " + "WHERE dialogue_id = ?;"; + + CassStatement* getTimeUpdateSt = cass_statement_new(getTimeUpdate, 1); + cass_statement_bind_uuid(getTimeUpdateSt, 1, uuid); + CassFuture* getTimeUpdateSt_future = cass_session_execute(session_, getTimeUpdateSt); + + const CassResult* result = cass_future_get_result(getTimeUpdateSt_future); + if (result == NULL) { // throw exception + cass_statement_free(getTimeUpdateSt); + cass_future_free(getTimeUpdateSt_future); + return; + } + + if (cass_result_first_row(result) == NULL) { // exception + cass_result_free(result); + cass_statement_free(getTimeUpdateSt); + cass_future_free(getTimeUpdateSt_future); + return; + } + + const CassRow* row = cass_result_first_row(result); + const CassValue* timeSentValue = cass_row_get_column(row, 0); + time_t timeSent; + cass_value_get_int64(timeSentValue, &timeSent); + if (timeSent < message.getTimeSent()) { + const char* updateTime = "UPDATE mainDB.user_dialogues " + "SET time_update = ? " + "WHERE login = ? and dialogue_id = ?;"; + CassStatement* updateTimeSt = cass_statement_new(updateTime, 3); + cass_statement_bind_uuid(updateTimeSt, 2, uuid); + cass_statement_bind_string(updateTimeSt, 1, message.getSenderLogin().data()); + cass_statement_bind_int64(updateTimeSt, 0, message.getTimeSent()); + CassFuture* updateTimeSt_future = cass_session_execute(session_, updateTimeSt); + cass_statement_free(updateTimeSt); + cass_future_free(updateTimeSt_future); + } + cass_statement_free(insertMessageSt); + cass_statement_free(getTimeUpdateSt); cass_future_free(insertMessageSt_future); + cass_future_free(getTimeUpdateSt_future); } -std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, long count) { +std::vector MainDb::getNLastMessagesFromDialogue(std::string dialogueId, long count) { + std::vector messages; char* getNMessagesQ = "SELECT * FROM maindb.messages_by_id " "WHERE dialogue_id = ? LIMIT ?;"; CassStatement* getNMessagesSt = cass_statement_new(getNMessagesQ, 2); @@ -329,19 +349,18 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, if (result == NULL) { // throw exception cass_statement_free(getNMessagesSt); cass_future_free(getNMessagesSt_future); - return nullptr; + return messages; } if (cass_result_first_row(result) == NULL) { // user doesn't exist or password is incorrect cass_result_free(result); cass_statement_free(getNMessagesSt); cass_future_free(getNMessagesSt_future); - return nullptr; + return messages; } CassIterator* messages_iterator = cass_iterator_from_result(result); - std::vector * messages = new std::vector ; while (cass_iterator_next(messages_iterator)) { const CassRow* row = cass_iterator_get_row(messages_iterator); @@ -389,10 +408,9 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, messageCodeStr, messageTimeT, isReadB); - messages->push_back(newMessage); + messages.push_back(newMessage); } - cass_result_free(result); cass_iterator_free(messages_iterator); cass_statement_free(getNMessagesSt); @@ -401,9 +419,10 @@ std::vector * MainDb::getNMessagesFromDialogue(std::string dialogueId, return messages; } -std::vector * MainDb::getDialogueListByLogin(std::string login) { - const char* searchDialogues = "SELECT dialogues_id FROM maindb.users_by_login " - "WHERE login = ? LIMIT 1;"; +std::vector MainDb::getAllDialoguesIdByLogin(std::string login) { + std::vector dialoguesId; + const char* searchDialogues = "SELECT dialogue_id FROM maindb.user_dialogues " + "WHERE login = ?;"; CassStatement* searchDialoguesSt = cass_statement_new(searchDialogues, 1); cass_statement_bind_string(searchDialoguesSt, 0, login.data()); CassFuture* searchDialoguesSt_future = cass_session_execute(session_, searchDialoguesSt); @@ -419,10 +438,10 @@ std::vector * MainDb::getDialogueListByLogin(std::string login) { } const CassResult* result = cass_future_get_result(searchDialoguesSt_future); - if (result == NULL) { // throw exception + if (result == NULL) { cass_statement_free(searchDialoguesSt); cass_future_free(searchDialoguesSt_future); - return nullptr; + return dialoguesId; // throw exception } const CassRow* row = cass_result_first_row(result); @@ -430,24 +449,21 @@ std::vector * MainDb::getDialogueListByLogin(std::string login) { cass_result_free(result); cass_statement_free(searchDialoguesSt); cass_future_free(searchDialoguesSt_future); - return nullptr; + return dialoguesId; // throw exception } - const CassValue* dialogues_column = cass_row_get_column(row, 0); - std::vector * dialogues = new std::vector ; - CassIterator* dialogues_iterator = cass_iterator_from_collection(dialogues_column); + CassIterator* dialogues_iterator = cass_iterator_from_result(result); while (cass_iterator_next(dialogues_iterator)) { - const CassValue* current_dialogue = cass_iterator_get_value(dialogues_iterator); + const CassRow* row = cass_iterator_get_row(dialogues_iterator); - const char* dialogue_value; - size_t dialogue_value_length; - cass_value_get_string(current_dialogue, &dialogue_value, &dialogue_value_length); - - std::string temp_str = dialogue_value; - temp_str[dialogue_value_length] = '\0'; - - dialogues->push_back(temp_str); + CassUuid dialogueUuid; + char dialogueUuidStr[CASS_UUID_STRING_LENGTH]; + const CassValue* dialogueId = cass_row_get_column_by_name(row, "dialogue_id"); + cass_value_get_uuid(dialogueId, &dialogueUuid); + cass_uuid_string(dialogueUuid, dialogueUuidStr); + + dialoguesId.push_back(dialogueUuidStr); } cass_result_free(result); @@ -455,56 +471,47 @@ std::vector * MainDb::getDialogueListByLogin(std::string login) { cass_statement_free(searchDialoguesSt); cass_future_free(searchDialoguesSt_future); - return dialogues; + return dialoguesId; } -DialogueList& MainDb::getLastNDialoguesWithLastMessage(User user, long count) { - DialogueList returnedDialogues; - char* getNDialogues = "SELECT * FROM maindb.messages_by_id " - "WHERE dialogue_id = ? LIMIT ?;"; - CassStatement* getNMessagesSt = cass_statement_new(getNMessagesQ, 2); - CassUuid uuid; - cass_uuid_from_string(dialogueId.data(), &uuid); - cass_statement_bind_uuid(getNMessagesSt, 0, uuid); - cass_statement_bind_int32(getNMessagesSt, 1, count); - CassFuture* getNMessagesSt_future = cass_session_execute(session_, getNMessagesSt); +std::vector MainDb::getLastNDialoguesIdByLogin(std::string login, long count) { + std::vector dialoguesId; + const char* searchDialogues = "SELECT dialogue_id FROM maindb.user_dialogues " + "WHERE login = ? LIMIT = ?;"; + CassStatement* searchDialoguesSt = cass_statement_new(searchDialogues, 2); + cass_statement_bind_string(searchDialoguesSt, 0, login.data()); + cass_statement_bind_int32(searchDialoguesSt, 1, count); + CassFuture* searchDialoguesSt_future = cass_session_execute(session_, searchDialoguesSt); - CassError rc = cass_future_error_code(getNMessagesSt_future); + CassError rc = cass_future_error_code(searchDialoguesSt_future); if (rc != CASS_OK) { /* Display connection error message */ const char* message; size_t message_length; - cass_future_error_message(getNMessagesSt_future, &message, &message_length); + cass_future_error_message(searchDialoguesSt_future, &message, &message_length); fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); } - const CassResult* result = cass_future_get_result(getNMessagesSt_future); - if (result == NULL) { // throw exception - cass_statement_free(getNMessagesSt); - cass_future_free(getNMessagesSt_future); - return nullptr; + const CassResult* result = cass_future_get_result(searchDialoguesSt_future); + if (result == NULL) { + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); + return dialoguesId; // throw exception } - if (cass_result_first_row(result) == NULL) { // user doesn't exist or password is incorrect + const CassRow* row = cass_result_first_row(result); + if (row == NULL) { // user doesn't exist or password is incorrect cass_result_free(result); - cass_statement_free(getNMessagesSt); - cass_future_free(getNMessagesSt_future); - return nullptr; + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); + return dialoguesId; // throw exception } - CassIterator* messages_iterator = cass_iterator_from_result(result); - - std::vector * messages = new std::vector ; - while (cass_iterator_next(messages_iterator)) { - const CassRow* row = cass_iterator_get_row(messages_iterator); - - CassUuid messageUuid; - char messageUuidStr[CASS_UUID_STRING_LENGTH]; - const CassValue* messageId = cass_row_get_column_by_name(row, "message_id"); - cass_value_get_uuid(messageId, &messageUuid); - cass_uuid_string(messageUuid, messageUuidStr); + CassIterator* dialogues_iterator = cass_iterator_from_result(result); + while (cass_iterator_next(dialogues_iterator)) { + const CassRow* row = cass_iterator_get_row(dialogues_iterator); CassUuid dialogueUuid; char dialogueUuidStr[CASS_UUID_STRING_LENGTH]; @@ -512,56 +519,118 @@ DialogueList& MainDb::getLastNDialoguesWithLastMessage(User user, long count) { cass_value_get_uuid(dialogueId, &dialogueUuid); cass_uuid_string(dialogueUuid, dialogueUuidStr); - CassUuid senderUuid; - char senderUuidStr[CASS_UUID_STRING_LENGTH]; - const CassValue* senderId = cass_row_get_column_by_name(row, "sender_id"); - cass_value_get_uuid(senderId, &senderUuid); - cass_uuid_string(senderUuid, senderUuidStr); + dialoguesId.push_back(dialogueUuidStr); + } - const char* messageTextStr; - size_t messageTextLength; - const CassValue* messageText = cass_row_get_column_by_name(row, "message_text"); - cass_value_get_string(messageText, &messageTextStr, &messageTextLength); + cass_result_free(result); + cass_iterator_free(dialogues_iterator); + cass_statement_free(searchDialoguesSt); + cass_future_free(searchDialoguesSt_future); - const char* messageCodeStr; - size_t messageCodeLength; - const CassValue* messageCode = cass_row_get_column_by_name(row, "message_code"); - cass_value_get_string(messageCode, &messageCodeStr, &messageCodeLength); + return dialoguesId; +} - time_t messageTimeT; - const CassValue* messageTime = cass_row_get_column_by_name(row, "time_sent"); - cass_value_get_int64(messageTime, &messageTimeT); +std::vector MainDb::getParticipantsLoginsFromDialogue(std::string dialogueId) { + std::vector participantsLogins; + const char* searchUser = "SELECT participants_logins FROM maindb.dialogues_by_id " + "WHERE dialogue_id = ? LIMIT 1;"; + CassStatement* returnedUser = cass_statement_new(searchUser, 1); + cass_statement_bind_string(returnedUser, 0, dialogueId.data()); + CassFuture* returnedUser_future = cass_session_execute(session_, returnedUser); - bool isReadB; - cass_bool_t cassBool; - const CassValue* isRead = cass_row_get_column_by_name(row, "is_read"); - cass_value_get_bool(isRead, &cassBool); - isReadB = cassBool; + CassError rc = cass_future_error_code(returnedUser_future); - Message newMessage(messageUuidStr, dialogueUuidStr, - senderUuidStr, messageTextStr, - messageCodeStr, messageTimeT, isReadB); + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(returnedUser_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } - - messages->push_back(newMessage); + const CassResult* result = cass_future_get_result(returnedUser_future); + if (result == NULL) { // throw exception + cass_statement_free(returnedUser); + cass_future_free(returnedUser_future); + return participantsLogins; } + const CassRow* row = cass_result_first_row(result); + if (row == NULL) { // exception + cass_result_free(result); + cass_statement_free(returnedUser); + cass_future_free(returnedUser_future); + return participantsLogins; + } - cass_result_free(result); - cass_iterator_free(messages_iterator); - cass_statement_free(getNMessagesSt); - cass_future_free(getNMessagesSt_future); + const CassValue* dialoguesColumn = cass_row_get_column_by_name(row, "participants_logins"); - return messages; + CassIterator* dialoguesIterator = cass_iterator_from_collection(dialoguesColumn); + while (cass_iterator_next(dialoguesIterator)) { + const CassValue* currentDialogue = cass_iterator_get_value(dialoguesIterator); + + const char* dialogueStr; + size_t dialogueStrLength; + cass_value_get_string(currentDialogue, &dialogueStr, &dialogueStrLength); + + participantsLogins.push_back(dialogueStr); + } + return participantsLogins; } +DialogueList MainDb::getLastNDialoguesWithLastMessage(User user, long count) { + std::vector dialoguesId = getLastNDialoguesIdByLogin(user.getLogin(), count); + DialogueList dialogues; + + for (int i = 0; i < dialoguesId.size(); i++) { + std::vector messagesFromCurrDialogue = getNLastMessagesFromDialogue(dialoguesId[i], 1); + std::vector participantsList = getParticipantsLoginsFromDialogue(dialoguesId[i]); + Dialogue currDialogue(dialoguesId[i], participantsList, messagesFromCurrDialogue); + dialogues.emplace(); + } + + return dialogues; +} Dialogue MainDb::createDialogue(std::string firstId, std::string secondId) { - std::vector a; - std::vector b; + const char* newDialogue = "INSERT INTO maindb.dialogues_by_id (dialogue_id, participants_logins) " + "VALUES (?, ?);"; + CassStatement* newDialogueSt = cass_statement_new(newDialogue, 2); + CassUuidGen* uuidGen = cass_uuid_gen_new(); + CassUuid uuid; + + char uuidStr[CASS_UUID_STRING_LENGTH]; + + cass_uuid_gen_random(uuidGen, &uuid); + cass_uuid_gen_free(uuidGen); + cass_uuid_string(uuid, uuidStr); + + cass_statement_bind_uuid(newDialogueSt, 0, uuid); + + CassCollection* set = cass_collection_new(CASS_COLLECTION_TYPE_SET, 2); + + cass_collection_append_string(set, firstId.data()); + cass_collection_append_string(set, secondId.data()); + cass_statement_bind_collection(newDialogueSt, 1, set); + + CassFuture* newDialogueSt_future = cass_session_execute(session_, newDialogueSt); + + CassError rc = cass_future_error_code(newDialogueSt_future); + + if (rc != CASS_OK) { + /* Display connection error message */ + const char* message; + size_t message_length; + cass_future_error_message(newDialogueSt_future, &message, &message_length); + fprintf(stderr, "St error: '%.*s'\n", (int)message_length, message); + } + std::vector messages; + std::vector participants; + participants.push_back(firstId); + participants.push_back(secondId); - return Dialogue("", "", a, b); + return Dialogue(uuidStr, participants, messages); } void MainDb::deleteMessage(Message& message) { diff --git a/project/src/Models.cpp b/project/src/Models.cpp index 5589cfc..1959f41 100644 --- a/project/src/Models.cpp +++ b/project/src/Models.cpp @@ -12,6 +12,10 @@ std::string User::getToken() const { return userToken_; } +Message Dialogue::getLastMessage() const { + return *dialogueMessageList_.begin(); +} + int User::getStatus() const { return userStatus_; } @@ -121,7 +125,7 @@ std::string Dialogue::getName(User& user) const { void Dialogue::pushNewMessage(const Message &newMessage) { - dialogueMessageList_.push_back(newMessage); + dialogueMessageList_.insert(dialogueMessageList_.begin(), newMessage); } void Dialogue::pushNewParticipant(std::string newParticipantId) { diff --git a/project/src/main.cpp b/project/src/main.cpp index fd00f93..81ea98f 100644 --- a/project/src/main.cpp +++ b/project/src/main.cpp @@ -5,31 +5,8 @@ int main() { MainDb db; - CassUuidGen* uuid_gen = cass_uuid_gen_new(); - CassUuid uuid, puuid, suuid; - char uuid_str[CASS_UUID_STRING_LENGTH]; - char puuid_str[CASS_UUID_STRING_LENGTH]; - char suuid_str[CASS_UUID_STRING_LENGTH]; - cass_uuid_gen_random(uuid_gen, &uuid); - cass_uuid_gen_random(uuid_gen, &puuid); - cass_uuid_gen_random(uuid_gen, &suuid); - cass_uuid_gen_free(uuid_gen); - cass_uuid_string(uuid, uuid_str); - cass_uuid_string(puuid, puuid_str); - cass_uuid_string(suuid, suuid_str); - Message message(uuid_str, "25f9e3e4-e1ba-4ae2-b8d8-35b2617e5482", suuid_str, "iuuas3", "cout << shhh", 323, false); db.connectToDb("127.0.0.1"); - // std::string out = db.getCodeFromMessage("c033e0ba-aaaf-4ea1-94f7-301954e9d023"); - // db.writeMessage(message); - // db.writeMessage(message); - // db.writeMessage(message); - std::vector * messages = db.getNMessagesFromDialogue("25f9e3e4-e1ba-4ae2-b8d8-35b2617e5482", 5); - if (messages) { - for (const auto &message: *messages) { - std::cout << message.getMessageId() << std::endl; - } - } // std::cout << out << std::endl; db.disconnectFromDb();