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 @@ -74,11 +74,13 @@ ${_data_stores_path}/DraftStore.h ${_data_stores_path}/ThreadStore.h ${_data_stores_path}/MessageStore.h + ${_data_stores_path}/ReportStore.h ) set(DATA_STORES_SRCS ${_data_stores_path}/DraftStore.cpp ${_data_stores_path}/ThreadStore.cpp ${_data_stores_path}/MessageStore.cpp + ${_data_stores_path}/ReportStore.cpp ) add_library(comm-modules-persistentstorage 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 @@ -7,6 +7,7 @@ #include "JSIRust.h" #include "PersistentStorageUtilities/DataStores/DraftStore.h" #include "PersistentStorageUtilities/DataStores/MessageStore.h" +#include "PersistentStorageUtilities/DataStores/ReportStore.h" #include "PersistentStorageUtilities/DataStores/ThreadStore.h" #include #include @@ -28,6 +29,7 @@ DraftStore draftStore; ThreadStore threadStore; MessageStore messageStore; + ReportStore reportStore; virtual jsi::Value getDraft(jsi::Runtime &rt, jsi::String key) override; virtual jsi::Value 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 @@ -107,22 +107,6 @@ }); } -jsi::Array parseDBReportStore( - jsi::Runtime &rt, - std::shared_ptr> reportStoreVectorPtr) { - size_t numReports = reportStoreVectorPtr->size(); - jsi::Array jsiReports = jsi::Array(rt, numReports); - size_t writeIdx = 0; - - for (const Report &report : *reportStoreVectorPtr) { - jsi::Object jsiReport = jsi::Object(rt); - jsiReport.setProperty(rt, "id", report.id); - jsiReport.setProperty(rt, "report", report.report); - jsiReports.setValueAtIndex(rt, writeIdx++, jsiReport); - } - return jsiReports; -} - jsi::Value CommCoreModule::getClientDBStore(jsi::Runtime &rt) { return createPromiseAsJSIValue( rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { @@ -167,7 +151,8 @@ promise, draftStore = this->draftStore, threadStore = this->threadStore, - messageStore = this->messageStore]() { + messageStore = this->messageStore, + reportStore = this->reportStore]() { if (error.size()) { promise->reject(error); return; @@ -182,7 +167,7 @@ messageStore.parseDBMessageStoreThreads( innerRt, messageStoreThreadsVectorPtr); jsi::Array jsiReportStore = - parseDBReportStore(innerRt, reportStoreVectorPtr); + reportStore.parseDBDataStore(innerRt, reportStoreVectorPtr); auto jsiClientDBStore = jsi::Object(innerRt); jsiClientDBStore.setProperty(innerRt, "messages", jsiMessages); @@ -281,105 +266,16 @@ this->threadStore.processStoreOperationsSync(rt, std::move(operations)); } -const std::string REPLACE_REPORT_OPERATION = "replace_report"; -const std::string REMOVE_REPORTS_OPERATION = "remove_reports"; -const std::string REMOVE_ALL_REPORTS_OPERATION = "remove_all_reports"; - -std::vector> -createReportStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) { - std::vector> reportStoreOps; - 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_REPORTS_OPERATION) { - reportStoreOps.push_back(std::make_unique()); - continue; - } - - auto payload_obj = op.getProperty(rt, "payload").asObject(rt); - if (op_type == REPLACE_REPORT_OPERATION) { - reportStoreOps.push_back( - std::make_unique(rt, payload_obj)); - } else if (op_type == REMOVE_REPORTS_OPERATION) { - reportStoreOps.push_back( - std::make_unique(rt, payload_obj)); - } else { - throw std::runtime_error{"unsupported operation: " + op_type}; - } - } - return reportStoreOps; -} - jsi::Value CommCoreModule::processReportStoreOperations( jsi::Runtime &rt, jsi::Array operations) { - std::string createOperationsError; - std::shared_ptr>> - reportStoreOpsPtr; - try { - auto reportStoreOps = createReportStoreOperations(rt, operations); - reportStoreOpsPtr = std::make_shared< - std::vector>>( - std::move(reportStoreOps)); - } catch (std::runtime_error &e) { - createOperationsError = e.what(); - } - - return 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 : *reportStoreOpsPtr) { - 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_); - }); + return this->reportStore.processStoreOperations(rt, std::move(operations)); } void CommCoreModule::processReportStoreOperationsSync( jsi::Runtime &rt, jsi::Array operations) { - std::vector> reportStoreOps; - - try { - reportStoreOps = createReportStoreOperations(rt, operations); - } catch (const std::exception &e) { - throw jsi::JSError(rt, e.what()); - } - - NativeModuleUtils::runSyncOrThrowJSError(rt, [&reportStoreOps]() { - try { - DatabaseManager::getQueryExecutor().beginTransaction(); - for (const auto &operation : reportStoreOps) { - operation->execute(); - } - DatabaseManager::getQueryExecutor().commitTransaction(); - } catch (const std::exception &e) { - DatabaseManager::getQueryExecutor().rollbackTransaction(); - throw e; - } - }); + this->reportStore.processStoreOperationsSync(rt, std::move(operations)); } void CommCoreModule::terminate(jsi::Runtime &rt) { @@ -705,7 +601,8 @@ cryptoThread(std::make_unique("crypto")), draftStore(jsInvoker), threadStore(jsInvoker), - messageStore(jsInvoker) { + messageStore(jsInvoker), + reportStore(jsInvoker) { GlobalDBSingleton::instance.enableMultithreading(); } diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ReportStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ReportStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ReportStore.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../../DatabaseManagers/entities/Report.h" +#include "BaseDataStore.h" +#include "ReportStoreOperations.h" + +#include + +namespace comm { + +class ReportStore : public BaseDataStore { +private: + static OperationType REPLACE_REPORT_OPERATION; + static OperationType REMOVE_REPORTS_OPERATION; + static OperationType REMOVE_ALL_REPORTS_OPERATION; + +public: + ReportStore(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/ReportStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ReportStore.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ReportStore.cpp @@ -0,0 +1,62 @@ +#include "ReportStore.h" + +#include +#include + +namespace comm { + +using namespace facebook::react; + +OperationType ReportStore::REPLACE_REPORT_OPERATION = "replace_report"; +OperationType ReportStore::REMOVE_REPORTS_OPERATION = "remove_reports"; +OperationType ReportStore::REMOVE_ALL_REPORTS_OPERATION = "remove_all_reports"; + +ReportStore::ReportStore( + std::shared_ptr jsInvoker) + : BaseDataStore(jsInvoker) { +} + +jsi::Array ReportStore::parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr> reportStoreVectorPtr) const { + size_t numReports = reportStoreVectorPtr->size(); + jsi::Array jsiReports = jsi::Array(rt, numReports); + size_t writeIdx = 0; + + for (const Report &report : *reportStoreVectorPtr) { + jsi::Object jsiReport = jsi::Object(rt); + jsiReport.setProperty(rt, "id", report.id); + jsiReport.setProperty(rt, "report", report.report); + jsiReports.setValueAtIndex(rt, writeIdx++, jsiReport); + } + return jsiReports; +} + +std::vector> +ReportStore::createOperations(jsi::Runtime &rt, const jsi::Array &operations) + const { + std::vector> reportStoreOps; + 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_REPORTS_OPERATION) { + reportStoreOps.push_back(std::make_unique()); + continue; + } + + auto payload_obj = op.getProperty(rt, "payload").asObject(rt); + if (op_type == REPLACE_REPORT_OPERATION) { + reportStoreOps.push_back( + std::make_unique(rt, payload_obj)); + } else if (op_type == REMOVE_REPORTS_OPERATION) { + reportStoreOps.push_back( + std::make_unique(rt, payload_obj)); + } else { + throw std::runtime_error{"unsupported operation: " + op_type}; + } + } + return reportStoreOps; +} + +} // 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 @@ -52,6 +52,7 @@ 8ED8B5342A4DD4EB00D3DA26 /* CommQueryExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8ED8B5332A4DCCE300D3DA26 /* CommQueryExecutor.cpp */; }; 8EF7756B2A7433630046A385 /* ThreadStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF775692A7433630046A385 /* ThreadStore.cpp */; }; 8EF7756E2A7513F40046A385 /* MessageStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF7756D2A7513F40046A385 /* MessageStore.cpp */; }; + 8EF775712A751B780046A385 /* ReportStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF7756F2A751B780046A385 /* ReportStore.cpp */; }; B71AFF1F265EDD8600B22352 /* IBMPlexSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B71AFF1E265EDD8600B22352 /* IBMPlexSans-Medium.ttf */; }; CB1648AF27CFBE6A00394D9D /* CryptoModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 71BF5B7B26BBDA6100EDE27D /* CryptoModule.cpp */; }; CB24361829A39A2500FEC4E1 /* NotificationsCryptoModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB24361729A39A2500FEC4E1 /* NotificationsCryptoModule.cpp */; }; @@ -208,6 +209,8 @@ 8EF7756A2A7433630046A385 /* ThreadStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadStore.h; path = PersistentStorageUtilities/DataStores/ThreadStore.h; sourceTree = ""; }; 8EF7756C2A7513F40046A385 /* MessageStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MessageStore.h; path = PersistentStorageUtilities/DataStores/MessageStore.h; sourceTree = ""; }; 8EF7756D2A7513F40046A385 /* MessageStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageStore.cpp; path = PersistentStorageUtilities/DataStores/MessageStore.cpp; sourceTree = ""; }; + 8EF7756F2A751B780046A385 /* ReportStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ReportStore.cpp; path = PersistentStorageUtilities/DataStores/ReportStore.cpp; sourceTree = ""; }; + 8EF775702A751B780046A385 /* ReportStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ReportStore.h; path = PersistentStorageUtilities/DataStores/ReportStore.h; sourceTree = ""; }; 913E5A7BDECB327E3DE11053 /* Pods-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.release.xcconfig"; sourceTree = ""; }; 994BEBDD4E4959F69CEA0BC3 /* libPods-Comm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Comm.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B7055C6B26E477CF00BE0548 /* MessageStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MessageStoreOperations.h; sourceTree = ""; }; @@ -567,6 +570,8 @@ 8EA59BD02A6E786200EB4F53 /* DataStores */ = { isa = PBXGroup; children = ( + 8EF7756F2A751B780046A385 /* ReportStore.cpp */, + 8EF775702A751B780046A385 /* ReportStore.h */, 8EF7756D2A7513F40046A385 /* MessageStore.cpp */, 8EF7756C2A7513F40046A385 /* MessageStore.h */, 8EF775692A7433630046A385 /* ThreadStore.cpp */, @@ -1048,6 +1053,7 @@ 71142A7726C2650B0039DCBD /* CommSecureStoreIOSWrapper.mm in Sources */, 7FBB2A7B29EEA2A4002C6493 /* Base64.cpp in Sources */, CB38F2B1286C6C870010535C /* MessageOperationsUtilities.cpp in Sources */, + 8EF775712A751B780046A385 /* ReportStore.cpp in Sources */, 71CA4A64262DA8E500835C89 /* Logger.mm in Sources */, 71BF5B7F26BBDD7400EDE27D /* CryptoModule.cpp in Sources */, CB24361829A39A2500FEC4E1 /* NotificationsCryptoModule.cpp in Sources */,