rest of fix for handling corrupt offline news stores (313147) and make nsIMsgDatabase::getNewList scriptable, part of work for 312940 beef up new msg notification, sr=mscott

This commit is contained in:
bienvenu%nventure.com 2005-10-27 13:56:50 +00:00
Родитель 728735cdd4
Коммит 7cc7b271c7
4 изменённых файлов: 54 добавлений и 38 удалений

Просмотреть файл

@ -236,6 +236,8 @@ NS_IMETHODIMP nsMsgDBFolder::Shutdown(PRBool shutdownChildren)
// Reset incoming server pointer and pathname.
mServer = nsnull;
mPath = nsnull;
mHaveParsedURI = PR_FALSE;
mName.SetLength(0);
mSubFolders->Clear();
}
return NS_OK;
@ -458,12 +460,14 @@ NS_IMETHODIMP nsMsgDBFolder::ClearNewMessages()
//If there's no db then there's nothing to clear.
if(mDatabase)
{
nsMsgKeyArray *newMessageKeys = nsnull;
rv = mDatabase->GetNewList(&newMessageKeys);
PRUint32 numNewKeys;
PRUint32 *newMessageKeys;
rv = mDatabase->GetNewList(&numNewKeys, &newMessageKeys);
if (NS_SUCCEEDED(rv) && newMessageKeys)
m_saveNewMsgs.CopyArray(newMessageKeys);
NS_DELETEXPCOM (newMessageKeys);
rv = mDatabase->ClearNewList(PR_TRUE);
{
m_saveNewMsgs.RemoveAll();
m_saveNewMsgs.Add(newMessageKeys, numNewKeys);
}
m_newMsgs.RemoveAll();
}
mNumNewBiffMessages = 0;
@ -675,13 +679,11 @@ NS_IMETHODIMP nsMsgDBFolder::GetOfflineFileStream(nsMsgKey msgKey, PRUint32 *off
// check if message starts with From, or is a draft and starts with FCC
if (NS_FAILED(rv) || bytesRead != sizeof(startOfMsg) ||
(strncmp(startOfMsg, "From ", 5) && (! (mFlags & MSG_FOLDER_FLAG_DRAFTS) || strncmp(startOfMsg, "FCC", 3))))
{
if (mDatabase)
mDatabase->MarkOffline(msgKey, PR_FALSE, nsnull);
rv = NS_ERROR_FAILURE;
}
}
}
if (NS_FAILED(rv) && mDatabase)
mDatabase->MarkOffline(msgKey, PR_FALSE, nsnull);
}
return rv;
}
@ -789,11 +791,15 @@ nsMsgDBFolder::SetMsgDatabase(nsIMsgDatabase *aMsgDatabase)
mDatabase->ClearCachedHdrs();
if (!aMsgDatabase)
{
nsMsgKeyArray *newMessageKeys = nsnull;
nsresult rv = mDatabase->GetNewList(&newMessageKeys);
PRUint32 numNewKeys;
PRUint32 *newMessageKeys;
nsresult rv = mDatabase->GetNewList(&numNewKeys, &newMessageKeys);
if (NS_SUCCEEDED(rv) && newMessageKeys)
m_newMsgs.CopyArray(newMessageKeys);
NS_DELETEXPCOM (newMessageKeys);
{
m_newMsgs.RemoveAll();
m_newMsgs.Add(newMessageKeys, numNewKeys);
}
nsMemory::Free (newMessageKeys);
}
}
mDatabase = aMsgDatabase;
@ -1895,16 +1901,19 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgWindow *aMsgWindow, PRBool *aFiltersRun)
// get the list of new messages
//
nsMsgKeyArray *newMessageKeys;
rv = mDatabase->GetNewList(&newMessageKeys);
PRUint32 numNewKeys;
PRUint32 *newKeys;
rv = mDatabase->GetNewList(&numNewKeys, &newKeys);
NS_ENSURE_SUCCESS(rv, rv);
if (!newMessageKeys && m_saveNewMsgs.GetSize() > 0)
newMessageKeys = new nsMsgKeyArray;
newMessageKeys->InsertAt(0, &m_saveNewMsgs);
nsMsgKeyArray newMessageKeys;
if (numNewKeys)
newMessageKeys.Add(newKeys, numNewKeys);
newMessageKeys.InsertAt(0, &m_saveNewMsgs);
// if there weren't any, just return
//
if (!newMessageKeys || !newMessageKeys->GetSize())
if (!newMessageKeys.GetSize())
return NS_OK;
spamSettings->GetUseWhiteList(&useWhiteList);
@ -1934,12 +1943,12 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgWindow *aMsgWindow, PRBool *aFiltersRun)
nsXPIDLCString uri;
nsMsgKeyArray keysToClassify;
PRUint32 numNewMessages = newMessageKeys->GetSize();
PRUint32 numNewMessages = newMessageKeys.GetSize();
for ( PRUint32 i=0 ; i < numNewMessages ; ++i )
{
nsXPIDLCString junkScore;
nsCOMPtr <nsIMsgDBHdr> msgHdr;
nsMsgKey msgKey = newMessageKeys->GetAt(i);
nsMsgKey msgKey = newMessageKeys.GetAt(i);
rv = mDatabase->GetMsgHdrForKey(msgKey, getter_AddRefs(msgHdr));
if (!NS_SUCCEEDED(rv))
continue;
@ -1970,7 +1979,7 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgWindow *aMsgWindow, PRBool *aFiltersRun)
}
}
keysToClassify.Add(newMessageKeys->GetAt(i));
keysToClassify.Add(newMessageKeys.GetAt(i));
}
@ -2001,7 +2010,6 @@ nsMsgDBFolder::CallFilterPlugins(nsIMsgWindow *aMsgWindow, PRBool *aFiltersRun)
}
m_saveNewMsgs.RemoveAll();
NS_DELETEXPCOM(newMessageKeys);
return rv;
}
@ -3674,6 +3682,8 @@ NS_IMETHODIMP nsMsgDBFolder::SetFlag(PRUint32 flag)
PRBool flagSet;
nsresult rv;
PRBool dbWasOpen = mDatabase != nsnull;
if (NS_FAILED(rv = GetFlag(flag, &flagSet)))
return rv;
@ -3682,6 +3692,8 @@ NS_IMETHODIMP nsMsgDBFolder::SetFlag(PRUint32 flag)
mFlags |= flag;
OnFlagChange(flag);
}
if (!dbWasOpen && mDatabase)
SetMsgDatabase(nsnull);
return NS_OK;
}

