From 194a7bb58e59c6389a30b13f8865914bbfe88eb9 Mon Sep 17 00:00:00 2001 From: Alexander Bondarenko <486682+dpwiz@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:49:50 +0200 Subject: [PATCH] agent: remove redirect entries when deleting rcv files (#995) * agent: remove redirect entries when deleting rcv files * update schema dump * use rcv_file primary key for redirect lookup * allow multiple redirects --- src/Simplex/FileTransfer/Agent.hs | 16 ++++++++++------ src/Simplex/Messaging/Agent/Store/SQLite.hs | 8 +++++++- .../SQLite/Migrations/M20240124_file_redirect.hs | 2 +- .../Store/SQLite/Migrations/agent_schema.sql | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Simplex/FileTransfer/Agent.hs b/src/Simplex/FileTransfer/Agent.hs index 3bed1ce21..24bb9c789 100644 --- a/src/Simplex/FileTransfer/Agent.hs +++ b/src/Simplex/FileTransfer/Agent.hs @@ -288,12 +288,16 @@ runXFTPRcvLocalWorker c Worker {doWork} = do xftpDeleteRcvFile' :: AgentMonad m => AgentClient -> RcvFileId -> m () xftpDeleteRcvFile' c rcvFileEntityId = do - RcvFile {rcvFileId, prefixPath, status} <- withStore c $ \db -> getRcvFileByEntityId db rcvFileEntityId - if status == RFSComplete || status == RFSError - then do - removePath prefixPath - withStore' c (`deleteRcvFile'` rcvFileId) - else withStore' c (`updateRcvFileDeleted` rcvFileId) + rcvFile@RcvFile {rcvFileId} <- withStore c $ \db -> getRcvFileByEntityId db rcvFileEntityId + handleError (const $ pure ()) $ withStore' c (`getRcvFileRedirects` rcvFileId) >>= mapM_ remove + remove rcvFile + where + remove RcvFile {rcvFileId, prefixPath, status} = + if status == RFSComplete || status == RFSError + then do + removePath prefixPath + withStore' c (`deleteRcvFile'` rcvFileId) + else withStore' c (`updateRcvFileDeleted` rcvFileId) notify :: forall m e. (MonadUnliftIO m, AEntityI e) => AgentClient -> EntityId -> ACommand 'Agent e -> m () notify c entId cmd = atomically $ writeTBQueue (subQ c) ("", entId, APC (sAEntity @e) cmd) diff --git a/src/Simplex/Messaging/Agent/Store/SQLite.hs b/src/Simplex/Messaging/Agent/Store/SQLite.hs index d007ff0ee..e9aca0b39 100644 --- a/src/Simplex/Messaging/Agent/Store/SQLite.hs +++ b/src/Simplex/Messaging/Agent/Store/SQLite.hs @@ -167,6 +167,7 @@ module Simplex.Messaging.Agent.Store.SQLite createRcvFileRedirect, getRcvFile, getRcvFileByEntityId, + getRcvFileRedirects, updateRcvChunkReplicaDelay, updateRcvFileChunkReceived, updateRcvFileStatus, @@ -242,7 +243,7 @@ import Data.List (foldl', intercalate, sortBy) import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as L import qualified Data.Map.Strict as M -import Data.Maybe (fromMaybe, isJust, listToMaybe) +import Data.Maybe (fromMaybe, isJust, listToMaybe, catMaybes) import Data.Ord (Down (..)) import Data.Text (Text) import qualified Data.Text as T @@ -2337,6 +2338,11 @@ getRcvFileIdByEntityId_ db rcvFileEntityId = firstRow fromOnly SEFileNotFound $ DB.query db "SELECT rcv_file_id FROM rcv_files WHERE rcv_file_entity_id = ?" (Only rcvFileEntityId) +getRcvFileRedirects :: DB.Connection -> DBRcvFileId -> IO [RcvFile] +getRcvFileRedirects db rcvFileId = do + redirects <- fromOnly <$$> DB.query db "SELECT rcv_file_id FROM rcv_files WHERE redirect_id = ?" (Only rcvFileId) + fmap catMaybes . forM redirects $ getRcvFile db >=> either (const $ pure Nothing) (pure . Just) + getRcvFile :: DB.Connection -> DBRcvFileId -> IO (Either StoreError RcvFile) getRcvFile db rcvFileId = runExceptT $ do f@RcvFile {rcvFileEntityId, userId, tmpPath} <- ExceptT getFile diff --git a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20240124_file_redirect.hs b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20240124_file_redirect.hs index e02932d63..be5e46157 100644 --- a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20240124_file_redirect.hs +++ b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20240124_file_redirect.hs @@ -11,7 +11,7 @@ m20240124_file_redirect = ALTER TABLE snd_files ADD COLUMN redirect_size INTEGER; ALTER TABLE snd_files ADD COLUMN redirect_digest BLOB; -ALTER TABLE rcv_files ADD COLUMN redirect_id INTEGER REFERENCES rcv_files ON DELETE CASCADE; +ALTER TABLE rcv_files ADD COLUMN redirect_id INTEGER REFERENCES rcv_files ON DELETE SET NULL; ALTER TABLE rcv_files ADD COLUMN redirect_entity_id BLOB; ALTER TABLE rcv_files ADD COLUMN redirect_size INTEGER; ALTER TABLE rcv_files ADD COLUMN redirect_digest BLOB; diff --git a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/agent_schema.sql b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/agent_schema.sql index 32df1520d..b9efaa05c 100644 --- a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/agent_schema.sql +++ b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/agent_schema.sql @@ -279,7 +279,7 @@ CREATE TABLE rcv_files( save_file_key BLOB, save_file_nonce BLOB, failed INTEGER DEFAULT 0, - redirect_id INTEGER REFERENCES rcv_files ON DELETE CASCADE, + redirect_id INTEGER REFERENCES rcv_files ON DELETE SET NULL, redirect_entity_id BLOB, redirect_size INTEGER, redirect_digest BLOB,