зеркало из https://github.com/mozilla/gecko-dev.git
more work on threading
This commit is contained in:
Родитель
9f0ada3e17
Коммит
caf8c5bd81
|
@ -34,6 +34,7 @@ class ListContext;
|
|||
class nsMsgKeyArray;
|
||||
class nsNewsSet;
|
||||
class nsMsgThread;
|
||||
class nsIMsgThread;
|
||||
|
||||
class nsMsgDatabase : public nsIMsgDatabase {
|
||||
public:
|
||||
|
@ -185,6 +186,8 @@ public:
|
|||
nsresult RowCellColumnToMime2EncodedString(nsIMdbRow *row, mdb_token columnToken, nsString &resultStr);
|
||||
nsresult RowCellColumnToCollationKey(nsIMdbRow *row, mdb_token columnToken, nsString &resultStr);
|
||||
|
||||
// helper functions to put values in cells for the passed-in row
|
||||
nsresult UInt32ToRowCellColumn(nsIMdbRow *row, mdb_token columnToken, PRUint32 value);
|
||||
// helper functions to copy an nsString to a yarn, int32 to yarn, and vice versa.
|
||||
static struct mdbYarn *nsStringToYarn(struct mdbYarn *yarn, nsString *str);
|
||||
static struct mdbYarn *UInt32ToYarn(struct mdbYarn *yarn, PRUint32 i);
|
||||
|
@ -199,6 +202,7 @@ public:
|
|||
#endif
|
||||
|
||||
friend class nsMsgHdr; // use this to get access to cached tokens for hdr fields
|
||||
friend class nsMsgThread; // use this to get access to cached tokens for hdr fields
|
||||
friend class nsMsgDBEnumerator;
|
||||
|
||||
protected:
|
||||
|
@ -223,6 +227,7 @@ protected:
|
|||
nsMsgHdr * GetMsgHdrForMessageID(const char *msgID);
|
||||
nsMsgThread * GetThreadContainingMsgHdr(nsMsgHdr *msgHdr);
|
||||
// threading interfaces
|
||||
virtual nsresult CreateNewThread(nsMsgKey key, nsMsgThread **newThread);
|
||||
virtual PRBool ThreadBySubjectWithoutRe();
|
||||
virtual nsresult ThreadNewHdr(nsMsgHdr* hdr, PRBool &newThread);
|
||||
virtual nsresult AddNewThread(nsMsgHdr *msgHdr);
|
||||
|
@ -266,6 +271,7 @@ protected:
|
|||
|
||||
mdb_token m_hdrRowScopeToken;
|
||||
mdb_token m_hdrTableKindToken;
|
||||
mdb_token m_threadTableKindToken;
|
||||
mdb_token m_subjectColumnToken;
|
||||
mdb_token m_senderColumnToken;
|
||||
mdb_token m_messageIdColumnToken;
|
||||
|
@ -278,6 +284,8 @@ protected:
|
|||
mdb_token m_statusOffsetColumnToken;
|
||||
mdb_token m_numLinesColumnToken;
|
||||
mdb_token m_ccListColumnToken;
|
||||
mdb_token m_threadChildrenColumnToken;
|
||||
mdb_token m_threadUnreadChildrenColumnToken;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
class nsMsgDatabase;
|
||||
class nsString2;
|
||||
|
||||
// this could inherit from nsISupports mainly to get ref-counting semantics
|
||||
// but I don't intend it to be a public interface. I'll just
|
||||
// declare AddRef and Release as methods..
|
||||
|
||||
class nsMsgHdr : public nsRDFResource, public nsIMessage {
|
||||
public:
|
||||
|
||||
|
@ -99,8 +95,6 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
void SetCSID(PRUint16 csid) {m_csID = csid;}
|
||||
PRInt16 GetCSID();
|
||||
nsIMdbRow *GetMDBRow() {return m_mdbRow;}
|
||||
protected:
|
||||
nsresult SetStringColumn(const char *str, mdb_token token);
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
#include "nsString.h"
|
||||
#include "MailNewsTypes.h"
|
||||
|
||||
class nsIMdbTable;
|
||||
class nsIMessage;
|
||||
class nsMsgDatabase;
|
||||
|
||||
class nsMsgThread : public nsIMsgThread {
|
||||
public:
|
||||
nsMsgThread();
|
||||
nsMsgThread(nsMsgDatabase *db, nsIMdbTable *table);
|
||||
virtual ~nsMsgThread();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -46,11 +49,24 @@ public:
|
|||
NS_IMETHOD RemoveChild(nsMsgKey msgKey);
|
||||
NS_IMETHOD MarkChildRead(PRBool bRead);
|
||||
|
||||
// non-interface methods
|
||||
nsIMdbTable *GetMDBTable() {return m_mdbTable;}
|
||||
nsIMdbRow *GetMetaRow() {return m_metaRow;}
|
||||
nsMsgDatabase *m_mdbDB ;
|
||||
|
||||
protected:
|
||||
|
||||
void Init();
|
||||
nsresult ChangeChildCount(PRInt32 delta);
|
||||
nsresult ChangeUnreadChildCount(PRInt32 delta);
|
||||
|
||||
nsMsgKey m_threadKey;
|
||||
PRUint32 m_numChildren;
|
||||
PRUint32 m_numUnreadChildren;
|
||||
PRUint32 m_flags;
|
||||
nsIMdbTable *m_mdbTable;
|
||||
nsIMdbRow *m_metaRow;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -330,6 +330,7 @@ nsMsgDatabase::nsMsgDatabase()
|
|||
m_mdbTokensInitialized(PR_FALSE), m_ChangeListeners(nsnull),
|
||||
m_hdrRowScopeToken(0),
|
||||
m_hdrTableKindToken(0),
|
||||
m_threadTableKindToken(0),
|
||||
m_subjectColumnToken(0),
|
||||
m_senderColumnToken(0),
|
||||
m_messageIdColumnToken(0),
|
||||
|
@ -341,7 +342,9 @@ nsMsgDatabase::nsMsgDatabase()
|
|||
m_priorityColumnToken(0),
|
||||
m_statusOffsetColumnToken(0),
|
||||
m_numLinesColumnToken(0),
|
||||
m_ccListColumnToken(0)
|
||||
m_ccListColumnToken(0),
|
||||
m_threadChildrenColumnToken(0),
|
||||
m_threadUnreadChildrenColumnToken(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
@ -709,6 +712,7 @@ NS_IMETHODIMP nsMsgDatabase::Close(PRBool forceCommit /* = TRUE */)
|
|||
|
||||
const char *kMsgHdrsScope = "ns:msg:db:row:scope:msgs:all";
|
||||
const char *kMsgHdrsTableKind = "ns:msg:db:table:kind:msgs";
|
||||
const char *kThreadTableKind = "ns:msg:db:table:kind:thread";
|
||||
const char *kSubjectColumnName = "subject";
|
||||
const char *kSenderColumnName = "sender";
|
||||
const char *kMessageIdColumnName = "message-id";
|
||||
|
@ -721,6 +725,8 @@ const char *kPriorityColumnName = "priority";
|
|||
const char *kStatusOffsetColumnName = "statusOfset";
|
||||
const char *kNumLinesColumnName = "numLines";
|
||||
const char *kCCListColumnName = "ccList";
|
||||
const char *kThreadChildrenColumnName = "children";
|
||||
const char *kThreadUnreadChildrenColumnName = "unreadChildren";
|
||||
|
||||
struct mdbOid gAllMsgHdrsTableOID;
|
||||
|
||||
|
@ -797,8 +803,12 @@ nsresult nsMsgDatabase::InitMDBInfo()
|
|||
GetStore()->StringToToken(GetEnv(), kStatusOffsetColumnName, &m_statusOffsetColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kNumLinesColumnName, &m_numLinesColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kCCListColumnName, &m_ccListColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kThreadChildrenColumnName, &m_threadChildrenColumnToken);
|
||||
GetStore()->StringToToken(GetEnv(), kThreadUnreadChildrenColumnName, &m_threadUnreadChildrenColumnToken);
|
||||
|
||||
err = GetStore()->StringToToken(GetEnv(), kMsgHdrsTableKind, &m_hdrTableKindToken);
|
||||
if (err == NS_OK)
|
||||
err = GetStore()->StringToToken(GetEnv(), kThreadTableKind, &m_threadTableKindToken);
|
||||
if (err == NS_OK)
|
||||
{
|
||||
// The table of all message hdrs will have table id 1.
|
||||
|
@ -1865,7 +1875,7 @@ NS_IMETHODIMP nsMsgDatabase::CopyHdrFromExistingHdr(nsMsgKey key, nsIMessage *ex
|
|||
{
|
||||
PRBool newThread;
|
||||
hdrStruct.m_messageKey = key;
|
||||
err = CreateNewHdrAndAddToDB(&newThread, &hdrStruct, newHdr, PR_FALSE);
|
||||
err = CreateNewHdrAndAddToDB(&newThread, &hdrStruct, newHdr, PR_TRUE);
|
||||
}
|
||||
#endif // MDB_DOES_CELL_CURSORS_OR_COPY_ROW
|
||||
}
|
||||
|
@ -1981,6 +1991,18 @@ nsresult nsMsgDatabase::RowCellColumnToUInt32(nsIMdbRow *hdrRow, mdb_token colum
|
|||
return err;
|
||||
}
|
||||
|
||||
nsresult nsMsgDatabase::UInt32ToRowCellColumn(nsIMdbRow *row, mdb_token columnToken, PRUint32 value)
|
||||
{
|
||||
struct mdbYarn yarn;
|
||||
char yarnBuf[100];
|
||||
|
||||
yarn.mYarn_Buf = (void *) yarnBuf;
|
||||
yarn.mYarn_Size = sizeof(yarnBuf);
|
||||
yarn.mYarn_Fill = yarn.mYarn_Size;
|
||||
yarn.mYarn_Form = 0;
|
||||
yarn.mYarn_Grow = NULL;
|
||||
return row->AddColumn(GetEnv(), columnToken, UInt32ToYarn(&yarn, value));
|
||||
}
|
||||
|
||||
/* static */struct mdbYarn *nsMsgDatabase::nsStringToYarn(struct mdbYarn *yarn, nsString *str)
|
||||
{
|
||||
|
@ -2042,6 +2064,29 @@ nsresult nsMsgDatabase::SetSummaryValid(PRBool valid /* = PR_TRUE */)
|
|||
|
||||
// protected routines
|
||||
|
||||
nsresult nsMsgDatabase::CreateNewThread(nsMsgKey threadId, nsMsgThread **pnewThread)
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
nsIMdbTable *threadTable;
|
||||
struct mdbOid threadTableOID;
|
||||
|
||||
if (!pnewThread)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
threadTableOID.mOid_Scope = m_hdrRowScopeToken;
|
||||
threadTableOID.mOid_Id = threadId; // presumes 0 is valid key value
|
||||
|
||||
err = GetStore()->NewTableWithOid(GetEnv(), &threadTableOID, m_threadTableKindToken,
|
||||
PR_FALSE, nsnull, &threadTable);
|
||||
if (NS_FAILED(err))
|
||||
return err;
|
||||
*pnewThread = new nsMsgThread(this, threadTable);
|
||||
if (*pnewThread)
|
||||
(*pnewThread)->SetThreadKey(threadId);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
nsMsgThread *nsMsgDatabase::GetThreadForReference(const char * msgID)
|
||||
{
|
||||
nsMsgHdr *msgHdr = GetMsgHdrForMessageID(msgID);
|
||||
|
@ -2131,6 +2176,7 @@ nsresult nsMsgDatabase::ThreadNewHdr(nsMsgHdr* newHdr, PRBool &newThread)
|
|||
|
||||
nsresult nsMsgDatabase::AddToThread(nsMsgHdr *newHdr, nsMsgThread *thread, PRBool threadInThread)
|
||||
{
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -2162,19 +2208,28 @@ nsMsgThread *nsMsgDatabase::GetThreadForMsgKey(nsMsgKey msgKey)
|
|||
// make the passed in header a thread header
|
||||
nsresult nsMsgDatabase::AddNewThread(nsMsgHdr *msgHdr)
|
||||
{
|
||||
nsMsgThread *threadHdr = new nsMsgThread;
|
||||
|
||||
if (!msgHdr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsMsgThread *threadHdr = nsnull;
|
||||
|
||||
nsresult err = CreateNewThread(msgHdr->m_messageKey, &threadHdr);
|
||||
if (threadHdr)
|
||||
{
|
||||
// nsString subject;
|
||||
|
||||
threadHdr->AddRef();
|
||||
threadHdr->SetThreadKey(msgHdr->m_messageKey);
|
||||
// threadHdr->SetSubject
|
||||
// err = msgHdr->GetSubject(subject);
|
||||
// threadHdr->SetThreadKey(msgHdr->m_messageKey);
|
||||
// threadHdr->SetSubject(subject);
|
||||
|
||||
// need to add the thread table to the db.
|
||||
AddToThread(msgHdr, threadHdr, FALSE);
|
||||
|
||||
threadHdr->Release();
|
||||
}
|
||||
return NS_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,16 +24,42 @@
|
|||
NS_IMPL_ISUPPORTS(nsMsgThread, nsMsgThread::GetIID())
|
||||
|
||||
nsMsgThread::nsMsgThread()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
nsMsgThread::nsMsgThread(nsMsgDatabase *db, nsIMdbTable *table)
|
||||
{
|
||||
Init();
|
||||
m_mdbTable = table;
|
||||
m_mdbDB = db;
|
||||
if (db)
|
||||
db->AddRef();
|
||||
|
||||
if (table && db)
|
||||
table->GetMetaRow(db->GetEnv(), nil, nil, &m_metaRow);
|
||||
}
|
||||
|
||||
void nsMsgThread::Init()
|
||||
{
|
||||
m_threadKey = nsMsgKey_None;
|
||||
m_numChildren = 0;
|
||||
m_numUnreadChildren = 0;
|
||||
m_flags = 0;
|
||||
m_mdbTable = nsnull;
|
||||
m_mdbDB = nsnull;
|
||||
m_metaRow = nsnull;
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
|
||||
nsMsgThread::~nsMsgThread()
|
||||
{
|
||||
if (m_mdbTable)
|
||||
m_mdbTable->Release();
|
||||
if (m_mdbDB)
|
||||
m_mdbDB->Release();
|
||||
if (m_metaRow)
|
||||
m_metaRow->Release();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::SetThreadKey(nsMsgKey threadKey)
|
||||
|
@ -55,7 +81,6 @@ NS_IMETHODIMP nsMsgThread::GetThreadKey(nsMsgKey *result)
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgThread::GetFlags(PRUint32 *result)
|
||||
{
|
||||
nsresult ret;
|
||||
|
@ -105,6 +130,14 @@ NS_IMETHODIMP nsMsgThread::GetNumUnreadChildren (PRUint32 *result)
|
|||
NS_IMETHODIMP nsMsgThread::AddChild(nsIMessage *child, PRBool threadInThread)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
nsMsgHdr* hdr = NS_STATIC_CAST(nsMsgHdr*, child); // closed system, cast ok
|
||||
|
||||
nsIMdbRow *hdrRow = hdr->GetMDBRow();
|
||||
if (m_mdbTable)
|
||||
{
|
||||
m_mdbTable->AddRow(m_mdbDB->GetEnv(), hdrRow);
|
||||
ChangeChildCount(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -157,4 +190,24 @@ NS_IMETHODIMP nsMsgThread::MarkChildRead(PRBool bRead)
|
|||
return ret;
|
||||
}
|
||||
|
||||
nsresult nsMsgThread::ChangeChildCount(PRInt32 delta)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
PRUint32 childCount = 0;
|
||||
m_mdbDB->RowCellColumnToUInt32(m_metaRow, m_mdbDB->m_threadChildrenColumnToken, childCount);
|
||||
childCount += delta;
|
||||
|
||||
ret = m_mdbDB->UInt32ToRowCellColumn(m_metaRow, m_mdbDB->m_threadChildrenColumnToken, childCount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult nsMsgThread::ChangeUnreadChildCount(PRInt32 delta)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
PRUint32 childCount = 0;
|
||||
m_mdbDB->RowCellColumnToUInt32(m_metaRow, m_mdbDB->m_threadUnreadChildrenColumnToken, childCount);
|
||||
childCount += delta;
|
||||
|
||||
ret = m_mdbDB->UInt32ToRowCellColumn(m_metaRow, m_mdbDB->m_threadUnreadChildrenColumnToken, childCount);
|
||||
return ret;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче