diff --git a/native/cpp/CommonCpp/NativeModules/CMakeLists.txt b/native/cpp/CommonCpp/NativeModules/CMakeLists.txt --- a/native/cpp/CommonCpp/NativeModules/CMakeLists.txt +++ b/native/cpp/CommonCpp/NativeModules/CMakeLists.txt @@ -26,6 +26,7 @@ "ThreadActivityStoreOperations.h" "EntryStoreOperations.h" "MessageSearchStoreOperations.h" + "DMOperationStoreOperations.h" ) set(NATIVE_SRCS @@ -95,6 +96,7 @@ ${_data_stores_path}/ThreadActivityStore.h ${_data_stores_path}/EntryStore.h ${_data_stores_path}/MessageSearchStore.h + ${_data_stores_path}/DMOperationStore.h ) set(DATA_STORES_SRCS ${_data_stores_path}/DraftStore.cpp @@ -110,6 +112,7 @@ ${_data_stores_path}/ThreadActivityStore.cpp ${_data_stores_path}/EntryStore.cpp ${_data_stores_path}/MessageSearchStore.cpp + ${_data_stores_path}/DMOperationStore.cpp ) set(_backup_op_path ./PersistentStorageUtilities/BackupOperationsUtilities) diff --git a/native/cpp/CommonCpp/NativeModules/DMOperationStoreOperations.h b/native/cpp/CommonCpp/NativeModules/DMOperationStoreOperations.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/DMOperationStoreOperations.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../DatabaseManagers/entities/DMOperation.h" +#include "DBOperationBase.h" +#include "DatabaseManager.h" +#include <vector> + +namespace comm { +class RemoveDMOperationsOperation : public DBOperationBase { +public: + RemoveDMOperationsOperation(std::vector<std::string> ids) : ids{ids} { + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().removeDMOperations(this->ids); + } + +private: + std::vector<std::string> ids; +}; + +class ReplaceDMOperationOperation : public DBOperationBase { +public: + ReplaceDMOperationOperation(DMOperation &&operation) + : operation{std::move(operation)} { + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().replaceDMOperation(this->operation); + } + +private: + DMOperation operation; +}; + +class RemoveAllDMOperationsOperation : public DBOperationBase { +public: + virtual void execute() override { + DatabaseManager::getQueryExecutor().removeAllDMOperations(); + } +}; + +} // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../../DatabaseManagers/entities/DMOperation.h" +#include "../../DBOperationBase.h" +#include "BaseDataStore.h" +#include "DMOperationStoreOperations.h" + +#include <jsi/jsi.h> + +namespace comm { + +class DMOperationStore : public BaseDataStore<DBOperationBase, DMOperation> { +private: + static OperationType REMOVE_OPERATION; + static OperationType REMOVE_ALL_OPERATION; + static OperationType REPLACE_OPERATION; + +public: + DMOperationStore(std::shared_ptr<facebook::react::CallInvoker> jsInvoker); + + std::vector<std::unique_ptr<DBOperationBase>> createOperations( + jsi::Runtime &rt, + const jsi::Array &operations) const override; + + jsi::Array parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr<std::vector<DMOperation>> dataVectorPtr) const override; +}; + +} // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/DMOperationStore.cpp @@ -0,0 +1,77 @@ +#include "DMOperationStore.h" + +#include "../../DBOperationBase.h" +#include <ReactCommon/TurboModuleUtils.h> +#include <jsi/jsi.h> + +namespace comm { +OperationType DMOperationStore::REMOVE_OPERATION = "remove_dm_operations"; +OperationType DMOperationStore::REMOVE_ALL_OPERATION = + "remove_all_dm_operations"; +OperationType DMOperationStore::REPLACE_OPERATION = "replace_dm_operation"; + +DMOperationStore::DMOperationStore( + std::shared_ptr<facebook::react::CallInvoker> jsInvoker) + : BaseDataStore(jsInvoker) { +} + +jsi::Array DMOperationStore::parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr<std::vector<DMOperation>> operationsVectorPtr) const { + size_t numOperations = operationsVectorPtr->size(); + jsi::Array jsiOperations = jsi::Array(rt, numOperations); + size_t writeIdx = 0; + for (const DMOperation &operation : *operationsVectorPtr) { + jsi::Object jsiOperation = jsi::Object(rt); + jsiOperation.setProperty(rt, "id", operation.id); + jsiOperation.setProperty(rt, "type", operation.type); + jsiOperation.setProperty(rt, "operation", operation.operation); + jsiOperations.setValueAtIndex(rt, writeIdx++, jsiOperation); + } + return jsiOperations; +} + +std::vector<std::unique_ptr<DBOperationBase>> +DMOperationStore::createOperations( + jsi::Runtime &rt, + const jsi::Array &operations) const { + std::vector<std::unique_ptr<DBOperationBase>> dmOperationStoreOps; + + for (size_t idx = 0; idx < operations.size(rt); idx++) { + jsi::Object op = operations.getValueAtIndex(rt, idx).asObject(rt); + std::string opType = op.getProperty(rt, "type").asString(rt).utf8(rt); + + if (opType == REMOVE_OPERATION) { + std::vector<std::string> idsToRemove; + jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); + jsi::Array ids = + payloadObj.getProperty(rt, "ids").asObject(rt).asArray(rt); + for (int i = 0; i < ids.size(rt); i++) { + idsToRemove.push_back(ids.getValueAtIndex(rt, i).asString(rt).utf8(rt)); + } + dmOperationStoreOps.push_back( + std::make_unique<RemoveDMOperationsOperation>( + std::move(idsToRemove))); + } else if (opType == REMOVE_ALL_OPERATION) { + dmOperationStoreOps.push_back( + std::make_unique<RemoveAllDMOperationsOperation>()); + } else if (opType == REPLACE_OPERATION) { + jsi::Object obj = op.getProperty(rt, "payload").asObject(rt); + std::string id = obj.getProperty(rt, "id").asString(rt).utf8(rt); + std::string type = obj.getProperty(rt, "type").asString(rt).utf8(rt); + std::string operation = + obj.getProperty(rt, "operation").asString(rt).utf8(rt); + + DMOperation dmOperation{id, type, operation}; + + dmOperationStoreOps.push_back( + std::make_unique<ReplaceDMOperationOperation>( + std::move(dmOperation))); + } else { + throw std::runtime_error("unsupported operation: " + opType); + } + }; + return dmOperationStoreOps; +} + +} // namespace comm diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj --- a/native/ios/Comm.xcodeproj/project.pbxproj +++ b/native/ios/Comm.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0E02677D2D81ED6600788249 /* DMOperationStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0E02677C2D81ED6600788249 /* DMOperationStore.cpp */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; @@ -144,6 +145,9 @@ /* Begin PBXFileReference section */ 0E02676D2D81EAD800788249 /* DMOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DMOperation.h; sourceTree = "<group>"; }; + 0E02677B2D81ED6600788249 /* DMOperationStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DMOperationStore.h; path = PersistentStorageUtilities/DataStores/DMOperationStore.h; sourceTree = "<group>"; }; + 0E02677C2D81ED6600788249 /* DMOperationStore.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DMOperationStore.cpp; path = PersistentStorageUtilities/DataStores/DMOperationStore.cpp; sourceTree = "<group>"; }; + 0E02677E2D81ED7B00788249 /* DMOperationStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DMOperationStoreOperations.h; sourceTree = "<group>"; }; 13B07F961A680F5B00A75B9A /* Comm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Comm.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Comm/AppDelegate.h; sourceTree = "<group>"; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Comm/AppDelegate.mm; sourceTree = "<group>"; }; @@ -502,6 +506,7 @@ 71BE843A2636A944002849D2 /* NativeModules */ = { isa = PBXGroup; children = ( + 0E02677E2D81ED7B00788249 /* DMOperationStoreOperations.h */, CBAB63872BFCB071003B089F /* EntryStoreOperations.h */, B3B02EBE2B8538860020D118 /* CommunityStoreOperations.h */, 34329B3E2B9EBD3400233438 /* IntegrityStoreOperations.h */, @@ -688,6 +693,8 @@ 8EA59BD02A6E786200EB4F53 /* DataStores */ = { isa = PBXGroup; children = ( + 0E02677B2D81ED6600788249 /* DMOperationStore.h */, + 0E02677C2D81ED6600788249 /* DMOperationStore.cpp */, 816D2D582C480E60001C0B67 /* MessageSearchStore.cpp */, 816D2D592C480E60001C0B67 /* MessageSearchStore.h */, CBAB63882BFCB087003B089F /* EntryStore.cpp */, @@ -1258,6 +1265,7 @@ DFD5E7862B052B1400C32B6A /* RustAESCrypto.cpp in Sources */, 816D2D5A2C480E60001C0B67 /* MessageSearchStore.cpp in Sources */, 8EF775712A751B780046A385 /* ReportStore.cpp in Sources */, + 0E02677D2D81ED6600788249 /* DMOperationStore.cpp in Sources */, 34329B442B9EC7EC00233438 /* IntegrityStore.cpp in Sources */, 71CA4A64262DA8E500835C89 /* Logger.mm in Sources */, 71BF5B7F26BBDD7400EDE27D /* CryptoModule.cpp in Sources */,