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 @@ -72,9 +72,11 @@ set(DATA_STORES_HDRS ${_data_stores_path}/BaseDataStore.h ${_data_stores_path}/DraftStore.h + ${_data_stores_path}/ThreadStore.h ) set(DATA_STORES_SRCS ${_data_stores_path}/DraftStore.cpp + ${_data_stores_path}/ThreadStore.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 @@ -6,6 +6,7 @@ #include "../_generated/commJSI.h" #include "JSIRust.h" #include "PersistentStorageUtilities/DataStores/DraftStore.h" +#include "PersistentStorageUtilities/DataStores/ThreadStore.h" #include #include #include @@ -24,6 +25,7 @@ const std::string publicCryptoAccountID = "publicCryptoAccountID"; std::unique_ptr cryptoModule; DraftStore draftStore; + ThreadStore threadStore; 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 @@ -158,69 +158,6 @@ return jsiMessages; } -jsi::Array parseDBThreads( - jsi::Runtime &rt, - std::shared_ptr> threadsVectorPtr) { - size_t numThreads = threadsVectorPtr->size(); - jsi::Array jsiThreads = jsi::Array(rt, numThreads); - size_t writeIdx = 0; - for (const Thread &thread : *threadsVectorPtr) { - jsi::Object jsiThread = jsi::Object(rt); - jsiThread.setProperty(rt, "id", thread.id); - jsiThread.setProperty(rt, "type", thread.type); - jsiThread.setProperty( - rt, - "name", - thread.name ? jsi::String::createFromUtf8(rt, *thread.name) - : jsi::Value::null()); - jsiThread.setProperty( - rt, - "description", - thread.description - ? jsi::String::createFromUtf8(rt, *thread.description) - : jsi::Value::null()); - jsiThread.setProperty(rt, "color", thread.color); - jsiThread.setProperty( - rt, "creationTime", std::to_string(thread.creation_time)); - jsiThread.setProperty( - rt, - "parentThreadID", - thread.parent_thread_id - ? jsi::String::createFromUtf8(rt, *thread.parent_thread_id) - : jsi::Value::null()); - jsiThread.setProperty( - rt, - "containingThreadID", - thread.containing_thread_id - ? jsi::String::createFromUtf8(rt, *thread.containing_thread_id) - : jsi::Value::null()); - jsiThread.setProperty( - rt, - "community", - thread.community ? jsi::String::createFromUtf8(rt, *thread.community) - : jsi::Value::null()); - jsiThread.setProperty(rt, "members", thread.members); - jsiThread.setProperty(rt, "roles", thread.roles); - jsiThread.setProperty(rt, "currentUser", thread.current_user); - jsiThread.setProperty( - rt, - "sourceMessageID", - thread.source_message_id - ? jsi::String::createFromUtf8(rt, *thread.source_message_id) - : jsi::Value::null()); - jsiThread.setProperty(rt, "repliesCount", thread.replies_count); - jsiThread.setProperty(rt, "pinnedCount", thread.pinned_count); - - if (thread.avatar) { - auto avatar = jsi::String::createFromUtf8(rt, *thread.avatar); - jsiThread.setProperty(rt, "avatar", avatar); - } - - jsiThreads.setValueAtIndex(rt, writeIdx++, jsiThread); - } - return jsiThreads; -} - jsi::Array parseDBMessageStoreThreads( jsi::Runtime &rt, std::shared_ptr> threadsVectorPtr) { @@ -301,7 +238,8 @@ reportStoreVectorPtr, error, promise, - draftStore = this->draftStore]() { + draftStore = this->draftStore, + threadStore = this->threadStore]() { if (error.size()) { promise->reject(error); return; @@ -310,7 +248,8 @@ draftStore.parseDBDataStore(innerRt, draftsVectorPtr); jsi::Array jsiMessages = parseDBMessages(innerRt, messagesVectorPtr); - jsi::Array jsiThreads = parseDBThreads(innerRt, threadsVectorPtr); + jsi::Array jsiThreads = + threadStore.parseDBDataStore(innerRt, threadsVectorPtr); jsi::Array jsiMessageStoreThreads = parseDBMessageStoreThreads( innerRt, messageStoreThreadsVectorPtr); jsi::Array jsiReportStore = @@ -515,194 +454,22 @@ auto threadsVectorPtr = std::make_shared>(std::move(threadsVector)); - jsi::Array jsiThreads = parseDBThreads(rt, threadsVectorPtr); + jsi::Array jsiThreads = + this->threadStore.parseDBDataStore(rt, threadsVectorPtr); return jsiThreads; } -std::vector> -createThreadStoreOperations(jsi::Runtime &rt, const jsi::Array &operations) { - std::vector> threadStoreOps; - - 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 threadIDsToRemove; - jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); - jsi::Array threadIDs = - payloadObj.getProperty(rt, "ids").asObject(rt).asArray(rt); - for (int threadIdx = 0; threadIdx < threadIDs.size(rt); threadIdx++) { - threadIDsToRemove.push_back( - threadIDs.getValueAtIndex(rt, threadIdx).asString(rt).utf8(rt)); - } - threadStoreOps.push_back(std::make_unique( - std::move(threadIDsToRemove))); - } else if (opType == REMOVE_ALL_OPERATION) { - threadStoreOps.push_back(std::make_unique()); - } else if (opType == REPLACE_OPERATION) { - jsi::Object threadObj = op.getProperty(rt, "payload").asObject(rt); - std::string threadID = - threadObj.getProperty(rt, "id").asString(rt).utf8(rt); - int type = std::lround(threadObj.getProperty(rt, "type").asNumber()); - jsi::Value maybeName = threadObj.getProperty(rt, "name"); - std::unique_ptr name = maybeName.isString() - ? std::make_unique(maybeName.asString(rt).utf8(rt)) - : nullptr; - - jsi::Value maybeDescription = threadObj.getProperty(rt, "description"); - std::unique_ptr description = maybeDescription.isString() - ? std::make_unique( - maybeDescription.asString(rt).utf8(rt)) - : nullptr; - - std::string color = - threadObj.getProperty(rt, "color").asString(rt).utf8(rt); - int64_t creationTime = std::stoll( - threadObj.getProperty(rt, "creationTime").asString(rt).utf8(rt)); - - jsi::Value maybeParentThreadID = - threadObj.getProperty(rt, "parentThreadID"); - std::unique_ptr parentThreadID = - maybeParentThreadID.isString() - ? std::make_unique( - maybeParentThreadID.asString(rt).utf8(rt)) - : nullptr; - - jsi::Value maybeContainingThreadID = - threadObj.getProperty(rt, "containingThreadID"); - std::unique_ptr containingThreadID = - maybeContainingThreadID.isString() - ? std::make_unique( - maybeContainingThreadID.asString(rt).utf8(rt)) - : nullptr; - - jsi::Value maybeCommunity = threadObj.getProperty(rt, "community"); - std::unique_ptr community = maybeCommunity.isString() - ? std::make_unique(maybeCommunity.asString(rt).utf8(rt)) - : nullptr; - - std::string members = - threadObj.getProperty(rt, "members").asString(rt).utf8(rt); - std::string roles = - threadObj.getProperty(rt, "roles").asString(rt).utf8(rt); - std::string currentUser = - threadObj.getProperty(rt, "currentUser").asString(rt).utf8(rt); - - jsi::Value maybeSourceMessageID = - threadObj.getProperty(rt, "sourceMessageID"); - std::unique_ptr sourceMessageID = - maybeSourceMessageID.isString() - ? std::make_unique( - maybeSourceMessageID.asString(rt).utf8(rt)) - : nullptr; - - int repliesCount = - std::lround(threadObj.getProperty(rt, "repliesCount").asNumber()); - - jsi::Value maybeAvatar = threadObj.getProperty(rt, "avatar"); - std::unique_ptr avatar = maybeAvatar.isString() - ? std::make_unique(maybeAvatar.asString(rt).utf8(rt)) - : nullptr; - - jsi::Value maybePinnedCount = threadObj.getProperty(rt, "pinnedCount"); - int pinnedCount = maybePinnedCount.isNumber() - ? std::lround(maybePinnedCount.asNumber()) - : 0; - Thread thread{ - threadID, - type, - std::move(name), - std::move(description), - color, - creationTime, - std::move(parentThreadID), - std::move(containingThreadID), - std::move(community), - members, - roles, - currentUser, - std::move(sourceMessageID), - repliesCount, - std::move(avatar), - pinnedCount}; - - threadStoreOps.push_back( - std::make_unique(std::move(thread))); - } else { - throw std::runtime_error("unsupported operation: " + opType); - } - }; - return threadStoreOps; -} - jsi::Value CommCoreModule::processThreadStoreOperations( jsi::Runtime &rt, jsi::Array operations) { - std::string operationsError; - std::shared_ptr>> - threadStoreOpsPtr; - try { - auto threadStoreOps = createThreadStoreOperations(rt, operations); - threadStoreOpsPtr = std::make_shared< - std::vector>>( - std::move(threadStoreOps)); - } catch (std::runtime_error &e) { - operationsError = e.what(); - } - return createPromiseAsJSIValue( - rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { - taskType job = [=]() { - std::string error = operationsError; - if (!error.size()) { - try { - DatabaseManager::getQueryExecutor().beginTransaction(); - for (const auto &operation : *threadStoreOpsPtr) { - 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->threadStore.processStoreOperations(rt, std::move(operations)); } void CommCoreModule::processThreadStoreOperationsSync( jsi::Runtime &rt, jsi::Array operations) { - std::vector> threadStoreOps; - - try { - threadStoreOps = createThreadStoreOperations(rt, operations); - } catch (const std::exception &e) { - throw jsi::JSError(rt, e.what()); - } - - NativeModuleUtils::runSyncOrThrowJSError(rt, [&threadStoreOps]() { - try { - DatabaseManager::getQueryExecutor().beginTransaction(); - for (const auto &operation : threadStoreOps) { - operation->execute(); - } - DatabaseManager::getQueryExecutor().commitTransaction(); - } catch (const std::exception &e) { - DatabaseManager::getQueryExecutor().rollbackTransaction(); - throw e; - } - }); + this->threadStore.processStoreOperationsSync(rt, std::move(operations)); } const std::string REPLACE_REPORT_OPERATION = "replace_report"; @@ -1127,7 +894,8 @@ std::shared_ptr jsInvoker) : facebook::react::CommCoreModuleSchemaCxxSpecJSI(jsInvoker), cryptoThread(std::make_unique("crypto")), - draftStore(jsInvoker) { + draftStore(jsInvoker), + threadStore(jsInvoker) { GlobalDBSingleton::instance.enableMultithreading(); } diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ThreadStore.h b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ThreadStore.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ThreadStore.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../../../DatabaseManagers/entities/Thread.h" +#include "BaseDataStore.h" +#include "ThreadStoreOperations.h" + +#include + +namespace comm { + +class ThreadStore : public BaseDataStore { +private: + static OperationType REMOVE_OPERATION; + static OperationType REMOVE_ALL_OPERATION; + static OperationType REPLACE_OPERATION; + +public: + ThreadStore(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/ThreadStore.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ThreadStore.cpp new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/DataStores/ThreadStore.cpp @@ -0,0 +1,200 @@ +#include "ThreadStore.h" + +#include +#include + +namespace comm { + +using namespace facebook::react; + +OperationType ThreadStore::REMOVE_OPERATION = "remove"; +OperationType ThreadStore::REMOVE_ALL_OPERATION = "remove_all"; +OperationType ThreadStore::REPLACE_OPERATION = "replace"; + +ThreadStore::ThreadStore( + std::shared_ptr jsInvoker) + : BaseDataStore(jsInvoker) { +} + +jsi::Array ThreadStore::parseDBDataStore( + jsi::Runtime &rt, + std::shared_ptr> threadsVectorPtr) const { + size_t numThreads = threadsVectorPtr->size(); + jsi::Array jsiThreads = jsi::Array(rt, numThreads); + size_t writeIdx = 0; + for (const Thread &thread : *threadsVectorPtr) { + jsi::Object jsiThread = jsi::Object(rt); + jsiThread.setProperty(rt, "id", thread.id); + jsiThread.setProperty(rt, "type", thread.type); + jsiThread.setProperty( + rt, + "name", + thread.name ? jsi::String::createFromUtf8(rt, *thread.name) + : jsi::Value::null()); + jsiThread.setProperty( + rt, + "description", + thread.description + ? jsi::String::createFromUtf8(rt, *thread.description) + : jsi::Value::null()); + jsiThread.setProperty(rt, "color", thread.color); + jsiThread.setProperty( + rt, "creationTime", std::to_string(thread.creation_time)); + jsiThread.setProperty( + rt, + "parentThreadID", + thread.parent_thread_id + ? jsi::String::createFromUtf8(rt, *thread.parent_thread_id) + : jsi::Value::null()); + jsiThread.setProperty( + rt, + "containingThreadID", + thread.containing_thread_id + ? jsi::String::createFromUtf8(rt, *thread.containing_thread_id) + : jsi::Value::null()); + jsiThread.setProperty( + rt, + "community", + thread.community ? jsi::String::createFromUtf8(rt, *thread.community) + : jsi::Value::null()); + jsiThread.setProperty(rt, "members", thread.members); + jsiThread.setProperty(rt, "roles", thread.roles); + jsiThread.setProperty(rt, "currentUser", thread.current_user); + jsiThread.setProperty( + rt, + "sourceMessageID", + thread.source_message_id + ? jsi::String::createFromUtf8(rt, *thread.source_message_id) + : jsi::Value::null()); + jsiThread.setProperty(rt, "repliesCount", thread.replies_count); + jsiThread.setProperty(rt, "pinnedCount", thread.pinned_count); + + if (thread.avatar) { + auto avatar = jsi::String::createFromUtf8(rt, *thread.avatar); + jsiThread.setProperty(rt, "avatar", avatar); + } + + jsiThreads.setValueAtIndex(rt, writeIdx++, jsiThread); + } + return jsiThreads; +} + +std::vector> +ThreadStore::createOperations(jsi::Runtime &rt, const jsi::Array &operations) + const { + std::vector> threadStoreOps; + + 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 threadIDsToRemove; + jsi::Object payloadObj = op.getProperty(rt, "payload").asObject(rt); + jsi::Array threadIDs = + payloadObj.getProperty(rt, "ids").asObject(rt).asArray(rt); + for (int threadIdx = 0; threadIdx < threadIDs.size(rt); threadIdx++) { + threadIDsToRemove.push_back( + threadIDs.getValueAtIndex(rt, threadIdx).asString(rt).utf8(rt)); + } + threadStoreOps.push_back(std::make_unique( + std::move(threadIDsToRemove))); + } else if (opType == REMOVE_ALL_OPERATION) { + threadStoreOps.push_back(std::make_unique()); + } else if (opType == REPLACE_OPERATION) { + jsi::Object threadObj = op.getProperty(rt, "payload").asObject(rt); + std::string threadID = + threadObj.getProperty(rt, "id").asString(rt).utf8(rt); + int type = std::lround(threadObj.getProperty(rt, "type").asNumber()); + jsi::Value maybeName = threadObj.getProperty(rt, "name"); + std::unique_ptr name = maybeName.isString() + ? std::make_unique(maybeName.asString(rt).utf8(rt)) + : nullptr; + + jsi::Value maybeDescription = threadObj.getProperty(rt, "description"); + std::unique_ptr description = maybeDescription.isString() + ? std::make_unique( + maybeDescription.asString(rt).utf8(rt)) + : nullptr; + + std::string color = + threadObj.getProperty(rt, "color").asString(rt).utf8(rt); + int64_t creationTime = std::stoll( + threadObj.getProperty(rt, "creationTime").asString(rt).utf8(rt)); + + jsi::Value maybeParentThreadID = + threadObj.getProperty(rt, "parentThreadID"); + std::unique_ptr parentThreadID = + maybeParentThreadID.isString() + ? std::make_unique( + maybeParentThreadID.asString(rt).utf8(rt)) + : nullptr; + + jsi::Value maybeContainingThreadID = + threadObj.getProperty(rt, "containingThreadID"); + std::unique_ptr containingThreadID = + maybeContainingThreadID.isString() + ? std::make_unique( + maybeContainingThreadID.asString(rt).utf8(rt)) + : nullptr; + + jsi::Value maybeCommunity = threadObj.getProperty(rt, "community"); + std::unique_ptr community = maybeCommunity.isString() + ? std::make_unique(maybeCommunity.asString(rt).utf8(rt)) + : nullptr; + + std::string members = + threadObj.getProperty(rt, "members").asString(rt).utf8(rt); + std::string roles = + threadObj.getProperty(rt, "roles").asString(rt).utf8(rt); + std::string currentUser = + threadObj.getProperty(rt, "currentUser").asString(rt).utf8(rt); + + jsi::Value maybeSourceMessageID = + threadObj.getProperty(rt, "sourceMessageID"); + std::unique_ptr sourceMessageID = + maybeSourceMessageID.isString() + ? std::make_unique( + maybeSourceMessageID.asString(rt).utf8(rt)) + : nullptr; + + int repliesCount = + std::lround(threadObj.getProperty(rt, "repliesCount").asNumber()); + + jsi::Value maybeAvatar = threadObj.getProperty(rt, "avatar"); + std::unique_ptr avatar = maybeAvatar.isString() + ? std::make_unique(maybeAvatar.asString(rt).utf8(rt)) + : nullptr; + + jsi::Value maybePinnedCount = threadObj.getProperty(rt, "pinnedCount"); + int pinnedCount = maybePinnedCount.isNumber() + ? std::lround(maybePinnedCount.asNumber()) + : 0; + Thread thread{ + threadID, + type, + std::move(name), + std::move(description), + color, + creationTime, + std::move(parentThreadID), + std::move(containingThreadID), + std::move(community), + members, + roles, + currentUser, + std::move(sourceMessageID), + repliesCount, + std::move(avatar), + pinnedCount}; + + threadStoreOps.push_back( + std::make_unique(std::move(thread))); + } else { + throw std::runtime_error("unsupported operation: " + opType); + } + }; + return threadStoreOps; +} + +} // 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 @@ -50,6 +50,7 @@ 8E86A6D329537EBB000BBE7D /* DatabaseManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E86A6D229537EBB000BBE7D /* DatabaseManager.cpp */; }; 8EA59BD62A6E8E0400EB4F53 /* DraftStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EA59BD42A6E8E0400EB4F53 /* DraftStore.cpp */; }; 8ED8B5342A4DD4EB00D3DA26 /* CommQueryExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8ED8B5332A4DCCE300D3DA26 /* CommQueryExecutor.cpp */; }; + 8EF7756B2A7433630046A385 /* ThreadStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8EF775692A7433630046A385 /* ThreadStore.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 */; }; @@ -202,6 +203,8 @@ 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 = ""; }; 8EE6E4A02A39CCAB00AE6BCD /* DraftStoreOperations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DraftStoreOperations.h; sourceTree = ""; }; + 8EF775692A7433630046A385 /* ThreadStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadStore.cpp; path = PersistentStorageUtilities/DataStores/ThreadStore.cpp; sourceTree = ""; }; + 8EF7756A2A7433630046A385 /* ThreadStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadStore.h; path = PersistentStorageUtilities/DataStores/ThreadStore.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 = ""; }; @@ -561,6 +564,8 @@ 8EA59BD02A6E786200EB4F53 /* DataStores */ = { isa = PBXGroup; children = ( + 8EF775692A7433630046A385 /* ThreadStore.cpp */, + 8EF7756A2A7433630046A385 /* ThreadStore.h */, 8EA59BD42A6E8E0400EB4F53 /* DraftStore.cpp */, 8EA59BD52A6E8E0400EB4F53 /* DraftStore.h */, 8EA59BD32A6E8CB700EB4F53 /* BaseDataStore.h */, @@ -1012,6 +1017,7 @@ buildActionMask = 2147483647; files = ( 8ED8B5342A4DD4EB00D3DA26 /* CommQueryExecutor.cpp in Sources */, + 8EF7756B2A7433630046A385 /* ThreadStore.cpp in Sources */, CB2689002A2DF58000EC7300 /* CommConstants.cpp in Sources */, CB7EF17E295C674300B17035 /* CommIOSNotifications.mm in Sources */, CB7EF180295C674300B17035 /* CommIOSNotificationsBridgeQueue.mm in Sources */,