From 11946e7dfda3e53b9c065d8c5c47440aa2047a10 Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Fri, 5 Jan 2001 04:40:27 +0000 Subject: [PATCH] more work on newsgroup hdr purging sr=sspitzer 17217 git-svn-id: svn://10.0.0.236/trunk@84417 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/base/util/nsMsgDBFolder.cpp | 1 + .../base/util/nsMsgIncomingServer.cpp | 24 ++- .../mailnews/db/msgdb/public/nsDBFolderInfo.h | 4 +- .../db/msgdb/public/nsIDBFolderInfo.idl | 2 +- .../db/msgdb/public/nsIMsgDatabase.idl | 2 + .../mailnews/db/msgdb/public/nsMsgDatabase.h | 3 + .../mailnews/db/msgdb/src/nsDBFolderInfo.cpp | 14 +- .../mailnews/db/msgdb/src/nsMsgDatabase.cpp | 156 +++++++++++++++++- mozilla/mailnews/news/src/nsNewsFolder.cpp | 22 +++ mozilla/mailnews/news/src/nsNewsFolder.h | 1 + 10 files changed, 212 insertions(+), 17 deletions(-) diff --git a/mozilla/mailnews/base/util/nsMsgDBFolder.cpp b/mozilla/mailnews/base/util/nsMsgDBFolder.cpp index 57a043436a7..c7f6c354958 100644 --- a/mozilla/mailnews/base/util/nsMsgDBFolder.cpp +++ b/mozilla/mailnews/base/util/nsMsgDBFolder.cpp @@ -1281,6 +1281,7 @@ NS_IMETHODIMP nsMsgDBFolder::GetRetentionSettings(nsIMsgRetentionSettings **sett } } *settings = m_retentionSettings; + NS_IF_ADDREF(*settings); return rv; } diff --git a/mozilla/mailnews/base/util/nsMsgIncomingServer.cpp b/mozilla/mailnews/base/util/nsMsgIncomingServer.cpp index a9d755ef2c3..4485e53278e 100644 --- a/mozilla/mailnews/base/util/nsMsgIncomingServer.cpp +++ b/mozilla/mailnews/base/util/nsMsgIncomingServer.cpp @@ -1057,15 +1057,35 @@ nsMsgIncomingServer::getProtocolInfo(nsIMsgProtocolInfo **aResult) NS_IMETHODIMP nsMsgIncomingServer::GetRetentionSettings(nsIMsgRetentionSettings **settings) { NS_ENSURE_ARG_POINTER(settings); + nsMsgRetainByPreference retainByPreference; + PRInt32 daysToKeepHdrs = 0; + PRInt32 numHeadersToKeep = 0; + PRBool keepUnreadMessagesOnly = PR_FALSE; + PRInt32 daysToKeepBodies = 0; + nsresult rv = NS_OK; if (!m_retentionSettings) { m_retentionSettings = do_CreateInstance(NS_MSG_RETENTIONSETTINGS_CONTRACTID); - + if (m_retentionSettings) + { + rv = GetBoolValue("keepUnreadOnly", &keepUnreadMessagesOnly); + rv = GetIntValue("retainBy", (PRInt32*) &retainByPreference); + rv = GetIntValue("numHdrsToKeep", &numHeadersToKeep); + rv = GetIntValue("daysToKeepHdrs", &daysToKeepHdrs); + rv = GetIntValue("daysToKeepBodies", &daysToKeepBodies); + m_retentionSettings->SetRetainByPreference(retainByPreference); + m_retentionSettings->SetNumHeadersToKeep((PRUint32) numHeadersToKeep); + m_retentionSettings->SetKeepUnreadMessagesOnly(keepUnreadMessagesOnly); + m_retentionSettings->SetDaysToKeepBodies(daysToKeepBodies); + m_retentionSettings->SetDaysToKeepHdrs(daysToKeepHdrs); + } + else + rv = NS_ERROR_OUT_OF_MEMORY; // Create an empty retention settings object, // get the settings from the server prefs, and init the object from the prefs. } *settings = m_retentionSettings; - return NS_OK; + NS_IF_ADDREF(*settings); return rv; } NS_IMETHODIMP nsMsgIncomingServer::SetRetentionSettings(nsIMsgRetentionSettings *settings) diff --git a/mozilla/mailnews/db/msgdb/public/nsDBFolderInfo.h b/mozilla/mailnews/db/msgdb/public/nsDBFolderInfo.h index 11aacbd8e66..5702f7833d1 100644 --- a/mozilla/mailnews/db/msgdb/public/nsDBFolderInfo.h +++ b/mozilla/mailnews/db/msgdb/public/nsDBFolderInfo.h @@ -78,8 +78,8 @@ public: nsresult SetUint32PropertyWithToken(mdb_token aProperty, PRUint32 propertyValue); nsresult SetInt32PropertyWithToken(mdb_token aProperty, PRInt32 propertyValue); nsresult GetPropertyWithToken(mdb_token aProperty, nsString *resultProperty); - nsresult GetUint32PropertyWithToken(mdb_token aProperty, PRUint32 &propertyValue); - nsresult GetInt32PropertyWithToken(mdb_token aProperty, PRInt32 &propertyValue); + nsresult GetUint32PropertyWithToken(mdb_token aProperty, PRUint32 &propertyValue, PRUint32 defaultValue = 0); + nsresult GetInt32PropertyWithToken(mdb_token aProperty, PRInt32 &propertyValue, PRInt32 defaultValue = 0); nsMsgKeyArray m_lateredKeys; // list of latered messages diff --git a/mozilla/mailnews/db/msgdb/public/nsIDBFolderInfo.idl b/mozilla/mailnews/db/msgdb/public/nsIDBFolderInfo.idl index 86af95e6ad1..03679499dce 100644 --- a/mozilla/mailnews/db/msgdb/public/nsIDBFolderInfo.idl +++ b/mozilla/mailnews/db/msgdb/public/nsIDBFolderInfo.idl @@ -57,7 +57,7 @@ interface nsIDBFolderInfo : nsISupports { void GetCharPtrProperty(in string propertyName, out string resultProperty); void SetUint32Property(in string propertyName, in unsigned long propertyValue); - unsigned long GetUint32Property(in string propertyName); + void GetUint32Property(in string propertyName, out unsigned long result, in unsigned long defaultValue); void GetTransferInfo(out nsIDBFolderInfo transferInfo); void InitFromTransferInfo(in nsIDBFolderInfo transferInfo); diff --git a/mozilla/mailnews/db/msgdb/public/nsIMsgDatabase.idl b/mozilla/mailnews/db/msgdb/public/nsIMsgDatabase.idl index 68a2f2e4cd5..75807ac4a36 100644 --- a/mozilla/mailnews/db/msgdb/public/nsIMsgDatabase.idl +++ b/mozilla/mailnews/db/msgdb/public/nsIMsgDatabase.idl @@ -192,6 +192,8 @@ interface nsIMsgDatabase : nsIDBChangeAnnouncer { readonly attribute nsMsgKey FirstNew; attribute nsIMsgRetentionSettings msgRetentionSettings; + // purge unwanted message headers and/or bodies + void ApplyRetentionSettings(in nsIMsgRetentionSettings msgRetentionSettings); boolean HasNew(); void ClearNewList(in boolean notify); diff --git a/mozilla/mailnews/db/msgdb/public/nsMsgDatabase.h b/mozilla/mailnews/db/msgdb/public/nsMsgDatabase.h index d077967978f..04c5d598bab 100644 --- a/mozilla/mailnews/db/msgdb/public/nsMsgDatabase.h +++ b/mozilla/mailnews/db/msgdb/public/nsMsgDatabase.h @@ -170,6 +170,9 @@ protected: nsCOMPtr m_mimeConverter; nsCOMPtr m_retentionSettings; + nsresult PurgeMessagesOlderThan(PRUint32 daysToKeepHdrs, PRBool keepUnreadMessagesOnly); + nsresult PurgeExcessMessages(PRUint32 numHeadersToKeep, PRBool keepUnreadMessagesOnly); + // mdb bookkeeping stuff nsresult InitExistingDB(); nsresult InitNewDB(); diff --git a/mozilla/mailnews/db/msgdb/src/nsDBFolderInfo.cpp b/mozilla/mailnews/db/msgdb/src/nsDBFolderInfo.cpp index a24a103c922..10ab651b7cb 100644 --- a/mozilla/mailnews/db/msgdb/src/nsDBFolderInfo.cpp +++ b/mozilla/mailnews/db/msgdb/src/nsDBFolderInfo.cpp @@ -636,7 +636,7 @@ NS_IMETHODIMP nsDBFolderInfo::GetCharacterSetOverride(PRBool *characterSetOverri { *characterSetOverride = PR_FALSE; PRUint32 propertyValue; - nsresult rv = GetUint32Property(kCharacterSetOverrideColumnName, &propertyValue); + nsresult rv = GetUint32Property(kCharacterSetOverrideColumnName, &propertyValue, 0); if (NS_SUCCEEDED(rv)) *characterSetOverride = propertyValue; return rv; @@ -839,17 +839,17 @@ nsresult nsDBFolderInfo::GetPropertyWithToken(mdb_token aProperty, nsString *res return m_mdb->RowCellColumnTonsString(m_mdbRow, aProperty, *resultProperty); } -nsresult nsDBFolderInfo::GetUint32PropertyWithToken(mdb_token aProperty, PRUint32 &propertyValue) +nsresult nsDBFolderInfo::GetUint32PropertyWithToken(mdb_token aProperty, PRUint32 &propertyValue, PRUint32 defaultValue) { - return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, propertyValue); + return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, propertyValue, defaultValue); } -nsresult nsDBFolderInfo::GetInt32PropertyWithToken(mdb_token aProperty, PRInt32 &propertyValue) +nsresult nsDBFolderInfo::GetInt32PropertyWithToken(mdb_token aProperty, PRInt32 &propertyValue, PRInt32 defaultValue) { - return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, (PRUint32 &) propertyValue); + return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, (PRUint32 &) propertyValue, defaultValue); } -NS_IMETHODIMP nsDBFolderInfo::GetUint32Property(const char *propertyName, PRUint32 *propertyValue) +NS_IMETHODIMP nsDBFolderInfo::GetUint32Property(const char *propertyName, PRUint32 *propertyValue, PRUint32 defaultValue) { nsresult err = NS_OK; mdb_token property_token; @@ -858,7 +858,7 @@ NS_IMETHODIMP nsDBFolderInfo::GetUint32Property(const char *propertyName, PRUint return NS_ERROR_NULL_POINTER; err = m_mdb->GetStore()->StringToToken(m_mdb->GetEnv(), propertyName, &property_token); if (err == NS_OK) - return GetUint32PropertyWithToken(property_token, *propertyValue); + return GetUint32PropertyWithToken(property_token, *propertyValue, defaultValue); return err; } diff --git a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp index 00b04c8a6cc..6b46736a046 100644 --- a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -3507,11 +3507,11 @@ NS_IMETHODIMP nsMsgDatabase::GetMsgRetentionSettings(nsIMsgRetentionSettings **r PRBool keepUnreadMessagesOnly = PR_FALSE; PRUint32 daysToKeepBodies = 0; - rv = m_dbFolderInfo->GetUint32Property("retainBy", &retainByPreference); - m_dbFolderInfo->GetUint32Property("daysToKeepHdrs", &daysToKeepHdrs); - m_dbFolderInfo->GetUint32Property("numHdrsToKeep", &numHeadersToKeep); - m_dbFolderInfo->GetUint32Property("daysToKeepBodies", &daysToKeepBodies); - m_dbFolderInfo->GetUint32Property("keepUnreadOnly", &keepUnreadMessagesProp); + rv = m_dbFolderInfo->GetUint32Property("retainBy", &retainByPreference, nsIMsgRetentionSettings::nsMsgRetainByServerDefaults); + m_dbFolderInfo->GetUint32Property("daysToKeepHdrs", &daysToKeepHdrs, 0); + m_dbFolderInfo->GetUint32Property("numHdrsToKeep", &numHeadersToKeep, 0); + m_dbFolderInfo->GetUint32Property("daysToKeepBodies", &daysToKeepBodies, 0); + m_dbFolderInfo->GetUint32Property("keepUnreadOnly", &keepUnreadMessagesProp, 0); keepUnreadMessagesOnly = (keepUnreadMessagesProp == 1); m_retentionSettings->SetRetainByPreference(retainByPreference); m_retentionSettings->SetDaysToKeepHdrs(daysToKeepHdrs); @@ -3525,6 +3525,152 @@ NS_IMETHODIMP nsMsgDatabase::GetMsgRetentionSettings(nsIMsgRetentionSettings **r return NS_OK; } +NS_IMETHODIMP nsMsgDatabase::ApplyRetentionSettings(nsIMsgRetentionSettings *msgRetentionSettings) +{ + NS_ENSURE_ARG_POINTER(msgRetentionSettings); + nsresult rv = NS_OK; + + nsMsgRetainByPreference retainByPreference; + PRUint32 daysToKeepHdrs = 0; + PRUint32 numHeadersToKeep = 0; + PRUint32 keepUnreadMessagesProp = 0; + PRBool keepUnreadMessagesOnly = PR_FALSE; + PRUint32 daysToKeepBodies = 0; + msgRetentionSettings->GetRetainByPreference(&retainByPreference); + msgRetentionSettings->GetKeepUnreadMessagesOnly(&keepUnreadMessagesOnly); + + switch (retainByPreference) + { + case nsIMsgRetentionSettings::nsMsgRetainByServerDefaults: + NS_ASSERTION(PR_FALSE, "shouldn't be passing this in here"); // fall through and ignore + case nsIMsgRetentionSettings::nsMsgRetainAll: + break; + case nsIMsgRetentionSettings::nsMsgRetainByAge: + msgRetentionSettings->GetDaysToKeepHdrs(&daysToKeepHdrs); + return PurgeMessagesOlderThan(daysToKeepHdrs, keepUnreadMessagesOnly); + case nsIMsgRetentionSettings::nsMsgRetainByNumHeaders: + msgRetentionSettings->GetNumHeadersToKeep(&numHeadersToKeep); + return PurgeExcessMessages(numHeadersToKeep, keepUnreadMessagesOnly); + } + return rv; +} + +nsresult nsMsgDatabase::PurgeMessagesOlderThan(PRUint32 daysToKeepHdrs, PRBool keepUnreadMessagesOnly) +{ + nsresult rv = NS_OK; + PRInt32 numPurged = 0; + nsMsgHdr *pHeader; + nsCOMPtr hdrs; + rv = EnumerateMessages(getter_AddRefs(hdrs)); + if (NS_FAILED(rv)) + return rv; + PRBool hasMore = PR_FALSE; + + PRTime now = PR_Now(); + PRTime cutOffDay; + + PRInt64 microSecondsPerSecond, secondsInDays, microSecondsInDay; + + LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC); + LL_UI2L(secondsInDays, 60 * 60 * 24 * daysToKeepHdrs); + LL_MUL(microSecondsInDay, secondsInDays, microSecondsPerSecond); + + LL_SUB(cutOffDay, now, microSecondsInDay); // = now - term->m_value.u.age * 60 * 60 * 24; + // so now cutOffDay is the PRTime cut-off point. Any msg with a date less than that will get purged. + while (NS_SUCCEEDED(rv = hdrs->HasMoreElements(&hasMore)) && (hasMore == PR_TRUE)) + { + PRBool purgeHdr = PR_FALSE; + + rv = hdrs->GetNext((nsISupports**)&pHeader); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsMsgDBEnumerator broken"); + if (NS_FAILED(rv)) + break; + + if (keepUnreadMessagesOnly) + { + PRBool isRead; + IsHeaderRead(pHeader, &isRead); + if (isRead) + purgeHdr = PR_TRUE; + + } + if (!purgeHdr) + { + PRTime date; + pHeader->GetDate(&date); + if (LL_CMP(date, <, cutOffDay)) + purgeHdr = PR_TRUE; + } + if (purgeHdr) + { + DeleteHeader(pHeader, nsnull, PR_FALSE, PR_TRUE); + numPurged++; + } + NS_RELEASE(pHeader); + } + + if (numPurged > 10) // commit every once in a while + Commit(nsMsgDBCommitType::kCompressCommit); + else if (numPurged > 0) + Commit(nsMsgDBCommitType::kLargeCommit); + return rv; +} + +nsresult nsMsgDatabase::PurgeExcessMessages(PRUint32 numHeadersToKeep, PRBool keepUnreadMessagesOnly) +{ + nsresult rv = NS_OK; + PRInt32 numPurged = 0; + nsMsgHdr *pHeader; + nsCOMPtr hdrs; + rv = EnumerateMessages(getter_AddRefs(hdrs)); + if (NS_FAILED(rv)) + return rv; + PRBool hasMore = PR_FALSE; + + mdb_count numHdrs = 0; + if (m_mdbAllMsgHeadersTable) + m_mdbAllMsgHeadersTable->GetCount(GetEnv(), &numHdrs); + else + return NS_ERROR_NULL_POINTER; + + while (NS_SUCCEEDED(rv = hdrs->HasMoreElements(&hasMore)) && (hasMore == PR_TRUE)) + { + PRBool purgeHdr = PR_FALSE; + rv = hdrs->GetNext((nsISupports**)&pHeader); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsMsgDBEnumerator broken"); + if (NS_FAILED(rv)) + break; + + if (keepUnreadMessagesOnly) + { + PRBool isRead; + IsHeaderRead(pHeader, &isRead); + if (isRead) + purgeHdr = PR_TRUE; + + } + // this isn't quite right - we want to prefer unread messages (keep all of those we can) + if (numHdrs > numHeadersToKeep) + purgeHdr = PR_TRUE; + + if (purgeHdr) + { + DeleteHeader(pHeader, nsnull, PR_FALSE, PR_TRUE); + numHdrs--; + numPurged++; + } + NS_RELEASE(pHeader); + } + + if (numPurged > 10) // commit every once in a while + Commit(nsMsgDBCommitType::kCompressCommit); + else if (numPurged > 0) + Commit(nsMsgDBCommitType::kLargeCommit); + return rv; + + return rv; +} + NS_IMPL_ISUPPORTS1(nsMsgRetentionSettings, nsIMsgRetentionSettings) nsMsgRetentionSettings::nsMsgRetentionSettings() diff --git a/mozilla/mailnews/news/src/nsNewsFolder.cpp b/mozilla/mailnews/news/src/nsNewsFolder.cpp index 9a911d7c922..a8352b3ae6b 100644 --- a/mozilla/mailnews/news/src/nsNewsFolder.cpp +++ b/mozilla/mailnews/news/src/nsNewsFolder.cpp @@ -396,6 +396,13 @@ NS_IMETHODIMP nsMsgNewsFolder::UpdateFolder(nsIMsgWindow *aWindow) { GetDatabase(aWindow); // want this cached... + if (mDatabase) + { + nsCOMPtr retentionSettings; + nsresult rv = GetRetentionSettings(getter_AddRefs(retentionSettings)); + if (NS_SUCCEEDED(rv)) + rv = mDatabase->ApplyRetentionSettings(retentionSettings); + } return GetNewMessages(aWindow); } @@ -1757,3 +1764,18 @@ NS_IMETHODIMP nsMsgNewsFolder::NotifyDownloadedLine(const char *line, nsMsgKey k return rv; } +NS_IMETHODIMP nsMsgNewsFolder::Compact(nsIUrlListener *aListener) +{ + nsresult rv; + + rv = GetDatabase(nsnull); + if (mDatabase) + { + nsCOMPtr retentionSettings; + rv = GetRetentionSettings(getter_AddRefs(retentionSettings)); + if (NS_SUCCEEDED(rv)) + rv = mDatabase->ApplyRetentionSettings(retentionSettings); + } + return rv; +} + diff --git a/mozilla/mailnews/news/src/nsNewsFolder.h b/mozilla/mailnews/news/src/nsNewsFolder.h index 89a4fe6349c..a4a4298bd51 100644 --- a/mozilla/mailnews/news/src/nsNewsFolder.h +++ b/mozilla/mailnews/news/src/nsNewsFolder.h @@ -94,6 +94,7 @@ public: NS_IMETHOD GetCanRename(PRBool *aResult); NS_IMETHOD OnReadChanged(nsIDBChangeListener * aInstigator); + NS_IMETHOD Compact(nsIUrlListener *aListener); // for nsMsgLineBuffer virtual PRInt32 HandleLine(char *line, PRUint32 line_size);