--- a/mailnews/base/public/nsIMsgFolder.idl
+++ b/mailnews/base/public/nsIMsgFolder.idl
@@ -413,16 +413,29 @@ interface nsIMsgFolder : nsISupports {
void addMessageDispositionState(in nsIMsgDBHdr aMessage,
in nsMsgDispositionState aDispositionFlag);
void markMessagesRead(in nsIArray messages, in boolean markRead);
void markAllMessagesRead(in nsIMsgWindow aMsgWindow);
void markMessagesFlagged(in nsIArray messages, in boolean markFlagged);
void markThreadRead(in nsIMsgThread thread);
void setLabelForMessages(in nsIArray messages, in nsMsgLabelValue label);
+ /**
+ * Gets the message database for the folder.
+ *
+ * Note that if the database is out of date, the implementation MAY choose to
+ * throw an error. For a handle to the database which MAY NOT throw an error,
+ * one can use getDBFolderInfoAndDB.
+ *
+ * @exception NS_MSG_ERROR_FOLDER_SUMMARY_MISSING If the database does not
+ * exist.
+ * @exception NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE If the database contains
+ * out of date information.
+ * @see nsIMsgFolder::getDBFolderInfoAndDB.
+ */
nsIMsgDatabase getMsgDatabase(in nsIMsgWindow msgWindow);
void setMsgDatabase (in nsIMsgDatabase msgDatabase);
/**
* Get the backup message database, used in reparsing. This database must
* be created first using closeAndBackupFolderDB()
*
* @return backup message database
*/
--- a/mailnews/base/search/src/nsMsgFilterService.cpp
+++ b/mailnews/base/search/src/nsMsgFilterService.cpp
@@ -385,17 +385,17 @@ nsresult nsMsgFilterAfterTheFact::Advanc
{
if (m_curFolderIndex >= m_numFolders)
return OnEndExecution(NS_OK);
nsresult rv = m_folders->QueryElementAt(m_curFolderIndex++, NS_GET_IID(nsIMsgFolder), getter_AddRefs(m_curFolder));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
rv = m_curFolder->GetDBFolderInfoAndDB(getter_AddRefs(dbFolderInfo), getter_AddRefs(m_curFolderDB));
- if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING || rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
+ if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
{
nsCOMPtr<nsIMsgLocalMailFolder> localFolder = do_QueryInterface(m_curFolder, &rv);
if (NS_SUCCEEDED(rv) && localFolder)
return localFolder->ParseFolder(m_msgWindow, this);
}
return RunNextFilter();
}
--- a/mailnews/base/search/src/nsMsgLocalSearch.cpp
+++ b/mailnews/base/search/src/nsMsgLocalSearch.cpp
@@ -301,17 +301,16 @@ nsresult nsMsgSearchOfflineMail::OpenSum
}
else
return err; // not sure why m_folder wouldn't be set.
switch (err)
{
case NS_OK:
break;
- case NS_MSG_ERROR_FOLDER_SUMMARY_MISSING:
case NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE:
{
nsCOMPtr<nsIMsgLocalMailFolder> localFolder = do_QueryInterface(scopeFolder, &err);
if (NS_SUCCEEDED(err) && localFolder)
{
nsCOMPtr<nsIMsgSearchSession> searchSession;
m_scope->GetSearchSession(getter_AddRefs(searchSession));
if (searchSession)
--- a/mailnews/base/src/nsMsgFolderCompactor.cpp
+++ b/mailnews/base/src/nsMsgFolderCompactor.cpp
@@ -197,17 +197,18 @@ nsFolderCompactState::Compact(nsIMsgFold
nsCString baseMessageURI;
nsCOMPtr <nsIMsgLocalMailFolder> localFolder = do_QueryInterface(folder, &rv);
if (NS_SUCCEEDED(rv) && localFolder)
{
rv=localFolder->GetDatabaseWOReparse(getter_AddRefs(db));
if (NS_FAILED(rv) || !db)
{
- if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING || rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
+ if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING ||
+ rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
{
m_folder = folder; //will be used to compact
m_parsingFolder = PR_TRUE;
rv = localFolder->ParseFolder(m_window, this);
}
return rv;
}
else
--- a/mailnews/db/msgdb/public/nsIMsgDatabase.idl
+++ b/mailnews/db/msgdb/public/nsIMsgDatabase.idl
@@ -15,31 +15,49 @@
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Joshua Cranmer <Pidgeot18@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
+/**
+ * @defgroup msgdb Mailnews message database
+ * This module is the access point to locally-stored databases.
+ *
+ * These databases are stored in .msf files. Each file contains useful cached
+ * information, like the message id or references, as well as the cc header or
+ * tag information. This cached information is encapsulated in nsIMsgDBHdr.
+ *
+ * Also included is threading information, mostly encapsulated in nsIMsgThread.
+ * The final component is the database folder info, which contains information
+ * on the view and basic information also stored in the folder cache such as the
+ * name or most recent update.
+ *
+ * What this module does not do is access individual messages. Access is
+ * strictly controlled by the nsIMsgFolder objects and their backends.
+ * @{
+ */
#include "nsISupports.idl"
#include "MailNewsTypes2.idl"
#include "nsIDBChangeAnnouncer.idl"
#include "nsIMsgDBView.idl"
%{C++
#include "nsTArray.h"
%}
@@ -101,58 +119,129 @@ interface nsMsgDBCommitType
const long kLargeCommit = 1;
const long kSessionCommit = 2;
const long kCompressCommit = 3;
};
[ref] native nsMsgKeyArrayRef(nsTArray<nsMsgKey>);
[ptr] native nsMsgKeyArrayPtr(nsTArray<nsMsgKey>);
-[scriptable, uuid(03223c50-1e88-45e8-ba1a-7ce792dc3fc3)]
+/**
+ * A service to open mail databases and manipulate listeners automatically.
+ *
+ * The contract ID for this component is
+ * <tt>\@mozilla.org/msgDatabase/msgDBService;1</tt>.
+ */
+[scriptable, uuid(26cb7242-a4ba-4811-ad7b-ff993450aae3)]
interface nsIMsgDBService : nsISupports
{
- // want to remove this method from nsIMsgDatabase...
- // if a db is opened on the folder, the listener will automatically be added
-
/**
- * Opens a database folder.
+ * Opens a database for a given folder.
+ *
+ * This method is preferred over nsIMsgDBService::openMailDBFromFile if the
+ * caller has an actual nsIMsgFolder around. If the database detects that it
+ * is unreadable or out of date (using nsIMsgDatabase::outOfDate) it will
+ * destroy itself and prepare to be rebuilt, unless aLeaveInvalidDB is true.
*
- * @param aFolderName The name of the folder to create.
- * @param aCreate Whether or not the file should be created.
- * @param aLeaveInvalidDB Set to true if you do not want the database to be
- * deleted if it is invalid.
- * @return A new nsIMsgDatabase object representing the
- * folder database that was opened.
+ * If one gets a NS_MSG_ERROR_FOLDER_SUMMARY_MISSING message, then one
+ * should call nsIMsgDBService::createNewDB to create the new database.
+ *
+ * @param aFolder The folder whose database should be returned.
+ * @param aLeaveInvalidDB Whether or not the database should be deleted if it
+ * is invalid.
+ * @return A new nsIMsgDatabase object representing the folder
+ * database that was opened.
* @exception NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
- * aFolderName doesn't exist and aCreate was false.
+ * The file could not be created.
* @exception NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE
* The database is present (and was opened), but the
* summary file is out of date.
* @exception NS_MSG_ERROR_FOLDER_SUMMARY_MISSING
- * The database is present (and was opened), but the
- * summary file is missing.
+ * The database is present, but the summary file is
+ * missing.
+ * @see nsIMsgDatabase::Open
+ * @see nsIMsgDBService::createNewDB
+ */
+ nsIMsgDatabase openFolderDB(in nsIMsgFolder aFolder,
+ in boolean aLeaveInvalidDB);
+
+ /**
+ * Creates a new database for the given folder.
+ *
+ * If the database already exists, it will return the database, emit a
+ * warning, but not fully initialize it. For this reason, it should only be
+ * used when it is known that the database does not exist, such as when
+ * nsIMsgDBService::openFolderDB throws an error.
+ *
+ * @see nsIMsgDBService::openFolderDB
*/
- nsIMsgDatabase openFolderDB(in nsIMsgFolder aFolder, in boolean aCreate,
- in boolean aLeaveInvalidDB);
- nsIMsgDatabase openMailDBFromFile(in nsILocalFile aFolderName, in boolean aCreate, in boolean aLeaveInvalidDB);
- void registerPendingListener(in nsIMsgFolder aFolder, in nsIDBChangeListener aListener);
- void unregisterPendingListener(in nsIDBChangeListener aListener);
+ nsIMsgDatabase createNewDB(in nsIMsgFolder aFolder);
+
+ /**
+ * Opens or creates a database for a given file.
+ *
+ * This method should only be used if the caller does not have a folder
+ * instance, because the resulting db and message headers retrieved from the
+ * database would not know their owning folder, which limits their usefulness.
+ * For this reason, one should use nsIMsgDBService::openFolderDB instead
+ * except under special circumstances.
+ *
+ * Unlike nsIMsgDBService::openFolderDB, there is no corresponding method to
+ * create a new database if opening the database failed. However, this method
+ * will never throw NS_MSG_ERROR_FOLDER_SUMMARY_MISSING, so no corresponding
+ * method is needed.
+ *
+ * @param aFile The file for which the database should be returned.
+ * @param aCreate Whether or not the file should be created.
+ * @param aLeaveInvalidDB Whether or not the database should be deleted if it
+ * is invalid.
+ * @return A new nsIMsgDatabase object encapsulating the file
+ * passed in.
+ * @exception NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
+ * The file could not be created.
+ * @see nsIMsgDBService::openFolderDB
+ * @see nsIMsgDatabase::Open
+ */
+ nsIMsgDatabase openMailDBFromFile(in nsILocalFile aFile,
+ in boolean aCreate,
+ in boolean aLeaveInvalidDB);
+ /**
+ * Adds the given listener to the listener set for the folder.
+ *
+ * Since the message database will likely be opened and closed many times, by
+ * registering using this method, one will be guaranteed to see all subsequent
+ * modifications. This will also add the listener to the database if it is
+ * already opened.
+ *
+ * @param aFolder The folder to add a listener to.
+ * @param aListener The listener to add the folder to.
+ */
+ void registerPendingListener(in nsIMsgFolder aFolder,
+ in nsIDBChangeListener aListener);
+ /**
+ * Removes the listener from all folder listener sets.
+ *
+ * @param aListener The listener to remove.
+ * @exception NS_ERROR_FAILURE
+ * The listener is not registered.
+ */
+ void unregisterPendingListener(in nsIDBChangeListener aListener);
};
[scriptable, uuid(55EEECA9-FCF6-4a94-A9D4-0ECFBAAE8CAA)]
interface nsIMsgDatabase : nsIDBChangeAnnouncer {
/**
* Opens a database folder.
*
* @param aFolderName The name of the folder to create.
* @param aCreate Whether or not the file should be created.
* @param aLeaveInvalidDB Set to true if you do not want the database to be
* deleted if it is invalid.
* @exception NS_ERROR_FILE_TARGET_DOES_NOT_EXIST
- * aFolderName doesn't exist and aCreate was false.
+ * The file could not be created.
* @exception NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE
* The database is present (and was opened), but the
* summary file is out of date.
* @exception NS_MSG_ERROR_FOLDER_SUMMARY_MISSING
* The database is present (and was opened), but the
* summary file is missing.
*/
void Open(in nsILocalFile aFolderName, in boolean aCreate,
@@ -352,9 +441,9 @@ interface nsIMsgDatabase : nsIDBChangeAn
// These are used for caching search hits in a db, to speed up saved search folders.
nsISimpleEnumerator getCachedHits(in string aSearchFolderUri);
void refreshCache(in string aSearchFolderUri, in unsigned long aNumKeys, [array, size_is (aNumKeys)] in nsMsgKey aNewHits,
out unsigned long aNumBadHits, [array, size_is(aNumBadHits)] out nsMsgKey aStaleHits);
void updateHdrInCache(in string aSearchFolderUri, in nsIMsgDBHdr aHdr, in boolean aAdd);
boolean hdrIsInCache(in string aSearchFolderUri, in nsIMsgDBHdr aHdr);
};
-
+/** @} */
--- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp
+++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp
@@ -97,17 +97,19 @@ nsMsgDBService::nsMsgDBService()
{
}
nsMsgDBService::~nsMsgDBService()
{
}
-NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder, PRBool aCreate, PRBool aLeaveInvalidDB, nsIMsgDatabase **_retval)
+NS_IMETHODIMP nsMsgDBService::OpenFolderDB(nsIMsgFolder *aFolder,
+ PRBool aLeaveInvalidDB,
+ nsIMsgDatabase **_retval)
{
NS_ENSURE_ARG(aFolder);
nsMsgDatabase *cacheDB = (nsMsgDatabase *) nsMsgDatabase::FindInCache(aFolder);
if (cacheDB)
{
// this db could have ended up in the folder cache w/o an m_folder pointer via
// OpenMailDBFromFile. If so, take this chance to fix the folder.
if (!cacheDB->m_folder)
@@ -123,20 +125,22 @@ NS_IMETHODIMP nsMsgDBService::OpenFolder
incomingServer->GetLocalStoreType(localStoreType);
nsCAutoString dbContractID(NS_MSGDB_CONTRACTID);
dbContractID.Append(localStoreType.get());
nsCOMPtr <nsIMsgDatabase> msgDB = do_CreateInstance(dbContractID.get(), &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsILocalFile> folderPath;
rv = aFolder->GetFilePath(getter_AddRefs(folderPath));
NS_ENSURE_SUCCESS(rv, rv);
- rv = msgDB->Open(folderPath, aCreate, aLeaveInvalidDB);
- if (NS_FAILED(rv) && (rv != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING
- && rv != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE || !aCreate))
+
+ // Don't try to create the database yet--let the createNewDB call do that.
+ rv = msgDB->Open(folderPath, PR_FALSE, aLeaveInvalidDB);
+ if (NS_FAILED(rv) && rv != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
return rv;
+
NS_IF_ADDREF(*_retval = msgDB);
nsMsgDatabase *msgDatabase = static_cast<nsMsgDatabase *>(*_retval);
msgDatabase->m_folder = aFolder;
if (NS_FAILED(rv))
{
#ifdef DEBUG
// Doing these checks for debug only as we don't want to report certain
@@ -202,16 +206,54 @@ NS_IMETHODIMP nsMsgDBService::OpenMailDB
if (rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
return rv;
NS_IF_ADDREF(*pMessageDB = msgDB);
if (aCreate && msgDB && rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
rv = NS_OK;
return rv;
}
+NS_IMETHODIMP nsMsgDBService::CreateNewDB(nsIMsgFolder *aFolder,
+ nsIMsgDatabase **_retval)
+{
+ NS_ENSURE_ARG(aFolder);
+
+ nsCOMPtr <nsIMsgIncomingServer> incomingServer;
+ nsresult rv = aFolder->GetServer(getter_AddRefs(incomingServer));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString localStoreType;
+ incomingServer->GetLocalStoreType(localStoreType);
+ nsCAutoString dbContractID(NS_MSGDB_CONTRACTID);
+ dbContractID.Append(localStoreType.get());
+
+ nsCOMPtr <nsIMsgDatabase> msgDB = do_CreateInstance(dbContractID.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr <nsILocalFile> folderPath;
+ rv = aFolder->GetFilePath(getter_AddRefs(folderPath));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = msgDB->Open(folderPath, PR_TRUE, PR_TRUE);
+ NS_ENSURE_TRUE(rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING, rv);
+
+ NS_IF_ADDREF(*_retval = msgDB);
+ nsMsgDatabase *msgDatabase = static_cast<nsMsgDatabase *>(*_retval);
+ msgDatabase->m_folder = aFolder;
+
+ // Add all pending listeners to the database
+ for (PRInt32 listenerIndex = 0;
+ listenerIndex < m_foldersPendingListeners.Count(); listenerIndex++)
+ {
+ if (m_foldersPendingListeners[listenerIndex] == aFolder)
+ msgDatabase->AddListener(m_pendingListeners.ObjectAt(listenerIndex));
+ }
+ return NS_OK;
+}
+
/* void registerPendingListener (in nsIMsgFolder aFolder, in nsIDBChangeListener aListener); */
NS_IMETHODIMP nsMsgDBService::RegisterPendingListener(nsIMsgFolder *aFolder, nsIDBChangeListener *aListener)
{
// need to make sure we don't hold onto these forever. Maybe a shutdown listener?
// if there is a db open on this folder already, we should register the listener.
m_foldersPendingListeners.AppendObject(aFolder);
m_pendingListeners.AppendObject(aListener);
nsCOMPtr <nsIMsgDatabase> openDB;
--- a/mailnews/db/msgdb/test/unit/test_maildb.js
+++ b/mailnews/db/msgdb/test/unit/test_maildb.js
@@ -10,18 +10,18 @@ function run_test() {
// Get the root folder
var root = gLocalIncomingServer.rootFolder;
root.createSubfolder("dbTest", null);
var dbService = Components.classes["@mozilla.org/msgDatabase/msgDBService;1"]
.getService(Components.interfaces.nsIMsgDBService);
var folder = root.getChildNamed("dbTest");
- var db = dbService.openFolderDB(folder, true, true);
+ var db = dbService.openFolderDB(folder, true);
do_check_neq(db, null);
db.dBFolderInfo.highWater = 10;
db.Close(true);
- db = dbService.openFolderDB(folder, true, true);
+ db = dbService.openFolderDB(folder, true);
do_check_neq(db, null);
do_check_eq(db.dBFolderInfo.highWater, 10);
db.dBFolderInfo.onKeyAdded(15);
do_check_eq(db.dBFolderInfo.highWater, 15);
}
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -649,46 +649,41 @@ NS_IMETHODIMP nsImapMailFolder::GetSubFo
return aResult ? NS_NewArrayEnumerator(aResult, mSubFolders) : NS_ERROR_NULL_POINTER;
}
//Makes sure the database is open and exists. If the database is valid then
//returns NS_OK. Otherwise returns a failure error value.
nsresult nsImapMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
{
- nsresult folderOpen = NS_OK;
+ nsresult rv = NS_OK;
if (!mDatabase)
{
- nsresult rv;
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE, PR_FALSE, getter_AddRefs(mDatabase));
-
- if (NS_FAILED(folderOpen) && folderOpen != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE, PR_TRUE, getter_AddRefs(mDatabase));
-
- if (NS_FAILED(folderOpen) && folderOpen != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- return folderOpen;
-
- if(folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- folderOpen = NS_OK;
+ // Create the database, blowing it away if it needs to be rebuilt
+ rv = msgDBService->OpenFolderDB(this, PR_FALSE, getter_AddRefs(mDatabase));
+ if (NS_FAILED(rv))
+ rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
+
+ NS_ENSURE_SUCCESS(rv, rv);
if(mDatabase)
{
UpdateNewMessages();
if(mAddListener)
mDatabase->AddListener(this);
// UpdateSummaryTotals can null mDatabase during initialization, so we save a local copy
nsCOMPtr<nsIMsgDatabase> database(mDatabase);
UpdateSummaryTotals(PR_TRUE);
mDatabase = database;
}
}
- return folderOpen;
+ return rv;
}
NS_IMETHODIMP nsImapMailFolder::UpdateFolder(nsIMsgWindow * inMsgWindow)
{
return UpdateFolder(inMsgWindow, nsnull);
}
NS_IMETHODIMP nsImapMailFolder::UpdateFolder(nsIMsgWindow *msgWindow, nsIUrlListener *aUrlListener)
@@ -2554,22 +2549,18 @@ NS_IMETHODIMP nsImapMailFolder::UpdateIm
nsCOMPtr <nsILocalFile> summaryFile;
GetSummaryFileLocation(pathFile, getter_AddRefs(summaryFile));
// Remove summary file.
summaryFile->Remove(PR_FALSE);
// Create a new summary file, update the folder message counts, and
// Close the summary file db.
- rv = msgDBService->OpenFolderDB(this, PR_TRUE, PR_TRUE, getter_AddRefs(mDatabase));
-
- // ********** Important *************
- // David, help me here I don't know this is right or wrong
- if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- rv = NS_OK;
+ PRBool created;
+ rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
if (NS_FAILED(rv) && mDatabase)
{
mDatabase->ForceClosed();
mDatabase = nsnull;
}
else if (NS_SUCCEEDED(rv) && mDatabase)
{
--- a/mailnews/local/src/nsLocalMailFolder.cpp
+++ b/mailnews/local/src/nsLocalMailFolder.cpp
@@ -458,17 +458,19 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetD
if (m_parsingFolder)
return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE;
nsresult rv = NS_OK;
if (!mDatabase)
{
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- rv = msgDBService->OpenFolderDB(this, PR_FALSE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(mDatabase));
+
+ rv = msgDBService->OpenFolderDB(this, PR_TRUE, getter_AddRefs(mDatabase));
+
if (mDatabase && NS_SUCCEEDED(rv))
{
mDatabase->AddListener(this);
UpdateNewMessages();
}
}
NS_IF_ADDREF(*aDatabase = mDatabase);
return rv;
@@ -496,31 +498,30 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetD
nsCOMPtr <nsILocalFile> pathFile;
rv = GetFilePath(getter_AddRefs(pathFile));
if (NS_FAILED(rv)) return rv;
PRBool exists;
rv = pathFile->Exists(&exists);
NS_ENSURE_SUCCESS(rv,rv);
if (!exists)
return NS_ERROR_NULL_POINTER; //mDatabase will be null at this point.
- nsresult folderOpen = NS_OK;
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
- folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE, PR_TRUE, getter_AddRefs(mDatabase));
- if(NS_FAILED(folderOpen) && folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
+
+ nsresult folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE,
+ getter_AddRefs(mDatabase));
+ if (folderOpen == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
{
nsCOMPtr <nsIDBFolderInfo> dbFolderInfo;
nsCOMPtr <nsIDBFolderInfo> transferInfo;
if (mDatabase)
{
mDatabase->GetDBFolderInfo(getter_AddRefs(dbFolderInfo));
if (dbFolderInfo)
{
- if (folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- dbFolderInfo->SetFlags(mFlags);
dbFolderInfo->SetNumMessages(0);
dbFolderInfo->SetNumUnreadMessages(0);
dbFolderInfo->GetTransferInfo(getter_AddRefs(transferInfo));
}
dbFolderInfo = nsnull;
// A backup message database might have been created earlier, for example
// if the user requested a reindex. We'll use the earlier one if we can,
@@ -538,34 +539,38 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetD
}
nsCOMPtr <nsILocalFile> summaryFile;
rv = GetSummaryFileLocation(pathFile, getter_AddRefs(summaryFile));
NS_ENSURE_SUCCESS(rv, rv);
// Remove summary file.
summaryFile->Remove(PR_FALSE);
// if it's out of date then reopen with upgrade.
- if (NS_FAILED(rv = msgDBService->OpenFolderDB(this, PR_TRUE, PR_TRUE, getter_AddRefs(mDatabase)))
- && rv != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING && rv != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
- return rv;
- else if (transferInfo && mDatabase)
+ rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (transferInfo && mDatabase)
{
SetDBTransferInfo(transferInfo);
mDatabase->SetSummaryValid(PR_FALSE);
}
}
+ else if (folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
+ {
+ msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
+ }
if(mDatabase)
{
if(mAddListener)
mDatabase->AddListener(this);
// if we have to regenerate the folder, run the parser url.
- if(folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING ||
- folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
+ if (folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING ||
+ folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
{
if(NS_FAILED(rv = ParseFolder(aMsgWindow, aReparseUrlListener)))
{
if (rv == NS_MSG_FOLDER_BUSY)
{
mDatabase->RemoveListener(this); //we need to null out the db so that parsing gets kicked off again.
mDatabase = nsnull;
ThrowAlertMsg("parsingFolderFailed", aMsgWindow);
@@ -771,20 +776,22 @@ nsMsgLocalMailFolder::CreateSubfolder(co
return rv;
}
// Create an empty database for this mail folder, set its name from the user
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
if (msgDBService)
{
nsCOMPtr<nsIMsgDatabase> unusedDB;
- rv = msgDBService->OpenFolderDB(child, PR_TRUE, PR_TRUE, getter_AddRefs(unusedDB));
-
- if ((NS_SUCCEEDED(rv) || rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING
- || rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE) && unusedDB)
+ rv = msgDBService->OpenFolderDB(child, PR_TRUE, getter_AddRefs(unusedDB));
+ if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
+ rv = msgDBService->CreateNewDB(child, getter_AddRefs(unusedDB));
+
+ if ((NS_SUCCEEDED(rv) || rv == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE) &&
+ unusedDB)
{
//need to set the folder name
nsCOMPtr<nsIDBFolderInfo> folderInfo;
rv = unusedDB->GetDBFolderInfo(getter_AddRefs(folderInfo));
if(NS_SUCCEEDED(rv))
{
folderInfo->SetMailboxName(safeFolderName);
}
@@ -1286,23 +1293,22 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetN
{
ReadDBFolderInfo(PR_FALSE);
return nsMsgDBFolder::GetName(aName);
}
NS_IMETHODIMP
nsMsgLocalMailFolder::GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatabase **db)
{
- nsresult openErr = NS_ERROR_UNEXPECTED;
if(!db || !folderInfo || !mPath || mIsServer)
return NS_ERROR_NULL_POINTER; //ducarroz: should we use NS_ERROR_INVALID_ARG?
nsresult rv;
if (mDatabase)
- openErr = NS_OK;
+ rv = NS_OK;
else
{
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRBool folderEmpty = PR_FALSE;
nsCOMPtr <nsILocalFile> file;
rv = GetFilePath(getter_AddRefs(file));
@@ -1310,36 +1316,36 @@ nsMsgLocalMailFolder::GetDBFolderInfoAnd
// and in that case, tell msg db to create a new db and set it valid after opening it.
if (NS_SUCCEEDED(rv))
{
PRInt64 mailboxSize;
if (NS_SUCCEEDED(file->GetFileSize(&mailboxSize)))
folderEmpty = !mailboxSize;
}
- openErr = msgDBService->OpenFolderDB(this, folderEmpty, PR_FALSE, getter_AddRefs(mDatabase));
+ rv = msgDBService->OpenFolderDB(this, PR_FALSE, getter_AddRefs(mDatabase));
if (folderEmpty)
{
- if (openErr == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
+ if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
{
+ rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
if (mDatabase)
mDatabase->SetSummaryValid(PR_TRUE);
- openErr = NS_OK;
}
- else if (NS_FAILED(openErr))
+ else if (NS_FAILED(rv))
mDatabase = nsnull;
}
if (mAddListener && mDatabase)
mDatabase->AddListener(this);
}
NS_IF_ADDREF(*db = mDatabase);
- if (NS_SUCCEEDED(openErr)&& *db)
- openErr = (*db)->GetDBFolderInfo(folderInfo);
- return openErr;
+ if (NS_SUCCEEDED(rv) && *db)
+ rv = (*db)->GetDBFolderInfo(folderInfo);
+ return rv;
}
NS_IMETHODIMP nsMsgLocalMailFolder::ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element)
{
NS_ENSURE_ARG_POINTER(element);
nsresult rv = nsMsgDBFolder::ReadFromFolderCacheElem(element);
NS_ENSURE_SUCCESS(rv, rv);
nsCString utf8Name;
--- a/mailnews/local/src/nsParseMailbox.cpp
+++ b/mailnews/local/src/nsParseMailbox.cpp
@@ -153,18 +153,24 @@ NS_IMETHODIMP nsMsgMailboxParser::OnStar
path->GetFileSize(&fileSize);
// the size of the mailbox file is our total base line for measuring progress
m_graph_progress_total = (PRUint32) fileSize;
UpdateStatusText(LOCAL_STATUS_SELECTING_MAILBOX);
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
if (msgDBService)
{
- //Use OpenFolderDB to always open the db so that db's m_folder is set correctly.
- rv = msgDBService->OpenFolderDB(folder, PR_TRUE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(m_mailDB));
+ // Use OpenFolderDB to always open the db so that db's m_folder
+ // is set correctly.
+ rv = msgDBService->OpenFolderDB(folder, PR_TRUE,
+ getter_AddRefs(m_mailDB));
+ if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
+ rv = msgDBService->CreateNewDB(folder,
+ getter_AddRefs(m_mailDB));
+
if (m_mailDB)
m_mailDB->AddListener(this);
}
NS_ASSERTION(m_mailDB, "failed to open mail db parsing folder");
// try to get a backup message database
nsresult rvignore = folder->GetBackupMsgDatabase(
getter_AddRefs(m_backupMailDB));
@@ -1638,17 +1644,18 @@ nsParseNewMailState::Init(nsIMsgFolder *
m_msgWindow = aMsgWindow;
m_downloadFolder = downloadFolder;
m_downloadingToTempFile = downloadingToTempFile;
// the new mail parser isn't going to get the stream input, it seems, so we can't use
// the OnStartRequest mechanism the mailbox parser uses. So, let's open the db right now.
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
if (msgDBService)
- rv = msgDBService->OpenFolderDB(downloadFolder, PR_TRUE, PR_FALSE, (nsIMsgDatabase **) getter_AddRefs(m_mailDB));
+ rv = msgDBService->OpenFolderDB(downloadFolder, PR_FALSE,
+ getter_AddRefs(m_mailDB));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsIMsgFolder> rootMsgFolder = do_QueryInterface(serverFolder, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgIncomingServer> server;
rv = rootMsgFolder->GetServer(getter_AddRefs(server));
if (NS_SUCCEEDED(rv))
{
--- a/mailnews/news/src/nsNewsFolder.cpp
+++ b/mailnews/news/src/nsNewsFolder.cpp
@@ -287,23 +287,21 @@ nsMsgNewsFolder::GetSubFolders(nsISimple
nsresult nsMsgNewsFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
{
nsresult rv;
if (!mDatabase)
{
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
- nsresult folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE, PR_FALSE, getter_AddRefs(mDatabase));
-
- if (NS_FAILED(folderOpen) && folderOpen != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- folderOpen = msgDBService->OpenFolderDB(this, PR_TRUE, PR_TRUE, getter_AddRefs(mDatabase));
-
- if (NS_FAILED(folderOpen) && folderOpen != NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
- return folderOpen;
+ // Get the database, blowing it away if it's out of date.
+ rv = msgDBService->OpenFolderDB(this, PR_FALSE, getter_AddRefs(mDatabase));
+ if (NS_FAILED(rv))
+ rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
+ NS_ENSURE_SUCCESS(rv, rv);
if(mAddListener)
rv = mDatabase->AddListener(this);
nsCOMPtr<nsINewsDatabase> db = do_QueryInterface(mDatabase, &rv);
if (NS_FAILED(rv))
return rv;