diff --git a/native/android/app/CMakeLists.txt b/native/android/app/CMakeLists.txt --- a/native/android/app/CMakeLists.txt +++ b/native/android/app/CMakeLists.txt @@ -193,6 +193,7 @@ ../../cpp/CommonCpp/NativeModules ../../cpp/CommonCpp/NativeModules/InternalModules ../../cpp/CommonCpp/NativeModules/PersistentStorageUtilities + ../../cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores ../../cpp/CommonCpp/NativeModules/PersistentStorageUtilities/ThreadOperationsUtilities ../../cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities ../../cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities/MessageSpecs 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 @@ -68,12 +68,18 @@ ./PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp ) +set(_data_stores_path ./PersistentStorageUtilities/DataStores) +set(DATA_STORES_HDRS + ${_data_stores_path}/BaseDataStore.h +) + add_library(comm-modules-persistentstorage ${MESSAGE_HDRS} ${MESSAGE_SRCS} ${MESSAGE_SPEC_HDRS} ${THREAD_OP_HDRS} ${THREAD_OP_SRCS} + ${DATA_STORES_HDRS} ) # reference local directory when building, use installation path when installing 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 @@ -1,6 +1,7 @@ #include "CommCoreModule.h" #include "../CryptoTools/DeviceID.h" #include "../Notifications/BackgroundDataStorage/NotificationsCryptoModule.h" +#include "BaseDataStore.h" #include "DatabaseManager.h" #include "DraftStoreOperations.h" #include "InternalModules/GlobalDBSingleton.h" diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/BaseDataStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/BaseDataStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/BaseDataStore.h @@ -0,0 +1,103 @@ +#pragma once + +#include "DatabaseManager.h" +#include "GlobalDBSingleton.h" +#include "NativeModuleUtils.h" +#include "WorkerThread.h" + +#include +#include +#include + +namespace comm { + +namespace jsi = facebook::jsi; + +template class BaseDataStore { +private: + std::shared_ptr jsInvoker; + +public: + BaseDataStore(std::shared_ptr _jsInvoker) + : jsInvoker(_jsInvoker) { + } + + virtual ~BaseDataStore(){}; + + virtual std::vector> + createOperations(jsi::Runtime &rt, const jsi::Array &operations) const = 0; + + virtual jsi::Array parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr> dataVectorPtr) const = 0; + + jsi::Value processStoreOperations(jsi::Runtime &rt, jsi::Array &&operations) { + std::string createOperationsError; + std::shared_ptr>> storeOpsPtr; + + try { + auto storeOps = createOperations(rt, operations); + storeOpsPtr = std::make_shared>>( + std::move(storeOps)); + } catch (std::runtime_error &e) { + createOperationsError = e.what(); + } + + return facebook::react::createPromiseAsJSIValue( + rt, + [=](jsi::Runtime &innerRt, + std::shared_ptr promise) { + taskType job = [=]() { + std::string error = createOperationsError; + + if (!error.size()) { + try { + DatabaseManager::getQueryExecutor().beginTransaction(); + for (const auto &operation : *storeOpsPtr) { + operation->execute(); + } + DatabaseManager::getQueryExecutor().commitTransaction(); + } catch (std::system_error &e) { + error = e.what(); + DatabaseManager::getQueryExecutor().rollbackTransaction(); + } + } + + this->jsInvoker->invokeAsync([=]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + GlobalDBSingleton::instance.scheduleOrRunCancellable( + job, promise, this->jsInvoker); + }); + } + + void processStoreOperationsSync(jsi::Runtime &rt, jsi::Array &&operations) { + std::vector> storeOps; + + try { + storeOps = createOperations(rt, operations); + } catch (const std::exception &e) { + throw jsi::JSError(rt, e.what()); + } + + NativeModuleUtils::runSyncOrThrowJSError(rt, [&storeOps]() { + try { + DatabaseManager::getQueryExecutor().beginTransaction(); + for (const auto &operation : storeOps) { + operation->execute(); + } + DatabaseManager::getQueryExecutor().commitTransaction(); + } catch (const std::exception &e) { + DatabaseManager::getQueryExecutor().rollbackTransaction(); + throw e; + } + }); + } +}; + +} // 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 @@ -194,6 +194,7 @@ 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 = ""; }; 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 = ""; }; 8ED8B5322A4DCCE300D3DA26 /* CommQueryExecutor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommQueryExecutor.h; sourceTree = ""; }; 8ED8B5332A4DCCE300D3DA26 /* CommQueryExecutor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CommQueryExecutor.cpp; sourceTree = ""; }; 8EE6E49F2A39CCAB00AE6BCD /* ReportStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReportStoreOperations.h; sourceTree = ""; }; @@ -554,6 +555,14 @@ path = ../native_rust_library; sourceTree = ""; }; + 8EA59BD02A6E786200EB4F53 /* DataStores */ = { + isa = PBXGroup; + children = ( + 8EA59BD32A6E8CB700EB4F53 /* BaseDataStore.h */, + ); + name = DataStores; + sourceTree = ""; + }; AFF3F1F76178B42122C79BDE /* ExpoModulesProviders */ = { isa = PBXGroup; children = ( @@ -641,6 +650,7 @@ CBED0E2C284E086100CD3863 /* PersistentStorageUtilities */ = { isa = PBXGroup; children = ( + 8EA59BD02A6E786200EB4F53 /* DataStores */, CBFE582628858512003B94C9 /* ThreadOperationsUtilities */, CB38F2AC286C6C010010535C /* MessageOperationsUtilities */, );