diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h @@ -49,11 +49,13 @@ virtual void removeMessages(const std::vector &ids) const = 0; virtual void removeMessagesForThreads(const std::vector &threadIDs) const = 0; - virtual void replaceMessage(const Message &message) const = 0; + virtual void + replaceMessage(const Message &message, bool backupItem) const = 0; virtual void rekeyMessage(std::string from, std::string to) const = 0; virtual void removeAllMedia() const = 0; virtual void replaceMessageStoreThreads( - const std::vector &threads) const = 0; + const std::vector &threads, + bool backupItem) const = 0; virtual void removeMessageStoreThreads(const std::vector &ids) const = 0; virtual void removeAllMessageStoreThreads() const = 0; @@ -63,11 +65,11 @@ virtual void removeMediaForMessage(std::string msgID) const = 0; virtual void removeMediaForThreads(const std::vector &threadIDs) const = 0; - virtual void replaceMedia(const Media &media) const = 0; + virtual void replaceMedia(const Media &media, bool backupItem) const = 0; virtual void rekeyMediaContainers(std::string from, std::string to) const = 0; virtual std::vector getAllThreads() const = 0; virtual void removeThreads(std::vector ids) const = 0; - virtual void replaceThread(const Thread &thread) const = 0; + virtual void replaceThread(const Thread &thread, bool backupItem) const = 0; virtual void removeAllThreads() const = 0; virtual void replaceReport(const Report &report) const = 0; virtual void removeReports(const std::vector &ids) const = 0; @@ -108,18 +110,21 @@ virtual void removeAllAuxUserInfos() const = 0; virtual std::vector getAllAuxUserInfos() const = 0; virtual void replaceThreadActivityEntry( - const ThreadActivityEntry &threadActivityEntry) const = 0; + const ThreadActivityEntry &threadActivityEntry, + bool backupItem) const = 0; virtual void removeThreadActivityEntries(const std::vector &ids) const = 0; virtual void removeAllThreadActivityEntries() const = 0; virtual std::vector getAllThreadActivityEntries() const = 0; - virtual void replaceEntry(const EntryInfo &entryInfo) const = 0; + virtual void + replaceEntry(const EntryInfo &entryInfo, bool backupItem) const = 0; virtual void removeEntries(const std::vector &ids) const = 0; virtual void removeAllEntries() const = 0; virtual std::vector getAllEntries() const = 0; virtual void replaceMessageStoreLocalMessageInfo( - const LocalMessageInfo &localMessageInfo) const = 0; + const LocalMessageInfo &localMessageInfo, + bool backupItem) const = 0; virtual void removeMessageStoreLocalMessageInfos( const std::vector &ids) const = 0; virtual void removeAllMessageStoreLocalMessageInfos() const = 0; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h @@ -52,10 +52,11 @@ void removeMessages(const std::vector &ids) const override; void removeMessagesForThreads( const std::vector &threadIDs) const override; - void replaceMessage(const Message &message) const override; + void replaceMessage(const Message &message, bool backupItem) const override; void rekeyMessage(std::string from, std::string to) const override; void replaceMessageStoreThreads( - const std::vector &threads) const override; + const std::vector &threads, + bool backupItem) const override; void removeMessageStoreThreads(const std::vector &ids) const override; void removeAllMessageStoreThreads() const override; @@ -66,11 +67,11 @@ void removeMediaForMessage(std::string msgID) const override; void removeMediaForThreads( const std::vector &threadIDs) const override; - void replaceMedia(const Media &media) const override; + void replaceMedia(const Media &media, bool backupItem) const override; void rekeyMediaContainers(std::string from, std::string to) const override; std::vector getAllThreads() const override; void removeThreads(std::vector ids) const override; - void replaceThread(const Thread &thread) const override; + void replaceThread(const Thread &thread, bool backupItem) const override; void removeAllThreads() const override; void replaceReport(const Report &report) const override; void removeReports(const std::vector &ids) const override; @@ -108,17 +109,19 @@ void removeAllAuxUserInfos() const override; virtual std::vector getAllAuxUserInfos() const override; void replaceThreadActivityEntry( - const ThreadActivityEntry &threadActivityEntry) const override; + const ThreadActivityEntry &threadActivityEntry, + bool backupItem) const override; void removeThreadActivityEntries( const std::vector &ids) const override; void removeAllThreadActivityEntries() const override; std::vector getAllThreadActivityEntries() const override; - void replaceEntry(const EntryInfo &entryInfo) const override; + void replaceEntry(const EntryInfo &entryInfo, bool backupItem) const override; void removeEntries(const std::vector &ids) const override; void removeAllEntries() const override; std::vector getAllEntries() const override; void replaceMessageStoreLocalMessageInfo( - const LocalMessageInfo &localMessageInfo) const override; + const LocalMessageInfo &localMessageInfo, + bool backupItem) const override; void removeMessageStoreLocalMessageInfos( const std::vector &ids) const override; void removeAllMessageStoreLocalMessageInfos() const override; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp @@ -309,12 +309,15 @@ } } -void SQLiteQueryExecutor::replaceMessage(const Message &message) const { +void SQLiteQueryExecutor::replaceMessage( + const Message &message, + bool backupItem) const { int sidebarSourceTypeInt = static_cast(MessageType::SIDEBAR_SOURCE); std::string sidebarSourceType = std::to_string(sidebarSourceTypeInt); - static std::string replaceMessageSQL = - "REPLACE INTO messages (" + std::string tableName = backupItem ? "backup_messages" : "messages"; + std::string replaceMessageSQL = "REPLACE INTO " + tableName + + "(" " id, local_id, thread, user, type, future_type, content, time, " " target_message" ")" @@ -463,9 +466,10 @@ } } -void SQLiteQueryExecutor::replaceMedia(const Media &media) const { - static std::string replaceMediaSQL = - "REPLACE INTO media " +void SQLiteQueryExecutor::replaceMedia(const Media &media, bool backupItem) + const { + std::string tableName = backupItem ? "backup_media" : "media"; + std::string replaceMediaSQL = "REPLACE INTO " + tableName + "(id, container, thread, uri, type, extras) " "VALUES (?, ?, ?, ?, ?, ?)"; replaceEntity(this->getConnection(), replaceMediaSQL, media); @@ -482,9 +486,11 @@ } void SQLiteQueryExecutor::replaceMessageStoreThreads( - const std::vector &threads) const { - static std::string replaceMessageStoreThreadSQL = - "REPLACE INTO message_store_threads " + const std::vector &threads, + bool backupItem) const { + std::string tableName = + backupItem ? "backup_message_store_threads" : "message_store_threads"; + std::string replaceMessageStoreThreadSQL = "REPLACE INTO " + tableName + "(id, start_reached) " "VALUES (?, ?);"; @@ -560,9 +566,11 @@ } }; -void SQLiteQueryExecutor::replaceThread(const Thread &thread) const { - static std::string replaceThreadSQL = - "REPLACE INTO threads (" +void SQLiteQueryExecutor::replaceThread(const Thread &thread, bool backupItem) + const { + std::string tableName = backupItem ? "backup_threads" : "threads"; + std::string replaceThreadSQL = "REPLACE INTO " + tableName + + "(" " id, type, name, description, color, creation_time, parent_thread_id," " containing_thread_id, community, members, roles, current_user," " source_message_id, replies_count, avatar, pinned_count, timestamps) " @@ -903,9 +911,12 @@ } void SQLiteQueryExecutor::replaceThreadActivityEntry( - const ThreadActivityEntry &threadActivityEntry) const { - static std::string replaceThreadActivityEntrySQL = - "REPLACE INTO thread_activity (id, thread_activity_store_entry) " + const ThreadActivityEntry &threadActivityEntry, + bool backupItem) const { + std::string tableName = + backupItem ? "backup_thread_activity" : "thread_activity"; + std::string replaceThreadActivityEntrySQL = "REPLACE INTO " + tableName + + "(id, thread_activity_store_entry) " "VALUES (?, ?);"; replaceEntity( this->getConnection(), @@ -954,9 +965,12 @@ this->getConnection(), getAllThreadActivityEntriesSQL); } -void SQLiteQueryExecutor::replaceEntry(const EntryInfo &entryInfo) const { - static std::string replaceEntrySQL = - "REPLACE INTO entries (id, entry) " +void SQLiteQueryExecutor::replaceEntry( + const EntryInfo &entryInfo, + bool backupItem) const { + std::string tableName = backupItem ? "backup_entries" : "entries"; + std::string replaceEntrySQL = "REPLACE INTO " + tableName + + "(id, entry) " "VALUES (?, ?);"; replaceEntity(this->getConnection(), replaceEntrySQL, entryInfo); } @@ -995,9 +1009,12 @@ } void SQLiteQueryExecutor::replaceMessageStoreLocalMessageInfo( - const LocalMessageInfo &localMessageInfo) const { - static std::string replaceLocalMessageInfoSQL = - "REPLACE INTO message_store_local (id, local_message_info) " + const LocalMessageInfo &localMessageInfo, + bool backupItem) const { + std::string tableName = + backupItem ? "backup_message_store_local" : "message_store_local"; + std::string replaceLocalMessageInfoSQL = "REPLACE INTO " + tableName + + "(id, local_message_info) " "VALUES (?, ?);"; replaceEntity( this->getConnection(), replaceLocalMessageInfoSQL, localMessageInfo); diff --git a/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h b/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h --- a/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h +++ b/native/cpp/CommonCpp/NativeModules/EntryStoreOperations.h @@ -25,7 +25,7 @@ } virtual void execute(DatabaseIdentifier id) override { - DatabaseManager::getQueryExecutor(id).replaceEntry(this->entry); + DatabaseManager::getQueryExecutor(id).replaceEntry(this->entry, false); } private: diff --git a/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h b/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h --- a/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h +++ b/native/cpp/CommonCpp/NativeModules/MessageStoreOperations.h @@ -114,9 +114,11 @@ virtual void execute(DatabaseIdentifier id) override { DatabaseManager::getQueryExecutor().removeMediaForMessage(msg->id); for (auto &&media : this->media_vector) { - DatabaseManager::getQueryExecutor().replaceMedia(std::move(*media)); + DatabaseManager::getQueryExecutor().replaceMedia( + std::move(*media), false); } - DatabaseManager::getQueryExecutor().replaceMessage(std::move(*this->msg)); + DatabaseManager::getQueryExecutor().replaceMessage( + std::move(*this->msg), false); } private: @@ -169,7 +171,7 @@ virtual void execute(DatabaseIdentifier id) override { DatabaseManager::getQueryExecutor(id).replaceMessageStoreThreads( - this->msg_threads); + this->msg_threads, false); } private: @@ -242,7 +244,7 @@ virtual void execute(DatabaseIdentifier id) override { DatabaseManager::getQueryExecutor(id).replaceMessageStoreLocalMessageInfo( - this->localMessageInfo); + this->localMessageInfo, false); } private: diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.cpp --- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.cpp +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.cpp @@ -116,9 +116,9 @@ translateStringToClientDBMessageInfos(rawMessageInfosString); for (const auto &clientDBMessageInfo : clientDBMessageInfos) { DatabaseManager::getQueryExecutor().replaceMessage( - clientDBMessageInfo.message); + clientDBMessageInfo.message, false); for (const auto &mediaInfo : clientDBMessageInfo.medias) { - DatabaseManager::getQueryExecutor().replaceMedia(mediaInfo); + DatabaseManager::getQueryExecutor().replaceMedia(mediaInfo, false); } } } diff --git a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp --- a/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp +++ b/native/cpp/CommonCpp/NativeModules/PersistentStorageUtilities/ThreadOperationsUtilities/ThreadOperations.cpp @@ -35,6 +35,6 @@ return; } - DatabaseManager::getQueryExecutor().replaceThread(*thread); + DatabaseManager::getQueryExecutor().replaceThread(*thread, false); } } // namespace comm diff --git a/native/cpp/CommonCpp/NativeModules/ThreadActivityStoreOperations.h b/native/cpp/CommonCpp/NativeModules/ThreadActivityStoreOperations.h --- a/native/cpp/CommonCpp/NativeModules/ThreadActivityStoreOperations.h +++ b/native/cpp/CommonCpp/NativeModules/ThreadActivityStoreOperations.h @@ -30,7 +30,7 @@ virtual void execute(DatabaseIdentifier id) override { DatabaseManager::getQueryExecutor(id).replaceThreadActivityEntry( - this->threadActivityEntry); + this->threadActivityEntry, false); } private: diff --git a/native/cpp/CommonCpp/NativeModules/ThreadStoreOperations.h b/native/cpp/CommonCpp/NativeModules/ThreadStoreOperations.h --- a/native/cpp/CommonCpp/NativeModules/ThreadStoreOperations.h +++ b/native/cpp/CommonCpp/NativeModules/ThreadStoreOperations.h @@ -27,7 +27,7 @@ } virtual void execute(DatabaseIdentifier id) override { - DatabaseManager::getQueryExecutor(id).replaceThread(this->thread); + DatabaseManager::getQueryExecutor(id).replaceThread(this->thread, false); } private: diff --git a/web/shared-worker/_generated/comm_query_executor.wasm b/web/shared-worker/_generated/comm_query_executor.wasm index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ { @@ -101,16 +104,19 @@ }); it('should handle malformed JSON content gracefully', () => { - queryExecutor.replaceMessage({ - id: 'malformed', - localID: null, - thread: '1', - user: '1', - type: messageTypes.REACTION, - futureType: null, - content: 'invalid json{', - time: BigInt(1000), - }); + queryExecutor.replaceMessage( + { + id: 'malformed', + localID: null, + thread: '1', + user: '1', + type: messageTypes.REACTION, + futureType: null, + content: 'invalid json{', + time: BigInt(1000), + }, + false, + ); const results = queryExecutor.getRelatedMessages('malformed'); expect(results.length).toBe(1); @@ -331,16 +337,19 @@ content: 'Source message for sidebar', }); - queryExecutor.replaceMessage({ - id: 'sidebar1', - localID: null, - thread: '1', - user: '1', - type: messageTypes.SIDEBAR_SOURCE, - futureType: null, - content: sidebarContent, - time: BigInt(1000), - }); + queryExecutor.replaceMessage( + { + id: 'sidebar1', + localID: null, + thread: '1', + user: '1', + type: messageTypes.SIDEBAR_SOURCE, + futureType: null, + content: sidebarContent, + time: BigInt(1000), + }, + false, + ); const results = queryExecutor.getRelatedMessages('source_msg_id'); expect(results.length).toBe(1); diff --git a/web/shared-worker/queries/message-search.test.js b/web/shared-worker/queries/message-search.test.js --- a/web/shared-worker/queries/message-search.test.js +++ b/web/shared-worker/queries/message-search.test.js @@ -47,7 +47,7 @@ content: text, time: BigInt(123), }; - queryExecutor.replaceMessage(message); + queryExecutor.replaceMessage(message, false); queryExecutor.updateMessageSearchIndex(id, id, text); const result = queryExecutor.searchMessages('test', threadID, null, null); expect(result.length).toBe(1); @@ -57,30 +57,36 @@ it('should find all messages matching provided query', () => { const text1 = 'test text'; const id1 = '1'; - queryExecutor.replaceMessage({ - id: id1, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text1, - time: BigInt(1), - }); + queryExecutor.replaceMessage( + { + id: id1, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text1, + time: BigInt(1), + }, + false, + ); queryExecutor.updateMessageSearchIndex(id1, id1, text1); const text2 = 'I am test'; const id2 = '2'; - queryExecutor.replaceMessage({ - id: id2, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text2, - time: BigInt(1), - }); + queryExecutor.replaceMessage( + { + id: id2, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text2, + time: BigInt(1), + }, + false, + ); queryExecutor.updateMessageSearchIndex(id2, id2, text2); const result = queryExecutor.searchMessages('test', threadID, null, null); expect(result.length).toBe(2); @@ -99,21 +105,24 @@ content: text1, time: BigInt(123), }; - queryExecutor.replaceMessage(matchingMessage); + queryExecutor.replaceMessage(matchingMessage, false); queryExecutor.updateMessageSearchIndex(id1, id1, text1); const text2 = 'I am text'; const id2 = '2'; - queryExecutor.replaceMessage({ - id: id2, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text2, - time: BigInt(1), - }); + queryExecutor.replaceMessage( + { + id: id2, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text2, + time: BigInt(1), + }, + false, + ); queryExecutor.updateMessageSearchIndex(id2, id2, text2); const result = queryExecutor.searchMessages('test', threadID, null, null); expect(result.length).toBe(1); @@ -133,21 +142,24 @@ content: text1, time: BigInt(1), }; - queryExecutor.replaceMessage(matchingMessage); + queryExecutor.replaceMessage(matchingMessage, false); queryExecutor.updateMessageSearchIndex(id1, id1, text1); const text2 = 'I am test'; const id2 = '2'; - queryExecutor.replaceMessage({ - id: id2, - localID, - thread: threadID, - user: userID, - type: messageTypes.EDIT_MESSAGE, - futureType, - content: JSON.stringify({ targetMessageID: id1 }), - time: BigInt(5), - }); + queryExecutor.replaceMessage( + { + id: id2, + localID, + thread: threadID, + user: userID, + type: messageTypes.EDIT_MESSAGE, + futureType, + content: JSON.stringify({ targetMessageID: id1 }), + time: BigInt(5), + }, + false, + ); queryExecutor.updateMessageSearchIndex(id1, id2, text2); const result = queryExecutor.searchMessages('test', threadID, null, null); @@ -173,20 +185,23 @@ content: text, time: timeOlderThanSearchedFor, }; - queryExecutor.replaceMessage(matchingMessage); + queryExecutor.replaceMessage(matchingMessage, false); queryExecutor.updateMessageSearchIndex(id1, id1, text); const id2 = '2'; - queryExecutor.replaceMessage({ - id: id2, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text, - time: timeNewerThanSearchedFor, - }); + queryExecutor.replaceMessage( + { + id: id2, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text, + time: timeNewerThanSearchedFor, + }, + false, + ); queryExecutor.updateMessageSearchIndex(id2, id2, text); const result = queryExecutor.searchMessages( text, @@ -213,20 +228,23 @@ content: text, time, }; - queryExecutor.replaceMessage(matchingMessage); + queryExecutor.replaceMessage(matchingMessage, false); queryExecutor.updateMessageSearchIndex(id1, id1, text); const id2 = '2'; - queryExecutor.replaceMessage({ - id: id2, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text, - time, - }); + queryExecutor.replaceMessage( + { + id: id2, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text, + time, + }, + false, + ); queryExecutor.updateMessageSearchIndex(id2, id2, text); const result = queryExecutor.searchMessages( @@ -260,19 +278,22 @@ content: text, time: olderTimestamp, }; - queryExecutor.replaceMessage(matchingMessage); + queryExecutor.replaceMessage(matchingMessage, false); queryExecutor.updateMessageSearchIndex(greaterID, greaterID, text); - queryExecutor.replaceMessage({ - id: smallerID, - localID, - thread: threadID, - user: userID, - type: messageTypes.TEXT, - futureType, - content: text, - time: youngerTimestamp, - }); + queryExecutor.replaceMessage( + { + id: smallerID, + localID, + thread: threadID, + user: userID, + type: messageTypes.TEXT, + futureType, + content: text, + time: youngerTimestamp, + }, + false, + ); queryExecutor.updateMessageSearchIndex(smallerID, smallerID, text); const result = queryExecutor.searchMessages( text, @@ -300,7 +321,7 @@ content: text, time: BigInt(1), }; - queryExecutor.replaceMessage(secondMessage); + queryExecutor.replaceMessage(secondMessage, false); queryExecutor.updateMessageSearchIndex(id1, id1, text); const id2 = '2'; @@ -314,7 +335,7 @@ content: text, time: BigInt(2), }; - queryExecutor.replaceMessage(firstMessage); + queryExecutor.replaceMessage(firstMessage, false); queryExecutor.updateMessageSearchIndex(id2, id2, text); const result = queryExecutor.searchMessages(text, threadID, null, null); diff --git a/web/shared-worker/queries/message-store-local-queries.test.js b/web/shared-worker/queries/message-store-local-queries.test.js --- a/web/shared-worker/queries/message-store-local-queries.test.js +++ b/web/shared-worker/queries/message-store-local-queries.test.js @@ -21,22 +21,34 @@ if (!queryExecutor) { throw new Error('SQLiteQueryExecutor is missing'); } - queryExecutor.replaceMessageStoreLocalMessageInfo({ - id: '1', - localMessageInfo: JSON.stringify({}), - }); - queryExecutor.replaceMessageStoreLocalMessageInfo({ - id: '2', - localMessageInfo: JSON.stringify({ sendFailed: '1' }), - }); - queryExecutor.replaceMessageStoreLocalMessageInfo({ - id: '3', - localMessageInfo: JSON.stringify({ sendFailed: '0' }), - }); - queryExecutor.replaceMessageStoreLocalMessageInfo({ - id: '4', - localMessageInfo: JSON.stringify({ sendFailed: '1' }), - }); + queryExecutor.replaceMessageStoreLocalMessageInfo( + { + id: '1', + localMessageInfo: JSON.stringify({}), + }, + false, + ); + queryExecutor.replaceMessageStoreLocalMessageInfo( + { + id: '2', + localMessageInfo: JSON.stringify({ sendFailed: '1' }), + }, + false, + ); + queryExecutor.replaceMessageStoreLocalMessageInfo( + { + id: '3', + localMessageInfo: JSON.stringify({ sendFailed: '0' }), + }, + false, + ); + queryExecutor.replaceMessageStoreLocalMessageInfo( + { + id: '4', + localMessageInfo: JSON.stringify({ sendFailed: '1' }), + }, + false, + ); }); afterEach(() => { diff --git a/web/shared-worker/queries/message-store-threads-queries.test.js b/web/shared-worker/queries/message-store-threads-queries.test.js --- a/web/shared-worker/queries/message-store-threads-queries.test.js +++ b/web/shared-worker/queries/message-store-threads-queries.test.js @@ -21,12 +21,15 @@ if (!queryExecutor) { throw new Error('SQLiteQueryExecutor is missing'); } - queryExecutor.replaceMessageStoreThreads([ - { id: '1', startReached: 0 }, - { id: '2', startReached: 0 }, - { id: '3', startReached: 0 }, - { id: '4', startReached: 0 }, - ]); + queryExecutor.replaceMessageStoreThreads( + [ + { id: '1', startReached: 0 }, + { id: '2', startReached: 0 }, + { id: '3', startReached: 0 }, + { id: '4', startReached: 0 }, + ], + false, + ); }); afterEach(() => { diff --git a/web/shared-worker/queries/messages-and-media-queries.test.js b/web/shared-worker/queries/messages-and-media-queries.test.js --- a/web/shared-worker/queries/messages-and-media-queries.test.js +++ b/web/shared-worker/queries/messages-and-media-queries.test.js @@ -23,106 +23,133 @@ if (!queryExecutor) { throw new Error('SQLiteQueryExecutor is missing'); } - queryExecutor.replaceMessage({ - id: '1', - localID: null, - thread: '1', - user: '1', - type: 0, - futureType: null, - content: null, - time: BigInt(0), - }); - queryExecutor.replaceMessage({ - id: '2', - localID: null, - thread: '1', - user: '1', - type: 0, - futureType: null, - content: null, - time: BigInt(0), - }); - queryExecutor.replaceMessage({ - id: '3', - localID: null, - thread: '2', - user: '1', - type: 0, - futureType: 5, - content: null, - time: BigInt(0), - }); - queryExecutor.replaceMedia({ - id: '1', - container: '1', - thread: '1', - uri: '1', - type: 'photo', - extras: '1', - }); - queryExecutor.replaceMedia({ - id: '2', - container: '1', - thread: '1', - uri: '1', - type: 'photo', - extras: '1', - }); - queryExecutor.replaceMedia({ - id: '3', - container: '3', - thread: '2', - uri: '1', - type: 'photo', - extras: '1', - }); - queryExecutor.replaceMedia({ - id: '4', - container: '3', - thread: '2', - uri: '1', - type: 'photo', - extras: '1', - }); - queryExecutor.replaceThread({ - id: '1', - type: threadTypes.COMMUNITY_OPEN_SUBTHREAD, - name: null, - avatar: null, - description: null, - color: 'ffffff', - creationTime: BigInt(1), - parentThreadID: null, - containingThreadID: null, - community: null, - members: '1', - roles: '1', - currentUser: '{}', - sourceMessageID: null, - repliesCount: 0, - pinnedCount: 0, - timestamps: null, - }); - queryExecutor.replaceThread({ - id: '2', - type: threadTypes.COMMUNITY_OPEN_SUBTHREAD, - name: null, - avatar: null, - description: null, - color: 'ffffff', - creationTime: BigInt(1), - parentThreadID: null, - containingThreadID: null, - community: null, - members: '1', - roles: '1', - currentUser: '{}', - sourceMessageID: null, - repliesCount: 0, - pinnedCount: 0, - timestamps: null, - }); + queryExecutor.replaceMessage( + { + id: '1', + localID: null, + thread: '1', + user: '1', + type: 0, + futureType: null, + content: null, + time: BigInt(0), + }, + false, + ); + queryExecutor.replaceMessage( + { + id: '2', + localID: null, + thread: '1', + user: '1', + type: 0, + futureType: null, + content: null, + time: BigInt(0), + }, + false, + ); + queryExecutor.replaceMessage( + { + id: '3', + localID: null, + thread: '2', + user: '1', + type: 0, + futureType: 5, + content: null, + time: BigInt(0), + }, + false, + ); + queryExecutor.replaceMedia( + { + id: '1', + container: '1', + thread: '1', + uri: '1', + type: 'photo', + extras: '1', + }, + false, + ); + queryExecutor.replaceMedia( + { + id: '2', + container: '1', + thread: '1', + uri: '1', + type: 'photo', + extras: '1', + }, + false, + ); + queryExecutor.replaceMedia( + { + id: '3', + container: '3', + thread: '2', + uri: '1', + type: 'photo', + extras: '1', + }, + false, + ); + queryExecutor.replaceMedia( + { + id: '4', + container: '3', + thread: '2', + uri: '1', + type: 'photo', + extras: '1', + }, + false, + ); + queryExecutor.replaceThread( + { + id: '1', + type: threadTypes.COMMUNITY_OPEN_SUBTHREAD, + name: null, + avatar: null, + description: null, + color: 'ffffff', + creationTime: BigInt(1), + parentThreadID: null, + containingThreadID: null, + community: null, + members: '1', + roles: '1', + currentUser: '{}', + sourceMessageID: null, + repliesCount: 0, + pinnedCount: 0, + timestamps: null, + }, + false, + ); + queryExecutor.replaceThread( + { + id: '2', + type: threadTypes.COMMUNITY_OPEN_SUBTHREAD, + name: null, + avatar: null, + description: null, + color: 'ffffff', + creationTime: BigInt(1), + parentThreadID: null, + containingThreadID: null, + community: null, + members: '1', + roles: '1', + currentUser: '{}', + sourceMessageID: null, + repliesCount: 0, + pinnedCount: 0, + timestamps: null, + }, + false, + ); }); afterEach(() => { diff --git a/web/shared-worker/queries/thread-activity-queries.test.js b/web/shared-worker/queries/thread-activity-queries.test.js --- a/web/shared-worker/queries/thread-activity-queries.test.js +++ b/web/shared-worker/queries/thread-activity-queries.test.js @@ -25,27 +25,36 @@ if (!queryExecutor) { throw new Error('SQLiteQueryExecutor is missing'); } - queryExecutor?.replaceThreadActivityEntry({ - id: 'test_id_1', - threadActivityStoreEntry: JSON.stringify({ - lastNavigatedTo: 1, - lastPruned: 2, - }), - }); - queryExecutor?.replaceThreadActivityEntry({ - id: 'test_id_2', - threadActivityStoreEntry: JSON.stringify({ - lastNavigatedTo: 3, - lastPruned: 4, - }), - }); - queryExecutor?.replaceThreadActivityEntry({ - id: 'test_id_3', - threadActivityStoreEntry: JSON.stringify({ - lastNavigatedTo: 5, - lastPruned: 6, - }), - }); + queryExecutor?.replaceThreadActivityEntry( + { + id: 'test_id_1', + threadActivityStoreEntry: JSON.stringify({ + lastNavigatedTo: 1, + lastPruned: 2, + }), + }, + false, + ); + queryExecutor?.replaceThreadActivityEntry( + { + id: 'test_id_2', + threadActivityStoreEntry: JSON.stringify({ + lastNavigatedTo: 3, + lastPruned: 4, + }), + }, + false, + ); + queryExecutor?.replaceThreadActivityEntry( + { + id: 'test_id_3', + threadActivityStoreEntry: JSON.stringify({ + lastNavigatedTo: 5, + lastPruned: 6, + }), + }, + false, + ); }); afterEach(() => { @@ -70,13 +79,16 @@ }); it('should update thread activity entry test_id_2', () => { - queryExecutor?.replaceThreadActivityEntry({ - id: 'test_id_2', - threadActivityStoreEntry: JSON.stringify({ - lastNavigatedTo: 7, - lastPruned: 8, - }), - }); + queryExecutor?.replaceThreadActivityEntry( + { + id: 'test_id_2', + threadActivityStoreEntry: JSON.stringify({ + lastNavigatedTo: 7, + lastPruned: 8, + }), + }, + false, + ); const threadActivityEntries = queryExecutor?.getAllThreadActivityEntries(); if (!threadActivityEntries) { diff --git a/web/shared-worker/queries/threads-queries.test.js b/web/shared-worker/queries/threads-queries.test.js --- a/web/shared-worker/queries/threads-queries.test.js +++ b/web/shared-worker/queries/threads-queries.test.js @@ -21,63 +21,72 @@ if (!queryExecutor) { throw new Error('SQLiteQueryExecutor is missing'); } - queryExecutor.replaceThread({ - id: '1', - type: 1, - name: null, - avatar: null, - description: null, - color: '1', - creationTime: BigInt(1), - parentThreadID: null, - containingThreadID: null, - community: null, - members: '1', - roles: '1', - currentUser: '1', - sourceMessageID: null, - repliesCount: 1, - pinnedCount: 1, - timestamps: null, - }); - queryExecutor.replaceThread({ - id: '2', - type: 1, - name: null, - avatar: null, - description: null, - color: '1', - creationTime: BigInt(1), - parentThreadID: null, - containingThreadID: null, - community: null, - members: '1', - roles: '1', - currentUser: '1', - sourceMessageID: null, - repliesCount: 1, - pinnedCount: 1, - timestamps: null, - }); - queryExecutor.replaceThread({ - id: '3', - type: 1, - name: null, - avatar: null, - description: null, - color: '1', - creationTime: BigInt(1), - parentThreadID: null, - containingThreadID: null, - community: null, - members: '1', - roles: '1', - currentUser: '1', - sourceMessageID: null, - repliesCount: 1, - pinnedCount: 1, - timestamps: null, - }); + queryExecutor.replaceThread( + { + id: '1', + type: 1, + name: null, + avatar: null, + description: null, + color: '1', + creationTime: BigInt(1), + parentThreadID: null, + containingThreadID: null, + community: null, + members: '1', + roles: '1', + currentUser: '1', + sourceMessageID: null, + repliesCount: 1, + pinnedCount: 1, + timestamps: null, + }, + false, + ); + queryExecutor.replaceThread( + { + id: '2', + type: 1, + name: null, + avatar: null, + description: null, + color: '1', + creationTime: BigInt(1), + parentThreadID: null, + containingThreadID: null, + community: null, + members: '1', + roles: '1', + currentUser: '1', + sourceMessageID: null, + repliesCount: 1, + pinnedCount: 1, + timestamps: null, + }, + false, + ); + queryExecutor.replaceThread( + { + id: '3', + type: 1, + name: null, + avatar: null, + description: null, + color: '1', + creationTime: BigInt(1), + parentThreadID: null, + containingThreadID: null, + community: null, + members: '1', + roles: '1', + currentUser: '1', + sourceMessageID: null, + repliesCount: 1, + pinnedCount: 1, + timestamps: null, + }, + false, + ); }); afterEach(() => { diff --git a/web/shared-worker/types/sqlite-query-executor.js b/web/shared-worker/types/sqlite-query-executor.js --- a/web/shared-worker/types/sqlite-query-executor.js +++ b/web/shared-worker/types/sqlite-query-executor.js @@ -70,17 +70,18 @@ removeAllMessages(): void; removeMessages(ids: $ReadOnlyArray): void; removeMessagesForThreads(threadIDs: $ReadOnlyArray): void; - replaceMessage(message: WebMessage): void; + replaceMessage(message: WebMessage, backupItem: boolean): void; rekeyMessage(from: string, to: string): void; removeAllMedia(): void; removeMediaForThreads(threadIDs: $ReadOnlyArray): void; removeMediaForMessages(msgIDs: $ReadOnlyArray): void; removeMediaForMessage(msgID: string): void; - replaceMedia(media: Media): void; + replaceMedia(media: Media, backupItem: boolean): void; rekeyMediaContainers(from: string, to: string): void; replaceMessageStoreThreads( threads: $ReadOnlyArray<{ +id: string, +startReached: number }>, + backupItem: boolean, ): void; removeMessageStoreThreads($ReadOnlyArray): void; getAllMessageStoreThreads(): $ReadOnlyArray<{ @@ -107,7 +108,7 @@ removeAllUsers(): void; getAllUsers(): ClientDBUserInfo[]; - replaceThread(thread: WebClientDBThreadInfo): void; + replaceThread(thread: WebClientDBThreadInfo, backupItem: boolean): void; removeThreads(ids: $ReadOnlyArray): void; removeAllThreads(): void; getAllThreads(): WebClientDBThreadInfo[]; @@ -142,18 +143,20 @@ replaceThreadActivityEntry( threadActivityEntry: ClientDBThreadActivityEntry, + backupItem: boolean, ): void; removeThreadActivityEntries(ids: $ReadOnlyArray): void; removeAllThreadActivityEntries(): void; getAllThreadActivityEntries(): ClientDBThreadActivityEntry[]; - replaceEntry(entryInfo: ClientDBEntryInfo): void; + replaceEntry(entryInfo: ClientDBEntryInfo, backupItem: boolean): void; removeEntries(ids: $ReadOnlyArray): void; removeAllEntries(): void; getAllEntries(): $ReadOnlyArray; replaceMessageStoreLocalMessageInfo( localMessageInfo: ClientDBLocalMessageInfo, + backupItem: boolean, ): void; removeMessageStoreLocalMessageInfos(ids: $ReadOnlyArray): void; removeAllMessageStoreLocalMessageInfos(): void; diff --git a/web/shared-worker/worker/process-operations.js b/web/shared-worker/worker/process-operations.js --- a/web/shared-worker/worker/process-operations.js +++ b/web/shared-worker/worker/process-operations.js @@ -118,6 +118,7 @@ } else if (operation.type === 'replace') { sqliteQueryExecutor.replaceThread( clientDBThreadInfoToWebThread(operation.payload), + false, ); } else { throw new Error('Unsupported thread operation'); @@ -280,9 +281,9 @@ const { message, medias } = clientDBMessageInfoToWebMessage( operation.payload, ); - sqliteQueryExecutor.replaceMessage(message); + sqliteQueryExecutor.replaceMessage(message, false); for (const media of medias) { - sqliteQueryExecutor.replaceMedia(media); + sqliteQueryExecutor.replaceMedia(media, false); } } else if (operation.type === 'remove_all') { sqliteQueryExecutor.removeAllMessages(); @@ -298,6 +299,7 @@ id, startReached: Number(start_reached), })), + false, ); } else if (operation.type === 'remove_all_threads') { sqliteQueryExecutor.removeAllMessageStoreThreads(); @@ -306,10 +308,13 @@ sqliteQueryExecutor.removeMessagesForThreads(threadIDs); } else if (operation.type === 'replace_local_message_info') { const { id, localMessageInfo } = operation.payload; - sqliteQueryExecutor.replaceMessageStoreLocalMessageInfo({ - id, - localMessageInfo, - }); + sqliteQueryExecutor.replaceMessageStoreLocalMessageInfo( + { + id, + localMessageInfo, + }, + false, + ); } else if (operation.type === 'remove_local_message_infos') { const { ids } = operation.payload; sqliteQueryExecutor.removeMessageStoreLocalMessageInfos(ids); @@ -547,10 +552,13 @@ sqliteQueryExecutor.removeThreadActivityEntries(ids); } else if (operation.type === 'replace_thread_activity_entry') { const { id, threadActivityStoreEntry } = operation.payload; - sqliteQueryExecutor.replaceThreadActivityEntry({ - id, - threadActivityStoreEntry, - }); + sqliteQueryExecutor.replaceThreadActivityEntry( + { + id, + threadActivityStoreEntry, + }, + false, + ); } else { throw new Error('Unsupported thread activity operation'); } @@ -581,7 +589,7 @@ sqliteQueryExecutor.removeEntries(ids); } else if (operation.type === 'replace_entry') { const { id, entry } = operation.payload; - sqliteQueryExecutor.replaceEntry({ id, entry }); + sqliteQueryExecutor.replaceEntry({ id, entry }, false); } else { throw new Error('Unsupported entry store operation'); }