Просмотреть файл

@ -117,7 +117,7 @@ interface nsIMsgDBService : nsISupports
void unregisterPendingListener(in nsIDBChangeListener aListener);
};
[scriptable, uuid(1a706802-8121-4f91-a302-6e1f9a13204b)]
[scriptable, uuid(7b510984-bbac-4e8f-b6cd-134509000776)]
interface nsIMsgDatabase : nsIDBChangeAnnouncer {
void Open(in nsIFileSpec aFolderName, in boolean aCreate, in boolean aLeaveInvalidDB);
@ -296,10 +296,8 @@ interface nsIMsgDatabase : nsIDBChangeAnnouncer {
* The list of messages currently in the NEW state.
*
* If there are no such messages, a null pointer may be returned.
* Note that the since the structure itself is not refcounted,
* the caller should free when done using NS_DELETEXPCOM().
* the caller should free when done using nsMemory::Free.
*/
[noscript]
readonly attribute nsMsgKeyArrayPtr newList;
void getNewList(out unsigned long count, [array, size_is(count)] out nsMsgKey newKeys);
};

Просмотреть файл

@ -78,7 +78,7 @@ protected:
nsCOMArray <nsIDBChangeListener> m_pendingListeners;
};
class nsMsgDatabase : public nsIMsgDatabase
class nsMsgDatabase : public nsIMsgDatabase
{
public:
friend class nsMsgDBService;
@ -186,7 +186,11 @@ protected:
// open db cache
static void AddToCache(nsMsgDatabase* pMessageDB)
{GetDBCache()->AppendElement(pMessageDB);}
{
#ifdef DEBUG_David_Bienvenu
NS_ASSERTION(GetNumInCache() < 28, "28 or more open db's");
#endif
GetDBCache()->AppendElement(pMessageDB);}
static void RemoveFromCache(nsMsgDatabase* pMessageDB);
static int FindInCache(nsMsgDatabase* pMessageDB);
PRBool MatchDbName(nsFileSpec &dbName); // returns TRUE if they match

Просмотреть файл

@ -4756,23 +4756,25 @@ NS_IMETHODIMP nsMsgDatabase::SetFolderStream(nsIOFileStream *aFileStream)
}
/**
* [noscript] readonly attribute nsMsgKeySetPtr newList;
void getNewList(out unsigned long count, [array, size_is(count)] out long newKeys);
*/
NS_IMETHODIMP
nsMsgDatabase::GetNewList(nsMsgKeyArray * *aNewList)
nsMsgDatabase::GetNewList(PRUint32 *aCount, PRUint32 **aNewKeys)
{
NS_ENSURE_ARG_POINTER(aNewList);
NS_ENSURE_ARG_POINTER(aCount);
NS_ENSURE_ARG_POINTER(aNewKeys);
if (m_newSet.GetSize() > 0)
*aCount = m_newSet.GetSize();
if (*aCount > 0)
{
*aNewList = new nsMsgKeyArray;
if (!*aNewList)
*aNewKeys = NS_STATIC_CAST(PRUint32 *, nsMemory::Alloc(*aCount * sizeof(PRUint32)));
if (!*aNewKeys)
return NS_ERROR_OUT_OF_MEMORY;
(*aNewList)->CopyArray(m_newSet);
memcpy(*aNewKeys, m_newSet.GetArray(), *aCount * sizeof(PRUint32));
return NS_OK;
}
// if there were no new messages, signal this by returning a null pointer
//
*aNewList = 0;
*aNewKeys = nsnull;
return NS_OK;
}