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 @@ -24,6 +24,7 @@ "SyncedMetadataStoreOperations.h" "AuxUserStoreOperations.h" "ThreadActivityStoreOperations.h" + "EntryStoreOperations.h" ) set(NATIVE_SRCS @@ -91,6 +92,7 @@ ${_data_stores_path}/SyncedMetadataStore.h ${_data_stores_path}/AuxUserStore.h ${_data_stores_path}/ThreadActivityStore.h + ${_data_stores_path}/EntryStore.h ) set(DATA_STORES_SRCS ${_data_stores_path}/DraftStore.cpp @@ -104,6 +106,7 @@ ${_data_stores_path}/SyncedMetadataStore.cpp ${_data_stores_path}/AuxUserStore.cpp ${_data_stores_path}/ThreadActivityStore.cpp + ${_data_stores_path}/EntryStore.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 @@ -8,6 +8,7 @@ #include "PersistentStorageUtilities/DataStores/AuxUserStore.h" #include "PersistentStorageUtilities/DataStores/CommunityStore.h" #include "PersistentStorageUtilities/DataStores/DraftStore.h" +#include "PersistentStorageUtilities/DataStores/EntryStore.h" #include "PersistentStorageUtilities/DataStores/IntegrityStore.h" #include "PersistentStorageUtilities/DataStores/KeyserverStore.h" #include "PersistentStorageUtilities/DataStores/MessageStore.h" @@ -45,6 +46,7 @@ SyncedMetadataStore syncedMetadataStore; AuxUserStore auxUserStore; ThreadActivityStore threadActivityStore; + EntryStore entryStore; void persistCryptoModules(bool persistContentModule, bool persistNotifsModule); 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 @@ -124,6 +124,7 @@ std::vector syncedMetadataStoreVector; std::vector auxUserStoreVector; std::vector threadActivityStoreVector; + std::vector entryStoreVector; try { draftsVector = DatabaseManager::getQueryExecutor().getAllDrafts(); messagesVector = @@ -146,6 +147,8 @@ DatabaseManager::getQueryExecutor().getAllAuxUserInfos(); threadActivityStoreVector = DatabaseManager::getQueryExecutor() .getAllThreadActivityEntries(); + entryStoreVector = + DatabaseManager::getQueryExecutor().getAllEntries(); } catch (std::system_error &e) { error = e.what(); } @@ -181,6 +184,8 @@ auto threadActivityStoreVectorPtr = std::make_shared>( std::move(threadActivityStoreVector)); + auto entryStoreVectorPtr = std::make_shared>( + std::move(entryStoreVector)); this->jsInvoker_->invokeAsync([&innerRt, draftsVectorPtr, messagesVectorPtr, @@ -194,6 +199,7 @@ syncedMetadataStoreVectorPtr, auxUserStoreVectorPtr, threadActivityStoreVectorPtr, + entryStoreVectorPtr, error, promise, draftStore = this->draftStore, @@ -208,7 +214,8 @@ this->syncedMetadataStore, auxUserStore = this->auxUserStore, threadActivityStore = - this->threadActivityStore]() { + this->threadActivityStore, + entryStore = this->entryStore]() { if (error.size()) { promise->reject(error); return; @@ -240,6 +247,8 @@ jsi::Array jsiThreadActivityStore = threadActivityStore.parseDBDataStore( innerRt, threadActivityStoreVectorPtr); + jsi::Array jsiEntryStore = + entryStore.parseDBDataStore(innerRt, entryStoreVectorPtr); auto jsiClientDBStore = jsi::Object(innerRt); jsiClientDBStore.setProperty(innerRt, "messages", jsiMessages); @@ -261,6 +270,7 @@ innerRt, "auxUserInfos", jsiAuxUserStore); jsiClientDBStore.setProperty( innerRt, "threadActivityEntries", jsiThreadActivityStore); + jsiClientDBStore.setProperty(innerRt, "entries", jsiEntryStore); promise->resolve(std::move(jsiClientDBStore)); }); @@ -423,6 +433,8 @@ "threadActivityStoreOperations", this->threadActivityStore, storeOpsPtr); + this->appendDBStoreOps( + rt, operations, "entryStoreOperations", this->entryStore, storeOpsPtr); } catch (std::runtime_error &e) { createOperationsError = e.what(); } @@ -1694,7 +1706,8 @@ integrityStore(jsInvoker), syncedMetadataStore(jsInvoker), auxUserStore(jsInvoker), - threadActivityStore(jsInvoker) { + threadActivityStore(jsInvoker), + entryStore(jsInvoker) { GlobalDBSingleton::instance.enableMultithreading(); } diff --git a/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h b/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../DatabaseManagers/entities/EntryInfo.h" +#include "DBOperationBase.h" +#include "DatabaseManager.h" +#include + +namespace comm { +class RemoveEntriesOperation : public DBOperationBase { +public: + RemoveEntriesOperation(std::vector ids) : ids{ids} { + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().removeEntries(this->ids); + } + +private: + std::vector ids; +}; + +class ReplaceEntryOperation : public DBOperationBase { +public: + ReplaceEntryOperation(EntryInfo &&entry) : entry{std::move(entry)} { + } + + virtual void execute() override { + DatabaseManager::getQueryExecutor().replaceEntry(this->entry); + } + +private: + EntryInfo entry; +}; + +class RemoveAllEntriesOperation : public DBOperationBase { +public: + virtual void execute() override { + DatabaseManager::getQueryExecutor().removeAllEntries(); + } +}; + +} // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../../DatabaseManagers/entities/EntryInfo.h" +#include "../../DBOperationBase.h" +#include "BaseDataStore.h" +#include "EntryStoreOperations.h" + +#include + +namespace comm { + +class EntryStore : public BaseDataStore { +private: + static OperationType REMOVE_OPERATION; + static OperationType REMOVE_ALL_OPERATION; + static OperationType REPLACE_OPERATION; + +public: + EntryStore(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 diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/EntryStore.cpp @@ -0,0 +1,70 @@ +#include "EntryStore.h" + +#include "../../DBOperationBase.h" +#include +#include + +namespace comm { +OperationType EntryStore::REMOVE_OPERATION = "remove_entries"; +OperationType EntryStore::REMOVE_ALL_OPERATION = "remove_all_entries"; +OperationType EntryStore::REPLACE_OPERATION = "replace_entry"; + +EntryStore::EntryStore(std::shared_ptr jsInvoker) + : BaseDataStore(jsInvoker) { +} + +jsi::Array EntryStore::parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr> entriesVectorPtr) const { + size_t numEntries = entriesVectorPtr->size(); + jsi::Array jsiEntries = jsi::Array(rt, numEntries); + size_t writeIdx = 0; + for (const EntryInfo &entry : *entriesVectorPtr) { + jsi::Object jsiEntry = jsi::Object(rt); + jsiEntry.setProperty(rt, "id", entry.id); + jsiEntry.setProperty(rt, "entry", entry.entry); + jsiEntries.setValueAtIndex(rt, writeIdx++, jsiEntry); + } + return jsiEntries; +} + +std::vector> EntryStore::createOperations( + jsi::Runtime &rt, + const jsi::Array &operations) const { + std::vector> entryStoreOps; + + 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 entryIDsToRemove; + jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); + jsi::Array entryIDs = + payloadObj.getProperty(rt, "ids").asObject(rt).asArray(rt); + for (int entryIdx = 0; entryIdx < entryIDs.size(rt); entryIdx++) { + entryIDsToRemove.push_back( + entryIDs.getValueAtIndex(rt, entryIdx).asString(rt).utf8(rt)); + } + entryStoreOps.push_back(std::make_unique( + std::move(entryIDsToRemove))); + } else if (opType == REMOVE_ALL_OPERATION) { + entryStoreOps.push_back(std::make_unique()); + } else if (opType == REPLACE_OPERATION) { + jsi::Object entryObj = op.getProperty(rt, "payload").asObject(rt); + std::string id = entryObj.getProperty(rt, "id").asString(rt).utf8(rt); + std::string entry_info = + entryObj.getProperty(rt, "entry").asString(rt).utf8(rt); + + EntryInfo entry{id, entry_info}; + + entryStoreOps.push_back( + std::make_unique(std::move(entry))); + } else { + throw std::runtime_error("unsupported operation: " + opType); + } + }; + return entryStoreOps; +} + +} // 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 @@ -91,6 +91,7 @@ CB90951F29534B32002F2A7F /* CommSecureStore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 71D4D7CB26C50B1000FCDBCD /* CommSecureStore.mm */; }; CBA5F8852B6979F7005BE700 /* SQLiteConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBA5F8842B6979ED005BE700 /* SQLiteConnectionManager.cpp */; }; CBAAA4702B459181007599DA /* BackupOperationsExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBAAA46E2B459181007599DA /* BackupOperationsExecutor.cpp */; }; + CBAB638A2BFCCA9B003B089F /* EntryStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBAB63882BFCB087003B089F /* EntryStore.cpp */; }; CBB0DF602B768007008E22FF /* CommMMKV.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBB0DF5F2B768007008E22FF /* CommMMKV.mm */; }; CBB0DF612B768007008E22FF /* CommMMKV.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBB0DF5F2B768007008E22FF /* CommMMKV.mm */; }; CBCA09062A8E0E7400F75B3E /* StaffUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CBCA09052A8E0E6B00F75B3E /* StaffUtils.cpp */; }; @@ -319,6 +320,9 @@ CBA784382B28AC4300E9F419 /* CommServicesAuthMetadataEmitter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommServicesAuthMetadataEmitter.h; sourceTree = ""; }; CBAAA46E2B459181007599DA /* BackupOperationsExecutor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BackupOperationsExecutor.cpp; path = PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.cpp; sourceTree = ""; }; CBAAA46F2B459181007599DA /* BackupOperationsExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BackupOperationsExecutor.h; path = PersistentStorageUtilities/BackupOperationsUtilities/BackupOperationsExecutor.h; sourceTree = ""; }; + CBAB63872BFCB071003B089F /* EntryStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EntryStoreOperations.h; sourceTree = ""; }; + CBAB63882BFCB087003B089F /* EntryStore.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = EntryStore.cpp; path = PersistentStorageUtilities/DataStores/EntryStore.cpp; sourceTree = ""; }; + CBAB63892BFCB087003B089F /* EntryStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = EntryStore.h; path = PersistentStorageUtilities/DataStores/EntryStore.h; sourceTree = ""; }; CBB0DF5E2B767FDF008E22FF /* CommMMKV.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommMMKV.h; sourceTree = ""; }; CBB0DF5F2B768007008E22FF /* CommMMKV.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CommMMKV.mm; path = Comm/CommMMKV.mm; sourceTree = ""; }; CBCA09042A8E0E6B00F75B3E /* StaffUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StaffUtils.h; sourceTree = ""; }; @@ -488,6 +492,7 @@ 71BE843A2636A944002849D2 /* NativeModules */ = { isa = PBXGroup; children = ( + CBAB63872BFCB071003B089F /* EntryStoreOperations.h */, B3B02EBE2B8538860020D118 /* CommunityStoreOperations.h */, 34329B3E2B9EBD3400233438 /* IntegrityStoreOperations.h */, 8E2CC2562B5C999A000C94D6 /* KeyserverStoreOperations.h */, @@ -671,6 +676,8 @@ 8EA59BD02A6E786200EB4F53 /* DataStores */ = { isa = PBXGroup; children = ( + CBAB63882BFCB087003B089F /* EntryStore.cpp */, + CBAB63892BFCB087003B089F /* EntryStore.h */, 34FF25B82BB753B30075EC40 /* AuxUserStore.h */, 34FF25B92BB757860075EC40 /* AuxUserStore.cpp */, 8E2CC2582B5C99B0000C94D6 /* KeyserverStore.cpp */, @@ -1170,6 +1177,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CBAB638A2BFCCA9B003B089F /* EntryStore.cpp in Sources */, CB3CCB012B72470700793640 /* NativeSQLiteConnectionManager.cpp in Sources */, CBA5F8852B6979F7005BE700 /* SQLiteConnectionManager.cpp in Sources */, CB01F0C42B67F3A10089E1F9 /* SQLiteStatementWrapper.cpp in Sources */,