diff --git a/mozilla/mailnews/base/src/nsMsgFolderCompactor.cpp b/mozilla/mailnews/base/src/nsMsgFolderCompactor.cpp index 335ca5de053..9e4e43a6858 100644 --- a/mozilla/mailnews/base/src/nsMsgFolderCompactor.cpp +++ b/mozilla/mailnews/base/src/nsMsgFolderCompactor.cpp @@ -117,10 +117,10 @@ void nsFolderCompactState::CleanupTempFilesAfterError() nsresult nsFolderCompactState::BuildMessageURI(const char *baseURI, PRUint32 key, nsCString& uri) { - uri.Append(baseURI); - uri.Append('#'); - uri.AppendInt(key); - return NS_OK; + uri.Append(baseURI); + uri.Append('#'); + uri.AppendInt(key); + return NS_OK; } @@ -411,26 +411,49 @@ nsFolderCompactState::FinishCompact() // close down database of the original folder and remove the folder node // and all it's message node from the tree m_folder->ForceDBClosed(); + + PRBool folderRenameSucceeded = PR_FALSE; + PRBool msfRenameSucceeded = PR_FALSE; // remove the old folder and database fileSpec.Delete(PR_FALSE); - summarySpec.Delete(PR_FALSE); - // rename the copied folder and database to be the original folder and - // database - m_fileSpec.Rename(leafName.get()); - newSummarySpec.Rename(dbName.get()); - + if (!fileSpec.Exists()) + { + summarySpec.Delete(PR_FALSE); + if (!summarySpec.Exists()) + { + // rename the copied folder and database to be the original folder and + // database + rv = m_fileSpec.Rename(leafName.get()); + NS_ASSERTION(NS_SUCCEEDED(rv), "error renaming compacted folder"); + if (NS_SUCCEEDED(rv)) + { + folderRenameSucceeded = PR_TRUE; + rv = newSummarySpec.Rename(dbName.get()); + NS_ASSERTION(NS_SUCCEEDED(rv), "error renaming compacted folder's db"); + msfRenameSucceeded = NS_SUCCEEDED(rv); + } + } + } + NS_ASSERTION(msfRenameSucceeded && folderRenameSucceeded, "rename failed in compact"); + if (!folderRenameSucceeded) + m_fileSpec.Delete(PR_FALSE); + if (!msfRenameSucceeded) + newSummarySpec.Delete(PR_FALSE); rv = ReleaseFolderLock(); NS_ASSERTION(NS_SUCCEEDED(rv),"folder lock not released successfully"); - m_folder->SetDBTransferInfo(transferInfo); + if (msfRenameSucceeded && folderRenameSucceeded) + { + m_folder->SetDBTransferInfo(transferInfo); - nsCOMPtr dbFolderInfo; + nsCOMPtr dbFolderInfo; - m_folder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(m_db)); + m_folder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(m_db)); - // since we're transferring info from the old db, we need to reset the expunged bytes, - // and set the summary valid again. - if(dbFolderInfo) - dbFolderInfo->SetExpungedBytes(0); + // since we're transferring info from the old db, we need to reset the expunged bytes, + // and set the summary valid again. + if(dbFolderInfo) + dbFolderInfo->SetExpungedBytes(0); + } if (m_db) m_db->Close(PR_TRUE); m_db = nsnull; diff --git a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp index 46f80ab15b6..70e9ca23e26 100644 --- a/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mozilla/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -2747,7 +2747,7 @@ NS_IMETHODIMP nsMsgDatabase::ListAllKeys(nsMsgKeyArray &outputKeys) return err; } -class nsMsgDBThreadEnumerator : public nsISimpleEnumerator +class nsMsgDBThreadEnumerator : public nsISimpleEnumerator, public nsIDBChangeListener { public: NS_DECL_ISUPPORTS @@ -2755,6 +2755,8 @@ public: // nsISimpleEnumerator methods: NS_DECL_NSISIMPLEENUMERATOR + NS_DECL_NSIDBCHANGELISTENER + // nsMsgDBEnumerator methods: typedef nsresult (*nsMsgDBThreadEnumeratorFilter)(nsIMsgThread* thread); @@ -2778,17 +2780,63 @@ nsMsgDBThreadEnumerator::nsMsgDBThreadEnumerator(nsMsgDatabase* db, mFilter(filter) { NS_ADDREF(mDB); + mDB->AddListener(this); mNextPrefetched = PR_FALSE; } nsMsgDBThreadEnumerator::~nsMsgDBThreadEnumerator() { mTableCursor->Release(); - NS_IF_RELEASE(mResultThread); - NS_RELEASE(mDB); + NS_IF_RELEASE(mResultThread); + NS_IF_RELEASE(mDB); } -NS_IMPL_ISUPPORTS1(nsMsgDBThreadEnumerator, nsISimpleEnumerator) +NS_IMPL_ISUPPORTS2(nsMsgDBThreadEnumerator, nsISimpleEnumerator, nsIDBChangeListener) + + +/* void onHdrChange (in nsIMsgDBHdr aHdrChanged, in unsigned long aOldFlags, in unsigned long aNewFlags, in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnHdrChange(nsIMsgDBHdr *aHdrChanged, PRUint32 aOldFlags, PRUint32 aNewFlags, nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} + +/* void onHdrDeleted (in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags, in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnHdrDeleted(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} + +/* void onHdrAdded (in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags, in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnHdrAdded(nsIMsgDBHdr *aHdrChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} + +/* void onParentChanged (in nsMsgKey aKeyChanged, in nsMsgKey oldParent, in nsMsgKey newParent, in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnParentChanged(nsMsgKey aKeyChanged, nsMsgKey oldParent, nsMsgKey newParent, nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} + +/* void onAnnouncerGoingAway (in nsIDBChangeAnnouncer instigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnAnnouncerGoingAway(nsIDBChangeAnnouncer *instigator) +{ + mDB->RemoveListener(this); + mDB = nsnull; + return NS_OK; +} + +/* void onReadChanged (in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnReadChanged(nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} + +/* void onJunkScoreChanged (in nsIDBChangeListener aInstigator); */ +NS_IMETHODIMP nsMsgDBThreadEnumerator::OnJunkScoreChanged(nsIDBChangeListener *aInstigator) +{ + return NS_OK; +} nsresult nsMsgDBThreadEnumerator::GetTableCursor(void) { @@ -2830,7 +2878,10 @@ nsresult nsMsgDBThreadEnumerator::PrefetchNext() { nsresult rv; nsIMdbTable *table = nsnull; - + + if (!mDB) + return NS_ERROR_NULL_POINTER; + if (!mTableCursor) { rv = GetTableCursor();