Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32186642
D14858.1765085664.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
23 KB
Referenced Files
None
Subscribers
None
D14858.1765085664.diff
View Options
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
@@ -194,7 +194,8 @@
std::optional<std::string> timestampCursor,
std::optional<std::string> messageIDCursor) const = 0;
virtual std::vector<MessageEntity> getRelatedMessagesForSearch(
- const std::vector<std::string> &messageIDs) const = 0;
+ const std::vector<std::string> &messageIDs,
+ bool backupItem) const = 0;
virtual void replaceDMOperation(const DMOperation &operation) const = 0;
virtual void removeAllDMOperations() const = 0;
virtual void
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
@@ -186,7 +186,8 @@
std::optional<std::string> timestampCursor,
std::optional<std::string> messageIDCursor) const override;
std::vector<MessageEntity> getRelatedMessagesForSearch(
- const std::vector<std::string> &messageIDs) const override;
+ const std::vector<std::string> &messageIDs,
+ bool backupItem) const override;
void replaceDMOperation(const DMOperation &operation) const override;
void removeAllDMOperations() const override;
void removeDMOperations(const std::vector<std::string> &ids) 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
@@ -1509,18 +1509,28 @@
std::string threadID,
std::optional<std::string> timestampCursor,
std::optional<std::string> messageIDCursor) const {
+ bool backupItem = !threadIDMatchesKeyserverProtocol(threadID);
+ std::string messagesTable = backupItem ? "backup_messages" : "messages";
+ std::string mediaTable = backupItem ? "backup_media" : "media";
+
std::stringstream searchMessagesSQL;
searchMessagesSQL
<< "SELECT "
" m.id, m.local_id, m.thread, m.user, m.type, m.future_type, "
- " m.content, m.time, media.id, media.container, media.thread, "
- " media.uri, media.type, media.extras "
+ " m.content, m.time, md.id, md.container, md.thread, "
+ " md.uri, md.type, md.extras "
"FROM message_search AS s "
- "LEFT JOIN messages AS m "
+ "LEFT JOIN "
+ << messagesTable
+ << " AS m "
" ON m.id = s.original_message_id "
- "LEFT JOIN media "
- " ON m.id = media.container "
- "LEFT JOIN messages AS m2 "
+ "LEFT JOIN "
+ << mediaTable
+ << " AS md "
+ " ON m.id = md.container "
+ "LEFT JOIN "
+ << messagesTable
+ << " AS m2 "
" ON m2.target_message = m.id "
" AND m2.type = ? AND m2.thread = ? "
"WHERE s.processed_content MATCH ? "
@@ -1560,7 +1570,7 @@
messageIDs.push_back(message.message.id);
}
std::vector<MessageEntity> relatedMessages =
- this->getRelatedMessagesForSearch(messageIDs);
+ this->getRelatedMessagesForSearch(messageIDs, backupItem);
for (auto &entity : relatedMessages) {
messages.push_back(std::move(entity));
@@ -1569,17 +1579,24 @@
}
std::vector<MessageEntity> SQLiteQueryExecutor::getRelatedMessagesForSearch(
- const std::vector<std::string> &messageIDs) const {
+ const std::vector<std::string> &messageIDs,
+ bool backupItem) const {
+ std::string messagesTable = backupItem ? "backup_messages" : "messages";
+ std::string mediaTable = backupItem ? "backup_media" : "media";
std::stringstream selectRelatedMessagesSQLStream;
selectRelatedMessagesSQLStream << "SELECT "
" m.id, m.local_id, m.thread, m.user, "
" m.type, m.future_type, m.content, "
- " m.time, media.id, media.container, "
- " media.thread, media.uri, media.type, "
- " media.extras "
- "FROM messages AS m "
- "LEFT JOIN media "
- " ON m.id = media.container "
+ " m.time, md.id, md.container, "
+ " md.thread, md.uri, md.type, "
+ " md.extras "
+ "FROM "
+ << messagesTable
+ << " AS m "
+ "LEFT JOIN "
+ << mediaTable
+ << " AS md "
+ " ON m.id = md.container "
"WHERE m.target_message IN "
<< getSQLStatementArray(messageIDs.size())
<< "ORDER BY m.time DESC";
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$@<O00001
literal 0
Hc$@<O00001
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
@@ -1,5 +1,6 @@
// @flow
+import { getProtocolByThreadID } from 'lib/shared/threads/protocols/thread-protocols.js';
import { messageTypes } from 'lib/types/message-types-enum.js';
import { getDatabaseModule } from '../db-module.js';
@@ -11,11 +12,22 @@
describe('Message search queries', () => {
let queryExecutor;
let dbModule;
- const threadID = '100';
+
const userID = '111';
const futureType = null;
const localID = null;
+ const testCases = [
+ {
+ threadID: '40db5619-feb2-4e5f-bd0c-1f9a709d366e',
+ description: 'with thick thread',
+ },
+ {
+ threadID: '7A8BC7B3-BBBE-4980-8737-E3E67A26FBD2|115614',
+ description: 'with thin thread',
+ },
+ ];
+
beforeAll(async () => {
dbModule = getDatabaseModule();
});
@@ -34,31 +46,72 @@
clearSensitiveData(dbModule, FILE_PATH, queryExecutor);
});
- it('should find messages matching provided query', () => {
- const text = 'test text';
- const id = '1';
- const message: WebMessage = {
- id,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time: BigInt(123),
- };
- queryExecutor.replaceMessage(message, false);
- queryExecutor.updateMessageSearchIndex(id, id, text);
- const result = queryExecutor.searchMessages('test', threadID, null, null);
- expect(result.length).toBe(1);
- expect(result[0].message).toStrictEqual(message);
- });
-
- it('should find all messages matching provided query', () => {
- const text1 = 'test text';
- const id1 = '1';
- queryExecutor.replaceMessage(
- {
+ testCases.forEach(({ threadID, description }) => {
+ it(`should find messages matching provided query ${description}`, () => {
+ const text = 'test text';
+ const id = '1';
+ const message: WebMessage = {
+ id,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: text,
+ time: BigInt(123),
+ };
+ queryExecutor.replaceMessage(
+ message,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id, id, text);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(message);
+ });
+
+ it(`should find all messages matching provided query ${description}`, () => {
+ 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),
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ 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),
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id2, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(2);
+ });
+
+ it(`should ignore messages not matching provided query ${description}`, () => {
+ const text1 = 'test text';
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
id: id1,
localID,
thread: threadID,
@@ -66,281 +119,266 @@
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,
+ time: BigInt(123),
+ };
+ queryExecutor.replaceMessage(
+ matchingMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ 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),
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id2, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it(`should match message edits ${description}`, () => {
+ const text1 = 'I am text';
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
localID,
thread: threadID,
user: userID,
type: messageTypes.TEXT,
futureType,
- content: text2,
+ content: text1,
time: BigInt(1),
- },
- false,
- );
- queryExecutor.updateMessageSearchIndex(id2, id2, text2);
- const result = queryExecutor.searchMessages('test', threadID, null, null);
- expect(result.length).toBe(2);
- });
-
- it('should ignore messages not matching provided query', () => {
- const text1 = 'test text';
- const id1 = '1';
- const matchingMessage: WebMessage = {
- id: id1,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text1,
- time: BigInt(123),
- };
- queryExecutor.replaceMessage(matchingMessage, false);
- queryExecutor.updateMessageSearchIndex(id1, id1, text1);
-
- const text2 = 'I am text';
- const id2 = '2';
- queryExecutor.replaceMessage(
- {
- id: id2,
+ };
+ queryExecutor.replaceMessage(
+ matchingMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ 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),
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id1, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+
+ expect(result.length).toBe(2);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it(`should return only messages with time equal or smaller than timestampCursor ${description}`, () => {
+ const timeOlderThanSearchedFor = BigInt(1);
+ const timeSearchedFor = '1000';
+ const timeNewerThanSearchedFor = BigInt(2000);
+
+ const text = 'test';
+
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
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);
- expect(result[0].message).toStrictEqual(matchingMessage);
- });
-
- it('should match message edits', () => {
- const text1 = 'I am text';
- const id1 = '1';
- const matchingMessage: WebMessage = {
- id: id1,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text1,
- time: BigInt(1),
- };
- queryExecutor.replaceMessage(matchingMessage, false);
- queryExecutor.updateMessageSearchIndex(id1, id1, text1);
-
- const text2 = 'I am test';
- const id2 = '2';
- queryExecutor.replaceMessage(
- {
- id: id2,
+ content: text,
+ time: timeOlderThanSearchedFor,
+ };
+ queryExecutor.replaceMessage(
+ matchingMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ 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,
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+ const result = queryExecutor.searchMessages(
+ text,
+ threadID,
+ timeSearchedFor,
+ '0',
+ );
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it(`should correctly return messages with regards to messageIDCursor ${description}`, () => {
+ const text = 'test';
+ const time = BigInt(1);
+
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
localID,
thread: threadID,
user: userID,
- type: messageTypes.EDIT_MESSAGE,
+ type: messageTypes.TEXT,
futureType,
- content: JSON.stringify({ targetMessageID: id1 }),
- time: BigInt(5),
- },
- false,
- );
- queryExecutor.updateMessageSearchIndex(id1, id2, text2);
- const result = queryExecutor.searchMessages('test', threadID, null, null);
-
- expect(result.length).toBe(2);
- expect(result[0].message).toStrictEqual(matchingMessage);
- });
-
- it('should return only messages with time equal or smaller than timestampCursor', () => {
- const timeOlderThanSearchedFor = BigInt(1);
- const timeSearchedFor = '1000';
- const timeNewerThanSearchedFor = BigInt(2000);
-
- const text = 'test';
-
- const id1 = '1';
- const matchingMessage: WebMessage = {
- id: id1,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time: timeOlderThanSearchedFor,
- };
- queryExecutor.replaceMessage(matchingMessage, false);
- queryExecutor.updateMessageSearchIndex(id1, id1, text);
-
- const id2 = '2';
- queryExecutor.replaceMessage(
- {
- id: id2,
+ content: text,
+ time,
+ };
+ queryExecutor.replaceMessage(
+ matchingMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id1, id1, text);
+
+ const id2 = '2';
+ queryExecutor.replaceMessage(
+ {
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: text,
+ time,
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+
+ const result = queryExecutor.searchMessages(
+ text,
+ threadID,
+ time.toString(),
+ id2,
+ );
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it(`should prioritize timestampCursor over messageIDCursor ${description}`, () => {
+ const text = 'text';
+
+ const greaterID = '600';
+ const smallerID = '2';
+ const intBetweenIDs = '100';
+
+ const olderTimestamp = BigInt(1);
+ const youngerTimestamp = BigInt(1000);
+ const timeBetweenTimestamps = '500';
+
+ const matchingMessage: WebMessage = {
+ id: greaterID,
localID,
thread: threadID,
user: userID,
type: messageTypes.TEXT,
futureType,
content: text,
- time: timeNewerThanSearchedFor,
- },
- false,
- );
- queryExecutor.updateMessageSearchIndex(id2, id2, text);
- const result = queryExecutor.searchMessages(
- text,
- threadID,
- timeSearchedFor,
- '0',
- );
- expect(result.length).toBe(1);
- expect(result[0].message).toStrictEqual(matchingMessage);
- });
-
- it('should correctly return messages with regards to messageIDCursor', () => {
- const text = 'test';
- const time = BigInt(1);
-
- const id1 = '1';
- const matchingMessage: WebMessage = {
- id: id1,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time,
- };
- queryExecutor.replaceMessage(matchingMessage, false);
- queryExecutor.updateMessageSearchIndex(id1, id1, text);
-
- const id2 = '2';
- queryExecutor.replaceMessage(
- {
- id: id2,
+ time: olderTimestamp,
+ };
+ queryExecutor.replaceMessage(
+ matchingMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(greaterID, greaterID, text);
+
+ queryExecutor.replaceMessage(
+ {
+ id: smallerID,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: text,
+ time: youngerTimestamp,
+ },
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(smallerID, smallerID, text);
+ const result = queryExecutor.searchMessages(
+ text,
+ threadID,
+ timeBetweenTimestamps,
+ intBetweenIDs,
+ );
+
+ expect(result.length).toBe(1);
+ expect(result[0].message.id).toBe(greaterID);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it(`should return messages in correct order ${description}`, () => {
+ const text = 'test';
+
+ const id1 = '1';
+ const secondMessage: WebMessage = {
+ id: id1,
localID,
thread: threadID,
user: userID,
type: messageTypes.TEXT,
futureType,
content: text,
- time,
- },
- false,
- );
- queryExecutor.updateMessageSearchIndex(id2, id2, text);
-
- const result = queryExecutor.searchMessages(
- text,
- threadID,
- time.toString(),
- id2,
- );
- expect(result.length).toBe(1);
- expect(result[0].message).toStrictEqual(matchingMessage);
- });
-
- it('should prioritize timestampCursor over messageIDCursor', () => {
- const text = 'text';
-
- const greaterID = '600';
- const smallerID = '2';
- const intBetweenIDs = '100';
-
- const olderTimestamp = BigInt(1);
- const youngerTimestamp = BigInt(1000);
- const timeBetweenTimestamps = '500';
-
- const matchingMessage: WebMessage = {
- id: greaterID,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time: olderTimestamp,
- };
- queryExecutor.replaceMessage(matchingMessage, false);
- queryExecutor.updateMessageSearchIndex(greaterID, greaterID, text);
-
- queryExecutor.replaceMessage(
- {
- id: smallerID,
+ time: BigInt(1),
+ };
+ queryExecutor.replaceMessage(
+ secondMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id1, id1, text);
+
+ const id2 = '2';
+ const firstMessage: WebMessage = {
+ id: id2,
localID,
thread: threadID,
user: userID,
type: messageTypes.TEXT,
futureType,
content: text,
- time: youngerTimestamp,
- },
- false,
- );
- queryExecutor.updateMessageSearchIndex(smallerID, smallerID, text);
- const result = queryExecutor.searchMessages(
- text,
- threadID,
- timeBetweenTimestamps,
- intBetweenIDs,
- );
-
- expect(result.length).toBe(1);
- expect(result[0].message.id).toBe(greaterID);
- expect(result[0].message).toStrictEqual(matchingMessage);
- });
-
- it('should return messages in correct order', () => {
- const text = 'test';
-
- const id1 = '1';
- const secondMessage: WebMessage = {
- id: id1,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time: BigInt(1),
- };
- queryExecutor.replaceMessage(secondMessage, false);
- queryExecutor.updateMessageSearchIndex(id1, id1, text);
-
- const id2 = '2';
- const firstMessage: WebMessage = {
- id: id2,
- localID,
- thread: threadID,
- user: userID,
- type: messageTypes.TEXT,
- futureType,
- content: text,
- time: BigInt(2),
- };
- queryExecutor.replaceMessage(firstMessage, false);
- queryExecutor.updateMessageSearchIndex(id2, id2, text);
-
- const result = queryExecutor.searchMessages(text, threadID, null, null);
- expect(result.length).toBe(2);
- expect(result[0].message).toStrictEqual(firstMessage);
- expect(result[1].message).toStrictEqual(secondMessage);
+ time: BigInt(2),
+ };
+ queryExecutor.replaceMessage(
+ firstMessage,
+ !!getProtocolByThreadID(threadID)?.dataIsBackedUp,
+ );
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+
+ const result = queryExecutor.searchMessages(text, threadID, null, null);
+ expect(result.length).toBe(2);
+ expect(result[0].message).toStrictEqual(firstMessage);
+ expect(result[1].message).toStrictEqual(secondMessage);
+ });
});
});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 5:34 AM (15 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5835782
Default Alt Text
D14858.1765085664.diff (23 KB)
Attached To
Mode
D14858: [SQLite] update `searchMessages` and `getRelatedMessagesForSearch` to support regular and backup tables
Attached
Detach File
Event Timeline
Log In to Comment