diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /mailnews/db/msgdb/public | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'mailnews/db/msgdb/public')
-rw-r--r-- | mailnews/db/msgdb/public/moz.build | 27 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsDBFolderInfo.h | 135 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl | 33 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsIDBChangeListener.idl | 115 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsIDBFolderInfo.idl | 108 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsIMsgDatabase.idl | 570 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl | 53 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsINewsDatabase.idl | 18 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsImapMailDatabase.h | 52 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsMailDatabase.h | 67 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsMsgDBCID.h | 63 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsMsgDatabase.h | 462 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsMsgHdr.h | 86 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsMsgThread.h | 63 | ||||
-rw-r--r-- | mailnews/db/msgdb/public/nsNewsDatabase.h | 57 |
15 files changed, 1909 insertions, 0 deletions
diff --git a/mailnews/db/msgdb/public/moz.build b/mailnews/db/msgdb/public/moz.build new file mode 100644 index 000000000..9bf74e1d6 --- /dev/null +++ b/mailnews/db/msgdb/public/moz.build @@ -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', +] + diff --git a/mailnews/db/msgdb/public/nsDBFolderInfo.h b/mailnews/db/msgdb/public/nsDBFolderInfo.h new file mode 100644 index 000000000..9b3a51348 --- /dev/null +++ b/mailnews/db/msgdb/public/nsDBFolderInfo.h @@ -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 diff --git a/mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl b/mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl new file mode 100644 index 000000000..28551ea60 --- /dev/null +++ b/mailnews/db/msgdb/public/nsIDBChangeAnnouncer.idl @@ -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(); +}; + diff --git a/mailnews/db/msgdb/public/nsIDBChangeListener.idl b/mailnews/db/msgdb/public/nsIDBChangeListener.idl new file mode 100644 index 000000000..3acda8ad8 --- /dev/null +++ b/mailnews/db/msgdb/public/nsIDBChangeListener.idl @@ -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); +}; + diff --git a/mailnews/db/msgdb/public/nsIDBFolderInfo.idl b/mailnews/db/msgdb/public/nsIDBFolderInfo.idl new file mode 100644 index 000000000..59b294d3b --- /dev/null +++ b/mailnews/db/msgdb/public/nsIDBFolderInfo.idl @@ -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; +}; diff --git a/mailnews/db/msgdb/public/nsIMsgDatabase.idl b/mailnews/db/msgdb/public/nsIMsgDatabase.idl new file mode 100644 index 000000000..6b79fc940 --- /dev/null +++ b/mailnews/db/msgdb/public/nsIMsgDatabase.idl @@ -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); + +}; +/** @} */ diff --git a/mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl b/mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl new file mode 100644 index 000000000..b07beef63 --- /dev/null +++ b/mailnews/db/msgdb/public/nsIMsgOfflineImapOperation.idl @@ -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; +}; + diff --git a/mailnews/db/msgdb/public/nsINewsDatabase.idl b/mailnews/db/msgdb/public/nsINewsDatabase.idl new file mode 100644 index 000000000..151a42f01 --- /dev/null +++ b/mailnews/db/msgdb/public/nsINewsDatabase.idl @@ -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; +}; diff --git a/mailnews/db/msgdb/public/nsImapMailDatabase.h b/mailnews/db/msgdb/public/nsImapMailDatabase.h new file mode 100644 index 000000000..b6092c284 --- /dev/null +++ b/mailnews/db/msgdb/public/nsImapMailDatabase.h @@ -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 diff --git a/mailnews/db/msgdb/public/nsMailDatabase.h b/mailnews/db/msgdb/public/nsMailDatabase.h new file mode 100644 index 000000000..6a5c6b5c4 --- /dev/null +++ b/mailnews/db/msgdb/public/nsMailDatabase.h @@ -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 diff --git a/mailnews/db/msgdb/public/nsMsgDBCID.h b/mailnews/db/msgdb/public/nsMsgDBCID.h new file mode 100644 index 000000000..557cc24c0 --- /dev/null +++ b/mailnews/db/msgdb/public/nsMsgDBCID.h @@ -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 diff --git a/mailnews/db/msgdb/public/nsMsgDatabase.h b/mailnews/db/msgdb/public/nsMsgDatabase.h new file mode 100644 index 000000000..bb011e85c --- /dev/null +++ b/mailnews/db/msgdb/public/nsMsgDatabase.h @@ -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 diff --git a/mailnews/db/msgdb/public/nsMsgHdr.h b/mailnews/db/msgdb/public/nsMsgHdr.h new file mode 100644 index 000000000..6d23e7b49 --- /dev/null +++ b/mailnews/db/msgdb/public/nsMsgHdr.h @@ -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 + diff --git a/mailnews/db/msgdb/public/nsMsgThread.h b/mailnews/db/msgdb/public/nsMsgThread.h new file mode 100644 index 000000000..62d303bc8 --- /dev/null +++ b/mailnews/db/msgdb/public/nsMsgThread.h @@ -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 + diff --git a/mailnews/db/msgdb/public/nsNewsDatabase.h b/mailnews/db/msgdb/public/nsNewsDatabase.h new file mode 100644 index 000000000..33e225913 --- /dev/null +++ b/mailnews/db/msgdb/public/nsNewsDatabase.h @@ -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 |