diff --git a/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h b/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h index 6ee056e8d..29e009f90 100644 --- a/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h +++ b/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h @@ -1,213 +1,265 @@ #pragma once #include "../DatabaseManagers/entities/Media.h" #include "../DatabaseManagers/entities/Message.h" #include "DBOperationBase.h" #include "DatabaseManager.h" #include namespace comm { class RemoveMessagesOperation : public DBOperationBase { public: RemoveMessagesOperation(jsi::Runtime &rt, const jsi::Object &payload) : msg_ids_to_remove{} { auto payload_ids = payload.getProperty(rt, "ids").asObject(rt).asArray(rt); for (size_t idx = 0; idx < payload_ids.size(rt); idx++) { this->msg_ids_to_remove.push_back( payload_ids.getValueAtIndex(rt, idx).asString(rt).utf8(rt)); } } virtual void execute() override { DatabaseManager::getQueryExecutor().removeMessages(this->msg_ids_to_remove); DatabaseManager::getQueryExecutor().removeMediaForMessages( this->msg_ids_to_remove); } private: std::vector msg_ids_to_remove; }; class RemoveMessagesForThreadsOperation : public DBOperationBase { public: RemoveMessagesForThreadsOperation( jsi::Runtime &rt, const jsi::Object &payload) : thread_ids{} { auto payload_ids = payload.getProperty(rt, "threadIDs").asObject(rt).asArray(rt); for (size_t idx = 0; idx < payload_ids.size(rt); idx++) { this->thread_ids.push_back( payload_ids.getValueAtIndex(rt, idx).asString(rt).utf8(rt)); } } virtual void execute() override { DatabaseManager::getQueryExecutor().removeMessagesForThreads( this->thread_ids); DatabaseManager::getQueryExecutor().removeMediaForThreads(this->thread_ids); } private: std::vector thread_ids; }; class ReplaceMessageOperation : public DBOperationBase { public: ReplaceMessageOperation(jsi::Runtime &rt, const jsi::Object &payload) : media_vector{} { auto msg_id = payload.getProperty(rt, "id").asString(rt).utf8(rt); auto maybe_local_id = payload.getProperty(rt, "local_id"); auto local_id = maybe_local_id.isString() ? std::make_unique(maybe_local_id.asString(rt).utf8(rt)) : nullptr; auto thread = payload.getProperty(rt, "thread").asString(rt).utf8(rt); auto user = payload.getProperty(rt, "user").asString(rt).utf8(rt); auto type = std::stoi(payload.getProperty(rt, "type").asString(rt).utf8(rt)); auto maybe_future_type = payload.getProperty(rt, "future_type"); auto future_type = maybe_future_type.isString() ? std::make_unique( std::stoi(maybe_future_type.asString(rt).utf8(rt))) : nullptr; auto maybe_content = payload.getProperty(rt, "content"); auto content = maybe_content.isString() ? std::make_unique(maybe_content.asString(rt).utf8(rt)) : nullptr; auto time = std::stoll(payload.getProperty(rt, "time").asString(rt).utf8(rt)); this->msg = std::make_unique(Message{ msg_id, std::move(local_id), thread, user, type, std::move(future_type), std::move(content), time}); if (payload.getProperty(rt, "media_infos").isObject()) { auto media_infos = payload.getProperty(rt, "media_infos").asObject(rt).asArray(rt); for (size_t media_info_idx = 0; media_info_idx < media_infos.size(rt); media_info_idx++) { auto media_info = media_infos.getValueAtIndex(rt, media_info_idx).asObject(rt); auto media_id = media_info.getProperty(rt, "id").asString(rt).utf8(rt); auto media_uri = media_info.getProperty(rt, "uri").asString(rt).utf8(rt); auto media_type = media_info.getProperty(rt, "type").asString(rt).utf8(rt); auto media_extras = media_info.getProperty(rt, "extras").asString(rt).utf8(rt); this->media_vector.push_back(std::make_unique(Media{ media_id, msg_id, thread, media_uri, media_type, media_extras})); } } } virtual void execute() override { DatabaseManager::getQueryExecutor().removeMediaForMessage(msg->id); for (auto &&media : this->media_vector) { DatabaseManager::getQueryExecutor().replaceMedia(std::move(*media)); } DatabaseManager::getQueryExecutor().replaceMessage(std::move(*this->msg)); } private: std::unique_ptr msg; std::vector> media_vector; }; class RekeyMessageOperation : public DBOperationBase { public: RekeyMessageOperation(jsi::Runtime &rt, const jsi::Object &payload) { this->from = payload.getProperty(rt, "from").asString(rt).utf8(rt); this->to = payload.getProperty(rt, "to").asString(rt).utf8(rt); } virtual void execute() override { DatabaseManager::getQueryExecutor().rekeyMessage(this->from, this->to); DatabaseManager::getQueryExecutor().rekeyMediaContainers( this->from, this->to); } private: std::string from; std::string to; }; class RemoveAllMessagesOperation : public DBOperationBase { public: virtual void execute() override { DatabaseManager::getQueryExecutor().removeAllMessages(); DatabaseManager::getQueryExecutor().removeAllMedia(); } }; class ReplaceMessageThreadsOperation : public DBOperationBase { public: ReplaceMessageThreadsOperation(jsi::Runtime &rt, const jsi::Object &payload) : msg_threads{} { auto threads = payload.getProperty(rt, "threads").asObject(rt).asArray(rt); for (size_t idx = 0; idx < threads.size(rt); idx++) { auto thread = threads.getValueAtIndex(rt, idx).asObject(rt); auto thread_id = thread.getProperty(rt, "id").asString(rt).utf8(rt); auto start_reached = std::stoi( thread.getProperty(rt, "start_reached").asString(rt).utf8(rt)); MessageStoreThread msg_thread = MessageStoreThread{thread_id, start_reached}; this->msg_threads.push_back(msg_thread); } } virtual void execute() override { DatabaseManager::getQueryExecutor().replaceMessageStoreThreads( this->msg_threads); } private: std::vector msg_threads; }; class RemoveAllMessageStoreThreadsOperation : public DBOperationBase { public: virtual void execute() override { DatabaseManager::getQueryExecutor().removeAllMessageStoreThreads(); } }; class RemoveMessageStoreThreadsOperation : public DBOperationBase { public: RemoveMessageStoreThreadsOperation( jsi::Runtime &rt, const jsi::Object &payload) : thread_ids{} { auto payload_ids = payload.getProperty(rt, "ids").asObject(rt).asArray(rt); for (size_t idx = 0; idx < payload_ids.size(rt); idx++) { this->thread_ids.push_back( payload_ids.getValueAtIndex(rt, idx).asString(rt).utf8(rt)); } } virtual void execute() override { DatabaseManager::getQueryExecutor().removeMessageStoreThreads( this->thread_ids); } private: std::vector thread_ids; }; +class RemoveMessageStoreLocalMessageInfosOperation : public DBOperationBase { +public: + RemoveMessageStoreLocalMessageInfosOperation( + jsi::Runtime &rt, + const jsi::Object &payload) + : ids{} { + auto payload_ids = payload.getProperty(rt, "ids").asObject(rt).asArray(rt); + for (size_t idx = 0; idx < payload_ids.size(rt); idx++) { + this->ids.push_back( + payload_ids.getValueAtIndex(rt, idx).asString(rt).utf8(rt)); + } + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().removeMessageStoreLocalMessageInfos( + this->ids); + } + +private: + std::vector ids; +}; + +class ReplaceMessageStoreLocalMessageInfoOperation : public DBOperationBase { +public: + ReplaceMessageStoreLocalMessageInfoOperation( + jsi::Runtime &rt, + const jsi::Object &payload) + : localMessageInfo{} { + std::string id = payload.getProperty(rt, "id").asString(rt).utf8(rt); + std::string local_message_info = + payload.getProperty(rt, "localMessageInfo").asString(rt).utf8(rt); + + this->localMessageInfo = LocalMessageInfo{id, local_message_info}; + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().replaceMessageStoreLocalMessageInfo( + this->localMessageInfo); + } + +private: + LocalMessageInfo localMessageInfo; +}; + +class RemoveAllMessageStoreLocalMessageInfosOperation : public DBOperationBase { +public: + virtual void execute() override { + DatabaseManager::getQueryExecutor() + .removeAllMessageStoreLocalMessageInfos(); + } +}; + } // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.cpp index d3ce6e5f7..9260e5a5b 100644 --- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.cpp +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.cpp @@ -1,147 +1,164 @@ #include "MessageStore.h" #include "../../DBOperationBase.h" #include #include namespace comm { OperationType MessageStore::REKEY_OPERATION = "rekey"; OperationType MessageStore::REMOVE_OPERATION = "remove"; OperationType MessageStore::REPLACE_OPERATION = "replace"; OperationType MessageStore::REMOVE_MSGS_FOR_THREADS_OPERATION = "remove_messages_for_threads"; OperationType MessageStore::REMOVE_ALL_OPERATION = "remove_all"; OperationType MessageStore::REPLACE_MESSAGE_THREADS_OPERATION = "replace_threads"; OperationType MessageStore::REMOVE_MESSAGE_THREADS_OPERATION = "remove_threads"; OperationType MessageStore::REMOVE_ALL_MESSAGE_THREADS_OPERATION = "remove_all_threads"; +OperationType MessageStore::REPLACE_MESSAGE_STORE_LOCAL_MESSAGE_INFO_OPERATION = + "replace_local_message_info"; +OperationType MessageStore::REMOVE_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION = + "remove_local_message_infos"; +OperationType + MessageStore::REMOVE_ALL_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION = + "remove_all_local_message_infos"; + MessageStore::MessageStore( std::shared_ptr jsInvoker) : BaseDataStore(jsInvoker) { } jsi::Array MessageStore::parseDBDataStore( jsi::Runtime &rt, std::shared_ptr> messagesVectorPtr) const { size_t numMessages = messagesVectorPtr->size(); jsi::Array jsiMessages = jsi::Array(rt, numMessages); size_t writeIndex = 0; for (const auto &[message, media] : *messagesVectorPtr) { auto jsiMessage = jsi::Object(rt); jsiMessage.setProperty(rt, "id", message.id); if (message.local_id) { auto local_id = message.local_id.get(); jsiMessage.setProperty(rt, "local_id", *local_id); } jsiMessage.setProperty(rt, "thread", message.thread); jsiMessage.setProperty(rt, "user", message.user); jsiMessage.setProperty(rt, "type", std::to_string(message.type)); if (message.future_type) { auto future_type = message.future_type.get(); jsiMessage.setProperty(rt, "future_type", std::to_string(*future_type)); } if (message.content) { auto content = message.content.get(); jsiMessage.setProperty(rt, "content", *content); } jsiMessage.setProperty(rt, "time", std::to_string(message.time)); size_t media_idx = 0; jsi::Array jsiMediaArray = jsi::Array(rt, media.size()); for (const auto &media_info : media) { auto jsiMedia = jsi::Object(rt); jsiMedia.setProperty(rt, "id", media_info.id); jsiMedia.setProperty(rt, "uri", media_info.uri); jsiMedia.setProperty(rt, "type", media_info.type); jsiMedia.setProperty(rt, "extras", media_info.extras); jsiMediaArray.setValueAtIndex(rt, media_idx++, jsiMedia); } jsiMessage.setProperty(rt, "media_infos", jsiMediaArray); jsiMessages.setValueAtIndex(rt, writeIndex++, jsiMessage); } return jsiMessages; } std::vector> MessageStore::createOperations( jsi::Runtime &rt, const jsi::Array &operations) const { std::vector> messageStoreOps; for (auto idx = 0; idx < operations.size(rt); idx++) { auto op = operations.getValueAtIndex(rt, idx).asObject(rt); auto op_type = op.getProperty(rt, "type").asString(rt).utf8(rt); if (op_type == REMOVE_ALL_OPERATION) { messageStoreOps.push_back(std::make_unique()); continue; } if (op_type == REMOVE_ALL_MESSAGE_THREADS_OPERATION) { messageStoreOps.push_back( std::make_unique()); continue; } + if (op_type == REMOVE_ALL_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION) { + messageStoreOps.push_back( + std::make_unique()); + continue; + } auto payload_obj = op.getProperty(rt, "payload").asObject(rt); if (op_type == REMOVE_OPERATION) { messageStoreOps.push_back( std::make_unique(rt, payload_obj)); - } else if (op_type == REMOVE_MSGS_FOR_THREADS_OPERATION) { messageStoreOps.push_back( std::make_unique(rt, payload_obj)); - } else if (op_type == REPLACE_OPERATION) { messageStoreOps.push_back( std::make_unique(rt, payload_obj)); - } else if (op_type == REKEY_OPERATION) { messageStoreOps.push_back( std::make_unique(rt, payload_obj)); - } else if (op_type == REPLACE_MESSAGE_THREADS_OPERATION) { messageStoreOps.push_back( std::make_unique(rt, payload_obj)); } else if (op_type == REMOVE_MESSAGE_THREADS_OPERATION) { messageStoreOps.push_back( std::make_unique( rt, payload_obj)); + } else if (op_type == REPLACE_MESSAGE_STORE_LOCAL_MESSAGE_INFO_OPERATION) { + messageStoreOps.push_back( + std::make_unique( + rt, payload_obj)); + } else if (op_type == REMOVE_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION) { + messageStoreOps.push_back( + std::make_unique( + rt, payload_obj)); } else { throw std::runtime_error("unsupported operation: " + op_type); } } return messageStoreOps; } jsi::Array MessageStore::parseDBMessageStoreThreads( jsi::Runtime &rt, std::shared_ptr> threadsVectorPtr) const { size_t numThreads = threadsVectorPtr->size(); jsi::Array jsiThreads = jsi::Array(rt, numThreads); size_t writeIdx = 0; for (const MessageStoreThread &thread : *threadsVectorPtr) { jsi::Object jsiThread = jsi::Object(rt); jsiThread.setProperty(rt, "id", thread.id); jsiThread.setProperty( rt, "start_reached", std::to_string(thread.start_reached)); jsiThreads.setValueAtIndex(rt, writeIdx++, jsiThread); } return jsiThreads; } } // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.h index d2be4ce09..33b2179df 100644 --- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.h +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/MessageStore.h @@ -1,43 +1,52 @@ #pragma once #include "../../../DatabaseManagers/entities/Media.h" #include "../../../DatabaseManagers/entities/Message.h" #include "../../DBOperationBase.h" #include "BaseDataStore.h" #include "MessageStoreOperations.h" #include namespace comm { using MessageEntity = std::pair>; class MessageStore : public BaseDataStore { private: static OperationType REKEY_OPERATION; static OperationType REMOVE_OPERATION; static OperationType REPLACE_OPERATION; static OperationType REMOVE_MSGS_FOR_THREADS_OPERATION; static OperationType REMOVE_ALL_OPERATION; static OperationType REPLACE_MESSAGE_THREADS_OPERATION; static OperationType REMOVE_MESSAGE_THREADS_OPERATION; static OperationType REMOVE_ALL_MESSAGE_THREADS_OPERATION; + static OperationType REPLACE_MESSAGE_STORE_LOCAL_MESSAGE_INFO_OPERATION; + static OperationType REMOVE_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION; + static OperationType REMOVE_ALL_MESSAGE_STORE_LOCAL_MESSAGE_INFOS_OPERATION; + public: MessageStore(std::shared_ptr jsInvoker); std::vector> createOperations( jsi::Runtime &rt, const jsi::Array &operations) const override; jsi::Array parseDBDataStore( jsi::Runtime &rt, std::shared_ptr> dataVectorPtr) const override; jsi::Array parseDBMessageStoreThreads( jsi::Runtime &rt, std::shared_ptr> threadsVectorPtr) const; + + jsi::Array parseDBMessageStoreLocalMessageInfos( + jsi::Runtime &rt, + std::shared_ptr> localMessageInfosVectorPtr) + const; }; } // namespace comm