/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Container store.
*
*/
#ifndef __CONTAINER_STORE_H__
#define __CONTAINER_STORE_H__
// ========
// INCLUDES
// ========
#include <e32base.h>
#include <f32file.h>
#include <e32cmn.h>
//<cmail>
#include "debuglogmacros.h"
//</cmail>
#include "MessageStoreClientServer.h"
#include "EncryptableTable.h"
// ====================
// FORWARD DECLARATIONS
// ====================
class TDbBookmark;
class MCustomBehaviorProvider;
class MBackgroundOperationsObserver;
class MClient;
class CDeleteHandler;
class CHandler;
// classes for internal use only
class CContainerStoreContainersTable;
class CContainerStoreContentManager;
class CContainerStoreEncryption;
class CContainerStoreGeneralTable;
class CContainerStoreUtils;
class CContainerStoreAccountTable;
class CContainerStoreSortingTable;
class CContainerStoreSearchResultTable;
class TMsgStoreSortableFields;
class CMsgStoreSortResultRowSet;
class CContainerStoreSearchHandler;
class MContainerStoreSearchClient;
class CMessageStoreEncryptHandler;
class CContainerStoreMruAddressTable;
class CMruAddress;
// =====
// TYPES
// =====
/** This type defines the base type for container IDs. */
typedef TUint TContainerId;
// =========
// CONSTANTS
// =========
/** This value defines the ID used throughout the container store to represent a nonexistent container. */
const TContainerId KContainerInvalidId = 0;
/** The type is encoded in the first 4 bits of the ID. */
const TContainerId KContainerTypeMask = 0xF0000000;
/** This value means "any type" for operations that take type as a parameter. */
const TContainerId KContainerTypeAny = 0xF0000000;
// ==================
// CLASS DECLARATIONS
// ==================
struct TSortSession
{
TContainerId iSessionId;
CMsgStoreSortResultRowSet* iResultRowSet;
};
class RMsgStoreSortableFields
{
public:
void Close();
TInt64 iReceivedDate;
TUint iFlags;
TUint iSizeOnServer;
TUint iSizeOnClient;
RBuf iSubject;
RBuf iFrom;
RBuf iTo;
};
/** Defines the API for sorting observer.
*/
class MSortingTableObserver
{
public:
virtual void MessageUpdate ( TContainerId aMessageId,
TContainerId aFolderId,
TMsgStoreOperation aOperation, //EMsgStoreAdd, EMsgStoreDelete, EMsgStoreUpdateProperties
TUint aFieldsChanged = 0, //For EMsgStoreUpdateProperties only, combinations of TSortableFieldsMasks
const TDesC& aFrom = KNullDesC,
const TDesC& aTo = KNullDesC,
const TDesC& aSubject = KNullDesC,
TInt64 aReceivedDate = 0
) = 0;
virtual void FolderDeleted ( TContainerId aFolderId ) = 0;
virtual void MailBoxDeleted ( TContainerId aMailBoxId ) = 0;
};
/** Defines the API that must be implemented in order for clients to receive notification of modifications
of the contents of the container store.
*/
class MContainerStoreObserver
{
public:
// ==============
// PUBLIC METHODS
// ==============
/** Defines the types of operations that can be notified. */
enum TOperation
{
EAdd,
EMove,
EDelete,
EUpdateProperties,
EUpdateContent,
ERemoveContent,
ERenameAccount
}; // end TOperation
/* This function notifies the observer of an add/change/delete/move of a message store object.
\param aOtherId: this parameter will be the new parent ID for move operations,
the container's parent ID for adds and updates,
and KMsgStoreInvalidId otherwise
*/
virtual void ContainerModified( TOperation aOperation,
const RArray<TContainerId>& aHierarchy,
TContainerId aOtherId,
const TDesC8& aQuickProperties ) = 0;
virtual void AuthenticationChanged( TBool aAuthenticated ) = 0;
virtual void AccountModified( TOperation aOperation,
TInt32 aOwnerId,
const TDesC8& aName,
const TDesC8& aNewAccName,
TContainerId aMailboxId ) = 0;
}; // end class MContainerStoreObserver
/** The main class used to access and manipulate the contents of the container store. */
class CContainerStore : public CBase, public MSortingTableObserver, public MEncryptableTable
{
public:
static CContainerStore* NewL( const TDesC& aDbFilename,
TDriveNumber aDriveNumber,
MCustomBehaviorProvider& aCustomBehaviorProvider,
MBackgroundOperationsObserver& aBackgroundOperationsObserver,
TInt aBasePriority );
virtual ~CContainerStore();
static TInt WipeEverything( const TDesC& aDbFilename,
TDriveNumber aDriveNumber );
void SuspendCompactionLC();
void ResumeCompaction();
// AUTHENTICATION FUNCTIONS
TBool Authenticated();
TBool AuthenticateL( const TDesC& aPassword );
TBool HasPasswordL();
void ClearAuthentication();
void SetPasswordL( const TDesC& aPassword );
TBool ChangePasswordL( const TDesC& aOldPassword, const TDesC& aNewPassword );
void EnableEncryptionL();
void DisableEncryptionL();
// OBSERVER FUNCTIONS
void ObserveL( MContainerStoreObserver* aObserver );
void StopObserving( MContainerStoreObserver* aObserver );
//Account management
TContainerId CreateAccountL( TInt32 aOwnerId, const TDesC& aName, MContainerStoreObserver* aDoNotNotify, const TDesC8& aProperties );
TContainerId OpenAccountL( TInt32 aOwnerId, const TDesC& aName, RBuf8& aProperties );
void RenameAccountL( TInt32 aOwnerId, const TDesC& aOldName, const TDesC& aNewName, MContainerStoreObserver* aDoNotNotify );
void DeleteAccountL( TInt32 aOwnerId, const TDesC& aName, MContainerStoreObserver* aDoNotNotify );
void ListAccountsL( TDes8& aBuf );
// CONTAINER FUNCTIONS
//
// If an observer is passed in then that observer will not receive notification of the given
// operation.
void CreatePredefinedContainerIfNeededL( TContainerId aId,
TContainerId aType,
TContainerId aParentId,
const TDesC8& aProperties );
// This function doesn't commit the container. CommitContainerL (or AbandonContainerL) must
// subsequently called. If neither commit or abandon is called, then the container will be
// abandoned when the container store class is next constructed.
TContainerId CreateContainerL( TContainerId aType,
TContainerId aParentId,
TContainerId aGrandparentId,
const TDesC8& aProperties,
TContainerId aId = KMsgStoreInvalidId );
void CommitContainerL( TContainerId aId,
TContainerId aParentId,
TContainerId aMailBoxId,
MContainerStoreObserver* aObserver,
TContainerId aCopiedFromOriginalMsgId = KContainerInvalidId ); //used by Copying messages only
// Abandons an uncommitted container.
void AbandonContainerL( TContainerId aId );
void MoveContainerL( TContainerId aId,
TContainerId aOldParentId,
TContainerId aNewParentId,
MContainerStoreObserver* aObserver );
void DeleteContainerL( TContainerId aId,
TContainerId aParentId,
TContainerId aGrandparentId,
TContainerId aMailBoxId,
MContainerStoreObserver* aObserver );
// Recursively copies the container. CommitContainerL need not be called for the new container.
TContainerId CopyContainerL( TContainerId aId,
TContainerId aSourceId,
TContainerId aSourceParentId,
TContainerId aDestinationId,
TContainerId aDestinationParentId,
TContainerId aMailBoxId,
MContainerStoreObserver* aObserver );
void ChildrenCountsL( TContainerId aId, TDes8& aCounts );
void TotalCountsL( TContainerId aMailBoxId, TDes8& aCounts );
void ListChildrenL( RArray<TContainerId>& aChildren, // children of aId
TContainerId aId,
TContainerId aParentId = KContainerInvalidId,
TContainerId aType = KContainerTypeAny,
TBool aRecursive = EFalse );
TContainerId FirstChildL( TContainerId aId );
TContainerId FirstChildL( TContainerId aId, TBool& aIsChildEncrypted );
// PROPERTIES FUNCTIONS
void FetchPropertiesL( TContainerId aId,
TContainerId& aParentId,
TContainerId aGrandparentId,
RBuf8& aProperties,
TContainerId aMailboxId = KContainerInvalidId );
// This function is quicker than the FetchPropertiesL because it doesn't check the
// hierarchy of the container.
void FastFetchPropertiesL( TContainerId aId,
TBool aQuickProperties,
TContainerId& aParentId,
RBuf8& aProperties );
TBool PropertyValueL( TContainerId aId,
const TDesC8& aName,
RBuf8& aValue );
void UpdatePropertiesL( TContainerId aId,
TContainerId aParentId,
TContainerId aMailBoxId,
const TDesC8& aProperties,
MContainerStoreObserver* aObserver );
void UpdatePropertyL( TContainerId aId,
TContainerId aParentId,
TContainerId aMailBoxId,
const TDesC8& aName,
TUint8 aType,
const TDesC8& aValue,
MContainerStoreObserver* aObserver );
// CONTENT FUNCTIONS
TUint ContentLengthL( TContainerId aId,
TContainerId aParentId );
void ReplaceContentL( TContainerId aId,
TContainerId aParentId,
const TDesC8& aContent,
MContainerStoreObserver* aObserver );
void ReplaceContentL( TContainerId aId,
TContainerId aParentId,
RFile& aContentFile,
MContainerStoreObserver* aObserver );
void AppendContentL( TContainerId aId,
TContainerId aParentId,
const TDesC8& aContent,
MContainerStoreObserver* aObserver );
void PrependContentL( TContainerId aId,
TContainerId aParentId,
const TDesC8& aContent,
MContainerStoreObserver* aObserver );
void RemoveContentL( TContainerId aId,
TContainerId aParentId,
MContainerStoreObserver* aObserver );
// will truncate the content if the content buffer is too small
void FetchContentL( TContainerId aId,
TContainerId aParentId,
TDes8& aContent,
TUint aStartPosition = 0 );
void FetchContentL( TContainerId aId,
TContainerId aParentId,
RFile& aDestinationFile );
void OpenContentFileL( TContainerId aId,
TContainerId aParentId,
RFs& aFs,
RFile& aDestinationFile );
// SEARCH FUNCTIONS
// Currently only the content is searched.
CContainerStoreSearchHandler* SearchL( TContainerId aType,
TMsgStoreSearchCmdParams& aCmdParam,
RPointerArray<HBufC>& aSearchStrings,
RArray<TContainerId>& aFolderIds,
RPointerArray<HBufC8>& aPropertyNames,
MContainerStoreSearchClient& aSearchClient );
// SORTING FUNCTIONS
TContainerId StartSortingL( TMsgStoreSortCriteria& aSortCriteria,
RPointerArray<HBufC8>& aPropertyNames,
TBool aInMemorySort );
void EndSortingL( TContainerId aSessionId );
TBool GetSortedRowsL( TMsgStoreGetSortedRowsCmdParams aParams, RBuf8& aPropertiesBuf, const TDesC& aStartWith = KNullDesC );
TInt IteratorGroupCountL( TContainerId aSessionId, RArray<TUint>& aItemsInGroup );
void SortedIdsAndFlagsL( TContainerId aSessionId, RArray<TContainerId>& aIdArray, RArray<TUint32>& aFlagArray );
TInt SortedIndexOfL( TContainerId aSessionId, TContainerId aMessageId );
void SortedIdsL( TContainerId aSessionId, RArray<TContainerId>& aIdArray );
void SortedIdsAndGroupCountL( TContainerId aSessionId, RArray<TContainerId>& aIdArray, RArray<TUint>& aItemsInGroup );
//MRU address related methods
void SetMaxMruCountL( TInt aCount );
void SetMruAddressListL( TContainerId aMailboxId, RPointerArray<CMruAddress>& aMruAddressArray );
const RPointerArray<CMruAddress>& MruAddressListL( TContainerId aMailboxId );
//Methods inherited from MEncryptableTable
TBool EncryptFirstL( TDbBookmark& aNextRow );
TBool EncryptNextL( TDbBookmark& aNextRow );
TBool DecryptFirstL( TDbBookmark& aNextRow );
TBool DecryptNextL( TDbBookmark& aNextRow );
/**
* Allocates a block of container ids in a single transaction. Once
* allocated these ids cannot be "freed".
*/
void AllocateIdsBlockL(
RArray<TContainerId>& aIds,
TInt aBlockSize = 4 );
CContainerStoreUtils& StoreUtils();
CContainerStoreContentManager& ContentManager();
TBool IsEncryptionEnabled();
void BeginDatabaseTransactionLC();
void CommitDatabaseTransactionL();
const TDesC& PrivatePath();
#ifdef _DEBUG
void SimulateLowDiskSpace( TInt aLatency );
TInt GetEncryptionStateL();
#endif
private:
// ===============
// PRIVATE METHODS
// ===============
CContainerStore( MCustomBehaviorProvider& aCustomBehaviorProvider,
TInt aBasePriority );
void ConstructL( const TDesC& aDbFilename,
MBackgroundOperationsObserver& aBackgroundOperationsObserver,
TDriveNumber aDriveNumber );
void CreateTablesL();
void OpenTablesL();
void CloseTables();
void MarkUncommittedContainersForDeleteL();
void NotifyObservers( MContainerStoreObserver::TOperation aOperation,
const RArray<TContainerId>& aHierarchy,
const TDesC8& aQuickProperties,
MContainerStoreObserver* aDoNotNotify,
TContainerId aOtherId = KContainerInvalidId );
void NotifyObservers( TBool aAuthenticated );
void NotifyObservers( MContainerStoreObserver::TOperation aOperation,
TInt32 aOwnerId,
const TDesC8& aName,
const TDesC8& aNewName,
TContainerId aMailboxId,
MContainerStoreObserver* aDoNotNotify);
void ValidateParentL( TContainerId aParentId,
const RArray<TContainerId>& aHierarchy,
TBool aStrictComparison = ETrue );
void ValidateParentAndGrandparentL( TContainerId aParentId,
TContainerId aGrandparentId,
const RArray<TContainerId>& aHierarchy,
TBool aStrictComparison = ETrue );
TContainerId RecursiveCopyL( TUint aDepth,
TContainerId aId,
TContainerId aDestinationId );
void DoAbandonContainerL( TContainerId aId );
// DELETE HANDLER SUPPORT FUNCTIONS
friend class CDeleteHandler;
void FirstChildL( TContainerId aId,
TContainerId& aChildId,
TDbBookmark& aBookmark );
TBool DeleteIndividualContainerL( TDbBookmark aBookmark );
void GetSortableFieldsL( TContainerId aMessageId, RMsgStoreSortableFields& aSortableFields );
void CreateSystemFoldersL( TContainerId aMailboxId );
// =====================================
// Inherited from MSortingTableObserver
// =====================================
void MessageUpdate ( TContainerId aMessageId,
TContainerId aFolderId,
TMsgStoreOperation aOperation, //EMsgStoreAdd, EMsgStoreDelete, EMsgStoreUpdateProperties
TUint aFieldsChanged = 0, //For EMsgStoreUpdateProperties only, combinations of TSortableFieldsMasks
const TDesC& aFromVal = KNullDesC,
const TDesC& aToVal = KNullDesC,
const TDesC& aSubjectVal = KNullDesC,
TInt64 aReceivedDate = 0 );
void FolderDeleted ( TContainerId aFolderId );
void MailBoxDeleted ( TContainerId aMailBoxId );
TUint FindSortingSessionL( TContainerId aSessionId );
// ==================
// PRIVATE ATTRIBUTES
// ==================
MCustomBehaviorProvider& iCustomBehaviorProvider;
const TInt iBasePriority;
TUint iCountsLength;
CContainerStoreUtils* iUtils;
CContainerStoreEncryption* iEncryption;
CContainerStoreGeneralTable* iGeneralTable;
CContainerStoreAccountTable* iAccountTable;
CContainerStoreContainersTable* iContainersTable;
CContainerStoreSortingTable* iSortingTable;
CContainerStoreSearchResultTable* iSearchResultTable;
CContainerStoreMruAddressTable* iMruAddressTable;
CContainerStoreContentManager* iContentManager;
CMessageStoreEncryptHandler* iEncryptHandler;
RPointerArray<MContainerStoreObserver> iObservers;
CDeleteHandler* iDeleteHandler;
RBuf8 iTotalCounts;
// These variables are declared here because these types of data are very commonly used,
// and by declaring them here once we can avoid quite a few heap allocations/deallocations.
RArray<TContainerId> iHierarchy;
RBuf8 iQuickProperties;
RBuf8 iTotalCountsDelta;
TContainerId iNextSortSessionId; //running ID for sort sessions
RArray<TSortSession> iSortSessions;
__LOG_DECLARATION
}; // end class CContainerStore
/** The interface to be implemented by container store clients, to provide domain-specific behaviors. */
class MCustomBehaviorProvider
{
public:
// ==============
// PUBLIC METHODS
// ==============
virtual void QuickPropertiesAndCountsL( TContainerId aType,
const TDesC8& aProperties,
RBuf8& aQuickProperties,
TDes8& aCounts ) const = 0;
virtual void SortableFieldsL( const TDesC8& aQuickProperties, const TDesC8& aProperties, RMsgStoreSortableFields& aSortableFields ) const = 0;
virtual void LengthsL( TUint& aCountsLength,
TUint& aQuickPropertiesMaxLength ) const = 0;
virtual void InitializeCounts( TDes8& aCounts ) const = 0;
virtual void IncrementParentCounts( TDes8& aParentCounts, const TDesC8& aChildCounts ) const = 0;
virtual void DecrementParentCounts( TDes8& aParentCounts, const TDesC8& aChildCounts ) const = 0;
virtual void LogCounts( const TDesC& aDescription, const TDesC8& aCounts ) const = 0;
}; // end MCustomBehaviorProvider
/** The interface to be implemented observer's that need to be notified of background operations. */
class MBackgroundOperationsObserver
{
public:
// ==============
// PUBLIC METHODS
// ==============
virtual void BackgroundOperationsInProgress() = 0;
virtual void BackgroundOperationsCompleted() = 0;
}; // end class MBackgroundOperationsObserver
#endif // __CONTAINER_STORE_H__