From 211a440e7892021b9c97a629baa8f7a5b01752d1 Mon Sep 17 00:00:00 2001 From: IC Rainbow Date: Wed, 3 Jan 2024 20:50:04 +0200 Subject: [PATCH] use chat queries from Direct instead --- .../Chat/Migrations/M20240102_note_folders.hs | 8 +- src/Simplex/Chat/Store/Messages.hs | 100 ++++++++++-------- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/Simplex/Chat/Migrations/M20240102_note_folders.hs b/src/Simplex/Chat/Migrations/M20240102_note_folders.hs index b5dadc6e08..6e0fbe5e41 100644 --- a/src/Simplex/Chat/Migrations/M20240102_note_folders.hs +++ b/src/Simplex/Chat/Migrations/M20240102_note_folders.hs @@ -31,9 +31,11 @@ m20240102_note_folders = down_m20240102_note_folders :: Query down_m20240102_note_folders = [sql| -DROP TABLE note_folders; +DROP INDEX chat_items_note_folder_id; +DROP INDEX files_note_folder_id; + ALTER TABLE chat_items DROP COLUMN note_folder_id; -ALTER TABLE chat_items DROP INDEX chat_items_note_folder_id; ALTER TABLE files DROP COLUMN note_folder_id; -ALTER TABLE files DROP INDEX files_note_folder_id; + +DROP TABLE note_folders; |] diff --git a/src/Simplex/Chat/Store/Messages.hs b/src/Simplex/Chat/Store/Messages.hs index 61f53ca91f..f6157745ac 100644 --- a/src/Simplex/Chat/Store/Messages.hs +++ b/src/Simplex/Chat/Store/Messages.hs @@ -1114,71 +1114,85 @@ getLocalChat db user folderId pagination search_ = do CPBefore beforeId count -> getLocalChatBefore_ db user nf beforeId count search getLocalChatLast_ :: DB.Connection -> User -> NoteFolder -> Int -> String -> ExceptT StoreError IO (Chat 'CTLocal) -getLocalChatLast_ db user@User {userId} nf@NoteFolder {noteFolderId} count search = do +getLocalChatLast_ db user nf@NoteFolder {noteFolderId} count search = do let stats = ChatStats {unreadCount = 0, minUnreadItemId = 0, unreadChat = False} - chatItemIds <- liftIO getLocalChatItemIdsLast_ - chatItems <- mapM (getLocalChatItem db user noteFolderId) chatItemIds + chatItems <- getLocalChatItemsLast db user noteFolderId count search pure $ Chat (LocalChat nf) (reverse chatItems) stats - where - getLocalChatItemIdsLast_ :: IO [ChatItemId] - getLocalChatItemIdsLast_ = - map fromOnly - <$> DB.query - db - [sql| - SELECT chat_item_id - FROM chat_items - WHERE user_id = ? AND note_folder_id = ? AND item_text LIKE '%' || ? || '%' - ORDER BY item_ts DESC, chat_item_id DESC - LIMIT ? - |] - (userId, noteFolderId, search, count) + +-- the last items in reverse order (the last item in the conversation is the first in the returned list) +getLocalChatItemsLast :: DB.Connection -> User -> NoteFolderId -> Int -> String -> ExceptT StoreError IO [CChatItem 'CTLocal] +getLocalChatItemsLast db User {userId} noteFolderId count search = ExceptT $ do + currentTs <- getCurrentTime + mapM (toLocalChatItem currentTs) + <$> DB.query + db + [sql| + SELECT + -- ChatItem + i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.shared_msg_id, i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at, i.timed_ttl, i.timed_delete_at, i.item_live, + -- CIFile + f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol + FROM chat_items i + LEFT JOIN files f ON f.chat_item_id = i.chat_item_id + WHERE i.user_id = ? AND i.note_folder_id = ? AND i.item_text LIKE '%' || ? || '%' + ORDER BY i.created_at DESC, i.chat_item_id DESC + LIMIT ? + |] + (userId, noteFolderId, search, count) getLocalChatAfter_ :: DB.Connection -> User -> NoteFolder -> ChatItemId -> Int -> String -> ExceptT StoreError IO (Chat 'CTLocal) -getLocalChatAfter_ db user@User {userId} nf@NoteFolder {noteFolderId} afterChatItemId count search = do +getLocalChatAfter_ db User {userId} nf@NoteFolder {noteFolderId} afterChatItemId count search = do let stats = ChatStats {unreadCount = 0, minUnreadItemId = 0, unreadChat = False} - afterChatItem <- getLocalChatItem db user noteFolderId afterChatItemId - chatItemIds <- liftIO $ getLocalChatItemIdsAfter_ (chatItemTs afterChatItem) - chatItems <- mapM (getLocalChatItem db user noteFolderId) chatItemIds + chatItems <- ExceptT getLocalChatItemsAfter_ pure $ Chat (LocalChat nf) chatItems stats where - getLocalChatItemIdsAfter_ :: UTCTime -> IO [ChatItemId] - getLocalChatItemIdsAfter_ afterChatItemTs = - map fromOnly + getLocalChatItemsAfter_ :: IO (Either StoreError [CChatItem 'CTLocal]) + getLocalChatItemsAfter_ = do + currentTs <- getCurrentTime + mapM (toLocalChatItem currentTs) <$> DB.query db [sql| - SELECT chat_item_id - FROM chat_items - WHERE user_id = ? AND note_folder_id = ? AND item_text LIKE '%' || ? || '%' - AND (item_ts > ? OR (item_ts = ? AND chat_item_id > ?)) - ORDER BY item_ts ASC, chat_item_id ASC + SELECT + -- ChatItem + i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.shared_msg_id, i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at, i.timed_ttl, i.timed_delete_at, i.item_live, + -- CIFile + f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol + FROM chat_items i + LEFT JOIN files f ON f.chat_item_id = i.chat_item_id + WHERE i.user_id = ? AND i.note_folder_id = ? AND i.item_text LIKE '%' || ? || '%' + AND i.chat_item_id > ? + ORDER BY i.created_at ASC, i.chat_item_id ASC LIMIT ? |] - (userId, noteFolderId, search, afterChatItemTs, afterChatItemTs, afterChatItemId, count) + (userId, noteFolderId, search, afterChatItemId, count) getLocalChatBefore_ :: DB.Connection -> User -> NoteFolder -> ChatItemId -> Int -> String -> ExceptT StoreError IO (Chat 'CTLocal) -getLocalChatBefore_ db user@User {userId} nf@NoteFolder {noteFolderId} beforeChatItemId count search = do +getLocalChatBefore_ db User {userId} nf@NoteFolder {noteFolderId} beforeChatItemId count search = do let stats = ChatStats {unreadCount = 0, minUnreadItemId = 0, unreadChat = False} - beforeChatItem <- getLocalChatItem db user noteFolderId beforeChatItemId - chatItemIds <- liftIO $ getLocalChatItemIdsBefore_ (chatItemTs beforeChatItem) - chatItems <- mapM (getLocalChatItem db user noteFolderId) chatItemIds + chatItems <- ExceptT getLocalChatItemsBefore_ pure $ Chat (LocalChat nf) (reverse chatItems) stats where - getLocalChatItemIdsBefore_ :: UTCTime -> IO [ChatItemId] - getLocalChatItemIdsBefore_ beforeChatItemTs = - map fromOnly + getLocalChatItemsBefore_ :: IO (Either StoreError [CChatItem 'CTLocal]) + getLocalChatItemsBefore_ = do + currentTs <- getCurrentTime + mapM (toLocalChatItem currentTs) <$> DB.query db [sql| - SELECT chat_item_id - FROM chat_items - WHERE user_id = ? AND note_folder_id = ? AND item_text LIKE '%' || ? || '%' - AND (item_ts < ? OR (item_ts = ? AND chat_item_id < ?)) - ORDER BY item_ts DESC, chat_item_id DESC + SELECT + -- ChatItem + i.chat_item_id, i.item_ts, i.item_sent, i.item_content, i.item_text, i.item_status, i.shared_msg_id, i.item_deleted, i.item_deleted_ts, i.item_edited, i.created_at, i.updated_at, i.timed_ttl, i.timed_delete_at, i.item_live, + -- CIFile + f.file_id, f.file_name, f.file_size, f.file_path, f.file_crypto_key, f.file_crypto_nonce, f.ci_file_status, f.protocol + FROM chat_items i + LEFT JOIN files f ON f.chat_item_id = i.chat_item_id + WHERE i.user_id = ? AND i.note_folder_id = ? AND i.item_text LIKE '%' || ? || '%' + AND i.chat_item_id < ? + ORDER BY i.created_at DESC, i.chat_item_id DESC LIMIT ? |] - (userId, noteFolderId, search, beforeChatItemTs, beforeChatItemTs, beforeChatItemId, count) + (userId, noteFolderId, search, beforeChatItemId, count) toChatItemRef :: (ChatItemId, Maybe Int64, Maybe Int64, Maybe Int64) -> Either StoreError (ChatRef, ChatItemId) toChatItemRef = \case