IMAP: Extra local messages are now deleted.

* When a message on the server is deleted, it will now be deleted
  locally, too.
This commit is contained in:
Axel Dörfler
2016-01-14 21:03:46 +01:00
parent 618cc43b64
commit aeaf68cf4b
3 changed files with 53 additions and 6 deletions
@@ -370,8 +370,7 @@ public:
fTotalBytes += entries[i].size; fTotalBytes += entries[i].size;
fUIDsToFetch.push_back(entries[i].uid); fUIDsToFetch.push_back(entries[i].uid);
} else { } else {
fFolder->UpdateMessageFlags(entries[i].uid, fFolder->SyncMessageFlags(entries[i].uid, entries[i].flags);
entries[i].flags);
} }
} }
@@ -379,6 +378,8 @@ public:
fLastIndex = from - 1; fLastIndex = from - 1;
if (from == 1) { if (from == 1) {
fFolder->MessageEntriesFetched();
if (fUIDsToFetch.size() > 0) { if (fUIDsToFetch.size() > 0) {
// Add pending command to fetch the message headers // Add pending command to fetch the message headers
WorkerCommand* command = new FetchHeadersCommand(*fFolder, WorkerCommand* command = new FetchHeadersCommand(*fFolder,
@@ -178,6 +178,7 @@ IMAPFolder::SetUIDValidity(uint32 uidValidity)
if (fUIDValidity == uidValidity) if (fUIDValidity == uidValidity)
return; return;
// TODO: delete all mails that have the same UID validity value we had
fUIDValidity = uidValidity; fUIDValidity = uidValidity;
BNode node(&fRef); BNode node(&fRef);
@@ -221,8 +222,11 @@ IMAPFolder::MessageFlags(uint32 uid)
} }
/*! Synchronizes the message flags/state from the server with the local
one.
*/
void void
IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags) IMAPFolder::SyncMessageFlags(uint32 uid, uint32 mailboxFlags)
{ {
if (uid > LastUID()) if (uid > LastUID())
return; return;
@@ -233,7 +237,8 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
while (true) { while (true) {
status_t status = GetMessageEntryRef(uid, ref); status_t status = GetMessageEntryRef(uid, ref);
if (status == B_ENTRY_NOT_FOUND) { if (status == B_ENTRY_NOT_FOUND) {
// The message does not exist anymore locally, delete it on the server // The message does not exist anymore locally, delete it on the
// server
// TODO: copy it to the trash directory first! // TODO: copy it to the trash directory first!
fProtocol.UpdateMessageFlags(*this, uid, IMAP::kDeleted); fProtocol.UpdateMessageFlags(*this, uid, IMAP::kDeleted);
return; return;
@@ -247,6 +252,7 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
break; break;
} }
fSynchronizedUIDsSet.insert(uid);
uint32 previousFlags = MessageFlags(uid); uint32 previousFlags = MessageFlags(uid);
uint32 currentFlags = previousFlags; uint32 currentFlags = previousFlags;
@@ -279,6 +285,21 @@ IMAPFolder::UpdateMessageFlags(uint32 uid, uint32 mailboxFlags)
} }
void
IMAPFolder::MessageEntriesFetched()
{
// Delete all local messages that weren't synchronized with the server
UIDToRefMap::const_iterator iterator = fRefMap.begin();
for (; iterator != fRefMap.end(); iterator++) {
uint32 uid = iterator->first;
if (fSynchronizedUIDsSet.find(uid) == fSynchronizedUIDsSet.end())
_DeleteLocalMessage(uid);
}
fSynchronizedUIDsSet.clear();
}
/*! Stores the given \a stream into a temporary file using the provided /*! Stores the given \a stream into a temporary file using the provided
BFile object. A new file will be created, and the \a ref object will BFile object. A new file will be created, and the \a ref object will
point to it. The file will remain open when this method exits without point to it. The file will remain open when this method exits without
@@ -416,6 +437,9 @@ IMAPFolder::StoringBodyFailed(const entry_ref& ref, uint32 uid, status_t error)
void void
IMAPFolder::DeleteMessage(uint32 uid) IMAPFolder::DeleteMessage(uint32 uid)
{ {
// TODO: move message to trash (server side)
_DeleteLocalMessage(uid);
} }
@@ -471,7 +495,6 @@ IMAPFolder::_InitializeFolderState()
// _WriteUniqueID(node, uid); // _WriteUniqueID(node, uid);
// } // }
// //
fRefMap.insert(std::make_pair(uid, ref));
} }
fInitializing = false; fInitializing = false;
@@ -519,6 +542,22 @@ IMAPFolder::_GetMessageEntryRef(uint32 uid, entry_ref& ref) const
} }
status_t
IMAPFolder::_DeleteLocalMessage(uint32 uid)
{
entry_ref ref;
status_t status = GetMessageEntryRef(uid, ref);
if (status != B_OK)
return status;
fRefMap.erase(uid);
fFlagsMap.erase(uid);
BEntry entry(&ref);
return entry.Remove();
}
void void
IMAPFolder::_IMAPToMailFlags(uint32 flags, BMessage& attributes) IMAPFolder::_IMAPToMailFlags(uint32 flags, BMessage& attributes)
{ {
@@ -7,6 +7,8 @@
#include <hash_map> #include <hash_map>
#include <hash_set>
#include <sys/stat.h> #include <sys/stat.h>
#include <Entry.h> #include <Entry.h>
@@ -69,8 +71,9 @@ public:
uint32& uid) const; uint32& uid) const;
uint32 MessageFlags(uint32 uid); uint32 MessageFlags(uint32 uid);
void UpdateMessageFlags(uint32 uid, void SyncMessageFlags(uint32 uid,
uint32 mailboxFlags); uint32 mailboxFlags);
void MessageEntriesFetched();
status_t StoreMessage(uint32 fetchFlags, BDataIO& stream, status_t StoreMessage(uint32 fetchFlags, BDataIO& stream,
size_t& length, entry_ref& ref, size_t& length, entry_ref& ref,
@@ -101,6 +104,7 @@ private:
uint32 uid, status_t status); uint32 uid, status_t status);
status_t _GetMessageEntryRef(uint32 uid, status_t _GetMessageEntryRef(uint32 uid,
entry_ref& ref) const; entry_ref& ref) const;
status_t _DeleteLocalMessage(uint32 uid);
void _IMAPToMailFlags(uint32 flags, void _IMAPToMailFlags(uint32 flags,
BMessage& attributes); BMessage& attributes);
@@ -130,10 +134,12 @@ private:
typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap; typedef __gnu_cxx::hash_map<uint32, uint32> UIDToFlagsMap;
typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap; typedef __gnu_cxx::hash_map<uint32, entry_ref> UIDToRefMap;
typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap; typedef __gnu_cxx::hash_map<uint32, MessengerList> MessengerMap;
typedef __gnu_cxx::hash_set<uint32> UIDSet;
#else #else
typedef std::hash_map<uint32, uint32> UIDToFlagsMap; typedef std::hash_map<uint32, uint32> UIDToFlagsMap;
typedef std::hash_map<uint32, entry_ref> UIDToRefMap; typedef std::hash_map<uint32, entry_ref> UIDToRefMap;
typedef std::hash_map<uint32, MessengerList> MessengerMap; typedef std::hash_map<uint32, MessengerList> MessengerMap;
typedef std::hash_set<uint32> UIDSet;
#endif #endif
IMAPProtocol& fProtocol; IMAPProtocol& fProtocol;
@@ -147,6 +153,7 @@ private:
bool fInitializing; bool fInitializing;
UIDToRefMap fRefMap; UIDToRefMap fRefMap;
UIDToFlagsMap fFlagsMap; UIDToFlagsMap fFlagsMap;
UIDSet fSynchronizedUIDsSet;
MessengerMap fPendingBodies; MessengerMap fPendingBodies;
}; };