mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 01:47:31 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
9
mailnews/db/msgdb/moz.build
Normal file
9
mailnews/db/msgdb/moz.build
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DIRS += [
|
||||
'public',
|
||||
'src',
|
||||
]
|
||||
27
mailnews/db/msgdb/public/moz.build
Normal file
27
mailnews/db/msgdb/public/moz.build
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDBChangeAnnouncer.idl',
|
||||
'nsIDBChangeListener.idl',
|
||||
'nsIDBFolderInfo.idl',
|
||||
'nsIMsgDatabase.idl',
|
||||
'nsIMsgOfflineImapOperation.idl',
|
||||
'nsINewsDatabase.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'msgdb'
|
||||
|
||||
EXPORTS += [
|
||||
'nsDBFolderInfo.h',
|
||||
'nsImapMailDatabase.h',
|
||||
'nsMailDatabase.h',
|
||||
'nsMsgDatabase.h',
|
||||
'nsMsgDBCID.h',
|
||||
'nsMsgHdr.h',
|
||||
'nsMsgThread.h',
|
||||
'nsNewsDatabase.h',
|
||||
]
|
||||
|
||||
135
mailnews/db/msgdb/public/nsDBFolderInfo.h
Normal file
135
mailnews/db/msgdb/public/nsDBFolderInfo.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This class encapsulates the global information about a folder stored in the
|
||||
summary file.
|
||||
*/
|
||||
#ifndef _nsDBFolderInfo_H
|
||||
#define _nsDBFolderInfo_H
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "mdb.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIDBFolderInfo.h"
|
||||
#include <time.h>
|
||||
|
||||
class nsMsgDatabase;
|
||||
|
||||
// again, this could inherit from nsISupports, but I don't see the need as of yet.
|
||||
// I'm not sure it needs to be ref-counted (but I think it does).
|
||||
|
||||
// I think these getters and setters really need to go through mdb and not rely on the object
|
||||
// caching the values. If this somehow turns out to be prohibitively expensive, we can invent
|
||||
// some sort of dirty mechanism, but I think it turns out that these values will be cached by
|
||||
// the MSG_FolderInfo's anyway.
|
||||
class nsDBFolderInfo : public nsIDBFolderInfo
|
||||
{
|
||||
public:
|
||||
friend class nsMsgDatabase;
|
||||
|
||||
nsDBFolderInfo(nsMsgDatabase *mdb);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
// interface methods.
|
||||
NS_DECL_NSIDBFOLDERINFO
|
||||
// create the appropriate table and row in a new db.
|
||||
nsresult AddToNewMDB();
|
||||
// accessor methods.
|
||||
|
||||
bool TestFlag(int32_t flags);
|
||||
int16_t GetIMAPHierarchySeparator() ;
|
||||
void SetIMAPHierarchySeparator(int16_t hierarchyDelimiter) ;
|
||||
void ChangeImapTotalPendingMessages(int32_t delta);
|
||||
void ChangeImapUnreadPendingMessages(int32_t delta) ;
|
||||
|
||||
nsresult InitFromExistingDB();
|
||||
// get and set arbitrary property, aka row cell value.
|
||||
nsresult SetPropertyWithToken(mdb_token aProperty, const nsAString &propertyStr);
|
||||
nsresult SetUint32PropertyWithToken(mdb_token aProperty, uint32_t propertyValue);
|
||||
nsresult SetInt64PropertyWithToken(mdb_token aProperty, int64_t propertyValue);
|
||||
nsresult SetInt32PropertyWithToken(mdb_token aProperty, int32_t propertyValue);
|
||||
nsresult GetPropertyWithToken(mdb_token aProperty, nsAString &propertyValue);
|
||||
nsresult GetUint32PropertyWithToken(mdb_token aProperty, uint32_t &propertyValue, uint32_t defaultValue = 0);
|
||||
nsresult GetInt32PropertyWithToken(mdb_token aProperty, int32_t &propertyValue, int32_t defaultValue = 0);
|
||||
nsresult GetInt64PropertyWithToken(mdb_token aProperty,
|
||||
int64_t &propertyValue, int64_t defaultValue = 0);
|
||||
|
||||
nsTArray<nsMsgKey> m_lateredKeys; // list of latered messages
|
||||
|
||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return m_lateredKeys.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
protected:
|
||||
virtual ~nsDBFolderInfo();
|
||||
|
||||
// initialize from appropriate table and row in existing db.
|
||||
nsresult InitMDBInfo();
|
||||
nsresult LoadMemberVariables();
|
||||
|
||||
nsresult AdjustHighWater(nsMsgKey highWater, bool force);
|
||||
|
||||
void ReleaseExternalReferences(); // let go of any references to other objects.
|
||||
|
||||
int64_t m_folderSize;
|
||||
int64_t m_expungedBytes; // sum of size of deleted messages in folder
|
||||
uint32_t m_folderDate;
|
||||
nsMsgKey m_highWaterMessageKey; // largest news article number or imap uid whose header we've seen
|
||||
|
||||
// m_numUnreadMessages and m_numMessages can never be negative. 0 means 'no msgs'.
|
||||
int32_t m_numUnreadMessages;
|
||||
int32_t m_numMessages; // includes expunged and ignored messages
|
||||
|
||||
int32_t m_flags; // folder specific flags. This holds things like re-use thread pane,
|
||||
// configured for off-line use, use default retrieval, purge article/header options
|
||||
|
||||
uint16_t m_version; // for upgrading...
|
||||
int16_t m_IMAPHierarchySeparator; // imap path separator
|
||||
|
||||
// mail only (for now)
|
||||
|
||||
// IMAP only
|
||||
int32_t m_ImapUidValidity;
|
||||
int32_t m_totalPendingMessages;
|
||||
int32_t m_unreadPendingMessages;
|
||||
|
||||
// news only (for now)
|
||||
nsMsgKey m_expiredMark; // Highest invalid article number in group - for expiring
|
||||
// the db folder info will have to know what db and row it belongs to, since it is really
|
||||
// just a wrapper around the singleton folder info row in the mdb.
|
||||
nsMsgDatabase *m_mdb;
|
||||
nsIMdbTable *m_mdbTable; // singleton table in db
|
||||
nsIMdbRow *m_mdbRow; // singleton row in table;
|
||||
|
||||
nsCString m_charSet;
|
||||
bool m_charSetOverride;
|
||||
bool m_mdbTokensInitialized;
|
||||
|
||||
mdb_token m_rowScopeToken;
|
||||
mdb_token m_tableKindToken;
|
||||
// tokens for the pre-set columns - we cache these for speed, which may be silly
|
||||
mdb_token m_mailboxNameColumnToken;
|
||||
mdb_token m_numMessagesColumnToken;
|
||||
mdb_token m_numUnreadMessagesColumnToken;
|
||||
mdb_token m_flagsColumnToken;
|
||||
mdb_token m_folderSizeColumnToken;
|
||||
mdb_token m_expungedBytesColumnToken;
|
||||
mdb_token m_folderDateColumnToken;
|
||||
mdb_token m_highWaterMessageKeyColumnToken;
|
||||
|
||||
mdb_token m_imapUidValidityColumnToken;
|
||||
mdb_token m_totalPendingMessagesColumnToken;
|
||||
mdb_token m_unreadPendingMessagesColumnToken;
|
||||
mdb_token m_expiredMarkColumnToken;
|
||||
mdb_token m_versionColumnToken;
|
||||
};
|
||||
|
||||
#endif
|
||||
33
mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl
Normal file
33
mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "MailNewsTypes2.idl"
|
||||
|
||||
interface nsIDBChangeListener;
|
||||
interface nsIMsgDBHdr;
|
||||
|
||||
[scriptable, uuid(22baf00b-939d-42c3-ac51-21d99dfa1f05)]
|
||||
|
||||
interface nsIDBChangeAnnouncer : nsISupports {
|
||||
/* these 2 calls return NS_OK on success, NS_COMFALSE on failure */
|
||||
void AddListener(in nsIDBChangeListener listener);
|
||||
void RemoveListener(in nsIDBChangeListener listener);
|
||||
|
||||
void NotifyHdrChangeAll(in nsIMsgDBHdr aHdrChanged, in unsigned long aOldFlags, in unsigned long aNewFlags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyHdrAddedAll(in nsIMsgDBHdr aHdrAdded, in nsMsgKey parentKey, in long flags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyHdrDeletedAll(in nsIMsgDBHdr aHdrDeleted, in nsMsgKey parentKey, in long flags,
|
||||
in nsIDBChangeListener instigator);
|
||||
void NotifyParentChangedAll(in nsMsgKey keyReparented, in nsMsgKey oldParent, in nsMsgKey newParent, in nsIDBChangeListener instigator);
|
||||
|
||||
void NotifyReadChanged(in nsIDBChangeListener instigator);
|
||||
|
||||
void NotifyJunkScoreChanged(in nsIDBChangeListener aInstigator);
|
||||
|
||||
void NotifyAnnouncerGoingAway();
|
||||
};
|
||||
|
||||
115
mailnews/db/msgdb/public/nsIDBChangeListener.idl
Normal file
115
mailnews/db/msgdb/public/nsIDBChangeListener.idl
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "MailNewsTypes2.idl"
|
||||
|
||||
interface nsIDBChangeAnnouncer;
|
||||
interface nsIMsgDBHdr;
|
||||
interface nsIMsgDatabase;
|
||||
|
||||
/**
|
||||
* These callbacks are provided to allow listeners to the message database
|
||||
* to update their status when changes occur.
|
||||
*/
|
||||
[scriptable, uuid(21c56d34-71b9-42bb-9606-331a6a5f8210)]
|
||||
|
||||
interface nsIDBChangeListener : nsISupports {
|
||||
/**
|
||||
* Callback when message flags are changed.
|
||||
*
|
||||
* @param aHdrChanged The changed header.
|
||||
* @param aOldFlags Message flags prior to change.
|
||||
* @param aNewFlags Message flags after change.
|
||||
* @param aInstigator Object that initiated the change.
|
||||
*/
|
||||
void onHdrFlagsChanged(in nsIMsgDBHdr aHdrChanged, in unsigned long aOldFlags,
|
||||
in unsigned long aNewFlags, in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback when message is marked as deleted.
|
||||
*
|
||||
* @param aHdrChanged The message header that is going to be deleted.
|
||||
* @param aParentKey Key of parent.
|
||||
* @param aFlags Flags that message has before delete.
|
||||
* @param aInstigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onHdrDeleted(in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback when message is added.
|
||||
*
|
||||
* @param aHdrChanged The message header that is added.
|
||||
* @param aParentKey Parent key of message.
|
||||
* @param aFlags Flags that new message will have.
|
||||
* @param aInstigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onHdrAdded(in nsIMsgDBHdr aHdrChanged, in nsMsgKey aParentKey, in long aFlags,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback when message parrent is changed. Parent is changed when message is deleted or moved.
|
||||
*
|
||||
* @param aKeyChanged The message key that parent key was changed.
|
||||
* @param oldParent Old parent key.
|
||||
* @param newParent New parent key.
|
||||
* @param aInstigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onParentChanged(in nsMsgKey aKeyChanged, in nsMsgKey oldParent, in nsMsgKey newParent,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback when announcer is going away. This is good place to release strong pointers to announcer.
|
||||
*
|
||||
* @param instigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onAnnouncerGoingAway(in nsIDBChangeAnnouncer instigator);
|
||||
|
||||
/**
|
||||
* Callback when read flag is changed.
|
||||
*
|
||||
* @param aInstigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onReadChanged(in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback used in case when "junkscore" property is changed.
|
||||
*
|
||||
* @param aInstigator Object that initiated the change. Can be null.
|
||||
*/
|
||||
void onJunkScoreChanged(in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Callback used in the general case where any field may have changed.
|
||||
* OnHdrPropertyChanged is called twice per change. On the first call, aPreChange
|
||||
* is true, and aStatus is undefined. OnHdrPropertyChanged saves any required status in aStatus
|
||||
* (such as a filter match). The calling function stores the value of aStatus, changes the
|
||||
* header aHdrToChange, then calls OnHdrPropertyChanged again with aPreChange false. On this
|
||||
* second call, the stored value of aStatus is provided, so that any changes may be noted.
|
||||
*
|
||||
* @param aHdrToChange the message header that is changing.
|
||||
* @param aPreChange true on first call before change, false on second call after change
|
||||
* @param aStatus storage location provided by calling routine for status
|
||||
* @param aInstigator object that initiated the change
|
||||
*/
|
||||
void onHdrPropertyChanged(in nsIMsgDBHdr aHdrToChange, in boolean aPreChange, inout uint32_t aStatus,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
|
||||
/**
|
||||
* Generic notification for extensibility. Common events should be documented
|
||||
* here so we have a hope of keeping the documentation up to date.
|
||||
* Current events are:
|
||||
* "DBOpened" - When a pending listener becomes real. This can happen when
|
||||
* the existing db is force closed and a new one opened. Only
|
||||
* registered pending listeners are notified.
|
||||
*
|
||||
* @param aDB the db for this event.
|
||||
* @param aEvent type of event.
|
||||
*
|
||||
*/
|
||||
void onEvent(in nsIMsgDatabase aDB, in string aEvent);
|
||||
};
|
||||
|
||||
108
mailnews/db/msgdb/public/nsIDBFolderInfo.idl
Normal file
108
mailnews/db/msgdb/public/nsIDBFolderInfo.idl
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "MailNewsTypes2.idl"
|
||||
|
||||
[scriptable, uuid(a72dab4b-b3bd-471e-9a38-1b242b385459)]
|
||||
interface nsIDBFolderInfo : nsISupports {
|
||||
attribute long flags;
|
||||
|
||||
/**
|
||||
* Or's aFlags into flags.
|
||||
*
|
||||
* @param - the flags(s) to set
|
||||
*
|
||||
* @return - the resulting flags.
|
||||
*/
|
||||
long orFlags(in long aFlags);
|
||||
/**
|
||||
* And's aFlags with flags, set flags to the result
|
||||
*
|
||||
* @param the flags(s) to AND
|
||||
*
|
||||
* @return the resulting flags.
|
||||
*/
|
||||
long andFlags(in long aFlags);
|
||||
|
||||
/**
|
||||
* Allows us to keep track of the highwater mark
|
||||
*
|
||||
* @param aNewKey If larger than the current highwater
|
||||
* mark, sets the highwater mark to aNewKey.
|
||||
*/
|
||||
void onKeyAdded(in nsMsgKey aNewKey);
|
||||
|
||||
attribute nsMsgKey highWater;
|
||||
attribute nsMsgKey expiredMark;
|
||||
attribute long long folderSize;
|
||||
attribute unsigned long folderDate;
|
||||
void changeNumUnreadMessages(in long aDelta);
|
||||
void changeNumMessages(in long aDelta);
|
||||
|
||||
// numUnreadMessages and numMessages will never return negative numbers. 0 means 'no msgs'.
|
||||
attribute long numUnreadMessages;
|
||||
attribute long numMessages;
|
||||
|
||||
attribute long long expungedBytes;
|
||||
attribute long imapUidValidity;
|
||||
attribute unsigned long version;
|
||||
attribute long imapTotalPendingMessages;
|
||||
attribute long imapUnreadPendingMessages;
|
||||
|
||||
attribute nsMsgViewTypeValue viewType;
|
||||
attribute nsMsgViewFlagsTypeValue viewFlags;
|
||||
attribute nsMsgViewSortTypeValue sortType;
|
||||
attribute nsMsgViewSortOrderValue sortOrder;
|
||||
|
||||
void changeExpungedBytes(in long aDelta);
|
||||
|
||||
/**
|
||||
* Gets a string property from the folder.
|
||||
*
|
||||
* @param propertyName The name of the property for the value to retrieve.
|
||||
*/
|
||||
ACString getCharProperty(in string propertyName);
|
||||
|
||||
/**
|
||||
* Sets a string property from the folder.
|
||||
*
|
||||
* @param propertyName The name of the property for which to set a value
|
||||
* @param propertyValue The new value of the property.
|
||||
*/
|
||||
void setCharProperty(in string aPropertyName, in ACString aPropertyValue);
|
||||
void setUint32Property(in string propertyName, in unsigned long propertyValue);
|
||||
void setInt64Property(in string propertyName, in long long propertyValue);
|
||||
unsigned long getUint32Property(in string propertyName, in unsigned long defaultValue);
|
||||
long long getInt64Property(in string propertyName, in long long defaultValue);
|
||||
boolean getBooleanProperty(in string propertyName, in boolean defaultValue);
|
||||
void setBooleanProperty(in string propertyName, in boolean aPropertyValue);
|
||||
nsIDBFolderInfo GetTransferInfo();
|
||||
void initFromTransferInfo(in nsIDBFolderInfo transferInfo);
|
||||
|
||||
/**
|
||||
* Gets/Sets the current character set for the folder. If there is no
|
||||
* specific character set for the folder, it will return an empty string.
|
||||
*/
|
||||
attribute ACString characterSet;
|
||||
|
||||
/**
|
||||
* Returns the effective character set on the folder. If there is no specific
|
||||
* set defined for the folder, it will return the default character set.
|
||||
*/
|
||||
readonly attribute ACString effectiveCharacterSet;
|
||||
|
||||
attribute boolean characterSetOverride;
|
||||
|
||||
attribute AString locale;
|
||||
attribute AString mailboxName;
|
||||
|
||||
|
||||
AString getProperty(in string propertyName);
|
||||
void setProperty(in string propertyName, in AString propertyStr);
|
||||
|
||||
attribute string knownArtsSet;
|
||||
attribute ACString folderName;
|
||||
};
|
||||
570
mailnews/db/msgdb/public/nsIMsgDatabase.idl
Normal file
570
mailnews/db/msgdb/public/nsIMsgDatabase.idl
Normal file
|
|
@ -0,0 +1,570 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* @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 "nsIDBChangeAnnouncer.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsTArray.h"
|
||||
%}
|
||||
|
||||
interface nsIMutableArray;
|
||||
interface nsIMsgDatabase;
|
||||
interface nsIMsgDBView;
|
||||
interface nsIDBChangeListener;
|
||||
interface nsIMsgDBHdr;
|
||||
interface nsISimpleEnumerator;
|
||||
interface nsIMsgThread;
|
||||
interface nsIDBFolderInfo;
|
||||
interface nsIMsgOfflineImapOperation;
|
||||
interface nsIMsgFolder;
|
||||
interface nsIMsgKeyArray;
|
||||
interface nsIFile;
|
||||
interface nsIArray;
|
||||
|
||||
typedef unsigned long nsMsgRetainByPreference;
|
||||
|
||||
|
||||
[scriptable, uuid(fe8b7cec-eec8-4bcd-82ff-d8bb23cef3da)]
|
||||
|
||||
interface nsIMsgRetentionSettings : nsISupports
|
||||
{
|
||||
const unsigned long nsMsgRetainAll = 1;
|
||||
const unsigned long nsMsgRetainByAge = 2;
|
||||
const unsigned long nsMsgRetainByNumHeaders = 3;
|
||||
|
||||
attribute boolean useServerDefaults;
|
||||
attribute nsMsgRetainByPreference retainByPreference;
|
||||
attribute unsigned long daysToKeepHdrs;
|
||||
attribute unsigned long numHeadersToKeep;
|
||||
|
||||
// this is for keeping offline bodies.
|
||||
attribute boolean cleanupBodiesByDays;
|
||||
attribute unsigned long daysToKeepBodies;
|
||||
|
||||
/**
|
||||
* Should retention settings be applied to flagged/starred messages?
|
||||
* If false, flagged messages are never automatically deleted.
|
||||
*/
|
||||
attribute boolean applyToFlaggedMessages;
|
||||
};
|
||||
|
||||
[scriptable, uuid(86a9da90-14f1-11d5-a5c0-0060b0fc04b7)]
|
||||
interface nsIMsgDownloadSettings : nsISupports
|
||||
{
|
||||
attribute boolean useServerDefaults;
|
||||
attribute boolean downloadByDate;
|
||||
attribute boolean downloadUnreadOnly;
|
||||
attribute unsigned long ageLimitOfMsgsToDownload;
|
||||
};
|
||||
|
||||
typedef long nsMsgDBCommit;
|
||||
|
||||
[scriptable, uuid(15431853-e448-45dc-8978-9958bf74d9b7)]
|
||||
|
||||
interface nsMsgDBCommitType
|
||||
{
|
||||
const long kLargeCommit = 1;
|
||||
const long kSessionCommit = 2;
|
||||
const long kCompressCommit = 3;
|
||||
};
|
||||
|
||||
[ref] native nsMsgKeyArrayRef(nsTArray<nsMsgKey>);
|
||||
[ptr] native nsMsgKeyArrayPtr(nsTArray<nsMsgKey>);
|
||||
|
||||
/**
|
||||
* 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(4cbbf024-3760-402d-89f3-6ababafeb07d)]
|
||||
interface nsIMsgDBService : nsISupports
|
||||
{
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* 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, but the summary file is
|
||||
* missing.
|
||||
* @see nsIMsgDatabase::Open
|
||||
* @see nsIMsgDBService::createNewDB
|
||||
*/
|
||||
nsIMsgDatabase openFolderDB(in nsIMsgFolder aFolder,
|
||||
in boolean aLeaveInvalidDB);
|
||||
|
||||
/**
|
||||
* This is the same as a synchronous open in terms of params and errors.
|
||||
* But to finish opening the db, the caller must call
|
||||
* nsIMsgDBService::OpenMore repeatedly until the open is finished.
|
||||
* @see nsIMsgDBService::openFolderDB
|
||||
* @see nsIMsgDBService::openMore
|
||||
*/
|
||||
nsIMsgDatabase asyncOpenFolderDB(in nsIMsgFolder aFolder,
|
||||
in boolean aLeaveInvalidDB);
|
||||
|
||||
/**
|
||||
* Continues the open process for a db opened with
|
||||
* nsIMsgDBService::asyncOpenFolderDB. Returns true if the db is ready
|
||||
* to use, false if openMore needs to be called again.
|
||||
* This will throw the same kinds of exceptions as openFolderDB.
|
||||
* @param aTimeHint approximate number of milliseconds to spend
|
||||
* before returning. This is more of a floor than
|
||||
a ceiling, since we can't guarantee that there
|
||||
won't be one big chunk that we can't interrupt.
|
||||
* @return true if db is ready to use, false if openMore needs to
|
||||
* be called again.
|
||||
* @see nsIMsgDBService::openFolderDB
|
||||
*/
|
||||
boolean openMore(in nsIMsgDatabase aDB, in unsigned long aTimeHint);
|
||||
|
||||
/**
|
||||
* 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 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 aFolder Folder the db corresponds to (may be null)
|
||||
* @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 nsIFile aFile,
|
||||
in nsIMsgFolder aFolder,
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get the db for a folder, if already open.
|
||||
*
|
||||
* @param aFolder The folder to get the cached (open) db for.
|
||||
*
|
||||
* @returns null if the db isn't open, otherwise the db.
|
||||
*/
|
||||
nsIMsgDatabase cachedDBForFolder(in nsIMsgFolder aFolder);
|
||||
|
||||
/**
|
||||
* Close the db for a folder, if already open.
|
||||
*
|
||||
* @param aFolder The folder to close the cached (open) db for.
|
||||
*/
|
||||
void forceFolderDBClosed(in nsIMsgFolder aFolder);
|
||||
|
||||
/// an enumerator to iterate over the open dbs.
|
||||
readonly attribute nsIArray openDBs;
|
||||
};
|
||||
|
||||
[scriptable, uuid(b64e66f8-4717-423a-be42-482658fb2199)]
|
||||
interface nsIMsgDatabase : nsIDBChangeAnnouncer {
|
||||
void Close(in boolean aForceCommit);
|
||||
|
||||
void Commit(in nsMsgDBCommit commitType);
|
||||
// Force closed is evil, and we should see if we can do without it.
|
||||
// In 4.x, it was mainly used to remove corrupted databases.
|
||||
void ForceClosed();
|
||||
void clearCachedHdrs();
|
||||
void resetHdrCacheSize(in unsigned long size);
|
||||
|
||||
readonly attribute nsIDBFolderInfo dBFolderInfo;
|
||||
|
||||
/// Size of the database file in bytes.
|
||||
readonly attribute long long databaseSize;
|
||||
|
||||
/// Folder this db was opened on.
|
||||
readonly attribute nsIMsgFolder folder;
|
||||
|
||||
/**
|
||||
* This is used when deciding which db's to close to free up memory
|
||||
* and other resources in an LRU manner. It doesn't track every operation
|
||||
* on every object from the db, but high level things like open, commit,
|
||||
* and perhaps some of the list methods. Commit should be a proxy for all
|
||||
* the mutation methods.
|
||||
*
|
||||
* I'm allowing clients to set the last use time as well, so that
|
||||
* nsIMsgFolder.msgDatabase can set the last use time.
|
||||
*/
|
||||
attribute PRTime lastUseTime;
|
||||
|
||||
// get a message header for the given key. Caller must release()!
|
||||
|
||||
nsIMsgDBHdr GetMsgHdrForKey(in nsMsgKey key);
|
||||
nsIMsgDBHdr getMsgHdrForMessageID(in string messageID);
|
||||
|
||||
/**
|
||||
* get a message header for a Gmail message with the given X-GM-MSGID.
|
||||
*/
|
||||
nsIMsgDBHdr GetMsgHdrForGMMsgID(in string aGmailMessageID);
|
||||
//Returns whether or not this database contains the given key
|
||||
boolean ContainsKey(in nsMsgKey key);
|
||||
|
||||
/**
|
||||
* Must call AddNewHdrToDB after creating. The idea is that you create
|
||||
* a new header, fill in its properties, and then call AddNewHdrToDB.
|
||||
* AddNewHdrToDB will send notifications to any listeners.
|
||||
*
|
||||
* @param aKey msgKey for the new header. If aKey is nsMsgKey_None,
|
||||
* we will auto-assign a new key.
|
||||
*/
|
||||
nsIMsgDBHdr CreateNewHdr(in nsMsgKey aKey);
|
||||
|
||||
void AddNewHdrToDB(in nsIMsgDBHdr newHdr, in boolean notify);
|
||||
|
||||
nsIMsgDBHdr CopyHdrFromExistingHdr(in nsMsgKey key, in nsIMsgDBHdr existingHdr, in boolean addHdrToDB);
|
||||
|
||||
/**
|
||||
* Returns all message keys stored in the database.
|
||||
* Keys are returned in the order as stored in the database.
|
||||
* The caller should sort them if it needs to.
|
||||
*/
|
||||
void ListAllKeys(in nsIMsgKeyArray array);
|
||||
|
||||
nsISimpleEnumerator EnumerateMessages();
|
||||
nsISimpleEnumerator ReverseEnumerateMessages();
|
||||
nsISimpleEnumerator EnumerateThreads();
|
||||
|
||||
/**
|
||||
* Get an enumerator for use with nextMatchingHdrs. The enumerator
|
||||
* will only return messages that match the passed-in search terms.
|
||||
*
|
||||
* @param searchTerms array of search terms to evaluate.
|
||||
* @param reverse start at the end, defaults to false.
|
||||
*
|
||||
* @returns an enumerator for passing into nextMatchingHdrs
|
||||
*/
|
||||
nsISimpleEnumerator getFilterEnumerator(in nsIArray searchTerms,
|
||||
[optional] in boolean reverse);
|
||||
|
||||
/**
|
||||
* Get the next N matching headers using a filter enumerator
|
||||
* obtained by calling getFilterEnumerator.
|
||||
*
|
||||
* @param enumerator - This *must* be a filter enumerator
|
||||
* @param numHdrsToLookAt if non 0, the number of hdrs to advance the
|
||||
* enumerator before returning.
|
||||
* @param maxResults if non 0, the max results to return.
|
||||
* @param matchingHdrs if non null, array of matching hdrs.
|
||||
* @param numMatches if non null, the number of matching hdrs.
|
||||
*
|
||||
* @returns false, if done, true if more hdrs to look at.
|
||||
*/
|
||||
boolean nextMatchingHdrs(in nsISimpleEnumerator enumerator,
|
||||
in long numHdrsToLookAt,
|
||||
in long maxResults,
|
||||
in nsIMutableArray matchingHdrs,
|
||||
out long numMatches);
|
||||
|
||||
|
||||
// count the total and unread msgs, and adjust global count if needed
|
||||
void syncCounts();
|
||||
|
||||
nsIMsgThread GetThreadContainingMsgHdr(in nsIMsgDBHdr msgHdr) ;
|
||||
|
||||
// helpers for user command functions like delete, mark read, etc.
|
||||
|
||||
void MarkHdrRead(in nsIMsgDBHdr msgHdr, in boolean bRead,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkHdrReplied(in nsIMsgDBHdr msgHdr, in boolean bReplied,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkHdrMarked(in nsIMsgDBHdr msgHdr, in boolean mark,
|
||||
in nsIDBChangeListener instigator);
|
||||
/**
|
||||
* Remove the new status from a message.
|
||||
*
|
||||
* @param aMsgHdr The database reference header for the message
|
||||
* @param aInstigator Reference to original calling object
|
||||
*/
|
||||
void MarkHdrNotNew(in nsIMsgDBHdr aMsgHdr,
|
||||
in nsIDBChangeListener aInstigator);
|
||||
|
||||
// MDN support
|
||||
void MarkMDNNeeded(in nsMsgKey key, in boolean bNeeded,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
// MarkMDNneeded only used when mail server is a POP3 server
|
||||
// or when the IMAP server does not support user defined
|
||||
// PERMANENTFLAGS
|
||||
boolean IsMDNNeeded(in nsMsgKey key);
|
||||
|
||||
void MarkMDNSent(in nsMsgKey key, in boolean bNeeded,
|
||||
in nsIDBChangeListener instigator);
|
||||
boolean IsMDNSent(in nsMsgKey key);
|
||||
|
||||
// methods to get and set docsets for ids.
|
||||
void MarkRead(in nsMsgKey key, in boolean bRead,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkReplied(in nsMsgKey key, in boolean bReplied,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkForwarded(in nsMsgKey key, in boolean bForwarded,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkHasAttachments(in nsMsgKey key, in boolean bHasAttachments,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
void MarkThreadRead(in nsIMsgThread thread, in nsIDBChangeListener instigator,
|
||||
out unsigned long aCount,
|
||||
[array, size_is(aCount)] out nsMsgKey aKeys);
|
||||
|
||||
/// Mark the specified thread ignored.
|
||||
void MarkThreadIgnored(in nsIMsgThread thread, in nsMsgKey threadKey,
|
||||
in boolean bIgnored,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
/// Mark the specified thread watched.
|
||||
void MarkThreadWatched(in nsIMsgThread thread, in nsMsgKey threadKey,
|
||||
in boolean bWatched,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
/// Mark the specified subthread ignored.
|
||||
void MarkHeaderKilled(in nsIMsgDBHdr msg, in boolean bIgnored,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
/// Is the message read.
|
||||
boolean IsRead(in nsMsgKey key);
|
||||
/// Is the message part of an ignored thread.
|
||||
boolean IsIgnored(in nsMsgKey key);
|
||||
/// Is the message part of a watched thread.
|
||||
boolean IsWatched(in nsMsgKey key);
|
||||
/// Is the message flagged/starred.
|
||||
boolean IsMarked(in nsMsgKey key);
|
||||
/// Does the message have attachments.
|
||||
boolean HasAttachments(in nsMsgKey key);
|
||||
|
||||
void MarkAllRead(out unsigned long aCount,
|
||||
[array, size_is(aCount)] out nsMsgKey aKeys);
|
||||
|
||||
void deleteMessages(in unsigned long aNumKeys,
|
||||
[array, size_is(aNumKeys)] in nsMsgKey nsMsgKeys,
|
||||
in nsIDBChangeListener instigator);
|
||||
void DeleteMessage(in nsMsgKey key,
|
||||
in nsIDBChangeListener instigator,
|
||||
in boolean commit);
|
||||
void DeleteHeader(in nsIMsgDBHdr msgHdr, in nsIDBChangeListener instigator,
|
||||
in boolean commit, in boolean notify);
|
||||
|
||||
// lower level routine that doesn't remove hdr from thread or adjust counts
|
||||
void RemoveHeaderMdbRow(in nsIMsgDBHdr msgHdr);
|
||||
|
||||
void UndoDelete(in nsIMsgDBHdr msgHdr);
|
||||
|
||||
void MarkMarked(in nsMsgKey key, in boolean mark,
|
||||
in nsIDBChangeListener instigator);
|
||||
void MarkOffline(in nsMsgKey key, in boolean offline,
|
||||
in nsIDBChangeListener instigator);
|
||||
void SetLabel(in nsMsgKey key, in nsMsgLabelValue label);
|
||||
void setStringProperty(in nsMsgKey aKey, in string aProperty, in string aValue);
|
||||
/**
|
||||
* Set the value of a string property in a message header
|
||||
*
|
||||
* @param msgHdr Header of the message whose property will be changed
|
||||
* @param aProperty the property to change
|
||||
* @param aValue new value for the property
|
||||
*/
|
||||
void setStringPropertyByHdr(in nsIMsgDBHdr msgHdr, in string aProperty, in string aValue);
|
||||
|
||||
/**
|
||||
* Set the value of a uint32 property in a message header.
|
||||
*
|
||||
* @param aMsgHdr header of the message whose property will be changed
|
||||
* @param aProperty the property to change
|
||||
* @param aValue new value for the property
|
||||
*/
|
||||
void setUint32PropertyByHdr(in nsIMsgDBHdr aMsgHdr,
|
||||
in string aProperty, in unsigned long aValue);
|
||||
|
||||
void MarkImapDeleted(in nsMsgKey key, in boolean deleted,
|
||||
in nsIDBChangeListener instigator);
|
||||
|
||||
readonly attribute nsMsgKey FirstNew;
|
||||
|
||||
attribute nsIMsgRetentionSettings msgRetentionSettings;
|
||||
// purge unwanted message headers and/or bodies. If deleteViaFolder is
|
||||
// true, we'll call nsIMsgFolder::DeleteMessages to delete the messages.
|
||||
// Otherwise, we'll just delete them from the db.
|
||||
void applyRetentionSettings(in nsIMsgRetentionSettings aMsgRetentionSettings,
|
||||
in boolean aDeleteViaFolder);
|
||||
|
||||
attribute nsIMsgDownloadSettings msgDownloadSettings;
|
||||
|
||||
boolean HasNew();
|
||||
void ClearNewList(in boolean notify);
|
||||
void AddToNewList(in nsMsgKey key);
|
||||
|
||||
// used mainly to force the timestamp of a local mail folder db to
|
||||
// match the time stamp of the corresponding berkeley mail folder,
|
||||
// but also useful to tell the summary to mark itself invalid
|
||||
// Also, if a local folder is being reparsed, summary will be invalid
|
||||
// until the reparsing is done.
|
||||
attribute boolean summaryValid;
|
||||
|
||||
// batching - can be used to cache file stream for local mail,
|
||||
// and perhaps to use the mdb batching mechanism as well.
|
||||
void StartBatch();
|
||||
void EndBatch();
|
||||
// offline operations - we could move these into an offline operation interface
|
||||
// but it would have to be in nsMailDatabase, since local folders can be move destinations
|
||||
nsIMsgOfflineImapOperation GetOfflineOpForKey(in nsMsgKey messageKey, in boolean create);
|
||||
void RemoveOfflineOp(in nsIMsgOfflineImapOperation op);
|
||||
nsISimpleEnumerator EnumerateOfflineOps();
|
||||
[noscript] void ListAllOfflineOpIds(in nsMsgKeyArrayPtr offlineOpIds);
|
||||
[noscript] void ListAllOfflineDeletes(in nsMsgKeyArrayPtr offlineDeletes);
|
||||
void ListAllOfflineMsgs(in nsIMsgKeyArray aKeys);
|
||||
|
||||
void setAttributeOnPendingHdr(in nsIMsgDBHdr pendingHdr, in string property,
|
||||
in string propertyVal);
|
||||
|
||||
void setUint32AttributeOnPendingHdr(in nsIMsgDBHdr pendingHdr, in string property,
|
||||
in unsigned long propertyVal);
|
||||
|
||||
/**
|
||||
* Sets a pending 64 bit attribute, which tells the DB that when a message
|
||||
* which looks like the pendingHdr (e.g., same message-id) is added to the
|
||||
* db, set the passed in property and value on the new header. This is
|
||||
* usually because we've copied an imap message to a different folder, and
|
||||
* want to carry forward attributes from the original message to the copy,
|
||||
* but don't have the message hdr for the copy yet so we can't set
|
||||
* attributes directly.
|
||||
*
|
||||
* @param aPendingHdr usually the source of the copy.
|
||||
* @param aProperty name of property to set.
|
||||
* @param aPropertyVal 64 bit value of property to set.
|
||||
*/
|
||||
void setUint64AttributeOnPendingHdr(in nsIMsgDBHdr aPendingHdr,
|
||||
in string aProperty,
|
||||
in unsigned long long aPropertyVal);
|
||||
|
||||
/**
|
||||
* Given a message header with its message-id set, update any pending
|
||||
* attributes on the header.
|
||||
*
|
||||
* @param aNewHdr a new header that may have pending attributes.
|
||||
*/
|
||||
void updatePendingAttributes(in nsIMsgDBHdr aNewHdr);
|
||||
|
||||
readonly attribute nsMsgKey lowWaterArticleNum;
|
||||
readonly attribute nsMsgKey highWaterArticleNum;
|
||||
attribute nsMsgKey nextPseudoMsgKey; //for undo-redo of move pop->imap
|
||||
readonly attribute nsMsgKey nextFakeOfflineMsgKey; // for saving "fake" offline msg hdrs
|
||||
// for sorting
|
||||
void createCollationKey(in AString sourceString, out unsigned long aCount,
|
||||
[array, size_is(aCount)] out octet aKey);
|
||||
long compareCollationKeys(in unsigned long aLen1,
|
||||
[array, size_is(aLen1)] in octet key1,
|
||||
in unsigned long aLen2,
|
||||
[array, size_is(aLen2)] in octet key2);
|
||||
|
||||
// when creating a view, the default sort order and view flags
|
||||
// use these for the default. (this allows news to override, so that
|
||||
// news can be threaded by default)
|
||||
readonly attribute nsMsgViewFlagsTypeValue defaultViewFlags;
|
||||
readonly attribute nsMsgViewSortTypeValue defaultSortType;
|
||||
readonly attribute nsMsgViewSortOrderValue defaultSortOrder;
|
||||
|
||||
// for msg hdr hash table allocation. controllable by caller to improve folder loading preformance.
|
||||
attribute unsigned long msgHdrCacheSize;
|
||||
|
||||
/**
|
||||
* The list of messages currently in the NEW state.
|
||||
*
|
||||
* If there are no such messages, a null pointer may be returned.
|
||||
* the caller should free when done using free.
|
||||
*/
|
||||
void getNewList(out unsigned long count, [array, size_is(count)] out nsMsgKey newKeys);
|
||||
|
||||
// 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);
|
||||
|
||||
};
|
||||
/** @} */
|
||||
53
mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl
Normal file
53
mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "MailNewsTypes2.idl"
|
||||
// #include "nsIImapUrl.idl" // for imapMessageFlagsType
|
||||
|
||||
typedef unsigned short imapMessageFlagsType;
|
||||
|
||||
typedef long nsOfflineImapOperationType;
|
||||
|
||||
[scriptable, uuid(b5229a55-22bb-444b-be92-13d719353828)]
|
||||
|
||||
interface nsIMsgOfflineImapOperation : nsISupports
|
||||
{
|
||||
// type of stored imap operations
|
||||
const long kFlagsChanged = 0x1;
|
||||
const long kMsgMoved = 0x2;
|
||||
const long kMsgCopy = 0x4;
|
||||
const long kMoveResult = 0x8;
|
||||
const long kAppendDraft = 0x10;
|
||||
const long kAddedHeader = 0x20;
|
||||
const long kDeletedMsg = 0x40;
|
||||
const long kMsgMarkedDeleted = 0x80;
|
||||
const long kAppendTemplate = 0x100;
|
||||
const long kDeleteAllMsgs = 0x200;
|
||||
const long kAddKeywords = 0x400;
|
||||
const long kRemoveKeywords = 0x800;
|
||||
|
||||
attribute nsOfflineImapOperationType operation;
|
||||
void clearOperation(in nsOfflineImapOperationType operation);
|
||||
attribute nsMsgKey messageKey;
|
||||
|
||||
// for move/copy operations, the msg key of the source msg.
|
||||
attribute nsMsgKey srcMessageKey;
|
||||
|
||||
attribute imapMessageFlagsType flagOperation;
|
||||
attribute imapMessageFlagsType newFlags; // for kFlagsChanged
|
||||
attribute string destinationFolderURI; // for move or copy
|
||||
attribute string sourceFolderURI;
|
||||
void addKeywordToAdd(in string aKeyword);
|
||||
void addKeywordToRemove(in string aKeyword);
|
||||
readonly attribute string keywordsToAdd;
|
||||
readonly attribute string keywordsToRemove;
|
||||
readonly attribute long numberOfCopies;
|
||||
void addMessageCopyOperation(in string destinationBox);
|
||||
string getCopyDestination(in long copyIndex);
|
||||
attribute unsigned long msgSize;
|
||||
attribute boolean playingBack;
|
||||
};
|
||||
|
||||
18
mailnews/db/msgdb/public/nsINewsDatabase.idl
Normal file
18
mailnews/db/msgdb/public/nsINewsDatabase.idl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsMsgKeySet.h"
|
||||
%}
|
||||
|
||||
[ptr] native nsMsgKeySetPtr(nsMsgKeySet);
|
||||
|
||||
[scriptable, uuid(f700208a-1dd1-11b2-b947-e4e1e4fdf278)]
|
||||
|
||||
interface nsINewsDatabase : nsISupports {
|
||||
[noscript] attribute nsMsgKeySetPtr readSet;
|
||||
};
|
||||
52
mailnews/db/msgdb/public/nsImapMailDatabase.h
Normal file
52
mailnews/db/msgdb/public/nsImapMailDatabase.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _nsImapMailDatabase_H_
|
||||
#define _nsImapMailDatabase_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsMailDatabase.h"
|
||||
|
||||
class nsImapMailDatabase : public nsMailDatabase
|
||||
{
|
||||
public:
|
||||
// OK, it's dumb that this should require a fileSpec, since there is no file
|
||||
// for the folder. This is mainly because we're deriving from nsMailDatabase;
|
||||
// Perhaps we shouldn't...
|
||||
nsImapMailDatabase();
|
||||
virtual ~nsImapMailDatabase();
|
||||
|
||||
NS_IMETHOD StartBatch() override;
|
||||
NS_IMETHOD EndBatch() override;
|
||||
NS_IMETHOD GetSummaryValid(bool *aResult) override;
|
||||
NS_IMETHOD SetSummaryValid(bool valid = true) override;
|
||||
virtual nsresult AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr) override;
|
||||
|
||||
NS_IMETHOD ForceClosed() override;
|
||||
NS_IMETHOD AddNewHdrToDB(nsIMsgDBHdr *newHdr, bool notify) override;
|
||||
NS_IMETHOD SetAttributeOnPendingHdr(nsIMsgDBHdr *pendingHdr, const char *property,
|
||||
const char *propertyVal) override;
|
||||
NS_IMETHOD SetUint32AttributeOnPendingHdr(nsIMsgDBHdr *pendingHdr, const char *property,
|
||||
uint32_t propertyVal) override;
|
||||
NS_IMETHOD SetUint64AttributeOnPendingHdr(nsIMsgDBHdr *aPendingHdr,
|
||||
const char *aProperty,
|
||||
uint64_t aPropertyVal) override;
|
||||
NS_IMETHOD DeleteMessages(uint32_t aNumKeys, nsMsgKey* nsMsgKeys,
|
||||
nsIDBChangeListener *instigator) override;
|
||||
NS_IMETHOD UpdatePendingAttributes(nsIMsgDBHdr* aNewHdr) override;
|
||||
|
||||
protected:
|
||||
// IMAP does not set local file flags, override does nothing
|
||||
virtual void UpdateFolderFlag(nsIMsgDBHdr *msgHdr, bool bSet,
|
||||
nsMsgMessageFlagType flag, nsIOutputStream **ppFileStream);
|
||||
|
||||
nsresult GetRowForPendingHdr(nsIMsgDBHdr *pendingHdr, nsIMdbRow **row);
|
||||
nsresult GetAllPendingHdrsTable();
|
||||
mdb_token m_pendingHdrsRowScopeToken;
|
||||
mdb_token m_pendingHdrsTableKindToken;
|
||||
nsCOMPtr<nsIMdbTable> m_mdbAllPendingHdrsTable;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
67
mailnews/db/msgdb/public/nsMailDatabase.h
Normal file
67
mailnews/db/msgdb/public/nsMailDatabase.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsMailDatabase_H_
|
||||
#define _nsMailDatabase_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsMsgDatabase.h"
|
||||
#include "nsMsgMessageFlags.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
// This is the subclass of nsMsgDatabase that handles local mail messages.
|
||||
class nsIOFileStream;
|
||||
class nsIFile;
|
||||
class nsOfflineImapOperation;
|
||||
|
||||
class nsMailDatabase : public nsMsgDatabase
|
||||
{
|
||||
public:
|
||||
nsMailDatabase();
|
||||
virtual ~nsMailDatabase();
|
||||
NS_IMETHOD ForceClosed() override;
|
||||
NS_IMETHOD DeleteMessages(uint32_t aNumKeys, nsMsgKey* nsMsgKeys,
|
||||
nsIDBChangeListener *instigator) override;
|
||||
|
||||
NS_IMETHOD StartBatch() override;
|
||||
NS_IMETHOD EndBatch() override;
|
||||
|
||||
nsresult Open(nsMsgDBService* aDBService, nsIFile *aSummaryFile, bool create, bool upgrading) override;
|
||||
virtual nsMailDatabase *GetMailDB() {return this;}
|
||||
|
||||
virtual uint32_t GetCurVersion() override {return kMsgDBVersion;}
|
||||
|
||||
NS_IMETHOD GetOfflineOpForKey(nsMsgKey opKey, bool create,
|
||||
nsIMsgOfflineImapOperation **op) override;
|
||||
NS_IMETHOD RemoveOfflineOp(nsIMsgOfflineImapOperation *op) override;
|
||||
|
||||
NS_IMETHOD SetSummaryValid(bool valid) override;
|
||||
NS_IMETHOD GetSummaryValid(bool *valid) override;
|
||||
|
||||
NS_IMETHOD EnumerateOfflineOps(nsISimpleEnumerator **enumerator) override;
|
||||
NS_IMETHOD ListAllOfflineOpIds(nsTArray<nsMsgKey> *offlineOpIds) override;
|
||||
NS_IMETHOD ListAllOfflineDeletes(nsTArray<nsMsgKey> *offlineDeletes) override;
|
||||
|
||||
friend class nsMsgOfflineOpEnumerator;
|
||||
protected:
|
||||
|
||||
nsresult GetAllOfflineOpsTable(); // get this on demand
|
||||
|
||||
// get the time and date of the mailbox file
|
||||
void GetMailboxModProperties(int64_t *aSize, uint32_t *aDate);
|
||||
|
||||
nsCOMPtr <nsIMdbTable> m_mdbAllOfflineOpsTable;
|
||||
mdb_token m_offlineOpsRowScopeToken;
|
||||
mdb_token m_offlineOpsTableKindToken;
|
||||
|
||||
virtual void SetReparse(bool reparse);
|
||||
|
||||
protected:
|
||||
|
||||
bool m_reparse;
|
||||
};
|
||||
|
||||
#endif
|
||||
63
mailnews/db/msgdb/public/nsMsgDBCID.h
Normal file
63
mailnews/db/msgdb/public/nsMsgDBCID.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsMsgDBCID_h__
|
||||
#define nsMsgDBCID_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
// 03223c50-1e88-45e8-ba1a-7ce792dc3fc3
|
||||
#define NS_MSGDB_SERVICE_CID \
|
||||
{ 0x03223c50, 0x1e88, 0x45e8, \
|
||||
{ 0xba, 0x1a, 0x7c, 0xe7, 0x92, 0xdc, 0x3f, 0xc3 } }
|
||||
|
||||
#define NS_MSGDB_SERVICE_CONTRACTID \
|
||||
"@mozilla.org/msgDatabase/msgDBService;1"
|
||||
|
||||
#define NS_MSGDB_CONTRACTID \
|
||||
"@mozilla.org/nsMsgDatabase/msgDB-"
|
||||
|
||||
#define NS_MAILBOXDB_CONTRACTID \
|
||||
NS_MSGDB_CONTRACTID"mailbox"
|
||||
|
||||
// a86c86ae-e97f-11d2-a506-0060b0fc04b7
|
||||
#define NS_MAILDB_CID \
|
||||
{ 0xa86c86ae, 0xe97f, 0x11d2, \
|
||||
{ 0xa5, 0x06, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7 } }
|
||||
|
||||
#define NS_NEWSDB_CONTRACTID \
|
||||
NS_MSGDB_CONTRACTID"news"
|
||||
|
||||
// 36414aa0-e980-11d2-a506-0060b0fc04b7
|
||||
#define NS_NEWSDB_CID \
|
||||
{ 0x36414aa0, 0xe980, 0x11d2, \
|
||||
{ 0xa5, 0x06, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7 } }
|
||||
|
||||
#define NS_IMAPDB_CONTRACTID \
|
||||
NS_MSGDB_CONTRACTID"imap"
|
||||
|
||||
// 9e4b07ee-e980-11d2-a506-0060b0fc04b7
|
||||
#define NS_IMAPDB_CID \
|
||||
{ 0x9e4b07ee, 0xe980, 0x11d2, \
|
||||
{ 0xa5, 0x06, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7 } }
|
||||
|
||||
#define NS_MSG_RETENTIONSETTINGS_CID \
|
||||
{ 0x1bd976d6, 0xdf44, 0x11d4, \
|
||||
{0xa5, 0xb6, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7} }
|
||||
|
||||
#define NS_MSG_RETENTIONSETTINGS_CONTRACTID \
|
||||
"@mozilla.org/msgDatabase/retentionSettings;1"
|
||||
|
||||
// 4e3dae5a-157a-11d5-a5c0-0060b0fc04b7
|
||||
#define NS_MSG_DOWNLOADSETTINGS_CID \
|
||||
{ 0x4e3dae5a, 0x157a, 0x11d5, \
|
||||
{0xa5, 0xc0, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7} }
|
||||
|
||||
#define NS_MSG_DOWNLOADSETTINGS_CONTRACTID \
|
||||
"@mozilla.org/msgDatabase/downloadSettings;1"
|
||||
|
||||
#endif
|
||||
462
mailnews/db/msgdb/public/nsMsgDatabase.h
Normal file
462
mailnews/db/msgdb/public/nsMsgDatabase.h
Normal file
|
|
@ -0,0 +1,462 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsMsgDatabase_H_
|
||||
#define _nsMsgDatabase_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "nsMsgHdr.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIDBChangeListener.h"
|
||||
#include "nsIDBChangeAnnouncer.h"
|
||||
#include "nsMsgMessageFlags.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsDBFolderInfo.h"
|
||||
#include "nsICollation.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
#include "nsIMimeConverter.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "PLDHashTable.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTObserverArray.h"
|
||||
class ListContext;
|
||||
class nsMsgKeySet;
|
||||
class nsMsgThread;
|
||||
class nsMsgDatabase;
|
||||
class nsIMsgThread;
|
||||
class nsIDBFolderInfo;
|
||||
|
||||
const int32_t kMsgDBVersion = 1;
|
||||
|
||||
// Hopefully we're not opening up lots of databases at the same time, however
|
||||
// this will give us a buffer before we need to start reallocating the cache
|
||||
// array.
|
||||
const uint32_t kInitialMsgDBCacheSize = 20;
|
||||
|
||||
class nsMsgDBService final : public nsIMsgDBService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGDBSERVICE
|
||||
|
||||
nsMsgDBService();
|
||||
|
||||
void AddToCache(nsMsgDatabase* pMessageDB);
|
||||
void DumpCache();
|
||||
void EnsureCached(nsMsgDatabase* pMessageDB)
|
||||
{
|
||||
if (!m_dbCache.Contains(pMessageDB))
|
||||
m_dbCache.AppendElement(pMessageDB);
|
||||
}
|
||||
void RemoveFromCache(nsMsgDatabase* pMessageDB)
|
||||
{
|
||||
m_dbCache.RemoveElement(pMessageDB);
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsMsgDBService();
|
||||
void HookupPendingListeners(nsIMsgDatabase *db, nsIMsgFolder *folder);
|
||||
void FinishDBOpen(nsIMsgFolder *aFolder, nsMsgDatabase *aMsgDB);
|
||||
nsMsgDatabase* FindInCache(nsIFile *dbName);
|
||||
|
||||
nsCOMArray <nsIMsgFolder> m_foldersPendingListeners;
|
||||
nsCOMArray <nsIDBChangeListener> m_pendingListeners;
|
||||
AutoTArray<nsMsgDatabase*, kInitialMsgDBCacheSize> m_dbCache;
|
||||
};
|
||||
|
||||
class nsMsgDBEnumerator : public nsISimpleEnumerator {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator methods:
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
// nsMsgDBEnumerator methods:
|
||||
typedef nsresult (*nsMsgDBEnumeratorFilter)(nsIMsgDBHdr* hdr, void* closure);
|
||||
|
||||
nsMsgDBEnumerator(nsMsgDatabase* db, nsIMdbTable *table,
|
||||
nsMsgDBEnumeratorFilter filter, void* closure,
|
||||
bool iterateForwards = true);
|
||||
void Clear();
|
||||
|
||||
nsresult GetRowCursor();
|
||||
virtual nsresult PrefetchNext();
|
||||
RefPtr<nsMsgDatabase> mDB;
|
||||
nsCOMPtr<nsIMdbTableRowCursor> mRowCursor;
|
||||
mdb_pos mRowPos;
|
||||
nsCOMPtr<nsIMsgDBHdr> mResultHdr;
|
||||
bool mDone;
|
||||
bool mNextPrefetched;
|
||||
bool mIterateForwards;
|
||||
nsMsgDBEnumeratorFilter mFilter;
|
||||
nsCOMPtr <nsIMdbTable> mTable;
|
||||
void* mClosure;
|
||||
// This is used when the caller wants to limit how many headers the
|
||||
// enumerator looks at in any given time slice.
|
||||
mdb_pos mStopPos;
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgDBEnumerator();
|
||||
};
|
||||
|
||||
class nsMsgFilteredDBEnumerator : public nsMsgDBEnumerator
|
||||
{
|
||||
public:
|
||||
nsMsgFilteredDBEnumerator(nsMsgDatabase* db, nsIMdbTable *table,
|
||||
bool reverse, nsIArray *searchTerms);
|
||||
virtual ~nsMsgFilteredDBEnumerator();
|
||||
nsresult InitSearchSession(nsIArray *searchTerms, nsIMsgFolder *folder);
|
||||
|
||||
protected:
|
||||
virtual nsresult PrefetchNext() override;
|
||||
|
||||
nsCOMPtr <nsIMsgSearchSession> m_searchSession;
|
||||
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
namespace mailnews {
|
||||
class MsgDBReporter;
|
||||
}
|
||||
}
|
||||
|
||||
class nsMsgDatabase : public nsIMsgDatabase
|
||||
{
|
||||
public:
|
||||
friend class nsMsgDBService;
|
||||
friend class nsMsgPropertyEnumerator; // accesses m_mdbEnv and m_mdbStore
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDBCHANGEANNOUNCER
|
||||
NS_DECL_NSIMSGDATABASE
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
virtual nsresult Open(nsMsgDBService *aDBService, nsIFile *aFolderName,
|
||||
bool aCreate, bool aLeaveInvalidDB);
|
||||
virtual nsresult IsHeaderRead(nsIMsgDBHdr *hdr, bool *pRead);
|
||||
virtual nsresult MarkHdrReadInDB(nsIMsgDBHdr *msgHdr, bool bRead,
|
||||
nsIDBChangeListener *instigator);
|
||||
nsresult OpenInternal(nsMsgDBService *aDBService, nsIFile *aFolderName,
|
||||
bool aCreate, bool aLeaveInvalidDB, bool sync);
|
||||
nsresult CheckForErrors(nsresult err, bool sync, nsMsgDBService *aDBService, nsIFile *summaryFile);
|
||||
virtual nsresult OpenMDB(const char *dbName, bool create, bool sync);
|
||||
virtual nsresult CloseMDB(bool commit);
|
||||
virtual nsresult CreateMsgHdr(nsIMdbRow* hdrRow, nsMsgKey key, nsIMsgDBHdr **result);
|
||||
virtual nsresult GetThreadForMsgKey(nsMsgKey msgKey, nsIMsgThread **result);
|
||||
virtual nsresult EnumerateMessagesWithFlag(nsISimpleEnumerator* *result, uint32_t *pFlag);
|
||||
nsresult GetSearchResultsTable(const char *searchFolderUri, bool createIfMissing, nsIMdbTable **table);
|
||||
|
||||
// this might just be for debugging - we'll see.
|
||||
nsresult ListAllThreads(nsTArray<nsMsgKey> *threadIds);
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// nsMsgDatabase methods:
|
||||
nsMsgDatabase();
|
||||
|
||||
void GetMDBFactory(nsIMdbFactory ** aMdbFactory);
|
||||
nsIMdbEnv *GetEnv() {return m_mdbEnv;}
|
||||
nsIMdbStore *GetStore() {return m_mdbStore;}
|
||||
virtual uint32_t GetCurVersion();
|
||||
nsresult GetCollationKeyGenerator();
|
||||
nsIMimeConverter * GetMimeConverter();
|
||||
|
||||
nsresult GetTableCreateIfMissing(const char *scope, const char *kind, nsIMdbTable **table,
|
||||
mdb_token &scopeToken, mdb_token &kindToken);
|
||||
|
||||
//helper function to fill in nsStrings from hdr row cell contents.
|
||||
nsresult RowCellColumnTonsString(nsIMdbRow *row, mdb_token columnToken, nsAString &resultStr);
|
||||
nsresult RowCellColumnToUInt32(nsIMdbRow *row, mdb_token columnToken, uint32_t *uint32Result, uint32_t defaultValue = 0);
|
||||
nsresult RowCellColumnToUInt32(nsIMdbRow *row, mdb_token columnToken, uint32_t &uint32Result, uint32_t defaultValue = 0);
|
||||
nsresult RowCellColumnToUInt64(nsIMdbRow *row, mdb_token columnToken, uint64_t *uint64Result, uint64_t defaultValue = 0);
|
||||
nsresult RowCellColumnToMime2DecodedString(nsIMdbRow *row, mdb_token columnToken, nsAString &resultStr);
|
||||
nsresult RowCellColumnToCollationKey(nsIMdbRow *row, mdb_token columnToken, uint8_t **result, uint32_t *len);
|
||||
nsresult RowCellColumnToConstCharPtr(nsIMdbRow *row, mdb_token columnToken, const char **ptr);
|
||||
nsresult RowCellColumnToAddressCollationKey(nsIMdbRow *row, mdb_token colToken, uint8_t **result, uint32_t *len);
|
||||
|
||||
nsresult GetEffectiveCharset(nsIMdbRow *row, nsACString &resultCharset);
|
||||
|
||||
// these methods take the property name as a string, not a token.
|
||||
// they should be used when the properties aren't accessed a lot
|
||||
nsresult GetProperty(nsIMdbRow *row, const char *propertyName, char **result);
|
||||
nsresult SetProperty(nsIMdbRow *row, const char *propertyName, const char *propertyVal);
|
||||
nsresult GetPropertyAsNSString(nsIMdbRow *row, const char *propertyName, nsAString &result);
|
||||
nsresult SetPropertyFromNSString(nsIMdbRow *row, const char *propertyName, const nsAString &propertyVal);
|
||||
nsresult GetUint32Property(nsIMdbRow *row, const char *propertyName, uint32_t *result, uint32_t defaultValue = 0);
|
||||
nsresult GetUint64Property(nsIMdbRow *row, const char *propertyName, uint64_t *result, uint64_t defaultValue = 0);
|
||||
nsresult SetUint32Property(nsIMdbRow *row, const char *propertyName, uint32_t propertyVal);
|
||||
nsresult SetUint64Property(nsIMdbRow *row, const char *propertyName, uint64_t propertyVal);
|
||||
nsresult GetBooleanProperty(nsIMdbRow *row, const char *propertyName,
|
||||
bool *result, bool defaultValue = false);
|
||||
nsresult SetBooleanProperty(nsIMdbRow *row, const char *propertyName,
|
||||
bool propertyVal);
|
||||
// helper function for once we have the token.
|
||||
nsresult SetNSStringPropertyWithToken(nsIMdbRow *row, mdb_token aProperty, const nsAString &propertyStr);
|
||||
|
||||
// helper functions to put values in cells for the passed-in row
|
||||
nsresult UInt32ToRowCellColumn(nsIMdbRow *row, mdb_token columnToken, uint32_t value);
|
||||
nsresult CharPtrToRowCellColumn(nsIMdbRow *row, mdb_token columnToken, const char *charPtr);
|
||||
nsresult RowCellColumnToCharPtr(nsIMdbRow *row, mdb_token columnToken, char **result);
|
||||
nsresult UInt64ToRowCellColumn(nsIMdbRow *row, mdb_token columnToken, uint64_t value);
|
||||
|
||||
// helper functions to copy an nsString to a yarn, int32 to yarn, and vice versa.
|
||||
static struct mdbYarn *nsStringToYarn(struct mdbYarn *yarn, const nsAString &str);
|
||||
static struct mdbYarn *UInt32ToYarn(struct mdbYarn *yarn, uint32_t i);
|
||||
static struct mdbYarn *UInt64ToYarn(struct mdbYarn *yarn, uint64_t i);
|
||||
static void YarnTonsString(struct mdbYarn *yarn, nsAString &str);
|
||||
static void YarnTonsCString(struct mdbYarn *yarn, nsACString &str);
|
||||
static void YarnToUInt32(struct mdbYarn *yarn, uint32_t *i);
|
||||
static void YarnToUInt64(struct mdbYarn *yarn, uint64_t *i);
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual nsresult DumpContents();
|
||||
nsresult DumpThread(nsMsgKey threadId);
|
||||
nsresult DumpMsgChildren(nsIMsgDBHdr *msgHdr);
|
||||
#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;
|
||||
friend class nsMsgDBThreadEnumerator;
|
||||
protected:
|
||||
virtual ~nsMsgDatabase();
|
||||
|
||||
// prefs stuff - in future, we might want to cache the prefs interface
|
||||
nsresult GetBoolPref(const char *prefName, bool *result);
|
||||
nsresult GetIntPref(const char *prefName, int32_t *result);
|
||||
virtual void GetGlobalPrefs();
|
||||
// retrieval methods
|
||||
nsIMsgThread * GetThreadForReference(nsCString &msgID, nsIMsgDBHdr **pMsgHdr);
|
||||
nsIMsgThread * GetThreadForSubject(nsCString &subject);
|
||||
nsIMsgThread * GetThreadForMessageId(nsCString &msgId);
|
||||
nsIMsgThread * GetThreadForThreadId(nsMsgKey threadId);
|
||||
nsMsgHdr * GetMsgHdrForReference(nsCString &reference);
|
||||
nsIMsgDBHdr * GetMsgHdrForSubject(nsCString &subject);
|
||||
// threading interfaces
|
||||
virtual nsresult CreateNewThread(nsMsgKey key, const char *subject, nsMsgThread **newThread);
|
||||
virtual bool ThreadBySubjectWithoutRe();
|
||||
virtual bool UseStrictThreading();
|
||||
virtual bool UseCorrectThreading();
|
||||
virtual nsresult ThreadNewHdr(nsMsgHdr* hdr, bool &newThread);
|
||||
virtual nsresult AddNewThread(nsMsgHdr *msgHdr);
|
||||
virtual nsresult AddToThread(nsMsgHdr *newHdr, nsIMsgThread *thread, nsIMsgDBHdr *pMsgHdr, bool threadInThread);
|
||||
|
||||
static PRTime gLastUseTime; // global last use time
|
||||
PRTime m_lastUseTime; // last use time for this db
|
||||
// inline to make instrumentation as cheap as possible
|
||||
inline void RememberLastUseTime() {gLastUseTime = m_lastUseTime = PR_Now();}
|
||||
|
||||
bool MatchDbName(nsIFile *dbName); // returns TRUE if they match
|
||||
|
||||
// Flag handling routines
|
||||
virtual nsresult SetKeyFlag(nsMsgKey key, bool set, uint32_t flag,
|
||||
nsIDBChangeListener *instigator = NULL);
|
||||
virtual nsresult SetMsgHdrFlag(nsIMsgDBHdr *msgHdr, bool set, uint32_t flag,
|
||||
nsIDBChangeListener *instigator);
|
||||
|
||||
virtual bool SetHdrFlag(nsIMsgDBHdr *, bool bSet, nsMsgMessageFlagType flag);
|
||||
virtual bool SetHdrReadFlag(nsIMsgDBHdr *, bool pRead);
|
||||
virtual uint32_t GetStatusFlags(nsIMsgDBHdr *msgHdr, uint32_t origFlags);
|
||||
// helper function which doesn't involve thread object
|
||||
|
||||
virtual nsresult RemoveHeaderFromDB(nsMsgHdr *msgHdr);
|
||||
virtual nsresult RemoveHeaderFromThread(nsMsgHdr *msgHdr);
|
||||
virtual nsresult AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr);
|
||||
|
||||
nsCOMPtr <nsICollation> m_collationKeyGenerator;
|
||||
nsCOMPtr <nsIMimeConverter> m_mimeConverter;
|
||||
nsCOMPtr <nsIMsgRetentionSettings> m_retentionSettings;
|
||||
nsCOMPtr <nsIMsgDownloadSettings> m_downloadSettings;
|
||||
|
||||
nsresult PurgeMessagesOlderThan(uint32_t daysToKeepHdrs,
|
||||
bool applyToFlaggedMessages,
|
||||
nsIMutableArray *hdrsToDelete);
|
||||
nsresult PurgeExcessMessages(uint32_t numHeadersToKeep,
|
||||
bool applyToFlaggedMessages,
|
||||
nsIMutableArray *hdrsToDelete);
|
||||
|
||||
// mdb bookkeeping stuff
|
||||
virtual nsresult InitExistingDB();
|
||||
virtual nsresult InitNewDB();
|
||||
virtual nsresult InitMDBInfo();
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> m_folder;
|
||||
nsDBFolderInfo *m_dbFolderInfo;
|
||||
nsMsgKey m_nextPseudoMsgKey;
|
||||
nsIMdbEnv *m_mdbEnv; // to be used in all the db calls.
|
||||
nsIMdbStore *m_mdbStore;
|
||||
nsIMdbTable *m_mdbAllMsgHeadersTable;
|
||||
nsIMdbTable *m_mdbAllThreadsTable;
|
||||
|
||||
// Used for asynchronous db opens. If non-null, we're still opening
|
||||
// the underlying mork database. If null, the db has been completely opened.
|
||||
nsCOMPtr<nsIMdbThumb> m_thumb;
|
||||
// used to remember the args to Open for async open.
|
||||
bool m_create;
|
||||
bool m_leaveInvalidDB;
|
||||
|
||||
nsCString m_dbName;
|
||||
nsTArray<nsMsgKey> m_newSet; // new messages since last open.
|
||||
bool m_mdbTokensInitialized;
|
||||
nsTObserverArray<nsCOMPtr<nsIDBChangeListener> > m_ChangeListeners;
|
||||
mdb_token m_hdrRowScopeToken;
|
||||
mdb_token m_threadRowScopeToken;
|
||||
mdb_token m_hdrTableKindToken;
|
||||
mdb_token m_threadTableKindToken;
|
||||
mdb_token m_allThreadsTableKindToken;
|
||||
mdb_token m_subjectColumnToken;
|
||||
mdb_token m_senderColumnToken;
|
||||
mdb_token m_messageIdColumnToken;
|
||||
mdb_token m_referencesColumnToken;
|
||||
mdb_token m_recipientsColumnToken;
|
||||
mdb_token m_dateColumnToken;
|
||||
mdb_token m_messageSizeColumnToken;
|
||||
mdb_token m_flagsColumnToken;
|
||||
mdb_token m_priorityColumnToken;
|
||||
mdb_token m_labelColumnToken;
|
||||
mdb_token m_statusOffsetColumnToken;
|
||||
mdb_token m_numLinesColumnToken;
|
||||
mdb_token m_ccListColumnToken;
|
||||
mdb_token m_bccListColumnToken;
|
||||
mdb_token m_threadFlagsColumnToken;
|
||||
mdb_token m_threadIdColumnToken;
|
||||
mdb_token m_threadChildrenColumnToken;
|
||||
mdb_token m_threadUnreadChildrenColumnToken;
|
||||
mdb_token m_messageThreadIdColumnToken;
|
||||
mdb_token m_threadSubjectColumnToken;
|
||||
mdb_token m_messageCharSetColumnToken;
|
||||
mdb_token m_threadParentColumnToken;
|
||||
mdb_token m_threadRootKeyColumnToken;
|
||||
mdb_token m_threadNewestMsgDateColumnToken;
|
||||
mdb_token m_offlineMsgOffsetColumnToken;
|
||||
mdb_token m_offlineMessageSizeColumnToken;
|
||||
|
||||
// header caching stuff - MRU headers, keeps them around in memory
|
||||
nsresult AddHdrToCache(nsIMsgDBHdr *hdr, nsMsgKey key);
|
||||
nsresult ClearHdrCache(bool reInit);
|
||||
nsresult RemoveHdrFromCache(nsIMsgDBHdr *hdr, nsMsgKey key);
|
||||
// all headers currently instantiated, doesn't hold refs
|
||||
// these get added when msg hdrs get constructed, and removed when they get destroyed.
|
||||
nsresult GetHdrFromUseCache(nsMsgKey key, nsIMsgDBHdr* *result);
|
||||
nsresult AddHdrToUseCache(nsIMsgDBHdr *hdr, nsMsgKey key);
|
||||
nsresult ClearUseHdrCache();
|
||||
nsresult RemoveHdrFromUseCache(nsIMsgDBHdr *hdr, nsMsgKey key);
|
||||
|
||||
// not-reference holding array of threads we've handed out.
|
||||
// If a db goes away, it will clean up the outstanding threads.
|
||||
// We use an nsTArray because we don't expect to ever have very many
|
||||
// of these, rarely more than 5.
|
||||
nsTArray<nsMsgThread *> m_threads;
|
||||
// Clear outstanding thread objects
|
||||
void ClearThreads();
|
||||
nsMsgThread *FindExistingThread(nsMsgKey threadId);
|
||||
|
||||
mdb_pos FindInsertIndexInSortedTable(nsIMdbTable *table, mdb_id idToInsert);
|
||||
|
||||
void ClearCachedObjects(bool dbGoingAway);
|
||||
void ClearEnumerators();
|
||||
// all instantiated headers, but doesn't hold refs.
|
||||
PLDHashTable *m_headersInUse;
|
||||
static PLDHashNumber HashKey(const void* aKey);
|
||||
static bool MatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey);
|
||||
static void MoveEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aFrom, PLDHashEntryHdr* aTo);
|
||||
static void ClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry);
|
||||
static PLDHashTableOps gMsgDBHashTableOps;
|
||||
struct MsgHdrHashElement : public PLDHashEntryHdr {
|
||||
nsMsgKey mKey;
|
||||
nsIMsgDBHdr *mHdr;
|
||||
};
|
||||
PLDHashTable *m_cachedHeaders;
|
||||
bool m_bCacheHeaders;
|
||||
nsMsgKey m_cachedThreadId;
|
||||
nsCOMPtr <nsIMsgThread> m_cachedThread;
|
||||
nsCOMPtr<nsIMdbFactory> mMdbFactory;
|
||||
|
||||
// Message reference hash table
|
||||
static PLDHashTableOps gRefHashTableOps;
|
||||
struct RefHashElement : public PLDHashEntryHdr {
|
||||
const char *mRef; // Hash entry key, must come first
|
||||
nsMsgKey mThreadId;
|
||||
uint32_t mCount;
|
||||
};
|
||||
PLDHashTable *m_msgReferences;
|
||||
nsresult GetRefFromHash(nsCString &reference, nsMsgKey *threadId);
|
||||
nsresult AddRefToHash(nsCString &reference, nsMsgKey threadId);
|
||||
nsresult AddMsgRefsToHash(nsIMsgDBHdr *msgHdr);
|
||||
nsresult RemoveRefFromHash(nsCString &reference);
|
||||
nsresult RemoveMsgRefsFromHash(nsIMsgDBHdr *msgHdr);
|
||||
nsresult InitRefHash();
|
||||
|
||||
// not-reference holding array of enumerators we've handed out.
|
||||
// If a db goes away, it will clean up the outstanding enumerators.
|
||||
nsTArray<nsMsgDBEnumerator *> m_enumerators;
|
||||
|
||||
// Memory reporter details
|
||||
public:
|
||||
static size_t HeaderHashSizeOf(PLDHashEntryHdr *hdr,
|
||||
mozilla::MallocSizeOf aMallocSizeOf,
|
||||
void *arg);
|
||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
private:
|
||||
uint32_t m_cacheSize;
|
||||
RefPtr<mozilla::mailnews::MsgDBReporter> mMemReporter;
|
||||
};
|
||||
|
||||
class nsMsgRetentionSettings : public nsIMsgRetentionSettings
|
||||
{
|
||||
public:
|
||||
nsMsgRetentionSettings();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGRETENTIONSETTINGS
|
||||
protected:
|
||||
virtual ~nsMsgRetentionSettings();
|
||||
nsMsgRetainByPreference m_retainByPreference;
|
||||
uint32_t m_daysToKeepHdrs;
|
||||
uint32_t m_numHeadersToKeep;
|
||||
bool m_useServerDefaults;
|
||||
bool m_cleanupBodiesByDays;
|
||||
uint32_t m_daysToKeepBodies;
|
||||
bool m_applyToFlaggedMessages;
|
||||
};
|
||||
|
||||
class nsMsgDownloadSettings : public nsIMsgDownloadSettings
|
||||
{
|
||||
public:
|
||||
nsMsgDownloadSettings();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGDOWNLOADSETTINGS
|
||||
protected:
|
||||
virtual ~nsMsgDownloadSettings();
|
||||
bool m_useServerDefaults;
|
||||
bool m_downloadUnreadOnly;
|
||||
bool m_downloadByDate;
|
||||
int32_t m_ageLimitOfMsgsToDownload;
|
||||
};
|
||||
|
||||
#endif
|
||||
86
mailnews/db/msgdb/public/nsMsgHdr.h
Normal file
86
mailnews/db/msgdb/public/nsMsgHdr.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsMsgHdr_H
|
||||
#define _nsMsgHdr_H
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "mdb.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsMsgDatabase;
|
||||
class nsCString;
|
||||
class nsIMsgThread;
|
||||
|
||||
class nsMsgHdr : public nsIMsgDBHdr {
|
||||
public:
|
||||
NS_DECL_NSIMSGDBHDR
|
||||
friend class nsMsgDatabase;
|
||||
friend class nsMsgPropertyEnumerator; // accesses m_mdb
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsMsgHdr methods:
|
||||
nsMsgHdr(nsMsgDatabase *db, nsIMdbRow *dbRow);
|
||||
|
||||
virtual nsresult GetRawFlags(uint32_t *result);
|
||||
void Init();
|
||||
virtual nsresult InitCachedValues();
|
||||
virtual nsresult InitFlags();
|
||||
void ClearCachedValues() {m_initedValues = 0;}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsIMdbRow *GetMDBRow() {return m_mdbRow;}
|
||||
bool IsParentOf(nsIMsgDBHdr *possibleChild);
|
||||
bool IsAncestorOf(nsIMsgDBHdr *possibleChild);
|
||||
bool IsAncestorKilled(uint32_t ancestorsToCheck);
|
||||
void ReparentInThread(nsIMsgThread *thread);
|
||||
|
||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOfFun) const
|
||||
{
|
||||
return m_references.ShallowSizeOfExcludingThis(aMallocSizeOfFun);
|
||||
}
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOfFun) const
|
||||
{
|
||||
return aMallocSizeOfFun(this) + SizeOfExcludingThis(aMallocSizeOfFun);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgHdr();
|
||||
nsresult SetStringColumn(const char *str, mdb_token token);
|
||||
nsresult SetUInt32Column(uint32_t value, mdb_token token);
|
||||
nsresult GetUInt32Column(mdb_token token, uint32_t *pvalue, uint32_t defaultValue = 0);
|
||||
nsresult SetUInt64Column(uint64_t value, mdb_token token);
|
||||
nsresult GetUInt64Column(mdb_token token, uint64_t *pvalue, uint64_t defaultValue = 0);
|
||||
|
||||
// reference and threading stuff.
|
||||
nsresult ParseReferences(const char *references);
|
||||
const char* GetNextReference(const char *startNextRef, nsCString &reference,
|
||||
bool acceptNonDelimitedReferences);
|
||||
|
||||
nsMsgKey m_threadId;
|
||||
nsMsgKey m_messageKey; //news: article number, mail mbox offset, imap uid...
|
||||
nsMsgKey m_threadParent; // message this is a reply to, in thread.
|
||||
PRTime m_date;
|
||||
uint32_t m_messageSize; // lines for news articles, bytes for mail messages
|
||||
uint32_t m_statusOffset; // offset in a local mail message of the mozilla status hdr
|
||||
uint32_t m_flags;
|
||||
// avoid parsing references every time we want one
|
||||
nsTArray<nsCString> m_references;
|
||||
nsMsgPriorityValue m_priority;
|
||||
|
||||
// nsMsgHdrs will have to know what db and row they belong to, since they are really
|
||||
// just a wrapper around the msg row in the mdb. This could cause problems,
|
||||
// though I hope not.
|
||||
nsMsgDatabase *m_mdb;
|
||||
nsIMdbRow *m_mdbRow;
|
||||
uint32_t m_initedValues;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
63
mailnews/db/msgdb/public/nsMsgThread.h
Normal file
63
mailnews/db/msgdb/public/nsMsgThread.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsMsgThread_H
|
||||
#define _nsMsgThread_H
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIMsgThread.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "mdb.h"
|
||||
|
||||
class nsIMdbTable;
|
||||
class nsIMsgDBHdr;
|
||||
class nsMsgDatabase;
|
||||
|
||||
class nsMsgThread : public nsIMsgThread {
|
||||
public:
|
||||
nsMsgThread();
|
||||
nsMsgThread(nsMsgDatabase *db, nsIMdbTable *table);
|
||||
|
||||
friend class nsMsgThreadEnumerator;
|
||||
friend class nsMsgDatabase;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGTHREAD
|
||||
|
||||
RefPtr<nsMsgDatabase> m_mdbDB;
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgThread();
|
||||
|
||||
void Init();
|
||||
void Clear();
|
||||
virtual nsresult InitCachedValues();
|
||||
nsresult ChangeChildCount(int32_t delta);
|
||||
nsresult ChangeUnreadChildCount(int32_t delta);
|
||||
nsresult RemoveChild(nsMsgKey msgKey);
|
||||
nsresult SetThreadRootKey(nsMsgKey threadRootKey);
|
||||
nsresult GetChildHdrForKey(nsMsgKey desiredKey,
|
||||
nsIMsgDBHdr **result, int32_t *resultIndex);
|
||||
nsresult RerootThread(nsIMsgDBHdr *newParentOfOldRoot, nsIMsgDBHdr *oldRoot, nsIDBChangeAnnouncer *announcer);
|
||||
nsresult ReparentChildrenOf(nsMsgKey oldParent, nsMsgKey newParent, nsIDBChangeAnnouncer *announcer);
|
||||
|
||||
nsresult ReparentNonReferenceChildrenOf(nsIMsgDBHdr *topLevelHdr, nsMsgKey newParentKey,
|
||||
nsIDBChangeAnnouncer *announcer);
|
||||
nsresult ReparentMsgsWithInvalidParent(uint32_t numChildren, nsMsgKey threadParentKey);
|
||||
|
||||
nsMsgKey m_threadKey;
|
||||
uint32_t m_numChildren;
|
||||
uint32_t m_numUnreadChildren;
|
||||
uint32_t m_flags;
|
||||
nsCOMPtr<nsIMdbTable> m_mdbTable;
|
||||
nsCOMPtr<nsIMdbRow> m_metaRow;
|
||||
bool m_cachedValuesInitialized;
|
||||
nsMsgKey m_threadRootKey;
|
||||
uint32_t m_newestMsgDate;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
57
mailnews/db/msgdb/public/nsNewsDatabase.h
Normal file
57
mailnews/db/msgdb/public/nsNewsDatabase.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _nsNewsDatabase_H_
|
||||
#define _nsNewsDatabase_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsMsgDatabase.h"
|
||||
#include "nsINewsDatabase.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIDBChangeListener;
|
||||
class MSG_RetrieveArtInfo;
|
||||
class MSG_PurgeInfo;
|
||||
// news group database
|
||||
|
||||
class nsNewsDatabase : public nsMsgDatabase , public nsINewsDatabase
|
||||
{
|
||||
public:
|
||||
nsNewsDatabase();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINEWSDATABASE
|
||||
|
||||
NS_IMETHOD Close(bool forceCommit) override;
|
||||
NS_IMETHOD ForceClosed() override;
|
||||
NS_IMETHOD Commit(nsMsgDBCommit commitType) override;
|
||||
virtual uint32_t GetCurVersion() override;
|
||||
|
||||
// methods to get and set docsets for ids.
|
||||
NS_IMETHOD IsRead(nsMsgKey key, bool *pRead) override;
|
||||
virtual nsresult IsHeaderRead(nsIMsgDBHdr *msgHdr, bool *pRead) override;
|
||||
|
||||
NS_IMETHOD GetHighWaterArticleNum(nsMsgKey *key) override;
|
||||
NS_IMETHOD GetLowWaterArticleNum(nsMsgKey *key) override;
|
||||
NS_IMETHOD MarkAllRead(uint32_t *aNumMarked, nsMsgKey **thoseMarked) override;
|
||||
|
||||
virtual nsresult ExpireUpTo(nsMsgKey expireKey);
|
||||
virtual nsresult ExpireRange(nsMsgKey startRange, nsMsgKey endRange);
|
||||
|
||||
virtual bool SetHdrReadFlag(nsIMsgDBHdr *msgHdr, bool bRead) override;
|
||||
|
||||
virtual nsresult AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr) override;
|
||||
nsresult SyncWithReadSet();
|
||||
|
||||
NS_IMETHOD GetDefaultViewFlags(nsMsgViewFlagsTypeValue *aDefaultViewFlags) override;
|
||||
NS_IMETHOD GetDefaultSortType(nsMsgViewSortTypeValue *aDefaultSortType) override;
|
||||
NS_IMETHOD GetDefaultSortOrder(nsMsgViewSortOrderValue *aDefaultSortOrder) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNewsDatabase();
|
||||
// this is owned by the nsNewsFolder, which lives longer than the db.
|
||||
nsMsgKeySet *m_readSet;
|
||||
};
|
||||
|
||||
#endif
|
||||
18
mailnews/db/msgdb/src/moz.build
Normal file
18
mailnews/db/msgdb/src/moz.build
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SOURCES += [
|
||||
'nsDBFolderInfo.cpp',
|
||||
'nsImapMailDatabase.cpp',
|
||||
'nsMailDatabase.cpp',
|
||||
'nsMsgDatabase.cpp',
|
||||
'nsMsgHdr.cpp',
|
||||
'nsMsgOfflineImapOperation.cpp',
|
||||
'nsMsgThread.cpp',
|
||||
'nsNewsDatabase.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'mail'
|
||||
|
||||
977
mailnews/db/msgdb/src/nsDBFolderInfo.cpp
Normal file
977
mailnews/db/msgdb/src/nsDBFolderInfo.cpp
Normal file
|
|
@ -0,0 +1,977 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsDBFolderInfo.h"
|
||||
#include "nsMsgDatabase.h"
|
||||
#include "nsMsgFolderFlags.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIMsgDBView.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsImapCore.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
static const char *kDBFolderInfoScope = "ns:msg:db:row:scope:dbfolderinfo:all";
|
||||
static const char *kDBFolderInfoTableKind = "ns:msg:db:table:kind:dbfolderinfo";
|
||||
|
||||
struct mdbOid gDBFolderInfoOID;
|
||||
|
||||
static const char * kNumMessagesColumnName ="numMsgs";
|
||||
// have to leave this as numNewMsgs even though it's numUnread Msgs
|
||||
static const char * kNumUnreadMessagesColumnName = "numNewMsgs";
|
||||
static const char * kFlagsColumnName = "flags";
|
||||
static const char * kFolderSizeColumnName = "folderSize";
|
||||
static const char * kExpungedBytesColumnName = "expungedBytes";
|
||||
static const char * kFolderDateColumnName = "folderDate";
|
||||
static const char * kHighWaterMessageKeyColumnName = "highWaterKey";
|
||||
|
||||
static const char * kImapUidValidityColumnName = "UIDValidity";
|
||||
static const char * kTotalPendingMessagesColumnName = "totPendingMsgs";
|
||||
static const char * kUnreadPendingMessagesColumnName = "unreadPendingMsgs";
|
||||
static const char * kMailboxNameColumnName = "mailboxName";
|
||||
static const char * kKnownArtsSetColumnName = "knownArts";
|
||||
static const char * kExpiredMarkColumnName = "expiredMark";
|
||||
static const char * kVersionColumnName = "version";
|
||||
static const char * kCharacterSetColumnName = "charSet";
|
||||
static const char * kCharacterSetOverrideColumnName = "charSetOverride";
|
||||
static const char * kLocaleColumnName = "locale";
|
||||
|
||||
|
||||
#define kMAILNEWS_VIEW_DEFAULT_CHARSET "mailnews.view_default_charset"
|
||||
#define kMAILNEWS_DEFAULT_CHARSET_OVERRIDE "mailnews.force_charset_override"
|
||||
static nsCString* gDefaultCharacterSet = nullptr;
|
||||
static bool gDefaultCharacterOverride;
|
||||
static nsIObserver *gFolderCharsetObserver = nullptr;
|
||||
|
||||
// observer for charset related preference notification
|
||||
class nsFolderCharsetObserver : public nsIObserver {
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsFolderCharsetObserver() { }
|
||||
private:
|
||||
virtual ~nsFolderCharsetObserver() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsFolderCharsetObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP nsFolderCharsetObserver::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID))
|
||||
{
|
||||
nsDependentString prefName(someData);
|
||||
|
||||
if (prefName.EqualsLiteral(kMAILNEWS_VIEW_DEFAULT_CHARSET))
|
||||
{
|
||||
nsCOMPtr<nsIPrefLocalizedString> pls;
|
||||
rv = prefBranch->GetComplexValue(kMAILNEWS_VIEW_DEFAULT_CHARSET,
|
||||
NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsString ucsval;
|
||||
pls->ToString(getter_Copies(ucsval));
|
||||
if (!ucsval.IsEmpty())
|
||||
{
|
||||
if (gDefaultCharacterSet)
|
||||
CopyUTF16toUTF8(ucsval, *gDefaultCharacterSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (prefName.EqualsLiteral(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE))
|
||||
{
|
||||
rv = prefBranch->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
|
||||
{
|
||||
rv = prefBranch->RemoveObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, this);
|
||||
rv = prefBranch->RemoveObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, this);
|
||||
NS_IF_RELEASE(gFolderCharsetObserver);
|
||||
delete gDefaultCharacterSet;
|
||||
gDefaultCharacterSet = nullptr;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsDBFolderInfo)
|
||||
NS_IMPL_RELEASE(nsDBFolderInfo)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::QueryInterface(REFNSIID iid, void** result)
|
||||
{
|
||||
if (! result)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*result = nullptr;
|
||||
if(iid.Equals(NS_GET_IID(nsIDBFolderInfo)) ||
|
||||
iid.Equals(NS_GET_IID(nsISupports)))
|
||||
{
|
||||
*result = static_cast<nsIDBFolderInfo*>(this);
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
nsDBFolderInfo::nsDBFolderInfo(nsMsgDatabase *mdb)
|
||||
: m_flags(0),
|
||||
m_expiredMark(0),
|
||||
m_expiredMarkColumnToken(0)
|
||||
{
|
||||
m_mdbTable = NULL;
|
||||
m_mdbRow = NULL;
|
||||
m_version = 1; // for upgrading...
|
||||
m_IMAPHierarchySeparator = 0; // imap path separator
|
||||
// mail only (for now)
|
||||
m_folderSize = 0;
|
||||
m_folderDate = 0;
|
||||
m_expungedBytes = 0; // sum of size of deleted messages in folder
|
||||
m_highWaterMessageKey = 0;
|
||||
|
||||
m_numUnreadMessages = 0;
|
||||
m_numMessages = 0;
|
||||
// IMAP only
|
||||
m_ImapUidValidity = kUidUnknown;
|
||||
m_totalPendingMessages =0;
|
||||
m_unreadPendingMessages = 0;
|
||||
|
||||
m_mdbTokensInitialized = false;
|
||||
m_charSetOverride = false;
|
||||
|
||||
if (!gFolderCharsetObserver)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch));
|
||||
}
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIPrefLocalizedString> pls;
|
||||
rv = prefBranch->GetComplexValue(kMAILNEWS_VIEW_DEFAULT_CHARSET,
|
||||
NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsString ucsval;
|
||||
pls->ToString(getter_Copies(ucsval));
|
||||
if (!ucsval.IsEmpty())
|
||||
{
|
||||
if (!gDefaultCharacterSet)
|
||||
gDefaultCharacterSet = new nsCString;
|
||||
|
||||
if (gDefaultCharacterSet)
|
||||
CopyUTF16toUTF8(ucsval, *gDefaultCharacterSet);
|
||||
}
|
||||
}
|
||||
rv = prefBranch->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
|
||||
|
||||
gFolderCharsetObserver = new nsFolderCharsetObserver();
|
||||
NS_ASSERTION(gFolderCharsetObserver, "failed to create observer");
|
||||
|
||||
// register prefs callbacks
|
||||
if (gFolderCharsetObserver)
|
||||
{
|
||||
NS_ADDREF(gFolderCharsetObserver);
|
||||
rv = prefBranch->AddObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, gFolderCharsetObserver, false);
|
||||
rv = prefBranch->AddObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, gFolderCharsetObserver, false);
|
||||
|
||||
// also register for shutdown
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerService)
|
||||
{
|
||||
rv = observerService->AddObserver(gFolderCharsetObserver, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_mdb = mdb;
|
||||
if (mdb)
|
||||
{
|
||||
nsresult err;
|
||||
|
||||
// mdb->AddRef();
|
||||
err = m_mdb->GetStore()->StringToToken(mdb->GetEnv(), kDBFolderInfoScope, &m_rowScopeToken);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
err = m_mdb->GetStore()->StringToToken(mdb->GetEnv(), kDBFolderInfoTableKind, &m_tableKindToken);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
gDBFolderInfoOID.mOid_Scope = m_rowScopeToken;
|
||||
gDBFolderInfoOID.mOid_Id = 1;
|
||||
}
|
||||
}
|
||||
InitMDBInfo();
|
||||
}
|
||||
}
|
||||
|
||||
nsDBFolderInfo::~nsDBFolderInfo()
|
||||
{
|
||||
// nsMsgDatabase strictly owns nsDBFolderInfo, so don't ref-count db.
|
||||
ReleaseExternalReferences();
|
||||
}
|
||||
|
||||
// Release any objects we're holding onto. This needs to be safe
|
||||
// to call multiple times.
|
||||
void nsDBFolderInfo::ReleaseExternalReferences()
|
||||
{
|
||||
if (m_mdb)
|
||||
{
|
||||
if (m_mdbTable)
|
||||
{
|
||||
NS_RELEASE(m_mdbTable);
|
||||
m_mdbTable = nullptr;
|
||||
}
|
||||
if (m_mdbRow)
|
||||
{
|
||||
NS_RELEASE(m_mdbRow);
|
||||
m_mdbRow = nullptr;
|
||||
}
|
||||
m_mdb = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// this routine sets up a new db to know about the dbFolderInfo stuff...
|
||||
nsresult nsDBFolderInfo::AddToNewMDB()
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (m_mdb && m_mdb->GetStore())
|
||||
{
|
||||
nsIMdbStore *store = m_mdb->GetStore();
|
||||
// create the unique table for the dbFolderInfo.
|
||||
nsresult err = store->NewTable(m_mdb->GetEnv(), m_rowScopeToken,
|
||||
m_tableKindToken, true, nullptr, &m_mdbTable);
|
||||
|
||||
// create the singleton row for the dbFolderInfo.
|
||||
err = store->NewRowWithOid(m_mdb->GetEnv(),
|
||||
&gDBFolderInfoOID, &m_mdbRow);
|
||||
|
||||
// add the row to the singleton table.
|
||||
if (m_mdbRow && NS_SUCCEEDED(err))
|
||||
err = m_mdbTable->AddRow(m_mdb->GetEnv(), m_mdbRow);
|
||||
|
||||
ret = err; // what are we going to do about nsresult's?
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::InitFromExistingDB()
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (m_mdb && m_mdb->GetStore())
|
||||
{
|
||||
nsIMdbStore *store = m_mdb->GetStore();
|
||||
if (store)
|
||||
{
|
||||
mdb_pos rowPos;
|
||||
mdb_count outTableCount; // current number of such tables
|
||||
mdb_bool mustBeUnique; // whether port can hold only one of these
|
||||
mdb_bool hasOid;
|
||||
ret = store->GetTableKind(m_mdb->GetEnv(), m_rowScopeToken, m_tableKindToken, &outTableCount,
|
||||
&mustBeUnique, &m_mdbTable);
|
||||
// NS_ASSERTION(mustBeUnique && outTableCount == 1, "only one global db info allowed");
|
||||
|
||||
if (m_mdbTable)
|
||||
{
|
||||
// find singleton row for global info.
|
||||
ret = m_mdbTable->HasOid(m_mdb->GetEnv(), &gDBFolderInfoOID, &hasOid);
|
||||
if (NS_SUCCEEDED(ret))
|
||||
{
|
||||
nsIMdbTableRowCursor *rowCursor;
|
||||
rowPos = -1;
|
||||
ret= m_mdbTable->GetTableRowCursor(m_mdb->GetEnv(), rowPos, &rowCursor);
|
||||
if (NS_SUCCEEDED(ret))
|
||||
{
|
||||
ret = rowCursor->NextRow(m_mdb->GetEnv(), &m_mdbRow, &rowPos);
|
||||
NS_RELEASE(rowCursor);
|
||||
if (!m_mdbRow)
|
||||
ret = NS_ERROR_FAILURE;
|
||||
if (NS_SUCCEEDED(ret))
|
||||
LoadMemberVariables();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::InitMDBInfo()
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (!m_mdbTokensInitialized && m_mdb && m_mdb->GetStore())
|
||||
{
|
||||
nsIMdbStore *store = m_mdb->GetStore();
|
||||
nsIMdbEnv *env = m_mdb->GetEnv();
|
||||
|
||||
store->StringToToken(env, kNumMessagesColumnName, &m_numMessagesColumnToken);
|
||||
store->StringToToken(env, kNumUnreadMessagesColumnName, &m_numUnreadMessagesColumnToken);
|
||||
store->StringToToken(env, kFlagsColumnName, &m_flagsColumnToken);
|
||||
store->StringToToken(env, kFolderSizeColumnName, &m_folderSizeColumnToken);
|
||||
store->StringToToken(env, kExpungedBytesColumnName, &m_expungedBytesColumnToken);
|
||||
store->StringToToken(env, kFolderDateColumnName, &m_folderDateColumnToken);
|
||||
|
||||
store->StringToToken(env, kHighWaterMessageKeyColumnName, &m_highWaterMessageKeyColumnToken);
|
||||
store->StringToToken(env, kMailboxNameColumnName, &m_mailboxNameColumnToken);
|
||||
|
||||
store->StringToToken(env, kImapUidValidityColumnName, &m_imapUidValidityColumnToken);
|
||||
store->StringToToken(env, kTotalPendingMessagesColumnName, &m_totalPendingMessagesColumnToken);
|
||||
store->StringToToken(env, kUnreadPendingMessagesColumnName, &m_unreadPendingMessagesColumnToken);
|
||||
store->StringToToken(env, kExpiredMarkColumnName, &m_expiredMarkColumnToken);
|
||||
store->StringToToken(env, kVersionColumnName, &m_versionColumnToken);
|
||||
m_mdbTokensInitialized = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::LoadMemberVariables()
|
||||
{
|
||||
// it's really not an error for these properties to not exist...
|
||||
GetInt32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
|
||||
GetInt32PropertyWithToken(m_numUnreadMessagesColumnToken, m_numUnreadMessages);
|
||||
GetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
|
||||
GetInt64PropertyWithToken(m_folderSizeColumnToken, m_folderSize);
|
||||
GetUint32PropertyWithToken(m_folderDateColumnToken, m_folderDate);
|
||||
GetInt32PropertyWithToken(m_imapUidValidityColumnToken, m_ImapUidValidity, kUidUnknown);
|
||||
GetUint32PropertyWithToken(m_expiredMarkColumnToken, m_expiredMark);
|
||||
GetInt64PropertyWithToken(m_expungedBytesColumnToken, m_expungedBytes);
|
||||
GetUint32PropertyWithToken(m_highWaterMessageKeyColumnToken, m_highWaterMessageKey);
|
||||
int32_t version;
|
||||
|
||||
GetInt32PropertyWithToken(m_versionColumnToken, version);
|
||||
m_version = (uint16_t) version;
|
||||
m_charSetOverride = gDefaultCharacterOverride;
|
||||
uint32_t propertyValue;
|
||||
nsresult rv = GetUint32Property(kCharacterSetOverrideColumnName, gDefaultCharacterOverride, &propertyValue);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_charSetOverride = propertyValue;
|
||||
|
||||
m_mdb->GetProperty(m_mdbRow, kCharacterSetColumnName, getter_Copies(m_charSet));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetVersion(uint32_t version)
|
||||
{
|
||||
m_version = version;
|
||||
return SetUint32PropertyWithToken(m_versionColumnToken, (uint32_t) m_version);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetVersion(uint32_t *version)
|
||||
{
|
||||
*version = m_version;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult nsDBFolderInfo::AdjustHighWater(nsMsgKey highWater, bool force)
|
||||
{
|
||||
if (force || m_highWaterMessageKey < highWater)
|
||||
{
|
||||
m_highWaterMessageKey = highWater;
|
||||
SetUint32PropertyWithToken(m_highWaterMessageKeyColumnToken, highWater);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetHighWater(nsMsgKey highWater)
|
||||
{
|
||||
return AdjustHighWater(highWater, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::OnKeyAdded(nsMsgKey aNewKey)
|
||||
{
|
||||
return AdjustHighWater(aNewKey, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetFolderSize(int64_t *size)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(size);
|
||||
*size = m_folderSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetFolderSize(int64_t size)
|
||||
{
|
||||
m_folderSize = size;
|
||||
return SetInt64Property(kFolderSizeColumnName, m_folderSize);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetFolderDate(uint32_t *folderDate)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(folderDate);
|
||||
*folderDate = m_folderDate;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetFolderDate(uint32_t folderDate)
|
||||
{
|
||||
m_folderDate = folderDate;
|
||||
return SetUint32PropertyWithToken(m_folderDateColumnToken, folderDate);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetHighWater(nsMsgKey *result)
|
||||
{
|
||||
// Sanity check highwater - if it gets too big, other code
|
||||
// can fail. Look through last 100 messages to recalculate
|
||||
// the highwater mark.
|
||||
*result = m_highWaterMessageKey;
|
||||
if (m_highWaterMessageKey > 0xFFFFFF00 && m_mdb)
|
||||
{
|
||||
nsCOMPtr <nsISimpleEnumerator> hdrs;
|
||||
nsresult rv = m_mdb->ReverseEnumerateMessages(getter_AddRefs(hdrs));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
bool hasMore = false;
|
||||
nsCOMPtr<nsIMsgDBHdr> pHeader;
|
||||
nsMsgKey recalculatedHighWater = 1;
|
||||
int32_t i = 0;
|
||||
while(i++ < 100 && NS_SUCCEEDED(rv = hdrs->HasMoreElements(&hasMore))
|
||||
&& hasMore)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
(void) hdrs->GetNext(getter_AddRefs(supports));
|
||||
pHeader = do_QueryInterface(supports);
|
||||
if (pHeader)
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
pHeader->GetMessageKey(&msgKey);
|
||||
if (msgKey > recalculatedHighWater)
|
||||
recalculatedHighWater = msgKey;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(m_highWaterMessageKey >= recalculatedHighWater,
|
||||
"highwater incorrect");
|
||||
m_highWaterMessageKey = recalculatedHighWater;
|
||||
}
|
||||
*result = m_highWaterMessageKey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetExpiredMark(nsMsgKey expiredKey)
|
||||
{
|
||||
m_expiredMark = expiredKey;
|
||||
return SetUint32PropertyWithToken(m_expiredMarkColumnToken, expiredKey);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetExpiredMark(nsMsgKey *result)
|
||||
{
|
||||
*result = m_expiredMark;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The size of the argument depends on the maximum size of a single message
|
||||
NS_IMETHODIMP nsDBFolderInfo::ChangeExpungedBytes(int32_t delta)
|
||||
{
|
||||
return SetExpungedBytes(m_expungedBytes + delta);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetMailboxName(const nsAString &newBoxName)
|
||||
{
|
||||
return SetPropertyWithToken(m_mailboxNameColumnToken, newBoxName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetMailboxName(nsAString &boxName)
|
||||
{
|
||||
return GetPropertyWithToken(m_mailboxNameColumnToken, boxName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::ChangeNumUnreadMessages(int32_t delta)
|
||||
{
|
||||
m_numUnreadMessages += delta;
|
||||
// m_numUnreadMessages can never be set to negative.
|
||||
if (m_numUnreadMessages < 0)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu1
|
||||
NS_ASSERTION(false, "Hardcoded assertion");
|
||||
#endif
|
||||
m_numUnreadMessages = 0;
|
||||
}
|
||||
return SetUint32PropertyWithToken(m_numUnreadMessagesColumnToken, m_numUnreadMessages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::ChangeNumMessages(int32_t delta)
|
||||
{
|
||||
m_numMessages += delta;
|
||||
// m_numMessages can never be set to negative.
|
||||
if (m_numMessages < 0)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu
|
||||
NS_ASSERTION(false, "num messages can't be < 0");
|
||||
#endif
|
||||
m_numMessages = 0;
|
||||
}
|
||||
return SetUint32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetNumUnreadMessages(int32_t *result)
|
||||
{
|
||||
*result = m_numUnreadMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetNumUnreadMessages(int32_t numUnreadMessages)
|
||||
{
|
||||
m_numUnreadMessages = numUnreadMessages;
|
||||
return SetUint32PropertyWithToken(m_numUnreadMessagesColumnToken, m_numUnreadMessages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetNumMessages(int32_t *result)
|
||||
{
|
||||
*result = m_numMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetNumMessages(int32_t numMessages)
|
||||
{
|
||||
m_numMessages = numMessages;
|
||||
return SetUint32PropertyWithToken(m_numMessagesColumnToken, m_numMessages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetExpungedBytes(int64_t *result)
|
||||
{
|
||||
*result = m_expungedBytes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetExpungedBytes(int64_t expungedBytes)
|
||||
{
|
||||
m_expungedBytes = expungedBytes;
|
||||
return SetInt64PropertyWithToken(m_expungedBytesColumnToken, m_expungedBytes);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetFlags(int32_t *result)
|
||||
{
|
||||
*result = m_flags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetFlags(int32_t flags)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
|
||||
if (m_flags != flags)
|
||||
{
|
||||
NS_ASSERTION((m_flags & nsMsgFolderFlags::Inbox) == 0 || (flags & nsMsgFolderFlags::Inbox) != 0, "lost inbox flag");
|
||||
m_flags = flags;
|
||||
ret = SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::OrFlags(int32_t flags, int32_t *result)
|
||||
{
|
||||
m_flags |= flags;
|
||||
*result = m_flags;
|
||||
return SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::AndFlags(int32_t flags, int32_t *result)
|
||||
{
|
||||
m_flags &= flags;
|
||||
*result = m_flags;
|
||||
return SetInt32PropertyWithToken(m_flagsColumnToken, m_flags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetImapUidValidity(int32_t *result)
|
||||
{
|
||||
*result = m_ImapUidValidity;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetImapUidValidity(int32_t uidValidity)
|
||||
{
|
||||
m_ImapUidValidity = uidValidity;
|
||||
return SetUint32PropertyWithToken(m_imapUidValidityColumnToken, m_ImapUidValidity);
|
||||
}
|
||||
|
||||
bool nsDBFolderInfo::TestFlag(int32_t flags)
|
||||
{
|
||||
return (m_flags & flags) != 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetCharacterSet(nsACString &result)
|
||||
{
|
||||
if (!m_charSet.IsEmpty())
|
||||
result.Assign(m_charSet);
|
||||
else if (gDefaultCharacterSet)
|
||||
result.Assign(*gDefaultCharacterSet);
|
||||
else
|
||||
result.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetEffectiveCharacterSet(nsACString &result)
|
||||
{
|
||||
result.Truncate();
|
||||
if (NS_FAILED(GetCharProperty(kCharacterSetColumnName, result)) ||
|
||||
(result.IsEmpty() && gDefaultCharacterSet))
|
||||
result = *gDefaultCharacterSet;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetCharacterSet(const nsACString &charSet)
|
||||
{
|
||||
m_charSet.Assign(charSet);
|
||||
return SetCharProperty(kCharacterSetColumnName, charSet);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetCharacterSetOverride(bool *characterSetOverride)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(characterSetOverride);
|
||||
*characterSetOverride = m_charSetOverride;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetCharacterSetOverride(bool characterSetOverride)
|
||||
{
|
||||
m_charSetOverride = characterSetOverride;
|
||||
return SetUint32Property(kCharacterSetOverrideColumnName, characterSetOverride);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetLocale(nsAString &result)
|
||||
{
|
||||
GetProperty(kLocaleColumnName, result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetLocale(const nsAString &locale)
|
||||
{
|
||||
return SetProperty(kLocaleColumnName, locale);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetImapTotalPendingMessages(int32_t *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = m_totalPendingMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDBFolderInfo::ChangeImapTotalPendingMessages(int32_t delta)
|
||||
{
|
||||
m_totalPendingMessages+=delta;
|
||||
SetInt32PropertyWithToken(m_totalPendingMessagesColumnToken, m_totalPendingMessages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDBFolderInfo::GetImapUnreadPendingMessages(int32_t *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = m_unreadPendingMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetImapUnreadPendingMessages(int32_t numUnreadPendingMessages)
|
||||
{
|
||||
m_unreadPendingMessages = numUnreadPendingMessages;
|
||||
return SetUint32PropertyWithToken(m_unreadPendingMessagesColumnToken, m_unreadPendingMessages);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetImapTotalPendingMessages(int32_t numTotalPendingMessages)
|
||||
{
|
||||
m_totalPendingMessages = numTotalPendingMessages;
|
||||
return SetUint32PropertyWithToken(m_totalPendingMessagesColumnToken, m_totalPendingMessages);
|
||||
}
|
||||
|
||||
void nsDBFolderInfo::ChangeImapUnreadPendingMessages(int32_t delta)
|
||||
{
|
||||
m_unreadPendingMessages+=delta;
|
||||
SetInt32PropertyWithToken(m_unreadPendingMessagesColumnToken, m_unreadPendingMessages);
|
||||
}
|
||||
|
||||
/* attribute nsMsgViewTypeValue viewType; */
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetViewType(nsMsgViewTypeValue *aViewType)
|
||||
{
|
||||
uint32_t viewTypeValue;
|
||||
nsresult rv = GetUint32Property("viewType", nsMsgViewType::eShowAllThreads, &viewTypeValue);
|
||||
*aViewType = viewTypeValue;
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetViewType(nsMsgViewTypeValue aViewType)
|
||||
{
|
||||
return SetUint32Property("viewType", aViewType);
|
||||
}
|
||||
|
||||
/* attribute nsMsgViewFlagsTypeValue viewFlags; */
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetViewFlags(nsMsgViewFlagsTypeValue *aViewFlags)
|
||||
{
|
||||
nsMsgViewFlagsTypeValue defaultViewFlags;
|
||||
nsresult rv = m_mdb->GetDefaultViewFlags(&defaultViewFlags);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
uint32_t viewFlagsValue;
|
||||
rv = GetUint32Property("viewFlags", defaultViewFlags, &viewFlagsValue);
|
||||
*aViewFlags = viewFlagsValue;
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetViewFlags(nsMsgViewFlagsTypeValue aViewFlags)
|
||||
{
|
||||
return SetUint32Property("viewFlags", aViewFlags);
|
||||
}
|
||||
|
||||
/* attribute nsMsgViewSortTypeValue sortType; */
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetSortType(nsMsgViewSortTypeValue *aSortType)
|
||||
{
|
||||
nsMsgViewSortTypeValue defaultSortType;
|
||||
nsresult rv = m_mdb->GetDefaultSortType(&defaultSortType);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
uint32_t sortTypeValue;
|
||||
rv = GetUint32Property("sortType", defaultSortType, &sortTypeValue);
|
||||
*aSortType = sortTypeValue;
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetSortType(nsMsgViewSortTypeValue aSortType)
|
||||
{
|
||||
return SetUint32Property("sortType", aSortType);
|
||||
}
|
||||
|
||||
/* attribute nsMsgViewSortOrderValue sortOrder; */
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetSortOrder(nsMsgViewSortOrderValue *aSortOrder)
|
||||
{
|
||||
nsMsgViewSortOrderValue defaultSortOrder;
|
||||
nsresult rv = m_mdb->GetDefaultSortOrder(&defaultSortOrder);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
uint32_t sortOrderValue;
|
||||
rv = GetUint32Property("sortOrder", defaultSortOrder, &sortOrderValue);
|
||||
*aSortOrder = sortOrderValue;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetSortOrder(nsMsgViewSortOrderValue aSortOrder)
|
||||
{
|
||||
return SetUint32Property("sortOrder", aSortOrder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetKnownArtsSet(const char *newsArtSet)
|
||||
{
|
||||
return m_mdb->SetProperty(m_mdbRow, kKnownArtsSetColumnName, newsArtSet);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetKnownArtsSet(char **newsArtSet)
|
||||
{
|
||||
return m_mdb->GetProperty(m_mdbRow, kKnownArtsSetColumnName, newsArtSet);
|
||||
}
|
||||
|
||||
// get arbitrary property, aka row cell value.
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetProperty(const char *propertyName, nsAString &resultProperty)
|
||||
{
|
||||
return m_mdb->GetPropertyAsNSString(m_mdbRow, propertyName, resultProperty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetCharProperty(const char *aPropertyName,
|
||||
const nsACString &aPropertyValue)
|
||||
{
|
||||
return m_mdb->SetProperty(m_mdbRow, aPropertyName,
|
||||
nsCString(aPropertyValue).get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetCharProperty(const char *propertyName,
|
||||
nsACString &resultProperty)
|
||||
{
|
||||
nsCString result;
|
||||
nsresult rv = m_mdb->GetProperty(m_mdbRow, propertyName, getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
resultProperty.Assign(result);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetUint32Property(const char *propertyName, uint32_t propertyValue)
|
||||
{
|
||||
return m_mdb->SetUint32Property(m_mdbRow, propertyName, propertyValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetInt64Property(const char *propertyName, int64_t propertyValue)
|
||||
{
|
||||
return m_mdb->SetUint64Property(m_mdbRow, propertyName, (uint64_t) propertyValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetProperty(const char *propertyName, const nsAString &propertyStr)
|
||||
{
|
||||
return m_mdb->SetPropertyFromNSString(m_mdbRow, propertyName, propertyStr);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::SetPropertyWithToken(mdb_token aProperty, const nsAString &propertyStr)
|
||||
{
|
||||
return m_mdb->SetNSStringPropertyWithToken(m_mdbRow, aProperty, propertyStr);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::SetUint32PropertyWithToken(mdb_token aProperty, uint32_t propertyValue)
|
||||
{
|
||||
return m_mdb->UInt32ToRowCellColumn(m_mdbRow, aProperty, propertyValue);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::SetInt64PropertyWithToken(mdb_token aProperty, int64_t propertyValue)
|
||||
{
|
||||
return m_mdb->UInt64ToRowCellColumn(m_mdbRow, aProperty, (uint64_t) propertyValue);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::SetInt32PropertyWithToken(mdb_token aProperty, int32_t propertyValue)
|
||||
{
|
||||
nsAutoString propertyStr;
|
||||
propertyStr.AppendInt(propertyValue, 16);
|
||||
return SetPropertyWithToken(aProperty, propertyStr);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::GetPropertyWithToken(mdb_token aProperty, nsAString &resultProperty)
|
||||
{
|
||||
return m_mdb->RowCellColumnTonsString(m_mdbRow, aProperty, resultProperty);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::GetUint32PropertyWithToken(mdb_token aProperty, uint32_t &propertyValue, uint32_t defaultValue)
|
||||
{
|
||||
return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, propertyValue, defaultValue);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::GetInt32PropertyWithToken(mdb_token aProperty, int32_t &propertyValue, int32_t defaultValue)
|
||||
{
|
||||
return m_mdb->RowCellColumnToUInt32(m_mdbRow, aProperty, (uint32_t &) propertyValue, defaultValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetUint32Property(const char *propertyName, uint32_t defaultValue, uint32_t *propertyValue)
|
||||
{
|
||||
return m_mdb->GetUint32Property(m_mdbRow, propertyName, propertyValue, defaultValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetInt64Property(const char *propertyName, int64_t defaultValue, int64_t *propertyValue)
|
||||
{
|
||||
return m_mdb->GetUint64Property(m_mdbRow, propertyName, (uint64_t *) &propertyValue, defaultValue);
|
||||
}
|
||||
|
||||
nsresult nsDBFolderInfo::GetInt64PropertyWithToken(mdb_token aProperty,
|
||||
int64_t &propertyValue,
|
||||
int64_t defaultValue)
|
||||
{
|
||||
return m_mdb->RowCellColumnToUInt64(m_mdbRow, aProperty, (uint64_t *) &propertyValue, defaultValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetBooleanProperty(const char *propertyName, bool defaultValue, bool *propertyValue)
|
||||
{
|
||||
uint32_t defaultUint32Value = (defaultValue) ? 1 : 0;
|
||||
uint32_t returnValue;
|
||||
nsresult rv = m_mdb->GetUint32Property(m_mdbRow, propertyName, &returnValue, defaultUint32Value);
|
||||
*propertyValue = (returnValue != 0);
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetBooleanProperty(const char *propertyName, bool propertyValue)
|
||||
{
|
||||
return m_mdb->SetUint32Property(m_mdbRow, propertyName, propertyValue ? 1 : 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetFolderName(nsACString &folderName)
|
||||
{
|
||||
return GetCharProperty("folderName", folderName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDBFolderInfo::SetFolderName(const nsACString &folderName)
|
||||
{
|
||||
return SetCharProperty("folderName", folderName);
|
||||
}
|
||||
|
||||
class nsTransferDBFolderInfo : public nsDBFolderInfo
|
||||
{
|
||||
public:
|
||||
nsTransferDBFolderInfo();
|
||||
virtual ~nsTransferDBFolderInfo();
|
||||
// parallel arrays of properties and values
|
||||
nsTArray<nsCString> m_properties;
|
||||
nsTArray<nsCString> m_values;
|
||||
};
|
||||
|
||||
nsTransferDBFolderInfo::nsTransferDBFolderInfo() : nsDBFolderInfo(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsTransferDBFolderInfo::~nsTransferDBFolderInfo()
|
||||
{
|
||||
}
|
||||
|
||||
/* void GetTransferInfo (out nsIDBFolderInfo transferInfo); */
|
||||
NS_IMETHODIMP nsDBFolderInfo::GetTransferInfo(nsIDBFolderInfo **transferInfo)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(transferInfo);
|
||||
|
||||
nsTransferDBFolderInfo *newInfo = new nsTransferDBFolderInfo;
|
||||
*transferInfo = newInfo;
|
||||
NS_ADDREF(newInfo);
|
||||
|
||||
mdb_count numCells;
|
||||
mdbYarn cellYarn;
|
||||
mdb_column cellColumn;
|
||||
char columnName[100];
|
||||
mdbYarn cellName = { columnName, 0, sizeof(columnName), 0, 0, nullptr };
|
||||
|
||||
NS_ASSERTION(m_mdbRow, "null row in getTransferInfo");
|
||||
m_mdbRow->GetCount(m_mdb->GetEnv(), &numCells);
|
||||
// iterate over the cells in the dbfolderinfo remembering attribute names and values.
|
||||
for (mdb_count cellIndex = 0; cellIndex < numCells; cellIndex++)
|
||||
{
|
||||
nsresult err = m_mdbRow->SeekCellYarn(m_mdb->GetEnv(), cellIndex, &cellColumn, nullptr);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
err = m_mdbRow->AliasCellYarn(m_mdb->GetEnv(), cellColumn, &cellYarn);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
m_mdb->GetStore()->TokenToString(m_mdb->GetEnv(), cellColumn, &cellName);
|
||||
newInfo->m_values.AppendElement(Substring((const char *)cellYarn.mYarn_Buf,
|
||||
(const char *) cellYarn.mYarn_Buf + cellYarn.mYarn_Fill));
|
||||
newInfo->m_properties.AppendElement(Substring((const char *) cellName.mYarn_Buf,
|
||||
(const char *) cellName.mYarn_Buf + cellName.mYarn_Fill));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* void InitFromTransferInfo (in nsIDBFolderInfo transferInfo); */
|
||||
NS_IMETHODIMP nsDBFolderInfo::InitFromTransferInfo(nsIDBFolderInfo *aTransferInfo)
|
||||
{
|
||||
NS_ENSURE_ARG(aTransferInfo);
|
||||
|
||||
nsTransferDBFolderInfo *transferInfo = static_cast<nsTransferDBFolderInfo *>(aTransferInfo);
|
||||
|
||||
for (uint32_t i = 0; i < transferInfo->m_values.Length(); i++)
|
||||
SetCharProperty(transferInfo->m_properties[i].get(), transferInfo->m_values[i]);
|
||||
|
||||
LoadMemberVariables();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
249
mailnews/db/msgdb/src/nsImapMailDatabase.cpp
Normal file
249
mailnews/db/msgdb/src/nsImapMailDatabase.cpp
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsImapMailDatabase.h"
|
||||
#include "nsDBFolderInfo.h"
|
||||
|
||||
const char *kPendingHdrsScope = "ns:msg:db:row:scope:pending:all"; // scope for all offine ops table
|
||||
const char *kPendingHdrsTableKind = "ns:msg:db:table:kind:pending";
|
||||
struct mdbOid gAllPendingHdrsTableOID;
|
||||
|
||||
nsImapMailDatabase::nsImapMailDatabase()
|
||||
{
|
||||
m_mdbAllPendingHdrsTable = nullptr;
|
||||
}
|
||||
|
||||
nsImapMailDatabase::~nsImapMailDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::GetSummaryValid(bool *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
if (m_dbFolderInfo)
|
||||
{
|
||||
uint32_t version;
|
||||
m_dbFolderInfo->GetVersion(&version);
|
||||
*aResult = (GetCurVersion() == version);
|
||||
}
|
||||
else
|
||||
*aResult = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::SetSummaryValid(bool valid)
|
||||
{
|
||||
if (m_dbFolderInfo)
|
||||
{
|
||||
m_dbFolderInfo->SetVersion(valid ? GetCurVersion() : 0);
|
||||
Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// IMAP does not set local file flags, override does nothing
|
||||
void nsImapMailDatabase::UpdateFolderFlag(nsIMsgDBHdr * /* msgHdr */, bool /* bSet */,
|
||||
nsMsgMessageFlagType /* flag */, nsIOutputStream ** /* ppFileStream */)
|
||||
{
|
||||
}
|
||||
|
||||
// We override this to avoid our parent class (nsMailDatabase)'s
|
||||
// grabbing of the folder semaphore, and bailing on failure.
|
||||
NS_IMETHODIMP nsImapMailDatabase::DeleteMessages(uint32_t aNumKeys, nsMsgKey* nsMsgKeys, nsIDBChangeListener *instigator)
|
||||
{
|
||||
return nsMsgDatabase::DeleteMessages(aNumKeys, nsMsgKeys, instigator);
|
||||
}
|
||||
|
||||
// override so nsMailDatabase methods that deal with m_folderStream are *not* called
|
||||
NS_IMETHODIMP nsImapMailDatabase::StartBatch()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::EndBatch()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsImapMailDatabase::AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr)
|
||||
{
|
||||
uint32_t msgFlags;
|
||||
msgHdr->GetFlags(&msgFlags);
|
||||
if (msgFlags & nsMsgMessageFlags::Offline && m_dbFolderInfo)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
(void)msgHdr->GetOfflineMessageSize(&size);
|
||||
return m_dbFolderInfo->ChangeExpungedBytes (size);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::ForceClosed()
|
||||
{
|
||||
m_mdbAllPendingHdrsTable = nullptr;
|
||||
return nsMailDatabase::ForceClosed();
|
||||
}
|
||||
|
||||
nsresult nsImapMailDatabase::GetAllPendingHdrsTable()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!m_mdbAllPendingHdrsTable)
|
||||
rv = GetTableCreateIfMissing(kPendingHdrsScope, kPendingHdrsTableKind, getter_AddRefs(m_mdbAllPendingHdrsTable),
|
||||
m_pendingHdrsRowScopeToken, m_pendingHdrsTableKindToken) ;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::AddNewHdrToDB(nsIMsgDBHdr *newHdr, bool notify)
|
||||
{
|
||||
nsresult rv = nsMsgDatabase::AddNewHdrToDB(newHdr, notify);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = UpdatePendingAttributes(newHdr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::UpdatePendingAttributes(nsIMsgDBHdr* aNewHdr)
|
||||
{
|
||||
nsresult rv = GetAllPendingHdrsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mdb_count numPendingHdrs = 0;
|
||||
m_mdbAllPendingHdrsTable->GetCount(GetEnv(), &numPendingHdrs);
|
||||
if (numPendingHdrs > 0)
|
||||
{
|
||||
mdbYarn messageIdYarn;
|
||||
nsCOMPtr <nsIMdbRow> pendingRow;
|
||||
mdbOid outRowId;
|
||||
|
||||
nsCString messageId;
|
||||
aNewHdr->GetMessageId(getter_Copies(messageId));
|
||||
messageIdYarn.mYarn_Buf = (void*)messageId.get();
|
||||
messageIdYarn.mYarn_Fill = messageId.Length();
|
||||
messageIdYarn.mYarn_Form = 0;
|
||||
messageIdYarn.mYarn_Size = messageIdYarn.mYarn_Fill;
|
||||
|
||||
m_mdbStore->FindRow(GetEnv(), m_pendingHdrsRowScopeToken,
|
||||
m_messageIdColumnToken, &messageIdYarn, &outRowId, getter_AddRefs(pendingRow));
|
||||
if (pendingRow)
|
||||
{
|
||||
mdb_count numCells;
|
||||
mdbYarn cellYarn;
|
||||
mdb_column cellColumn;
|
||||
uint32_t existingFlags;
|
||||
|
||||
pendingRow->GetCount(GetEnv(), &numCells);
|
||||
aNewHdr->GetFlags(&existingFlags);
|
||||
// iterate over the cells in the pending hdr setting properties on the aNewHdr.
|
||||
// we skip cell 0, which is the messageId;
|
||||
nsMsgHdr* msgHdr = static_cast<nsMsgHdr*>(aNewHdr); // closed system, cast ok
|
||||
nsIMdbRow *row = msgHdr->GetMDBRow();
|
||||
for (mdb_count cellIndex = 1; cellIndex < numCells; cellIndex++)
|
||||
{
|
||||
nsresult err = pendingRow->SeekCellYarn(GetEnv(), cellIndex, &cellColumn, nullptr);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
err = pendingRow->AliasCellYarn(GetEnv(), cellColumn, &cellYarn);
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
if (row)
|
||||
row->AddColumn(GetEnv(), cellColumn, &cellYarn);
|
||||
}
|
||||
}
|
||||
}
|
||||
// We might have changed some cached values, so force a refresh.
|
||||
msgHdr->ClearCachedValues();
|
||||
uint32_t resultFlags;
|
||||
msgHdr->OrFlags(existingFlags, &resultFlags);
|
||||
m_mdbAllPendingHdrsTable->CutRow(GetEnv(), pendingRow);
|
||||
pendingRow->CutAllColumns(GetEnv());
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsImapMailDatabase::GetRowForPendingHdr(nsIMsgDBHdr *pendingHdr,
|
||||
nsIMdbRow **row)
|
||||
{
|
||||
nsresult rv = GetAllPendingHdrsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mdbYarn messageIdYarn;
|
||||
nsCOMPtr<nsIMdbRow> pendingRow;
|
||||
mdbOid outRowId;
|
||||
nsCString messageId;
|
||||
pendingHdr->GetMessageId(getter_Copies(messageId));
|
||||
messageIdYarn.mYarn_Buf = (void*)messageId.get();
|
||||
messageIdYarn.mYarn_Fill = messageId.Length();
|
||||
messageIdYarn.mYarn_Form = 0;
|
||||
messageIdYarn.mYarn_Size = messageIdYarn.mYarn_Fill;
|
||||
|
||||
rv = m_mdbStore->FindRow(GetEnv(), m_pendingHdrsRowScopeToken,
|
||||
m_messageIdColumnToken, &messageIdYarn, &outRowId, getter_AddRefs(pendingRow));
|
||||
|
||||
if (!pendingRow)
|
||||
rv = m_mdbStore->NewRow(GetEnv(), m_pendingHdrsRowScopeToken, getter_AddRefs(pendingRow));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (pendingRow)
|
||||
{
|
||||
// now we need to add cells to the row to remember the messageid, property and property value, and flags.
|
||||
// Then, when hdrs are added to the db, we'll check if they have a matching message-id, and if so,
|
||||
// set the property and flags
|
||||
// XXX we already fetched messageId from the pending hdr, could it have changed by the time we get here?
|
||||
nsCString messageId;
|
||||
pendingHdr->GetMessageId(getter_Copies(messageId));
|
||||
// we're just going to ignore messages without a message-id. They should be rare. If SPAM messages often
|
||||
// didn't have message-id's, they'd be filtered on the server, most likely, and spammers would then
|
||||
// start putting in message-id's.
|
||||
if (!messageId.IsEmpty())
|
||||
{
|
||||
extern const char *kMessageIdColumnName;
|
||||
m_mdbAllPendingHdrsTable->AddRow(GetEnv(), pendingRow);
|
||||
// make sure this is the first cell so that when we ignore the first
|
||||
// cell in nsImapMailDatabase::AddNewHdrToDB, we're ignoring the right one
|
||||
(void) SetProperty(pendingRow, kMessageIdColumnName, messageId.get());
|
||||
pendingRow.forget(row);
|
||||
}
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailDatabase::SetAttributeOnPendingHdr(nsIMsgDBHdr *pendingHdr, const char *property,
|
||||
const char *propertyVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(pendingHdr);
|
||||
nsCOMPtr<nsIMdbRow> pendingRow;
|
||||
nsresult rv = GetRowForPendingHdr(pendingHdr, getter_AddRefs(pendingRow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return SetProperty(pendingRow, property, propertyVal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapMailDatabase::SetUint32AttributeOnPendingHdr(nsIMsgDBHdr *pendingHdr,
|
||||
const char *property,
|
||||
uint32_t propertyVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(pendingHdr);
|
||||
nsCOMPtr<nsIMdbRow> pendingRow;
|
||||
nsresult rv = GetRowForPendingHdr(pendingHdr, getter_AddRefs(pendingRow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return SetUint32Property(pendingRow, property, propertyVal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapMailDatabase::SetUint64AttributeOnPendingHdr(nsIMsgDBHdr *aPendingHdr,
|
||||
const char *aProperty,
|
||||
uint64_t aPropertyVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPendingHdr);
|
||||
nsCOMPtr<nsIMdbRow> pendingRow;
|
||||
nsresult rv = GetRowForPendingHdr(aPendingHdr, getter_AddRefs(pendingRow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return SetUint64Property(pendingRow, aProperty, aPropertyVal);
|
||||
}
|
||||
444
mailnews/db/msgdb/src/nsMailDatabase.cpp
Normal file
444
mailnews/db/msgdb/src/nsMailDatabase.cpp
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsMailDatabase.h"
|
||||
#include "nsDBFolderInfo.h"
|
||||
#include "nsMsgLocalFolderHdrs.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsMsgOfflineImapOperation.h"
|
||||
#include "nsMsgFolderFlags.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "prprf.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsIMsgPluggableStore.h"
|
||||
|
||||
extern PRLogModuleInfo *IMAPOffline;
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// scope for all offine ops table
|
||||
const char *kOfflineOpsScope = "ns:msg:db:row:scope:ops:all";
|
||||
const char *kOfflineOpsTableKind = "ns:msg:db:table:kind:ops";
|
||||
struct mdbOid gAllOfflineOpsTableOID;
|
||||
|
||||
nsMailDatabase::nsMailDatabase() : m_reparse(false)
|
||||
{
|
||||
m_mdbAllOfflineOpsTable = nullptr;
|
||||
m_offlineOpsRowScopeToken = 0;
|
||||
m_offlineOpsTableKindToken = 0;
|
||||
}
|
||||
|
||||
nsMailDatabase::~nsMailDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
// caller passes in upgrading==true if they want back a db even if the db is out of date.
|
||||
// If so, they'll extract out the interesting info from the db, close it, delete it, and
|
||||
// then try to open the db again, prior to reparsing.
|
||||
nsresult nsMailDatabase::Open(nsMsgDBService* aDBService, nsIFile *aSummaryFile,
|
||||
bool aCreate, bool aUpgrading)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsString leafName;
|
||||
aSummaryFile->GetLeafName(leafName);
|
||||
if (!StringEndsWith(leafName, NS_LITERAL_STRING(".msf"),
|
||||
nsCaseInsensitiveStringComparator()))
|
||||
NS_ERROR("non summary file passed into open\n");
|
||||
#endif
|
||||
return nsMsgDatabase::Open(aDBService, aSummaryFile, aCreate, aUpgrading);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::ForceClosed()
|
||||
{
|
||||
m_mdbAllOfflineOpsTable = nullptr;
|
||||
return nsMsgDatabase::ForceClosed();
|
||||
}
|
||||
|
||||
// get this on demand so that only db's that have offline ops will
|
||||
// create the table.
|
||||
nsresult nsMailDatabase::GetAllOfflineOpsTable()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!m_mdbAllOfflineOpsTable)
|
||||
rv = GetTableCreateIfMissing(kOfflineOpsScope, kOfflineOpsTableKind, getter_AddRefs(m_mdbAllOfflineOpsTable),
|
||||
m_offlineOpsRowScopeToken, m_offlineOpsTableKindToken) ;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::StartBatch()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::EndBatch()
|
||||
{
|
||||
SetSummaryValid(true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::DeleteMessages(uint32_t aNumKeys, nsMsgKey* nsMsgKeys, nsIDBChangeListener *instigator)
|
||||
{
|
||||
nsresult rv;
|
||||
if (m_folder)
|
||||
{
|
||||
bool isLocked;
|
||||
m_folder->GetLocked(&isLocked);
|
||||
if (isLocked)
|
||||
{
|
||||
NS_ASSERTION(false, "Some other operation is in progress");
|
||||
return NS_MSG_FOLDER_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
rv = nsMsgDatabase::DeleteMessages(aNumKeys, nsMsgKeys, instigator);
|
||||
SetSummaryValid(true);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::GetSummaryValid(bool *aResult)
|
||||
{
|
||||
uint32_t version;
|
||||
m_dbFolderInfo->GetVersion(&version);
|
||||
if (GetCurVersion() != version)
|
||||
{
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIMsgPluggableStore> msgStore;
|
||||
if (!m_folder) {
|
||||
// If the folder is not set, we just return without checking the validity
|
||||
// of the summary file. For now, this is an expected condition when the
|
||||
// message database is being opened from a URL in
|
||||
// nsMailboxUrl::GetMsgHdrForKey() which calls
|
||||
// nsMsgDBService::OpenMailDBFromFile() without a folder.
|
||||
// Returning an error here would lead to the deletion of the MSF in the
|
||||
// caller nsMsgDatabase::CheckForErrors().
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = m_folder->GetMsgStore(getter_AddRefs(msgStore));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return msgStore->IsSummaryFileValid(m_folder, this, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::SetSummaryValid(bool aValid)
|
||||
{
|
||||
nsMsgDatabase::SetSummaryValid(aValid);
|
||||
|
||||
if (!m_folder)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// If this is a virtual folder, there is no storage.
|
||||
bool flag;
|
||||
m_folder->GetFlag(nsMsgFolderFlags::Virtual, &flag);
|
||||
if (flag)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIMsgPluggableStore> msgStore;
|
||||
nsresult rv = m_folder->GetMsgStore(getter_AddRefs(msgStore));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return msgStore->SetSummaryFileValid(m_folder, this, aValid);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::RemoveOfflineOp(nsIMsgOfflineImapOperation *op)
|
||||
{
|
||||
|
||||
nsresult rv = GetAllOfflineOpsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!op || !m_mdbAllOfflineOpsTable)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsMsgOfflineImapOperation* offlineOp = static_cast<nsMsgOfflineImapOperation*>(op); // closed system, so this is ok
|
||||
nsIMdbRow* row = offlineOp->GetMDBRow();
|
||||
rv = m_mdbAllOfflineOpsTable->CutRow(GetEnv(), row);
|
||||
row->CutAllColumns(GetEnv());
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::GetOfflineOpForKey(nsMsgKey msgKey, bool create, nsIMsgOfflineImapOperation **offlineOp)
|
||||
{
|
||||
mdb_bool hasOid;
|
||||
mdbOid rowObjectId;
|
||||
nsresult err;
|
||||
|
||||
if (!IMAPOffline)
|
||||
IMAPOffline = PR_NewLogModule("IMAPOFFLINE");
|
||||
nsresult rv = GetAllOfflineOpsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!offlineOp || !m_mdbAllOfflineOpsTable)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*offlineOp = NULL;
|
||||
|
||||
rowObjectId.mOid_Id = msgKey;
|
||||
rowObjectId.mOid_Scope = m_offlineOpsRowScopeToken;
|
||||
err = m_mdbAllOfflineOpsTable->HasOid(GetEnv(), &rowObjectId, &hasOid);
|
||||
if (NS_SUCCEEDED(err) && m_mdbStore && (hasOid || create))
|
||||
{
|
||||
nsCOMPtr <nsIMdbRow> offlineOpRow;
|
||||
err = m_mdbStore->GetRow(GetEnv(), &rowObjectId, getter_AddRefs(offlineOpRow));
|
||||
|
||||
if (create)
|
||||
{
|
||||
if (!offlineOpRow)
|
||||
{
|
||||
err = m_mdbStore->NewRowWithOid(GetEnv(), &rowObjectId, getter_AddRefs(offlineOpRow));
|
||||
NS_ENSURE_SUCCESS(err, err);
|
||||
}
|
||||
if (offlineOpRow && !hasOid)
|
||||
m_mdbAllOfflineOpsTable->AddRow(GetEnv(), offlineOpRow);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(err) && offlineOpRow)
|
||||
{
|
||||
*offlineOp = new nsMsgOfflineImapOperation(this, offlineOpRow);
|
||||
if (*offlineOp)
|
||||
(*offlineOp)->SetMessageKey(msgKey);
|
||||
NS_IF_ADDREF(*offlineOp);
|
||||
}
|
||||
if (!hasOid && m_dbFolderInfo)
|
||||
{
|
||||
// set initial value for flags so we don't lose them.
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
GetMsgHdrForKey(msgKey, getter_AddRefs(msgHdr));
|
||||
if (msgHdr)
|
||||
{
|
||||
uint32_t flags;
|
||||
msgHdr->GetFlags(&flags);
|
||||
(*offlineOp)->SetNewFlags(flags);
|
||||
}
|
||||
int32_t newFlags;
|
||||
m_dbFolderInfo->OrFlags(nsMsgFolderFlags::OfflineEvents, &newFlags);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::EnumerateOfflineOps(nsISimpleEnumerator **enumerator)
|
||||
{
|
||||
NS_ASSERTION(false, "not impl yet");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::ListAllOfflineOpIds(nsTArray<nsMsgKey> *offlineOpIds)
|
||||
{
|
||||
NS_ENSURE_ARG(offlineOpIds);
|
||||
nsresult rv = GetAllOfflineOpsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIMdbTableRowCursor *rowCursor;
|
||||
if (!IMAPOffline)
|
||||
IMAPOffline = PR_NewLogModule("IMAPOFFLINE");
|
||||
|
||||
if (m_mdbAllOfflineOpsTable)
|
||||
{
|
||||
nsresult err = m_mdbAllOfflineOpsTable->GetTableRowCursor(GetEnv(), -1, &rowCursor);
|
||||
while (NS_SUCCEEDED(err) && rowCursor)
|
||||
{
|
||||
mdbOid outOid;
|
||||
mdb_pos outPos;
|
||||
|
||||
err = rowCursor->NextRowOid(GetEnv(), &outOid, &outPos);
|
||||
// is this right? Mork is returning a 0 id, but that should valid.
|
||||
if (outPos < 0 || outOid.mOid_Id == (mdb_id) -1)
|
||||
break;
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
offlineOpIds->AppendElement(outOid.mOid_Id);
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
{
|
||||
nsCOMPtr <nsIMsgOfflineImapOperation> offlineOp;
|
||||
GetOfflineOpForKey(outOid.mOid_Id, false, getter_AddRefs(offlineOp));
|
||||
if (offlineOp)
|
||||
{
|
||||
nsMsgOfflineImapOperation *logOp = static_cast<nsMsgOfflineImapOperation *>(static_cast<nsIMsgOfflineImapOperation *>(offlineOp.get()));
|
||||
if (logOp)
|
||||
logOp->Log(IMAPOffline);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: would it cause a problem to replace this with "rv = err;" ?
|
||||
rv = (NS_SUCCEEDED(err)) ? NS_OK : NS_ERROR_FAILURE;
|
||||
rowCursor->Release();
|
||||
}
|
||||
|
||||
offlineOpIds->Sort();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailDatabase::ListAllOfflineDeletes(nsTArray<nsMsgKey> *offlineDeletes)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(offlineDeletes);
|
||||
|
||||
nsresult rv = GetAllOfflineOpsTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIMdbTableRowCursor *rowCursor;
|
||||
if (m_mdbAllOfflineOpsTable)
|
||||
{
|
||||
nsresult err = m_mdbAllOfflineOpsTable->GetTableRowCursor(GetEnv(), -1, &rowCursor);
|
||||
while (NS_SUCCEEDED(err) && rowCursor)
|
||||
{
|
||||
mdbOid outOid;
|
||||
mdb_pos outPos;
|
||||
nsIMdbRow* offlineOpRow;
|
||||
|
||||
err = rowCursor->NextRow(GetEnv(), &offlineOpRow, &outPos);
|
||||
// is this right? Mork is returning a 0 id, but that should valid.
|
||||
if (outPos < 0 || offlineOpRow == nullptr)
|
||||
break;
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
offlineOpRow->GetOid(GetEnv(), &outOid);
|
||||
nsIMsgOfflineImapOperation *offlineOp = new nsMsgOfflineImapOperation(this, offlineOpRow);
|
||||
if (offlineOp)
|
||||
{
|
||||
NS_ADDREF(offlineOp);
|
||||
imapMessageFlagsType newFlags;
|
||||
nsOfflineImapOperationType opType;
|
||||
|
||||
offlineOp->GetOperation(&opType);
|
||||
offlineOp->GetNewFlags(&newFlags);
|
||||
if (opType & nsIMsgOfflineImapOperation::kMsgMoved ||
|
||||
((opType & nsIMsgOfflineImapOperation::kFlagsChanged)
|
||||
&& (newFlags & nsIMsgOfflineImapOperation::kMsgMarkedDeleted)))
|
||||
offlineDeletes->AppendElement(outOid.mOid_Id);
|
||||
NS_RELEASE(offlineOp);
|
||||
}
|
||||
offlineOpRow->Release();
|
||||
}
|
||||
}
|
||||
// TODO: would it cause a problem to replace this with "rv = err;" ?
|
||||
rv = (NS_SUCCEEDED(err)) ? NS_OK : NS_ERROR_FAILURE;
|
||||
rowCursor->Release();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// This is used to remember that the db is out of sync with the mail folder
|
||||
// and needs to be regenerated.
|
||||
void nsMailDatabase::SetReparse(bool reparse)
|
||||
{
|
||||
m_reparse = reparse;
|
||||
}
|
||||
|
||||
class nsMsgOfflineOpEnumerator : public nsISimpleEnumerator {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISimpleEnumerator methods:
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
nsMsgOfflineOpEnumerator(nsMailDatabase* db);
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgOfflineOpEnumerator();
|
||||
nsresult GetRowCursor();
|
||||
nsresult PrefetchNext();
|
||||
nsMailDatabase* mDB;
|
||||
nsIMdbTableRowCursor* mRowCursor;
|
||||
nsCOMPtr <nsIMsgOfflineImapOperation> mResultOp;
|
||||
bool mDone;
|
||||
bool mNextPrefetched;
|
||||
};
|
||||
|
||||
nsMsgOfflineOpEnumerator::nsMsgOfflineOpEnumerator(nsMailDatabase* db)
|
||||
: mDB(db), mRowCursor(nullptr), mDone(false)
|
||||
{
|
||||
NS_ADDREF(mDB);
|
||||
mNextPrefetched = false;
|
||||
}
|
||||
|
||||
nsMsgOfflineOpEnumerator::~nsMsgOfflineOpEnumerator()
|
||||
{
|
||||
NS_IF_RELEASE(mRowCursor);
|
||||
NS_RELEASE(mDB);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMsgOfflineOpEnumerator, nsISimpleEnumerator)
|
||||
|
||||
nsresult nsMsgOfflineOpEnumerator::GetRowCursor()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
mDone = false;
|
||||
|
||||
if (!mDB || !mDB->m_mdbAllOfflineOpsTable)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = mDB->m_mdbAllOfflineOpsTable->GetTableRowCursor(mDB->GetEnv(), -1, &mRowCursor);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineOpEnumerator::GetNext(nsISupports **aItem)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aItem);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (!mNextPrefetched)
|
||||
rv = PrefetchNext();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (mResultOp)
|
||||
{
|
||||
*aItem = mResultOp;
|
||||
NS_ADDREF(*aItem);
|
||||
mNextPrefetched = false;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgOfflineOpEnumerator::PrefetchNext()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsIMdbRow* offlineOpRow;
|
||||
mdb_pos rowPos;
|
||||
|
||||
if (!mRowCursor)
|
||||
{
|
||||
rv = GetRowCursor();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = mRowCursor->NextRow(mDB->GetEnv(), &offlineOpRow, &rowPos);
|
||||
if (!offlineOpRow)
|
||||
{
|
||||
mDone = true;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
mDone = true;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIMsgOfflineImapOperation *op = new nsMsgOfflineImapOperation(mDB, offlineOpRow);
|
||||
mResultOp = op;
|
||||
if (!op)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (mResultOp)
|
||||
{
|
||||
mNextPrefetched = true;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineOpEnumerator::HasMoreElements(bool *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (!mNextPrefetched)
|
||||
PrefetchNext();
|
||||
*aResult = !mDone;
|
||||
return NS_OK;
|
||||
}
|
||||
5915
mailnews/db/msgdb/src/nsMsgDatabase.cpp
Normal file
5915
mailnews/db/msgdb/src/nsMsgDatabase.cpp
Normal file
File diff suppressed because it is too large
Load diff
1098
mailnews/db/msgdb/src/nsMsgHdr.cpp
Normal file
1098
mailnews/db/msgdb/src/nsMsgHdr.cpp
Normal file
File diff suppressed because it is too large
Load diff
378
mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp
Normal file
378
mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsMsgOfflineImapOperation.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
PRLogModuleInfo *IMAPOffline;
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS(nsMsgOfflineImapOperation, nsIMsgOfflineImapOperation)
|
||||
|
||||
// property names for offine imap operation fields.
|
||||
#define PROP_OPERATION "op"
|
||||
#define PROP_OPERATION_FLAGS "opFlags"
|
||||
#define PROP_NEW_FLAGS "newFlags"
|
||||
#define PROP_MESSAGE_KEY "msgKey"
|
||||
#define PROP_SRC_MESSAGE_KEY "srcMsgKey"
|
||||
#define PROP_SRC_FOLDER_URI "srcFolderURI"
|
||||
#define PROP_MOVE_DEST_FOLDER_URI "moveDest"
|
||||
#define PROP_NUM_COPY_DESTS "numCopyDests"
|
||||
#define PROP_COPY_DESTS "copyDests" // how to delimit these? Or should we do the "dest1","dest2" etc trick? But then we'd need to shuffle
|
||||
// them around since we delete off the front first.
|
||||
#define PROP_KEYWORD_ADD "addedKeywords"
|
||||
#define PROP_KEYWORD_REMOVE "removedKeywords"
|
||||
#define PROP_MSG_SIZE "msgSize"
|
||||
#define PROP_PLAYINGBACK "inPlayback"
|
||||
|
||||
nsMsgOfflineImapOperation::nsMsgOfflineImapOperation(nsMsgDatabase *db, nsIMdbRow *row)
|
||||
{
|
||||
NS_ASSERTION(db, "can't have null db");
|
||||
NS_ASSERTION(row, "can't have null row");
|
||||
m_operation = 0;
|
||||
m_operationFlags = 0;
|
||||
m_messageKey = nsMsgKey_None;
|
||||
m_sourceMessageKey = nsMsgKey_None;
|
||||
m_mdb = db;
|
||||
NS_ADDREF(m_mdb);
|
||||
m_mdbRow = row;
|
||||
m_newFlags = 0;
|
||||
m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION, (uint32_t *) &m_operation, 0);
|
||||
m_mdb->GetUint32Property(m_mdbRow, PROP_MESSAGE_KEY, &m_messageKey, 0);
|
||||
m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION_FLAGS, &m_operationFlags, 0);
|
||||
m_mdb->GetUint32Property(m_mdbRow, PROP_NEW_FLAGS, (uint32_t *) &m_newFlags, 0);
|
||||
}
|
||||
|
||||
nsMsgOfflineImapOperation::~nsMsgOfflineImapOperation()
|
||||
{
|
||||
// clear the row first, in case we're holding the last reference
|
||||
// to the db.
|
||||
m_mdbRow = nullptr;
|
||||
NS_IF_RELEASE(m_mdb);
|
||||
}
|
||||
|
||||
/* attribute nsOfflineImapOperationType operation; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetOperation(nsOfflineImapOperationType *aOperation)
|
||||
{
|
||||
NS_ENSURE_ARG(aOperation);
|
||||
*aOperation = m_operation;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetOperation(nsOfflineImapOperationType aOperation)
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x setOperation was %x add %x", m_messageKey, m_operation, aOperation));
|
||||
|
||||
m_operation |= aOperation;
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION, m_operation);
|
||||
}
|
||||
|
||||
/* void clearOperation (in nsOfflineImapOperationType operation); */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::ClearOperation(nsOfflineImapOperationType aOperation)
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x clearOperation was %x clear %x", m_messageKey, m_operation, aOperation));
|
||||
m_operation &= ~aOperation;
|
||||
switch (aOperation)
|
||||
{
|
||||
case kMsgMoved:
|
||||
case kAppendTemplate:
|
||||
case kAppendDraft:
|
||||
m_moveDestination.Truncate();
|
||||
break;
|
||||
case kMsgCopy:
|
||||
m_copyDestinations.RemoveElementAt(0);
|
||||
break;
|
||||
}
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION, m_operation);
|
||||
}
|
||||
|
||||
/* attribute nsMsgKey messageKey; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetMessageKey(nsMsgKey *aMessageKey)
|
||||
{
|
||||
NS_ENSURE_ARG(aMessageKey);
|
||||
*aMessageKey = m_messageKey;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetMessageKey(nsMsgKey aMessageKey)
|
||||
{
|
||||
m_messageKey = aMessageKey;
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_MESSAGE_KEY, m_messageKey);
|
||||
}
|
||||
|
||||
/* attribute nsMsgKey srcMessageKey; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetSrcMessageKey(nsMsgKey *aMessageKey)
|
||||
{
|
||||
NS_ENSURE_ARG(aMessageKey);
|
||||
return m_mdb->GetUint32Property(m_mdbRow, PROP_SRC_MESSAGE_KEY, aMessageKey, nsMsgKey_None);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetSrcMessageKey(nsMsgKey aMessageKey)
|
||||
{
|
||||
m_messageKey = aMessageKey;
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_SRC_MESSAGE_KEY, m_messageKey);
|
||||
}
|
||||
|
||||
/* attribute imapMessageFlagsType flagOperation; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetFlagOperation(imapMessageFlagsType *aFlagOperation)
|
||||
{
|
||||
NS_ENSURE_ARG(aFlagOperation);
|
||||
*aFlagOperation = m_operationFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetFlagOperation(imapMessageFlagsType aFlagOperation)
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x setFlagOperation was %x add %x", m_messageKey, m_operationFlags, aFlagOperation));
|
||||
SetOperation(kFlagsChanged);
|
||||
nsresult rv = SetNewFlags(aFlagOperation);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
m_operationFlags |= aFlagOperation;
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION_FLAGS, m_operationFlags);
|
||||
}
|
||||
|
||||
/* attribute imapMessageFlagsType flagOperation; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetNewFlags(imapMessageFlagsType *aNewFlags)
|
||||
{
|
||||
NS_ENSURE_ARG(aNewFlags);
|
||||
uint32_t flags;
|
||||
nsresult rv = m_mdb->GetUint32Property(m_mdbRow, PROP_NEW_FLAGS, &flags, 0);
|
||||
*aNewFlags = m_newFlags = (imapMessageFlagsType) flags;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetNewFlags(imapMessageFlagsType aNewFlags)
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info) && m_newFlags != aNewFlags)
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x SetNewFlags was %x to %x", m_messageKey, m_newFlags, aNewFlags));
|
||||
m_newFlags = aNewFlags;
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_NEW_FLAGS, m_newFlags);
|
||||
}
|
||||
|
||||
|
||||
/* attribute string destinationFolderURI; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetDestinationFolderURI(char * *aDestinationFolderURI)
|
||||
{
|
||||
NS_ENSURE_ARG(aDestinationFolderURI);
|
||||
(void) m_mdb->GetProperty(m_mdbRow, PROP_MOVE_DEST_FOLDER_URI, getter_Copies(m_moveDestination));
|
||||
*aDestinationFolderURI = ToNewCString(m_moveDestination);
|
||||
return (*aDestinationFolderURI) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetDestinationFolderURI(const char * aDestinationFolderURI)
|
||||
{
|
||||
if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x SetDestinationFolderURI to %s", m_messageKey, aDestinationFolderURI));
|
||||
m_moveDestination = aDestinationFolderURI ? aDestinationFolderURI : 0;
|
||||
return m_mdb->SetProperty(m_mdbRow, PROP_MOVE_DEST_FOLDER_URI, aDestinationFolderURI);
|
||||
}
|
||||
|
||||
/* attribute string sourceFolderURI; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetSourceFolderURI(char * *aSourceFolderURI)
|
||||
{
|
||||
NS_ENSURE_ARG(aSourceFolderURI);
|
||||
nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_SRC_FOLDER_URI, getter_Copies(m_sourceFolder));
|
||||
*aSourceFolderURI = ToNewCString(m_sourceFolder);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetSourceFolderURI(const char * aSourceFolderURI)
|
||||
{
|
||||
m_sourceFolder = aSourceFolderURI ? aSourceFolderURI : 0;
|
||||
SetOperation(kMoveResult);
|
||||
|
||||
return m_mdb->SetProperty(m_mdbRow, PROP_SRC_FOLDER_URI, aSourceFolderURI);
|
||||
}
|
||||
|
||||
/* attribute string keyword; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetKeywordsToAdd(char * *aKeywords)
|
||||
{
|
||||
NS_ENSURE_ARG(aKeywords);
|
||||
nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_KEYWORD_ADD, getter_Copies(m_keywordsToAdd));
|
||||
*aKeywords = ToNewCString(m_keywordsToAdd);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::AddKeywordToAdd(const char * aKeyword)
|
||||
{
|
||||
SetOperation(kAddKeywords);
|
||||
return AddKeyword(aKeyword, m_keywordsToAdd, PROP_KEYWORD_ADD, m_keywordsToRemove, PROP_KEYWORD_REMOVE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetKeywordsToRemove(char * *aKeywords)
|
||||
{
|
||||
NS_ENSURE_ARG(aKeywords);
|
||||
nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_KEYWORD_REMOVE, getter_Copies(m_keywordsToRemove));
|
||||
*aKeywords = ToNewCString(m_keywordsToRemove);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgOfflineImapOperation::AddKeyword(const char *aKeyword, nsCString &addList, const char *addProp,
|
||||
nsCString &removeList, const char *removeProp)
|
||||
{
|
||||
int32_t startOffset, keywordLength;
|
||||
if (!MsgFindKeyword(nsDependentCString(aKeyword), addList, &startOffset, &keywordLength))
|
||||
{
|
||||
if (!addList.IsEmpty())
|
||||
addList.Append(' ');
|
||||
addList.Append(aKeyword);
|
||||
}
|
||||
// if the keyword we're removing was in the list of keywords to add,
|
||||
// cut it from that list.
|
||||
if (MsgFindKeyword(nsDependentCString(aKeyword), removeList, &startOffset, &keywordLength))
|
||||
{
|
||||
removeList.Cut(startOffset, keywordLength);
|
||||
m_mdb->SetProperty(m_mdbRow, removeProp, removeList.get());
|
||||
}
|
||||
return m_mdb->SetProperty(m_mdbRow, addProp, addList.get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::AddKeywordToRemove(const char * aKeyword)
|
||||
{
|
||||
SetOperation(kRemoveKeywords);
|
||||
return AddKeyword(aKeyword, m_keywordsToRemove, PROP_KEYWORD_REMOVE, m_keywordsToAdd, PROP_KEYWORD_ADD);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::AddMessageCopyOperation(const char *destinationBox)
|
||||
{
|
||||
SetOperation(kMsgCopy);
|
||||
nsAutoCString newDest(destinationBox);
|
||||
nsresult rv = GetCopiesFromDB();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
m_copyDestinations.AppendElement(newDest);
|
||||
return SetCopiesToDB();
|
||||
}
|
||||
|
||||
// we write out the folders as one string, separated by 0x1.
|
||||
#define FOLDER_SEP_CHAR '\001'
|
||||
|
||||
nsresult nsMsgOfflineImapOperation::GetCopiesFromDB()
|
||||
{
|
||||
nsCString copyDests;
|
||||
m_copyDestinations.Clear();
|
||||
nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_COPY_DESTS, getter_Copies(copyDests));
|
||||
// use 0x1 as the delimiter between folder names since it's not a legal character
|
||||
if (NS_SUCCEEDED(rv) && !copyDests.IsEmpty())
|
||||
{
|
||||
int32_t curCopyDestStart = 0;
|
||||
int32_t nextCopyDestPos = 0;
|
||||
|
||||
while (nextCopyDestPos != -1)
|
||||
{
|
||||
nsCString curDest;
|
||||
nextCopyDestPos = copyDests.FindChar(FOLDER_SEP_CHAR, curCopyDestStart);
|
||||
if (nextCopyDestPos > 0)
|
||||
curDest = Substring(copyDests, curCopyDestStart, nextCopyDestPos - curCopyDestStart);
|
||||
else
|
||||
curDest = Substring(copyDests, curCopyDestStart, copyDests.Length() - curCopyDestStart);
|
||||
curCopyDestStart = nextCopyDestPos + 1;
|
||||
m_copyDestinations.AppendElement(curDest);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgOfflineImapOperation::SetCopiesToDB()
|
||||
{
|
||||
nsAutoCString copyDests;
|
||||
|
||||
// use 0x1 as the delimiter between folders
|
||||
for (uint32_t i = 0; i < m_copyDestinations.Length(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
copyDests.Append(FOLDER_SEP_CHAR);
|
||||
copyDests.Append(m_copyDestinations.ElementAt(i));
|
||||
}
|
||||
return m_mdb->SetProperty(m_mdbRow, PROP_COPY_DESTS, copyDests.get());
|
||||
}
|
||||
|
||||
/* attribute long numberOfCopies; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetNumberOfCopies(int32_t *aNumberOfCopies)
|
||||
{
|
||||
NS_ENSURE_ARG(aNumberOfCopies);
|
||||
nsresult rv = GetCopiesFromDB();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*aNumberOfCopies = m_copyDestinations.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* string getCopyDestination (in long copyIndex); */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetCopyDestination(int32_t copyIndex, char **retval)
|
||||
{
|
||||
NS_ENSURE_ARG(retval);
|
||||
nsresult rv = GetCopiesFromDB();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (copyIndex >= (int32_t)m_copyDestinations.Length())
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
*retval = ToNewCString(m_copyDestinations.ElementAt(copyIndex));
|
||||
return (*retval) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* attribute unsigned log msgSize; */
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetMsgSize(uint32_t *aMsgSize)
|
||||
{
|
||||
NS_ENSURE_ARG(aMsgSize);
|
||||
return m_mdb->GetUint32Property(m_mdbRow, PROP_MSG_SIZE, aMsgSize, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetMsgSize(uint32_t aMsgSize)
|
||||
{
|
||||
return m_mdb->SetUint32Property(m_mdbRow, PROP_MSG_SIZE, aMsgSize);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::SetPlayingBack(bool aPlayingBack)
|
||||
{
|
||||
return m_mdb->SetBooleanProperty(m_mdbRow, PROP_PLAYINGBACK, aPlayingBack);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgOfflineImapOperation::GetPlayingBack(bool *aPlayingBack)
|
||||
{
|
||||
NS_ENSURE_ARG(aPlayingBack);
|
||||
return m_mdb->GetBooleanProperty(m_mdbRow, PROP_PLAYINGBACK, aPlayingBack);
|
||||
}
|
||||
|
||||
|
||||
void nsMsgOfflineImapOperation::Log(PRLogModuleInfo *logFile)
|
||||
{
|
||||
if (!IMAPOffline)
|
||||
IMAPOffline = PR_NewLogModule("IMAPOFFLINE");
|
||||
if (!MOZ_LOG_TEST(IMAPOffline, LogLevel::Info))
|
||||
return;
|
||||
// const long kMoveResult = 0x8;
|
||||
// const long kAppendDraft = 0x10;
|
||||
// const long kAddedHeader = 0x20;
|
||||
// const long kDeletedMsg = 0x40;
|
||||
// const long kMsgMarkedDeleted = 0x80;
|
||||
// const long kAppendTemplate = 0x100;
|
||||
// const long kDeleteAllMsgs = 0x200;
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kFlagsChanged)
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x changeFlag:%x", m_messageKey, m_newFlags));
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kMsgMoved)
|
||||
{
|
||||
nsCString moveDestFolder;
|
||||
GetDestinationFolderURI(getter_Copies(moveDestFolder));
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x moveTo:%s", m_messageKey, moveDestFolder.get()));
|
||||
}
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kMsgCopy)
|
||||
{
|
||||
nsCString copyDests;
|
||||
m_mdb->GetProperty(m_mdbRow, PROP_COPY_DESTS, getter_Copies(copyDests));
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x moveTo:%s", m_messageKey, copyDests.get()));
|
||||
}
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kAppendDraft)
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x append draft", m_messageKey));
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kAddKeywords)
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x add keyword:%s", m_messageKey, m_keywordsToAdd.get()));
|
||||
if (m_operation & nsIMsgOfflineImapOperation::kRemoveKeywords)
|
||||
MOZ_LOG(IMAPOffline, LogLevel::Info, ("msg id %x remove keyword:%s", m_messageKey, m_keywordsToRemove.get()));
|
||||
}
|
||||
55
mailnews/db/msgdb/src/nsMsgOfflineImapOperation.h
Normal file
55
mailnews/db/msgdb/src/nsMsgOfflineImapOperation.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _nsMsgOfflineImapOperation_H_
|
||||
|
||||
#include "nsIMsgOfflineImapOperation.h"
|
||||
#include "mdb.h"
|
||||
#include "nsMsgDatabase.h"
|
||||
#include "prlog.h"
|
||||
|
||||
class nsMsgOfflineImapOperation : public nsIMsgOfflineImapOperation
|
||||
{
|
||||
public:
|
||||
/** Instance Methods **/
|
||||
nsMsgOfflineImapOperation(nsMsgDatabase *db, nsIMdbRow *row);
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGOFFLINEIMAPOPERATION
|
||||
|
||||
|
||||
nsIMdbRow *GetMDBRow() {return m_mdbRow;}
|
||||
nsresult GetCopiesFromDB();
|
||||
nsresult SetCopiesToDB();
|
||||
void Log(PRLogModuleInfo *logFile);
|
||||
protected:
|
||||
virtual ~nsMsgOfflineImapOperation();
|
||||
nsresult AddKeyword(const char *aKeyword, nsCString &addList, const char *addProp,
|
||||
nsCString &removeList, const char *removeProp);
|
||||
|
||||
nsOfflineImapOperationType m_operation;
|
||||
nsMsgKey m_messageKey;
|
||||
nsMsgKey m_sourceMessageKey;
|
||||
uint32_t m_operationFlags; // what to do on sync
|
||||
imapMessageFlagsType m_newFlags; // used for kFlagsChanged
|
||||
|
||||
// these are URI's, and are escaped. Thus, we can use a delimter like ' '
|
||||
// because the real spaces should be escaped.
|
||||
nsCString m_sourceFolder;
|
||||
nsCString m_moveDestination;
|
||||
nsTArray<nsCString> m_copyDestinations;
|
||||
|
||||
nsCString m_keywordsToAdd;
|
||||
nsCString m_keywordsToRemove;
|
||||
|
||||
// nsMsgOfflineImapOperation will have to know what db and row they belong to, since they are really
|
||||
// just a wrapper around the offline operation row in the mdb.
|
||||
// though I hope not.
|
||||
nsMsgDatabase *m_mdb;
|
||||
nsCOMPtr <nsIMdbRow> m_mdbRow;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* _nsMsgOfflineImapOperation_H_ */
|
||||
|
||||
1180
mailnews/db/msgdb/src/nsMsgThread.cpp
Normal file
1180
mailnews/db/msgdb/src/nsMsgThread.cpp
Normal file
File diff suppressed because it is too large
Load diff
360
mailnews/db/msgdb/src/nsNewsDatabase.cpp
Normal file
360
mailnews/db/msgdb/src/nsNewsDatabase.cpp
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsIMsgDBView.h"
|
||||
#include "nsIMsgThread.h"
|
||||
#include "nsNewsDatabase.h"
|
||||
#include "nsMsgKeySet.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(DEBUG_sspitzer_) || defined(DEBUG_seth_)
|
||||
#define DEBUG_NEWS_DATABASE 1
|
||||
#endif
|
||||
|
||||
nsNewsDatabase::nsNewsDatabase()
|
||||
{
|
||||
m_readSet = nullptr;
|
||||
}
|
||||
|
||||
nsNewsDatabase::~nsNewsDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsNewsDatabase, nsMsgDatabase)
|
||||
NS_IMPL_RELEASE_INHERITED(nsNewsDatabase, nsMsgDatabase)
|
||||
|
||||
NS_IMETHODIMP nsNewsDatabase::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
|
||||
*aInstancePtr = nullptr;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsINewsDatabase)))
|
||||
{
|
||||
*aInstancePtr = static_cast<nsINewsDatabase *>(this);
|
||||
}
|
||||
|
||||
if(*aInstancePtr)
|
||||
{
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsMsgDatabase::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::Close(bool forceCommit)
|
||||
{
|
||||
return nsMsgDatabase::Close(forceCommit);
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::ForceClosed()
|
||||
{
|
||||
return nsMsgDatabase::ForceClosed();
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::Commit(nsMsgDBCommit commitType)
|
||||
{
|
||||
if (m_dbFolderInfo && m_readSet)
|
||||
{
|
||||
// let's write out our idea of the read set so we can compare it with that of
|
||||
// the .rc file next time we start up.
|
||||
nsCString readSet;
|
||||
m_readSet->Output(getter_Copies(readSet));
|
||||
m_dbFolderInfo->SetCharProperty("readSet", readSet);
|
||||
}
|
||||
return nsMsgDatabase::Commit(commitType);
|
||||
}
|
||||
|
||||
|
||||
uint32_t nsNewsDatabase::GetCurVersion()
|
||||
{
|
||||
return kMsgDBVersion;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDatabase::IsRead(nsMsgKey key, bool *pRead)
|
||||
{
|
||||
NS_ASSERTION(pRead, "null out param in IsRead");
|
||||
if (!pRead) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!m_readSet) return NS_ERROR_FAILURE;
|
||||
|
||||
*pRead = m_readSet->IsMember(key);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::IsHeaderRead(nsIMsgDBHdr *msgHdr, bool *pRead)
|
||||
{
|
||||
nsresult rv;
|
||||
nsMsgKey messageKey;
|
||||
|
||||
if (!msgHdr || !pRead) return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = msgHdr->GetMessageKey(&messageKey);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = IsRead(messageKey,pRead);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// return highest article number we've seen.
|
||||
NS_IMETHODIMP nsNewsDatabase::GetHighWaterArticleNum(nsMsgKey *key)
|
||||
{
|
||||
NS_ASSERTION(m_dbFolderInfo, "null db folder info");
|
||||
if (!m_dbFolderInfo)
|
||||
return NS_ERROR_FAILURE;
|
||||
return m_dbFolderInfo->GetHighWater(key);
|
||||
}
|
||||
|
||||
// return the key of the first article number we know about.
|
||||
// Since the iterator iterates in id order, we can just grab the
|
||||
// messagekey of the first header it returns.
|
||||
// ### dmb
|
||||
// This will not deal with the situation where we get holes in
|
||||
// the headers we know about. Need to figure out how and when
|
||||
// to solve that. This could happen if a transfer is interrupted.
|
||||
// Do we need to keep track of known arts permanently?
|
||||
NS_IMETHODIMP nsNewsDatabase::GetLowWaterArticleNum(nsMsgKey *key)
|
||||
{
|
||||
nsresult rv;
|
||||
nsMsgHdr *pHeader;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> hdrs;
|
||||
rv = EnumerateMessages(getter_AddRefs(hdrs));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = hdrs->GetNext((nsISupports**)&pHeader);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "nsMsgDBEnumerator broken");
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return pHeader->GetMessageKey(key);
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::ExpireUpTo(nsMsgKey expireKey)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
nsresult nsNewsDatabase::ExpireRange(nsMsgKey startRange, nsMsgKey endRange)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsNewsDatabase::GetReadSet(nsMsgKeySet **pSet)
|
||||
{
|
||||
if (!pSet) return NS_ERROR_NULL_POINTER;
|
||||
*pSet = m_readSet;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDatabase::SetReadSet(nsMsgKeySet *pSet)
|
||||
{
|
||||
m_readSet = pSet;
|
||||
|
||||
if (m_readSet)
|
||||
{
|
||||
// compare this read set with the one in the db folder info.
|
||||
// If not equivalent, sync with this one.
|
||||
nsCString dbReadSet;
|
||||
if (m_dbFolderInfo)
|
||||
m_dbFolderInfo->GetCharProperty("readSet", dbReadSet);
|
||||
nsCString newsrcReadSet;
|
||||
m_readSet->Output(getter_Copies(newsrcReadSet));
|
||||
if (!dbReadSet.Equals(newsrcReadSet))
|
||||
SyncWithReadSet();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
bool nsNewsDatabase::SetHdrReadFlag(nsIMsgDBHdr *msgHdr, bool bRead)
|
||||
{
|
||||
nsresult rv;
|
||||
bool isRead;
|
||||
rv = IsHeaderRead(msgHdr, &isRead);
|
||||
|
||||
if (isRead == bRead)
|
||||
{
|
||||
// give the base class a chance to update m_flags.
|
||||
nsMsgDatabase::SetHdrReadFlag(msgHdr, bRead);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
nsMsgKey messageKey;
|
||||
|
||||
// give the base class a chance to update m_flags.
|
||||
nsMsgDatabase::SetHdrReadFlag(msgHdr, bRead);
|
||||
rv = msgHdr->GetMessageKey(&messageKey);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
|
||||
NS_ASSERTION(m_readSet, "m_readSet is null");
|
||||
if (!m_readSet) return false;
|
||||
|
||||
if (!bRead) {
|
||||
#ifdef DEBUG_NEWS_DATABASE
|
||||
printf("remove %d from the set\n",messageKey);
|
||||
#endif
|
||||
|
||||
m_readSet->Remove(messageKey);
|
||||
|
||||
rv = NotifyReadChanged(nullptr);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_NEWS_DATABASE
|
||||
printf("add %d to the set\n",messageKey);
|
||||
#endif
|
||||
|
||||
if (m_readSet->Add(messageKey) < 0) return false;
|
||||
|
||||
rv = NotifyReadChanged(nullptr);
|
||||
if (NS_FAILED(rv)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDatabase::MarkAllRead(uint32_t *aNumMarked,
|
||||
nsMsgKey **aThoseMarked)
|
||||
{
|
||||
nsMsgKey lowWater = nsMsgKey_None, highWater;
|
||||
nsCString knownArts;
|
||||
if (m_dbFolderInfo)
|
||||
{
|
||||
m_dbFolderInfo->GetKnownArtsSet(getter_Copies(knownArts));
|
||||
nsMsgKeySet *knownKeys = nsMsgKeySet::Create(knownArts.get());
|
||||
if (knownKeys)
|
||||
lowWater = knownKeys->GetFirstMember();
|
||||
|
||||
delete knownKeys;
|
||||
}
|
||||
if (lowWater == nsMsgKey_None)
|
||||
GetLowWaterArticleNum(&lowWater);
|
||||
GetHighWaterArticleNum(&highWater);
|
||||
if (lowWater > 2)
|
||||
m_readSet->AddRange(1, lowWater - 1);
|
||||
nsresult err = nsMsgDatabase::MarkAllRead(aNumMarked, aThoseMarked);
|
||||
if (NS_SUCCEEDED(err) && 1 <= highWater)
|
||||
m_readSet->AddRange(1, highWater); // mark everything read in newsrc.
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::SyncWithReadSet()
|
||||
{
|
||||
|
||||
// The code below attempts to update the underlying nsMsgDatabase's idea
|
||||
// of read/unread flags to match the read set in the .newsrc file. It should
|
||||
// only be called when they don't match, e.g., we crashed after committing the
|
||||
// db but before writing out the .newsrc
|
||||
nsCOMPtr <nsISimpleEnumerator> hdrs;
|
||||
nsresult rv = EnumerateMessages(getter_AddRefs(hdrs));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool hasMore = false, readInNewsrc, isReadInDB, changed = false;
|
||||
int32_t numMessages = 0, numUnreadMessages = 0;
|
||||
nsMsgKey messageKey;
|
||||
nsCOMPtr <nsIMsgThread> threadHdr;
|
||||
|
||||
// Scan all messages in DB
|
||||
while (NS_SUCCEEDED(rv = hdrs->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = hdrs->GetNext(getter_AddRefs(supports));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr <nsIMsgDBHdr> header = do_QueryInterface(supports, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsMsgDatabase::IsHeaderRead(header, &isReadInDB);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
header->GetMessageKey(&messageKey);
|
||||
IsRead(messageKey,&readInNewsrc);
|
||||
|
||||
numMessages++;
|
||||
if (!readInNewsrc)
|
||||
numUnreadMessages++;
|
||||
|
||||
// If DB and readSet disagree on Read/Unread, fix DB
|
||||
if (readInNewsrc!=isReadInDB)
|
||||
{
|
||||
MarkHdrRead(header, readInNewsrc, nullptr);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update FolderInfo Counters
|
||||
int32_t oldMessages, oldUnreadMessages;
|
||||
rv = m_dbFolderInfo->GetNumMessages(&oldMessages);
|
||||
if (NS_SUCCEEDED(rv) && oldMessages!=numMessages)
|
||||
{
|
||||
changed = true;
|
||||
m_dbFolderInfo->ChangeNumMessages(numMessages-oldMessages);
|
||||
}
|
||||
rv = m_dbFolderInfo->GetNumUnreadMessages(&oldUnreadMessages);
|
||||
if (NS_SUCCEEDED(rv) && oldUnreadMessages!=numUnreadMessages)
|
||||
{
|
||||
changed = true;
|
||||
m_dbFolderInfo->ChangeNumUnreadMessages(numUnreadMessages-oldUnreadMessages);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsNewsDatabase::AdjustExpungedBytesOnDelete(nsIMsgDBHdr *msgHdr)
|
||||
{
|
||||
uint32_t msgFlags;
|
||||
msgHdr->GetFlags(&msgFlags);
|
||||
if (msgFlags & nsMsgMessageFlags::Offline && m_dbFolderInfo)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
(void)msgHdr->GetOfflineMessageSize(&size);
|
||||
return m_dbFolderInfo->ChangeExpungedBytes (size);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNewsDatabase::GetDefaultViewFlags(nsMsgViewFlagsTypeValue *aDefaultViewFlags)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDefaultViewFlags);
|
||||
GetIntPref("mailnews.default_news_view_flags", aDefaultViewFlags);
|
||||
if (*aDefaultViewFlags < nsMsgViewFlagsType::kNone ||
|
||||
*aDefaultViewFlags > (nsMsgViewFlagsType::kThreadedDisplay |
|
||||
nsMsgViewFlagsType::kShowIgnored |
|
||||
nsMsgViewFlagsType::kUnreadOnly |
|
||||
nsMsgViewFlagsType::kExpandAll |
|
||||
nsMsgViewFlagsType::kGroupBySort))
|
||||
*aDefaultViewFlags = nsMsgViewFlagsType::kThreadedDisplay;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNewsDatabase::GetDefaultSortType(nsMsgViewSortTypeValue *aDefaultSortType)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDefaultSortType);
|
||||
GetIntPref("mailnews.default_news_sort_type", aDefaultSortType);
|
||||
if (*aDefaultSortType < nsMsgViewSortType::byDate ||
|
||||
*aDefaultSortType > nsMsgViewSortType::byAccount)
|
||||
*aDefaultSortType = nsMsgViewSortType::byThread;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNewsDatabase::GetDefaultSortOrder(nsMsgViewSortOrderValue *aDefaultSortOrder)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDefaultSortOrder);
|
||||
GetIntPref("mailnews.default_news_sort_order", aDefaultSortOrder);
|
||||
if (*aDefaultSortOrder != nsMsgViewSortOrder::descending)
|
||||
*aDefaultSortOrder = nsMsgViewSortOrder::ascending;
|
||||
return NS_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue