From 3c857c171bb80b92de284bb2689bdc9e5a1ffd29 Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Fri, 5 Feb 1999 03:03:10 +0000 Subject: [PATCH] start hooking up header deletion --- mailnews/db/msgdb/public/nsDBFolderInfo.h | 5 ++ mailnews/db/msgdb/public/nsMailDatabase.h | 3 +- mailnews/db/msgdb/public/nsMsgDatabase.h | 19 ++++- mailnews/db/msgdb/public/nsMsgHdr.h | 2 + mailnews/db/msgdb/src/nsDBFolderInfo.cpp | 18 +++++ mailnews/db/msgdb/src/nsMailDatabase.cpp | 23 ++++-- mailnews/db/msgdb/src/nsMsgDatabase.cpp | 88 +++++++++++++++++++++++ 7 files changed, 147 insertions(+), 11 deletions(-) diff --git a/mailnews/db/msgdb/public/nsDBFolderInfo.h b/mailnews/db/msgdb/public/nsDBFolderInfo.h index 805e04eee55d..cae7d1739793 100644 --- a/mailnews/db/msgdb/public/nsDBFolderInfo.h +++ b/mailnews/db/msgdb/public/nsDBFolderInfo.h @@ -93,9 +93,14 @@ public: MessageKey GetLastMessageLoaded(); void SetLastMessageLoaded(MessageKey lastLoaded); + + void SetFolderSize(PRUint32 size); + void SetFolderDate(time_t date); + // get and set arbitrary property, aka row cell value. nsresult GetProperty(const char *propertyName, nsString &resultProperty); nsresult SetProperty(const char *propertyName, nsString &propertyStr); + nsresult SetUint32Property(const char *propertyName, PRUint32 propertyValue); PRUint16 m_version; // for upgrading... PRInt32 m_sortType; // the last sort type open on this db. diff --git a/mailnews/db/msgdb/public/nsMailDatabase.h b/mailnews/db/msgdb/public/nsMailDatabase.h index 019f5a8c0a0a..1f97f415943a 100644 --- a/mailnews/db/msgdb/public/nsMailDatabase.h +++ b/mailnews/db/msgdb/public/nsMailDatabase.h @@ -25,7 +25,6 @@ // This is the subclass of nsMsgDatabase that handles local mail messages. class nsOfflineImapOperation; class nsMsgKeyArray; -class ChangeListener; class MSG_Master; class MSG_FolderInfo; @@ -45,7 +44,7 @@ public: virtual nsresult OnNewPath (nsFilePath &newPath); - virtual nsresult DeleteMessages(nsMsgKeyArray &messageKeys, ChangeListener *instigator); + virtual nsresult DeleteMessages(nsMsgKeyArray &messageKeys, nsIDBChangeListener *instigator); // virtual int GetCurVersion() {return kMailDBVersion;} static nsresult SetFolderInfoValid(nsFilePath &pathname, int num, int numunread); diff --git a/mailnews/db/msgdb/public/nsMsgDatabase.h b/mailnews/db/msgdb/public/nsMsgDatabase.h index 35ea14bd02d0..da80a8b7617f 100644 --- a/mailnews/db/msgdb/public/nsMsgDatabase.h +++ b/mailnews/db/msgdb/public/nsMsgDatabase.h @@ -24,11 +24,12 @@ #include "nsString.h" #include "nsFileSpec.h" #include "nsIDBChangeListener.h" +#include "nsMsgMessageFlags.h" class ListContext; class nsDBFolderInfo; class nsMsgKeyArray; -class ChangeListener; +class nsNewsSet; class nsDBChangeAnnouncer : public XPPtrArray // array of ChangeListeners { @@ -112,7 +113,10 @@ public: // helpers for user command functions like delete, mark read, etc. - virtual nsresult DeleteMessages(nsMsgKeyArray &messageKeys, ChangeListener *instigator); + virtual nsresult DeleteMessages(nsMsgKeyArray &messageKeys, nsIDBChangeListener *instigator); + virtual nsresult DeleteHeader(nsMsgHdr *msgHdr, nsIDBChangeListener *instigator, PRBool commit, PRBool notify = TRUE); + virtual nsresult RemoveHeaderFromDB(nsMsgHdr *msgHdr); + virtual nsresult IsRead(MessageKey messageKey, PRBool *pRead); // used mainly to force the timestamp of a local mail folder db to // match the time stamp of the corresponding berkeley mail folder, @@ -148,6 +152,8 @@ protected: mdbTable *m_mdbAllMsgHeadersTable; nsFilePath m_dbName; + nsNewsSet *m_newSet; // new messages since last open. + nsrefcnt mRefCnt; static void AddToCache(nsMsgDatabase* pMessageDB) @@ -155,6 +161,15 @@ protected: static void RemoveFromCache(nsMsgDatabase* pMessageDB); static int FindInCache(nsMsgDatabase* pMessageDB); PRBool MatchDbName(nsFilePath &dbName); // returns TRUE if they match + + virtual nsresult SetKeyFlag(MessageKey messageKey, PRBool set, PRInt32 flag, + nsIDBChangeListener *instigator = NULL); + virtual void SetHdrFlag(nsMsgHdr *, PRBool bSet, MsgFlags flag); + virtual void MarkHdrReadInDB(nsMsgHdr *msgHdr, PRBool bRead, + nsIDBChangeListener *instigator); + + virtual nsresult IsHeaderRead(nsMsgHdr *hdr, PRBool *pRead); + static nsMsgDatabaseArray* GetDBCache(); static nsMsgDatabaseArray *m_dbCache; diff --git a/mailnews/db/msgdb/public/nsMsgHdr.h b/mailnews/db/msgdb/public/nsMsgHdr.h index 805f98f45915..83632d29023d 100644 --- a/mailnews/db/msgdb/public/nsMsgHdr.h +++ b/mailnews/db/msgdb/public/nsMsgHdr.h @@ -47,6 +47,8 @@ public: MessageKey GetMessageKey(); MessageKey GetThreadId(); void SetMessageKey(MessageKey inKey) {m_messageKey = inKey;} + virtual PRUint32 GetMessageSize() {return m_messageSize;} + virtual PRUint32 GetFlags() {return m_flags;} // this is almost always the m_messageKey, except for the first message. // NeoAccess doesn't allow fID's of 0. diff --git a/mailnews/db/msgdb/src/nsDBFolderInfo.cpp b/mailnews/db/msgdb/src/nsDBFolderInfo.cpp index 799e76342937..32602c50fc89 100644 --- a/mailnews/db/msgdb/src/nsDBFolderInfo.cpp +++ b/mailnews/db/msgdb/src/nsDBFolderInfo.cpp @@ -189,6 +189,17 @@ void nsDBFolderInfo::SetHighWater(MessageKey highWater, PRBool force /* = FALSE } } +void nsDBFolderInfo::SetFolderSize(PRUint32 size) +{ + m_folderSize = size; +} + +void nsDBFolderInfo::SetFolderDate(time_t folderDate) +{ + m_folderDate = folderDate; +} + + MessageKey nsDBFolderInfo::GetHighWater() { return m_highWaterMessageKey; @@ -406,6 +417,13 @@ nsresult nsDBFolderInfo::GetProperty(const char *propertyName, nsString &resultP return err; } +nsresult nsDBFolderInfo::SetUint32Property(const char *propertyName, PRUint32 propertyValue) +{ + nsString propertyStr; + propertyStr.Append(propertyValue, 10); + return SetProperty(propertyName, propertyStr); +} + nsresult nsDBFolderInfo::SetProperty(const char *propertyName, nsString &propertyStr) { nsresult err = NS_OK; diff --git a/mailnews/db/msgdb/src/nsMailDatabase.cpp b/mailnews/db/msgdb/src/nsMailDatabase.cpp index 68e0b4e4bdde..24c0ea6b3bd2 100644 --- a/mailnews/db/msgdb/src/nsMailDatabase.cpp +++ b/mailnews/db/msgdb/src/nsMailDatabase.cpp @@ -138,7 +138,7 @@ nsresult nsMailDatabase::OnNewPath (nsFilePath &newPath) return ret; } -nsresult nsMailDatabase::DeleteMessages(nsMsgKeyArray &messageKeys, ChangeListener *instigator) +nsresult nsMailDatabase::DeleteMessages(nsMsgKeyArray &messageKeys, nsIDBChangeListener *instigator) { nsresult ret = NS_OK; m_folderFile = PR_Open(m_dbName, PR_RDWR, 0); @@ -151,9 +151,23 @@ nsresult nsMailDatabase::DeleteMessages(nsMsgKeyArray &messageKeys, ChangeListen } -/* static */ nsresult nsMailDatabase::SetFolderInfoValid(nsFilePath &pathname, int num, int numunread) +/* static */ nsresult nsMailDatabase::SetSummaryValid(PRBool valid) { nsresult ret = NS_OK; + struct stat st; + + if (stat(m_dbName, &st)) + return NS_MSG_ERROR_FOLDER_MISSING; + + if (valid) + { + m_dbFolderInfo->SetFolderSize(st.st_size); + m_dbFolderInfo->SetFolderDate(st.st_mtime); + } + else + { + m_dbFolderInfo->SetFolderDate(0); // that ought to do the trick. + } return ret; } @@ -215,11 +229,6 @@ nsresult SetSourceMailbox(nsOfflineImapOperation *op, const char *mailbox, Messa return ret; } -nsresult nsMailDatabase::SetSummaryValid(PRBool valid /* = TRUE */) -{ - nsresult ret = NS_OK; - return ret; -} nsresult nsMailDatabase::GetIdsWithNoBodies (nsMsgKeyArray &bodylessIds) { diff --git a/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mailnews/db/msgdb/src/nsMsgDatabase.cpp index b05c49ee62b3..89973d0c0441 100644 --- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -21,6 +21,7 @@ #include "nsMsgDatabase.h" #include "nsDBFolderInfo.h" +#include "nsNewsSet.h" #ifdef WE_HAVE_MDBINTERFACES static NS_DEFINE_IID(kIMDBIID, NS_IMDB_IID); @@ -397,6 +398,93 @@ nsresult nsMsgDatabase::GetMsgHdrForKey(MessageKey messageKey, nsMsgHdr **pmsgHd return err; } +nsresult nsMsgDatabase::DeleteMessages(nsMsgKeyArray &messageKeys, nsIDBChangeListener *instigator) +{ + nsresult err = NS_OK; + + for (PRUint32 index = 0; index < messageKeys.GetSize(); index++) + { + MessageKey messageKey = messageKeys.GetAt(index); + nsMsgHdr *msgHdr = NULL; + + err = GetMsgHdrForKey(messageKey, &msgHdr); + if (msgHdr == NULL || err != NS_OK) + { + err = NS_MSG_MESSAGE_NOT_FOUND; + break; + } + err = DeleteHeader(msgHdr, instigator, index % 300 == 0); + if (err != NS_OK) + break; + } +// Commit(); + return err; +} + + +nsresult nsMsgDatabase::DeleteHeader(nsMsgHdr *msgHdr, nsIDBChangeListener *instigator, PRBool commit, PRBool notify /* = TRUE */) +{ + MessageKey messageKey = msgHdr->GetMessageKey(); + // only need to do this for mail - will this speed up news expiration? Is dirtying objects + // we're about to delete slow for neoaccess? But are we short circuiting some + // notifications that we need? +// if (GetMailDB()) + SetHdrFlag(msgHdr, TRUE, MSG_FLAG_EXPUNGED); // tell mailbox (mail) + + if (m_newSet) // if it's in the new set, better get rid of it. + m_newSet->Remove(msgHdr->GetMessageKey()); + + if (m_dbFolderInfo != NULL) + { + PRBool isRead; + m_dbFolderInfo->ChangeNumMessages(-1); + m_dbFolderInfo->ChangeNumVisibleMessages(-1); + IsRead(msgHdr->GetMessageKey(), &isRead); + if (!isRead) + m_dbFolderInfo->ChangeNumNewMessages(-1); + + m_dbFolderInfo->m_expungedBytes += msgHdr->GetMessageSize(); + + } + + if (notify) + NotifyKeyChangeAll(messageKey, msgHdr->GetFlags(), instigator); // tell listeners + +// if (!onlyRemoveFromThread) // to speed up expiration, try this. But really need to do this in RemoveHeaderFromDB + RemoveHeaderFromDB(msgHdr); +// if (commit) +// Commit(); // ### dmb is this a good time to commit? + msgHdr->Release(); // even though we're deleting it from the db, need to unrefer. + return NS_OK; +} + +// This is a lower level routine which doesn't send notifcations or +// update folder info. One use is when a rule fires moving a header +// from one db to another, to remove it from the first db. + +nsresult nsMsgDatabase::RemoveHeaderFromDB(nsMsgHdr *msgHdr) +{ + return NS_OK; +} + +nsresult nsMsgDatabase::IsRead(MessageKey messageKey, PRBool *pRead) +{ + nsresult err = NS_OK; + nsMsgHdr *msgHdr; + + err = GetMsgHdrForKey(messageKey, &msgHdr); + if (err == NS_OK && msgHdr != NULL) + { + err = IsHeaderRead(msgHdr, pRead); + msgHdr->Release(); + return err; + } + else + { + return NS_MSG_MESSAGE_NOT_FOUND; + } +} + // header iteration methods.