more work on newsgroup hdr purging sr=sspitzer 17217
git-svn-id: svn://10.0.0.236/trunk@84417 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1281,6 +1281,7 @@ NS_IMETHODIMP nsMsgDBFolder::GetRetentionSettings(nsIMsgRetentionSettings **sett
|
||||
}
|
||||
}
|
||||
*settings = m_retentionSettings;
|
||||
NS_IF_ADDREF(*settings);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -170,6 +170,9 @@ protected:
|
||||
nsCOMPtr <nsIMimeConverter> m_mimeConverter;
|
||||
nsCOMPtr <nsIMsgRetentionSettings> m_retentionSettings;
|
||||
|
||||
nsresult PurgeMessagesOlderThan(PRUint32 daysToKeepHdrs, PRBool keepUnreadMessagesOnly);
|
||||
nsresult PurgeExcessMessages(PRUint32 numHeadersToKeep, PRBool keepUnreadMessagesOnly);
|
||||
|
||||
// mdb bookkeeping stuff
|
||||
nsresult InitExistingDB();
|
||||
nsresult InitNewDB();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <nsISimpleEnumerator> 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 <nsISimpleEnumerator> 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()
|
||||
|
||||
@@ -396,6 +396,13 @@ NS_IMETHODIMP
|
||||
nsMsgNewsFolder::UpdateFolder(nsIMsgWindow *aWindow)
|
||||
{
|
||||
GetDatabase(aWindow); // want this cached...
|
||||
if (mDatabase)
|
||||
{
|
||||
nsCOMPtr<nsIMsgRetentionSettings> 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<nsIMsgRetentionSettings> retentionSettings;
|
||||
rv = GetRetentionSettings(getter_AddRefs(retentionSettings));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = mDatabase->ApplyRetentionSettings(retentionSettings);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user