diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h @@ -181,6 +181,8 @@ std::string threadID, std::optional<std::string> timestampCursor, std::optional<std::string> messageIDCursor) const = 0; + virtual std::vector<MessageEntity> getRelatedMessagesForSearch( + const std::vector<std::string> &messageIDs) const = 0; #ifdef EMSCRIPTEN virtual std::vector<WebThread> getAllThreadsWeb() const = 0; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h @@ -11,6 +11,7 @@ #include "entities/LocalMessageInfo.h" #include "entities/Media.h" #include "entities/Message.h" +#include "entities/MessageSearchResult.h" #include "entities/SQLiteStatementWrapper.h" #include "entities/ThreadActivityEntry.h" #include "entities/UserInfo.h" @@ -194,6 +195,8 @@ std::string threadID, std::optional<std::string> timestampCursor, std::optional<std::string> messageIDCursor) const override; + std::vector<MessageEntity> getRelatedMessagesForSearch( + const std::vector<std::string> &messageIDs) const override; #ifdef EMSCRIPTEN std::vector<WebThread> getAllThreadsWeb() const override; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp @@ -2594,6 +2594,50 @@ bindStringToSQL(messageIDCursor.value(), preparedSQL, 7); } + std::vector<MessageEntity> messages = + this->processMessagesResults(preparedSQL); + std::vector<std::string> messageIDs; + for (const auto &message : messages) { + messageIDs.push_back(message.first.id); + } + std::vector<MessageEntity> relatedMessages = + this->getRelatedMessagesForSearch(messageIDs); + + for (auto &entity : relatedMessages) { + messages.push_back(std::move(entity)); + } + return messages; +} + +std::vector<MessageEntity> SQLiteQueryExecutor::getRelatedMessagesForSearch( + const std::vector<std::string> &messageIDs) const { + std::stringstream selectRelatedMessagesSQLStream; + selectRelatedMessagesSQLStream << "SELECT * " + "FROM messages " + "LEFT JOIN media " + " ON messages.id = media.container " + "WHERE messages.target_message IN " + << getSQLStatementArray(messageIDs.size()) + << "ORDER BY messages.time DESC"; + + std::string selectRelatedMessagesSQL = selectRelatedMessagesSQLStream.str(); + + SQLiteStatementWrapper preparedSQL( + SQLiteQueryExecutor::getConnection(), + selectRelatedMessagesSQL, + "Failed to fetch related messages."); + + for (int i = 0; i < messageIDs.size(); i++) { + int bindResult = bindStringToSQL(messageIDs[i], preparedSQL, i + 1); + if (bindResult != SQLITE_OK) { + std::stringstream error_message; + error_message << "Failed to bind key to SQL statement. Details: " + << sqlite3_errstr(bindResult) << std::endl; + sqlite3_finalize(preparedSQL); + throw std::runtime_error(error_message.str()); + } + } + return this->processMessagesResults(preparedSQL); } diff --git a/web/shared-worker/_generated/comm_query_executor.wasm b/web/shared-worker/_generated/comm_query_executor.wasm index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001 literal 0 Hc$@<O00001 diff --git a/web/shared-worker/queries/message-search.test.js b/web/shared-worker/queries/message-search.test.js --- a/web/shared-worker/queries/message-search.test.js +++ b/web/shared-worker/queries/message-search.test.js @@ -154,7 +154,7 @@ queryExecutor.updateMessageSearchIndex(id1, id2, text2); const result = queryExecutor.searchMessages('test', threadID, null, null); - expect(result.length).toBe(1); + expect(result.length).toBe(2); expect(result[0].message).toStrictEqual(matchingMessage); });