NS_IMETHODIMP nsFolderCompactState::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status) { nsCOMPtr<nsIMsgDBHdr> msgHdr; nsCOMPtr<nsIMsgDBHdr> newMsgHdr; if (NS_FAILED(status)) { m_status = status; // set the m_status to status so the destructor can remove the // temp folder and database m_folder->NotifyCompactCompleted(); ReleaseFolderLock(); } else { EndCopy(nsnull, status); if (m_curIndex >= m_size) { msgHdr = nsnull; newMsgHdr = nsnull; // no more to copy finish it up FinishCompact(); } else { // in case we're not getting an error, we still need to pretend we did get an error, // because the compact did not successfully complete. m_folder->NotifyCompactCompleted(); CleanupTempFilesAfterError(); ReleaseFolderLock(); } } Release(); // kill self return status; }
nsresult nsOfflineStoreCompactState::StartCompacting() { nsresult rv = NS_OK; if (m_size > 0 && m_curIndex == 0) { AddRef(); // we own ourselves, until we're done, anyway. ShowCompactingStatusMsg(); bool done = false; rv = CopyNextMessage(done); if (!done) return rv; } ReleaseFolderLock(); FinishCompact(); return rv; }
nsresult nsFolderCompactState::StartCompacting() { nsCOMPtr<nsIMsgPluggableStore> msgStore; nsCOMPtr<nsIMsgIncomingServer> server; nsresult rv = m_folder->GetServer(getter_AddRefs(server)); NS_ENSURE_SUCCESS(rv, rv); rv = server->GetMsgStore(getter_AddRefs(msgStore)); NS_ENSURE_SUCCESS(rv, rv); // Notify that compaction is beginning. We do this even if there are no // messages to be copied because the summary database still gets blown away // which is still pretty interesting. (And we like consistency.) nsCOMPtr<nsIMsgFolderNotificationService> notifier(do_GetService(NS_MSGNOTIFICATIONSERVICE_CONTRACTID)); if (notifier) notifier->NotifyItemEvent(m_folder, NS_LITERAL_CSTRING("FolderCompactStart"), nullptr); // TODO: test whether sorting the messages (m_keyArray) by messageOffset // would improve performance on large files (less seeks). // The m_keyArray is in the order as stored in DB and on IMAP or News // the messages stored on the mbox file are not necessarily in the same order. if (m_size > 0) { nsCOMPtr<nsIURI> notUsed; ShowCompactingStatusMsg(); AddRef(); rv = m_messageService->CopyMessages(m_size, m_keyArray->m_keys.Elements(), m_folder, this, false, nullptr, m_window, getter_AddRefs(notUsed)); } else { // no messages to copy with FinishCompact(); // Release(); // we don't "own" ourselves yet. } return rv; }
nsresult nsFolderCompactState::StartCompacting() { nsCOMPtr<nsIMsgPluggableStore> msgStore; nsCOMPtr<nsIMsgIncomingServer> server; nsresult rv = m_folder->GetServer(getter_AddRefs(server)); NS_ENSURE_SUCCESS(rv, rv); rv = server->GetMsgStore(getter_AddRefs(msgStore)); NS_ENSURE_SUCCESS(rv, rv); // Notify that compaction is beginning. We do this even if there are no // messages to be copied because the summary database still gets blown away // which is still pretty interesting. (And we like consistency.) nsCOMPtr<nsIMsgFolderNotificationService> notifier(do_GetService(NS_MSGNOTIFICATIONSERVICE_CONTRACTID)); if (notifier) notifier->NotifyItemEvent(m_folder, NS_LITERAL_CSTRING("FolderCompactStart"), nsnull); if (m_size > 0) { nsCOMPtr<nsIURI> notUsed; ShowCompactingStatusMsg(); AddRef(); rv = m_messageService->CopyMessages(m_size, m_keyArray->m_keys.Elements(), m_folder, this, false, nsnull, m_window, getter_AddRefs(notUsed)); } else { // no messages to copy with FinishCompact(); // Release(); // we don't "own" ourselves yet. } return rv; }
NS_IMETHODIMP nsOfflineStoreCompactState::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status) { nsresult rv = status; nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIMsgDBHdr> msgHdr; nsCOMPtr<nsIMsgDBHdr> newMsgHdr; nsCOMPtr <nsIMsgStatusFeedback> statusFeedback; bool done = false; // The NS_MSG_ERROR_MSG_NOT_OFFLINE error should allow us to continue, so we // check for it specifically and don't terminate the compaction. if (NS_FAILED(rv) && rv != NS_MSG_ERROR_MSG_NOT_OFFLINE) goto done; uri = do_QueryInterface(ctxt, &rv); if (NS_FAILED(rv)) goto done; rv = GetMessage(getter_AddRefs(msgHdr)); if (NS_FAILED(rv)) goto done; if (msgHdr) { if (NS_SUCCEEDED(status)) { msgHdr->SetMessageOffset(m_startOfNewMsg); char storeToken[100]; PR_snprintf(storeToken, sizeof(storeToken), "%lld", m_startOfNewMsg); msgHdr->SetStringProperty("storeToken", storeToken); msgHdr->SetOfflineMessageSize(m_offlineMsgSize); } else { PRUint32 resultFlags; msgHdr->AndFlags(~nsMsgMessageFlags::Offline, &resultFlags); } } if (m_window) { m_window->GetStatusFeedback(getter_AddRefs(statusFeedback)); if (statusFeedback) statusFeedback->ShowProgress (100 * m_curIndex / m_size); } // advance to next message m_curIndex++; rv = CopyNextMessage(done); if (done) { m_db->Commit(nsMsgDBCommitType::kCompressCommit); msgHdr = nsnull; newMsgHdr = nsnull; // no more to copy finish it up ReleaseFolderLock(); FinishCompact(); Release(); // kill self } done: if (NS_FAILED(rv)) { m_status = rv; // set the status to rv so the destructor can remove the // temp folder and database ReleaseFolderLock(); Release(); // kill self return rv; } return rv; }