more work on search BE, 33101 r=alecf parse local folders before searching

This commit is contained in:
bienvenu%netscape.com 2000-06-16 13:21:41 +00:00
Родитель c557ad7fb9
Коммит a2394b0581
8 изменённых файлов: 159 добавлений и 84 удалений

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

@ -89,7 +89,15 @@ interface nsIMsgSearchSession : nsISupports {
void Search(in nsIMsgWindow aWindow);
void InterruptSearch();
// these two methods are used when the search session is using
// a timer to do local search, and the search adapter needs
// to run a url (e.g., to reparse a local folder) and wants to
// pause the timer while running the url. This will fail if the
// current adapter is not using a timer.
void PauseSearch();
void ResumeSearch();
[noscript] readonly attribute voidPtr searchParam;
readonly attribute nsMsgSearchType searchType;
@ -101,6 +109,7 @@ interface nsIMsgSearchSession : nsISupports {
void AddSearchHit(in nsIMsgDBHdr header, in nsIMsgFolder folder);
readonly attribute long numResults;
attribute nsIMsgWindow window;
/* these longs are all actually of type nsMsgSearchBooleanOp */
const long BooleanOR=0;

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

@ -35,6 +35,8 @@
#include "nsMsgBaseCID.h"
#include "nsMsgSearchValue.h"
#include "nsIMsgLocalMailFolder.h"
#include "nsIMsgWindow.h"
static NS_DEFINE_CID(kValidityManagerCID, NS_MSGSEARCHVALIDITYMANAGER_CID);
@ -237,6 +239,7 @@ PRInt32 nsMsgSearchBoolExpression::GenerateEncodeStr(nsCString * buffer)
//---------------- Adapter class for searching offline IMAP folders -----------
//-----------------------------------------------------------------------------
nsMsgSearchIMAPOfflineMail::nsMsgSearchIMAPOfflineMail (nsIMsgSearchScopeTerm *scope, nsISupportsArray *termList) : nsMsgSearchOfflineMail(scope, termList)
{
@ -292,13 +295,12 @@ nsresult nsMsgSearchIMAPOfflineMail::ValidateTerms ()
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS_INHERITED(nsMsgSearchOfflineMail, nsMsgSearchAdapter, nsIUrlListener)
nsMsgSearchOfflineMail::nsMsgSearchOfflineMail (nsIMsgSearchScopeTerm *scope, nsISupportsArray *termList) : nsMsgSearchAdapter (scope, termList)
{
m_db = nsnull;
m_listContext = nsnull;
m_mailboxParser = nsnull;
m_parserState = kOpenFolderState;
}
@ -373,26 +375,22 @@ nsresult nsMsgSearchOfflineMail::OpenSummaryFile ()
break;
case NS_MSG_ERROR_FOLDER_SUMMARY_MISSING:
case NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE:
#ifdef HANDLE_OUT_OF_DATE_SUMMARY_FILES // which we don't yet.
m_mailboxParser = new nsMsgMailboxParser (m_scope->GetMailPath());
if (!m_mailboxParser)
err = NS_ERROR_OUT_OF_MEMORY;
else
{
nsCOMPtr<nsIMsgLocalMailFolder> localFolder = do_QueryInterface(scopeFolder, &err);
if (NS_SUCCEEDED(err) && localFolder)
{
// Remove the old summary file so maildb::open can create a new one
XP_FileRemove (m_scope->GetMailPath(), xpMailFolderSummary);
dbErr = MailDB::Open (m_scope->GetMailPath(), PR_TRUE /*create?*/, &mailDb, PR_TRUE /*upgrading?*/);
NS_ASSERTION(mailDb, "couldn't opn DB");
nsCOMPtr<nsIMsgSearchSession> searchSession;
m_scope->GetSearchSession(getter_AddRefs(searchSession));
if (searchSession)
{
nsCOMPtr <nsIMsgWindow> searchWindow;
// Initialize the async parser to rebuild the summary file
m_parserState = kOpenFolderState;
m_mailboxParser->SetContext (m_scope->m_frame->GetContext());
m_mailboxParser->SetDB (mailDb);
m_mailboxParser->SetFolder(m_scope->m_folder);
m_mailboxParser->SetIgnoreNonMailFolder(PR_TRUE);
err = NS_OK;
searchSession->GetWindow(getter_AddRefs(searchWindow));
searchSession->PauseSearch();
localFolder->ParseFolder(searchWindow, this);
}
}
#endif // HANDLE_OUT_OF_DATE_SUMMARY_FILES
}
break;
default:
{
@ -656,19 +654,14 @@ nsresult nsMsgSearchOfflineMail::Search (PRBool *aDone)
nsCOMPtr<nsIMsgDBHdr> msgDBHdr;
*aDone = PR_FALSE;
// If we need to parse the mailbox before searching it, give another time
// slice to the parser
if (m_mailboxParser)
err = BuildSummaryFile ();
else
// Try to open the DB lazily. This will set up a parser if one is required
if (!m_db)
err = OpenSummaryFile ();
// Try to open the DB lazily. This will set up a parser if one is required
if (!m_db)
err = OpenSummaryFile ();
if (!m_db) // must be reparsing.
return err;
// Reparsing is unnecessary or completed
if (m_mailboxParser == nsnull && NS_SUCCEEDED(err))
if (NS_SUCCEEDED(err))
{
NS_ASSERTION (m_db, "unable to open db for search");
if (!m_listContext)
dbErr = m_db->EnumerateMessages (getter_AddRefs(m_listContext));
if (NS_SUCCEEDED(dbErr) && m_listContext)
@ -753,12 +746,24 @@ nsMsgSearchOfflineMail::Abort ()
m_db->Close(PR_TRUE /* commit in case we downloaded new headers */);
m_db = nsnull;
// If we got aborted in the middle of parsing a mail folder, we should
// free the parser object (esp. so it releases the folderInfo's semaphore)
if (m_mailboxParser)
delete m_mailboxParser;
m_mailboxParser = nsnull;
return nsMsgSearchAdapter::Abort ();
}
/* void OnStartRunningUrl (in nsIURI url); */
NS_IMETHODIMP nsMsgSearchOfflineMail::OnStartRunningUrl(nsIURI *url)
{
return NS_OK;
}
/* void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode); */
NS_IMETHODIMP nsMsgSearchOfflineMail::OnStopRunningUrl(nsIURI *url, nsresult aExitCode)
{
nsCOMPtr<nsIMsgSearchSession> searchSession;
m_scope->GetSearchSession(getter_AddRefs(searchSession));
if (searchSession)
searchSession->ResumeSearch();
return NS_OK;
}

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

@ -35,12 +35,16 @@ class nsMsgMailboxParser;
class nsIMsgSearchScopeTerm;
class nsIMsgFolder;
class nsMsgSearchOfflineMail : public nsMsgSearchAdapter
class nsMsgSearchOfflineMail : public nsMsgSearchAdapter, public nsIUrlListener
{
public:
nsMsgSearchOfflineMail (nsIMsgSearchScopeTerm*, nsISupportsArray *);
virtual ~nsMsgSearchOfflineMail ();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIURLLISTENER;
NS_IMETHOD ValidateTerms ();
NS_IMETHOD Search (PRBool *aDone);
NS_IMETHOD Abort ();
@ -77,15 +81,6 @@ protected:
nsIMsgDatabase *m_db;
nsCOMPtr<nsISimpleEnumerator> m_listContext;
enum
{
kOpenFolderState,
kParseMoreState,
kCloseFolderState,
kDoneState
};
int m_parserState;
nsMsgMailboxParser *m_mailboxParser;
void CleanUpScope();
};

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

@ -44,6 +44,7 @@ nsMsgSearchSession::nsMsgSearchSession()
// m_calledStartingUpdate = PR_FALSE;
m_handlingError = PR_FALSE;
m_pSearchParam = nsnull;
m_searchPaused = PR_FALSE;
}
@ -291,6 +292,29 @@ NS_IMETHODIMP nsMsgSearchSession::InterruptSearch()
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::PauseSearch()
{
if (m_backgroundTimer)
{
m_backgroundTimer->Cancel();
m_searchPaused = PR_TRUE;
return NS_OK;
}
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsMsgSearchSession::ResumeSearch()
{
if (m_searchPaused)
{
m_searchPaused = PR_FALSE;
return StartTimer();
}
else
return NS_ERROR_FAILURE;
}
/* [noscript] readonly attribute voidStar searchParam; */
NS_IMETHODIMP nsMsgSearchSession::GetSearchParam(void * *aSearchParam)
{
@ -315,6 +339,20 @@ NS_IMETHODIMP nsMsgSearchSession::GetNumResults(PRInt32 *aNumResults)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgSearchSession::SetWindow(nsIMsgWindow *aWindow)
{
m_window = aWindow;
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::GetWindow(nsIMsgWindow **aWindowPtr)
{
NS_ENSURE_ARG(aWindowPtr);
*aWindowPtr = m_window;
NS_IF_ADDREF(*aWindowPtr);
return NS_OK;
}
/* void OnStartRunningUrl (in nsIURI url); */
NS_IMETHODIMP nsMsgSearchSession::OnStartRunningUrl(nsIURI *url)
{
@ -456,41 +494,26 @@ nsresult nsMsgSearchSession::AddUrl(const char *url)
PRBool done;
searchSession->TimeSlice(&done);
if (done)
{
aTimer->Cancel();
searchSession->m_backgroundTimer = nsnull;
}
}
nsresult nsMsgSearchSession::StartTimer()
{
nsresult err;
PRBool done;
m_backgroundTimer = do_CreateInstance("component://netscape/timer", &err);
m_backgroundTimer->Init(TimerCallback, (void *) this, 0, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
// ### start meteors?
return TimeSlice(&done);
}
nsresult nsMsgSearchSession::SearchWOUrls ()
{
nsresult err = NS_OK;
PRBool done;
m_backgroundTimer = do_CreateInstance("component://netscape/timer", &err);
m_backgroundTimer->Init(TimerCallback, (void *) this, 0, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
// ### start meteors?
err = TimeSlice(&done);
#if 0
if (!m_urlStruct)
m_urlStruct = NET_CreateURLStruct ("search-libmsg:", NET_DONT_RELOAD);
if (m_urlStruct)
{
// Set the internal_url flag so just in case someone else happens to have
// a search-libmsg URL, it won't fire my code, and surely crash.
m_urlStruct->internal_url = TRUE;
// Initiate the asynchronous search
int getUrlErr = m_pane->GetURL (m_urlStruct, FALSE);
if (getUrlErr)
err = (MSG_SearchError) -1; //###phil impedance mismatch
else
if (!XP_STRNCMP(m_urlStruct->address, "news:", 5) || !XP_STRNCMP(m_urlStruct->address, "snews:", 6))
BeginCylonMode();
}
else
err = NS_ERROR_OUT_OF_MEMORY;
#endif
return err;
return StartTimer();
}
NS_IMETHODIMP nsMsgSearchSession::GetRunningAdapter (nsIMsgSearchAdapter **aSearchAdapter)

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

@ -49,6 +49,7 @@ protected:
nsCOMPtr <nsIMsgWindow> m_window;
nsresult Initialize();
nsresult StartTimer();
nsresult TimeSlice (PRBool *aDone);
nsMsgSearchScopeTerm *GetRunningScope();
void StopRunning();
@ -84,6 +85,7 @@ protected:
PRBool m_handlingError;
nsCStringArray m_urlQueue;
nsCOMPtr <nsITimer> m_backgroundTimer;
PRBool m_searchPaused;
};

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

@ -21,6 +21,8 @@
*/
#include "nsISupports.idl"
interface nsIMsgWindow;
interface nsIUrlListener;
[scriptable, uuid(27D2DE40-BAF1-11d2-9578-00805F8AC615)]
interface nsIMsgLocalMailFolder : nsISupports {
@ -32,4 +34,5 @@ interface nsIMsgLocalMailFolder : nsISupports {
* like MSG_FOLDER_FLAG_INBOX | MSG_FOLDER_FLAG_DRAFTS | etc
*/
void setFlagsOnDefaultMailboxes(in unsigned long flags);
void ParseFolder(in nsIMsgWindow aMsgWindow, in nsIUrlListener listener);
};

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

@ -570,9 +570,17 @@ NS_IMETHODIMP nsMsgLocalMailFolder::AddSubfolder(nsAutoString *name,
//run the url to parse the mailbox
nsresult nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec& path)
NS_IMETHODIMP nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsIUrlListener *listener)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIFileSpec> pathSpec;
rv = GetPath(getter_AddRefs(pathSpec));
if (NS_FAILED(rv)) return rv;
nsFileSpec path;
rv = pathSpec->GetFileSpec(&path);
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIMailboxService, mailboxService,
kMailboxServiceCID, &rv);
@ -582,7 +590,7 @@ nsresult nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec&
if(!parser)
return NS_ERROR_OUT_OF_MEMORY;
rv = mailboxService->ParseMailbox(aMsgWindow, path, parser, this, nsnull);
rv = mailboxService->ParseMailbox(aMsgWindow, path, parser, listener, nsnull);
return rv;
}
@ -729,10 +737,6 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
rv = GetPath(getter_AddRefs(pathSpec));
if (NS_FAILED(rv)) return rv;
nsFileSpec path;
rv = pathSpec->GetFileSpec(&path);
if (NS_FAILED(rv)) return rv;
nsresult folderOpen = NS_OK;
nsCOMPtr<nsIMsgDatabase> mailDBFactory;
@ -780,7 +784,7 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
// 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(NS_FAILED(rv = ParseFolder(aMsgWindow, path)))
if(NS_FAILED(rv = ParseFolder(aMsgWindow, this)))
return rv;
else
return NS_ERROR_NOT_INITIALIZED;
@ -971,12 +975,47 @@ nsMsgLocalMailFolder::CreateSubfolder(const PRUnichar *folderName)
}
return rv;
}
#ifdef DEBUG_bienvenu
nsIMsgSearchSession *saveSearchSession;
#endif
NS_IMETHODIMP nsMsgLocalMailFolder::Compact()
{
// **** jefft -- needs to provide nsIMsgWindow for the compact status
// update; come back later
#ifdef DEBUG_bienvenu
nsCOMPtr<nsIMsgSearchSession> searchSession;
nsresult ret = nsComponentManager::CreateInstance(NS_MSGSEARCHSESSION_PROGID,
nsnull,
NS_GET_IID(nsIMsgSearchSession),
getter_AddRefs(searchSession));
if (searchSession)
{
nsCOMPtr <nsIMsgSearchValue> searchValue;
nsCOMPtr <nsIMsgSearchTerm> searchTerm;
nsCOMPtr<nsISupportsArray> searchTerms;
nsString valStr;
valStr.AssignWithConversion("test");
ret = NS_NewISupportsArray(getter_AddRefs(searchTerms));
searchSession->CreateSearchTerm(getter_AddRefs(searchTerm));
searchTerm->GetValue(getter_AddRefs(searchValue));
searchValue->SetStr(valStr.GetUnicode());
searchValue->SetAttrib(nsMsgSearchAttrib::Body);
searchTerm->SetAttrib(nsMsgSearchAttrib::Body);
searchTerm->SetOp(nsMsgSearchOp::Contains);
searchTerm->SetBooleanAnd(PR_FALSE);
searchTerm->SetValue(searchValue); // I guess this is right...
searchTerms->AppendElement(searchTerm);
searchSession->AddSearchTermArray(searchTerms);
searchSession->AddScopeTerm(nsMsgSearchScope::MailFolder, this);
saveSearchSession = searchSession;
NS_ADDREF(saveSearchSession);
searchSession->Search(nsnull);
return NS_OK;
}
#endif
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIMsgDatabase> db;
nsCOMPtr<nsIDBFolderInfo> folderInfo;

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

@ -143,7 +143,6 @@ public:
protected:
nsresult ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec& path);
nsresult CreateSubFolders(nsFileSpec &path);
nsresult AddDirectorySeparator(nsFileSpec &path);
nsresult GetDatabase(nsIMsgWindow *aMsgWindow);