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 @@ -27,6 +27,7 @@ "EntryStoreOperations.h" "MessageSearchStoreOperations.h" "DMOperationStoreOperations.h" + "HolderStoreOperations.h" ) set(NATIVE_SRCS @@ -97,6 +98,7 @@ ${_data_stores_path}/EntryStore.h ${_data_stores_path}/MessageSearchStore.h ${_data_stores_path}/DMOperationStore.h + ${_data_stores_path}/HolderStore.h ) set(DATA_STORES_SRCS ${_data_stores_path}/DraftStore.cpp @@ -113,6 +115,7 @@ ${_data_stores_path}/EntryStore.cpp ${_data_stores_path}/MessageSearchStore.cpp ${_data_stores_path}/DMOperationStore.cpp + ${_data_stores_path}/HolderStore.cpp ) set(_backup_op_path ./PersistentStorageUtilities/BackupOperationsUtilities) diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h @@ -11,6 +11,7 @@ #include "PersistentStorageUtilities/DataStores/DMOperationStore.h" #include "PersistentStorageUtilities/DataStores/DraftStore.h" #include "PersistentStorageUtilities/DataStores/EntryStore.h" +#include "PersistentStorageUtilities/DataStores/HolderStore.h" #include "PersistentStorageUtilities/DataStores/IntegrityStore.h" #include "PersistentStorageUtilities/DataStores/KeyserverStore.h" #include "PersistentStorageUtilities/DataStores/MessageSearchStore.h" @@ -51,6 +52,7 @@ EntryStore entryStore; MessageSearchStore messageSearchStore; DMOperationStore dmOperationStore; + HolderStore holderStore; void persistCryptoModules( bool persistContentModule, diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp --- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp @@ -79,6 +79,7 @@ std::vector entryStoreVector; std::vector messageStoreLocalMessageInfosVector; std::vector dmOperationsVector; + std::vector holdersVector; try { draftsVector = DatabaseManager::getQueryExecutor(identifier).getAllDrafts(); @@ -114,6 +115,8 @@ .getAllMessageStoreLocalMessageInfos(); dmOperationsVector = DatabaseManager::getQueryExecutor(identifier).getDMOperations(); + holdersVector = + DatabaseManager::getQueryExecutor(identifier).getHolders(); } catch (std::system_error &e) { error = e.what(); } @@ -156,6 +159,8 @@ auto dmOperationsVectorPtr = std::make_shared>( std::move(dmOperationsVector)); + auto holdersVectorPtr = + std::make_shared>(std::move(holdersVector)); this->jsInvoker_->invokeAsync( [&innerRt, draftsVectorPtr, @@ -173,6 +178,7 @@ entryStoreVectorPtr, messageStoreLocalMessageInfosVectorPtr, dmOperationsVectorPtr, + holdersVectorPtr, error, promise, draftStore = this->draftStore, @@ -187,7 +193,8 @@ auxUserStore = this->auxUserStore, threadActivityStore = this->threadActivityStore, entryStore = this->entryStore, - dmOperationStore = this->dmOperationStore]() { + dmOperationStore = this->dmOperationStore, + holderStore = this->holderStore]() { if (error.size()) { promise->reject(error); return; @@ -226,6 +233,8 @@ innerRt, messageStoreLocalMessageInfosVectorPtr); jsi::Array jsiDMOperations = dmOperationStore.parseDBDataStore( innerRt, dmOperationsVectorPtr); + jsi::Array jsiHolders = + holderStore.parseDBDataStore(innerRt, holdersVectorPtr); auto jsiClientDBStore = jsi::Object(innerRt); jsiClientDBStore.setProperty(innerRt, "messages", jsiMessages); @@ -255,6 +264,7 @@ jsiMessageStoreLocalMessageInfos); jsiClientDBStore.setProperty( innerRt, "dmOperations", jsiDMOperations); + jsiClientDBStore.setProperty(innerRt, "holders", jsiHolders); promise->resolve(std::move(jsiClientDBStore)); }); @@ -414,6 +424,12 @@ "dmOperationStoreOperations", this->dmOperationStore, storeOpsPtr); + this->appendDBStoreOps( + rt, + operations, + "holderStoreOperations", + this->holderStore, + storeOpsPtr); } catch (std::runtime_error &e) { createOperationsError = e.what(); } @@ -2103,7 +2119,8 @@ threadActivityStore(jsInvoker), entryStore(jsInvoker), messageSearchStore(jsInvoker), - dmOperationStore(jsInvoker) { + dmOperationStore(jsInvoker), + holderStore(jsInvoker) { GlobalDBSingleton::instance.enableMultithreading(); } diff --git a/native/cpp/CommonCpp/NativeModules/HolderStoreOperations.h b/native/cpp/CommonCpp/NativeModules/HolderStoreOperations.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/HolderStoreOperations.h @@ -0,0 +1,38 @@ +#pragma once + +#include "../DatabaseManagers/entities/Holder.h" +#include "DBOperationBase.h" +#include "DatabaseManager.h" +#include + +namespace comm { +class RemoveHoldersOperation : public DBOperationBase { +public: + RemoveHoldersOperation(std::vector hashes) : hashes{hashes} { + } + + virtual void execute(DatabaseIdentifier id) override { + DatabaseManager::getQueryExecutor(id).removeHolders(this->hashes); + } + +private: + std::vector hashes; +}; + +class ReplaceHoldersOperation : public DBOperationBase { +public: + ReplaceHoldersOperation(std::vector &&holders) + : holders{std::move(holders)} { + } + + virtual void execute(DatabaseIdentifier id) override { + for (auto holder : this->holders) { + DatabaseManager::getQueryExecutor(id).replaceHolder(holder); + } + } + +private: + std::vector holders; +}; + +} // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../../DatabaseManagers/entities/Holder.h" +#include "../../DBOperationBase.h" +#include "BaseDataStore.h" +#include "HolderStoreOperations.h" + +#include + +namespace comm { + +class HolderStore : public BaseDataStore { +private: + static OperationType REMOVE_OPERATION; + static OperationType REPLACE_OPERATION; + +public: + HolderStore(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; +}; + +} // namespace comm \ No newline at end of file diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/HolderStore.cpp @@ -0,0 +1,78 @@ +#include "HolderStore.h" + +#include "../../DBOperationBase.h" +#include +#include + +namespace comm { +OperationType HolderStore::REMOVE_OPERATION = "remove_holders"; +OperationType HolderStore::REPLACE_OPERATION = "replace_holders"; + +HolderStore::HolderStore( + std::shared_ptr jsInvoker) + : BaseDataStore(jsInvoker) { +} + +jsi::Array HolderStore::parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr> holdersVectorPtr) const { + size_t numHolders = holdersVectorPtr->size(); + jsi::Array jsiHolders = jsi::Array(rt, numHolders); + size_t writeIdx = 0; + for (const Holder &holder : *holdersVectorPtr) { + jsi::Object jsiHolder = jsi::Object(rt); + jsiHolder.setProperty(rt, "hash", holder.hash); + jsiHolder.setProperty(rt, "holder", holder.holder); + jsiHolder.setProperty(rt, "status", holder.status); + jsiHolders.setValueAtIndex(rt, writeIdx++, jsiHolder); + } + return jsiHolders; +} + +std::vector> HolderStore::createOperations( + jsi::Runtime &rt, + const jsi::Array &operations) const { + std::vector> holderStoreOps; + + 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 hashesToRemove; + jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); + jsi::Array hashes = + payloadObj.getProperty(rt, "hashes").asObject(rt).asArray(rt); + for (int i = 0; i < hashes.size(rt); i++) { + hashesToRemove.push_back( + hashes.getValueAtIndex(rt, i).asString(rt).utf8(rt)); + } + holderStoreOps.push_back( + std::make_unique(std::move(hashesToRemove))); + } else if (opType == REPLACE_OPERATION) { + std::vector holdersToReplace; + jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); + jsi::Array items = + payloadObj.getProperty(rt, "items").asObject(rt).asArray(rt); + for (int i = 0; i < items.size(rt); i++) { + jsi::Object item = items.getValueAtIndex(rt, i).asObject(rt); + std::string hash = item.getProperty(rt, "hash").asString(rt).utf8(rt); + std::string holder = + item.getProperty(rt, "holder").asString(rt).utf8(rt); + std::string status = + item.getProperty(rt, "status").asString(rt).utf8(rt); + + Holder holderItem{hash, holder, status}; + holdersToReplace.push_back(std::move(holderItem)); + } + + holderStoreOps.push_back(std::make_unique( + std::move(holdersToReplace))); + } else { + throw std::runtime_error("unsupported operation: " + opType); + } + }; + return holderStoreOps; +} + +} // namespace comm \ No newline at end of file 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 @@ -60,6 +60,7 @@ 8E3994552B039A7C00D5E950 /* UserStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E3994532B039A7C00D5E950 /* UserStore.cpp */; }; 8E43C32C291E5B4A009378F5 /* TerminateApp.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8E43C32B291E5B4A009378F5 /* TerminateApp.mm */; }; 8E86A6D329537EBB000BBE7D /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E86A6D229537EBB000BBE7D /* DatabaseManager.cpp */; }; + 8E8A8DFD2E15A4F100519F55 /* HolderStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E8A8DFC2E15A4F100519F55 /* HolderStore.cpp */; }; 8EA59BD62A6E8E0400EB4F53 /* DraftStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EA59BD42A6E8E0400EB4F53 /* DraftStore.cpp */; }; 8EA59BD92A73DAB000EB4F53 /* rustJSI-generated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EA59BD72A73DAB000EB4F53 /* rustJSI-generated.cpp */; }; 8ECF4E182DDDD9EF0079D3D6 /* WebSQLiteConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8ECF4E172DDDD9EF0079D3D6 /* WebSQLiteConnectionManager.cpp */; }; @@ -268,6 +269,9 @@ 8E43C32B291E5B4A009378F5 /* TerminateApp.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TerminateApp.mm; path = Comm/TerminateApp.mm; sourceTree = ""; }; 8E43C32E291E5B9D009378F5 /* TerminateApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TerminateApp.h; path = ../cpp/CommonCpp/Tools/TerminateApp.h; sourceTree = ""; }; 8E86A6D229537EBB000BBE7D /* DatabaseManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseManager.cpp; sourceTree = ""; }; + 8E8A8DFA2E15A4C400519F55 /* HolderStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HolderStoreOperations.h; sourceTree = ""; }; + 8E8A8DFB2E15A4F100519F55 /* HolderStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HolderStore.h; path = PersistentStorageUtilities/DataStores/HolderStore.h; sourceTree = ""; }; + 8E8A8DFC2E15A4F100519F55 /* HolderStore.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = HolderStore.cpp; path = PersistentStorageUtilities/DataStores/HolderStore.cpp; sourceTree = ""; }; 8EA59BD22A6E800100EB4F53 /* NativeModuleUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeModuleUtils.h; sourceTree = ""; }; 8EA59BD32A6E8CB700EB4F53 /* BaseDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseDataStore.h; path = PersistentStorageUtilities/DataStores/BaseDataStore.h; sourceTree = ""; }; 8EA59BD42A6E8E0400EB4F53 /* DraftStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DraftStore.cpp; path = PersistentStorageUtilities/DataStores/DraftStore.cpp; sourceTree = ""; }; @@ -529,6 +533,7 @@ 71BE843A2636A944002849D2 /* NativeModules */ = { isa = PBXGroup; children = ( + 8E8A8DFA2E15A4C400519F55 /* HolderStoreOperations.h */, 0E02677E2D81ED7B00788249 /* DMOperationStoreOperations.h */, CBAB63872BFCB071003B089F /* EntryStoreOperations.h */, B3B02EBE2B8538860020D118 /* CommunityStoreOperations.h */, @@ -726,6 +731,8 @@ 8EA59BD02A6E786200EB4F53 /* DataStores */ = { isa = PBXGroup; children = ( + 8E8A8DFB2E15A4F100519F55 /* HolderStore.h */, + 8E8A8DFC2E15A4F100519F55 /* HolderStore.cpp */, 0E02677B2D81ED6600788249 /* DMOperationStore.h */, 0E02677C2D81ED6600788249 /* DMOperationStore.cpp */, 816D2D582C480E60001C0B67 /* MessageSearchStore.cpp */, @@ -1267,6 +1274,7 @@ 7FBB2A7829E945C2002C6493 /* CommUtilsModule.cpp in Sources */, CB38B48228771C7A00171182 /* NonBlockingLock.mm in Sources */, 718DE99E2653D41C00365824 /* WorkerThread.cpp in Sources */, + 8E8A8DFD2E15A4F100519F55 /* HolderStore.cpp in Sources */, 8ECF4E182DDDD9EF0079D3D6 /* WebSQLiteConnectionManager.cpp in Sources */, 8B99BAAE28D511FF00EB5ADB /* lib.rs.cc in Sources */, 8EF0F6032DCA43CD00F2B171 /* SQLiteBackup.cpp in Sources */,