Reduce number of SQL queries during conversation update

This commit is contained in:
Fedor Indutny 2021-08-16 09:56:27 -07:00 committed by GitHub
parent 765b3eddc4
commit 962515031d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 91 deletions

View file

@ -48,6 +48,7 @@ import {
IdentityKeyType,
ItemKeyType,
ItemType,
LastConversationMessagesType,
MessageType,
MessageTypeUnhydrated,
PreKeyType,
@ -190,7 +191,6 @@ const dataInterface: ClientInterface = {
searchMessagesInConversation,
getMessageCount,
hasUserInitiatedMessages,
saveMessage,
saveMessages,
removeMessage,
@ -213,8 +213,7 @@ const dataInterface: ClientInterface = {
getTapToViewMessagesNeedingErase,
getOlderMessagesByConversation,
getNewerMessagesByConversation,
getLastConversationActivity,
getLastConversationPreview,
getLastConversationMessages,
getMessageMetricsForConversation,
hasGroupCallHistoryMessage,
migrateConversationMessages,
@ -1063,10 +1062,6 @@ async function getMessageCount(conversationId?: string) {
return channels.getMessageCount(conversationId);
}
async function hasUserInitiatedMessages(conversationId: string) {
return channels.hasUserInitiatedMessages(conversationId);
}
async function saveMessage(
data: MessageType,
options?: { forceSave?: boolean }
@ -1267,7 +1262,7 @@ async function getNewerMessagesByConversation(
return new MessageCollection(handleMessageJSON(messages));
}
async function getLastConversationActivity({
async function getLastConversationMessages({
conversationId,
ourConversationId,
Message,
@ -1275,33 +1270,21 @@ async function getLastConversationActivity({
conversationId: string;
ourConversationId: string;
Message: typeof MessageModel;
}): Promise<MessageModel | undefined> {
const result = await channels.getLastConversationActivity({
}): Promise<LastConversationMessagesType> {
const {
preview,
activity,
hasUserInitiatedMessages,
} = await channels.getLastConversationMessages({
conversationId,
ourConversationId,
});
if (result) {
return new Message(result);
}
return undefined;
}
async function getLastConversationPreview({
conversationId,
ourConversationId,
Message,
}: {
conversationId: string;
ourConversationId: string;
Message: typeof MessageModel;
}): Promise<MessageModel | undefined> {
const result = await channels.getLastConversationPreview({
conversationId,
ourConversationId,
});
if (result) {
return new Message(result);
}
return undefined;
return {
preview: preview ? new Message(preview) : undefined,
activity: activity ? new Message(activity) : undefined,
hasUserInitiatedMessages,
};
}
async function getMessageMetricsForConversation(conversationId: string) {
const result = await channels.getMessageMetricsForConversation(

View file

@ -201,6 +201,18 @@ export type UnprocessedUpdateType = {
decrypted?: string;
};
export type LastConversationMessagesServerType = {
activity?: MessageType;
preview?: MessageType;
hasUserInitiatedMessages: boolean;
};
export type LastConversationMessagesType = {
activity?: MessageModel;
preview?: MessageModel;
hasUserInitiatedMessages: boolean;
};
export type DataInterface = {
close: () => Promise<void>;
removeDB: () => Promise<void>;
@ -302,7 +314,6 @@ export type DataInterface = {
options?: { forceSave?: boolean }
) => Promise<void>;
getMessageCount: (conversationId?: string) => Promise<number>;
hasUserInitiatedMessages: (conversationId: string) => Promise<boolean>;
getAllMessageIds: () => Promise<Array<string>>;
getMessageMetricsForConversation: (
conversationId: string
@ -476,14 +487,10 @@ export type ServerInterface = DataInterface & {
conversationId: string,
options?: { limit?: number; receivedAt?: number; sentAt?: number }
) => Promise<Array<MessageTypeUnhydrated>>;
getLastConversationActivity: (options: {
getLastConversationMessages: (options: {
conversationId: string;
ourConversationId: string;
}) => Promise<MessageType | undefined>;
getLastConversationPreview: (options: {
conversationId: string;
ourConversationId: string;
}) => Promise<MessageType | undefined>;
}) => Promise<LastConversationMessagesServerType>;
getTapToViewMessagesNeedingErase: () => Promise<Array<MessageType>>;
removeConversation: (id: Array<string> | string) => Promise<void>;
removeMessage: (id: string) => Promise<void>;
@ -576,16 +583,11 @@ export type ClientInterface = DataInterface & {
MessageCollection: typeof MessageModelCollectionType;
}
) => Promise<MessageModelCollectionType>;
getLastConversationActivity: (options: {
getLastConversationMessages: (options: {
conversationId: string;
ourConversationId: string;
Message: typeof MessageModel;
}) => Promise<MessageModel | undefined>;
getLastConversationPreview: (options: {
conversationId: string;
ourConversationId: string;
Message: typeof MessageModel;
}) => Promise<MessageModel | undefined>;
}) => Promise<LastConversationMessagesType>;
getTapToViewMessagesNeedingErase: (options: {
MessageCollection: typeof MessageModelCollectionType;
}) => Promise<MessageModelCollectionType>;

View file

@ -52,6 +52,7 @@ import {
IdentityKeyType,
ItemKeyType,
ItemType,
LastConversationMessagesServerType,
MessageMetricsType,
MessageType,
MessageTypeUnhydrated,
@ -179,7 +180,6 @@ const dataInterface: ServerInterface = {
searchMessagesInConversation,
getMessageCount,
hasUserInitiatedMessages,
saveMessage,
saveMessages,
removeMessage,
@ -203,8 +203,7 @@ const dataInterface: ServerInterface = {
getOlderMessagesByConversation,
getNewerMessagesByConversation,
getMessageMetricsForConversation,
getLastConversationActivity,
getLastConversationPreview,
getLastConversationMessages,
hasGroupCallHistoryMessage,
migrateConversationMessages,
@ -3513,10 +3512,7 @@ async function getMessageCount(conversationId?: string): Promise<number> {
return row['count(*)'];
}
// Called only for private conversations
async function hasUserInitiatedMessages(
conversationId: string
): Promise<boolean> {
function hasUserInitiatedMessages(conversationId: string): boolean {
const db = getInstance();
// We apply the limit in the sub-query so that `json_extract` wouldn't run
@ -3538,10 +3534,10 @@ async function hasUserInitiatedMessages(
'keychange',
'group-v1-migration',
'universal-timer-notification',
'change-number-notification'
'change-number-notification',
'group-v2-change'
)
) AND
json_extract(json, '$.expirationTimerUpdate') IS NULL
)
LIMIT 1
);
`
@ -4218,13 +4214,13 @@ function getNewestMessageForConversation(
return row;
}
async function getLastConversationActivity({
function getLastConversationActivity({
conversationId,
ourConversationId,
}: {
conversationId: string;
ourConversationId: string;
}): Promise<MessageType | undefined> {
}): MessageType | undefined {
const db = getInstance();
const row = prepare(
db,
@ -4270,13 +4266,13 @@ async function getLastConversationActivity({
return jsonToObject(row.json);
}
async function getLastConversationPreview({
function getLastConversationPreview({
conversationId,
ourConversationId,
}: {
conversationId: string;
ourConversationId: string;
}): Promise<MessageType | undefined> {
}): MessageType | undefined {
const db = getInstance();
const row = prepare(
db,
@ -4317,6 +4313,31 @@ async function getLastConversationPreview({
return jsonToObject(row.json);
}
async function getLastConversationMessages({
conversationId,
ourConversationId,
}: {
conversationId: string;
ourConversationId: string;
}): Promise<LastConversationMessagesServerType> {
const db = getInstance();
return db.transaction(() => {
return {
activity: getLastConversationActivity({
conversationId,
ourConversationId,
}),
preview: getLastConversationPreview({
conversationId,
ourConversationId,
}),
hasUserInitiatedMessages: hasUserInitiatedMessages(conversationId),
};
})();
}
function getOldestUnreadMessageForConversation(
conversationId: string
): MessageMetricsType | undefined {