emailservices/emailstore/message_store/server/src/ContainerStore.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Container store implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========
       
    21 // INCLUDES
       
    22 // ========
       
    23 
       
    24 #include <bautils.h>
       
    25 
       
    26 #include "MsgStoreTypes.h"
       
    27 #include "ContainerStore.h"
       
    28 #include "ContainerStoreContainersTable.h"
       
    29 #include "ContainerStoreContentManager.h"
       
    30 #include "ContainerStoreDefs.h"
       
    31 #include "ContainerStoreDeleteHandler.h"
       
    32 #include "ContainerStoreEncryption.h"
       
    33 #include "ContainerStoreGeneralTable.h"
       
    34 #include "ContainerStoreAccountTable.h"
       
    35 #include "ContainerStoreSortingTable.h"
       
    36 #include "ContainerStoreUtils.h"
       
    37 #include "MsgStoreSortResultRowSet.h"
       
    38 #include "PropertiesSerializer.h"
       
    39 #include "ContainerStoreSearchHandler.h"
       
    40 #include "ContainerStoreSearchResultTable.h"
       
    41 #include "MessageStoreEncryptHandler.h"
       
    42 #include "ContainerStoreMRUAddressTable.h"
       
    43 #include "MsgStorePropertyKeys.h"
       
    44 
       
    45 // =========
       
    46 // CONSTANTS
       
    47 // =========
       
    48 
       
    49 _LIT8( KNullDes, "" );
       
    50 
       
    51 // The maximum recursion depth for the recursive copy function.
       
    52 const TUint KMaxRecursionDepth = 40;
       
    53 
       
    54 // Priorities, in descending order.
       
    55 const TInt KSearchPriorityOffset     = 0;
       
    56 const TInt KEncryptPriorityOffset    = -1;
       
    57 const TInt KDeletePriorityOffset     = -2;
       
    58 const TInt KCompactionPriorityOffset = -3;
       
    59 
       
    60 void RMsgStoreSortableFields::Close()
       
    61     {
       
    62     iSubject.Close();
       
    63     iFrom.Close();
       
    64     iTo.Close();
       
    65     }
       
    66 
       
    67 // ======================
       
    68 // METHOD IMPLEMENTATIONS
       
    69 // ======================
       
    70 
       
    71 // ==========================================================================
       
    72 // FUNCTION: NewL
       
    73 // ==========================================================================
       
    74 CContainerStore* CContainerStore::NewL( const TDesC&                   aDbFilename,
       
    75 									    TDriveNumber                   aDriveNumber, 
       
    76 									    MCustomBehaviorProvider&       aCustomBehaviorProvider,
       
    77 									    MBackgroundOperationsObserver& aBackgroundOperationsObserver, 
       
    78 									    TInt                           aBasePriority )
       
    79 	{
       
    80     CContainerStore* self = new( ELeave ) CContainerStore( aCustomBehaviorProvider, 
       
    81     													   aBasePriority );
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructL( aDbFilename, aBackgroundOperationsObserver, aDriveNumber );
       
    84     CleanupStack::Pop( self );
       
    85     return self;
       
    86 	} // end NewL
       
    87 
       
    88 // ==========================================================================
       
    89 // FUNCTION: Constructor
       
    90 // ==========================================================================
       
    91 CContainerStore::CContainerStore( MCustomBehaviorProvider& aCustomBehaviorProvider, 
       
    92 								  TInt                     aBasePriority ) :
       
    93 	iCustomBehaviorProvider( aCustomBehaviorProvider ),
       
    94 	iBasePriority( aBasePriority ),
       
    95     iNextSortSessionId( 0 )
       
    96 	{
       
    97 	__LOG_CONSTRUCT( "msg", "CContainerStore" )
       
    98 	} // end Constructor
       
    99 
       
   100 // ==========================================================================
       
   101 // FUNCTION: ConstructL
       
   102 // ==========================================================================
       
   103 void CContainerStore::ConstructL( const TDesC&                   aDbFilename,
       
   104 							      MBackgroundOperationsObserver& aBackgroundOperationsObserver,
       
   105                                   TDriveNumber                   aDriveNumber )
       
   106 	{
       
   107 	__LOG_ENTER( "ConstructL" )
       
   108 
       
   109     TUint quickPropertiesLength;
       
   110         
       
   111     iCustomBehaviorProvider.LengthsL( iCountsLength, quickPropertiesLength );
       
   112     
       
   113     iQuickProperties.CreateL( quickPropertiesLength );
       
   114 
       
   115 	iTotalCountsDelta.CreateL( iCountsLength );
       
   116 	
       
   117 	iDeleteHandler = CDeleteHandler::NewL( *this, 
       
   118 	                                       aBackgroundOperationsObserver, 
       
   119 	                                       iBasePriority + KDeletePriorityOffset );
       
   120 	
       
   121 	iUtils = CContainerStoreUtils::NewL( aDriveNumber, 
       
   122 	                                     iBasePriority + KCompactionPriorityOffset, 
       
   123 	                                     aDbFilename,
       
   124 	                                     *iDeleteHandler );
       
   125 	
       
   126 	iEncryption = CContainerStoreEncryption::NewL();
       
   127 	
       
   128 	// Open an existing database.
       
   129     TRAPD( err, iUtils->OpenDatabaseL(); OpenTablesL() );
       
   130     
       
   131 	switch( err )
       
   132 		{
       
   133 		case KErrNone:
       
   134 		
       
   135             // Success!  Nothing else to do.            
       
   136 			break;
       
   137 			
       
   138 		case KErrPathNotFound: // private path does not yet exist
       
   139 		case KErrNotFound:     // file not found, table not found
       
   140 		case KErrEof:          // something is wrong with the file
       
   141 		case KErrCorrupt:      // schema version mismatch
       
   142 			
       
   143 			__LOG_WRITE8_FORMAT1_ERROR( "open failed (%i), recreating database", err );
       
   144 			
       
   145 			CloseTables();
       
   146 	        iUtils->CloseDatabaseL();
       
   147 
       
   148 			// Unable to open the database. Create a new database.
       
   149     		iUtils->CreateDatabaseL();
       
   150     		CreateTablesL();
       
   151 			break;
       
   152 			
       
   153 		default:
       
   154 
       
   155 			// Something unexpected has occurred.
       
   156 			__LOG_WRITE8_FORMAT1_ERROR( "unable to open database (%i)", err );			
       
   157 			User::Leave( err );
       
   158 			break;
       
   159 			
       
   160 		}; // end switch
       
   161 		
       
   162     iEncryptHandler = CMessageStoreEncryptHandler::NewL( *iGeneralTable, *iUtils, iBasePriority + KEncryptPriorityOffset );
       
   163     iEncryptHandler->AddEncryptableTableL( this );
       
   164     iEncryptHandler->AddEncryptableTableL( iAccountTable );
       
   165     iEncryptHandler->AddEncryptableTableL( iSortingTable );
       
   166     iEncryptHandler->AddEncryptableTableL( iMruAddressTable );
       
   167     iEncryptHandler->StartL();
       
   168         
       
   169     iEncryption->SetAuthenticationRequired( iGeneralTable->IsAuthenticateRequiredL() );
       
   170 	iEncryption->SetEncryptionFlag( iGeneralTable->IsEncryptionOnL() );
       
   171 
       
   172     //Initialize the MRU address list
       
   173     //It leaves if the DB is not authenticated, so trap it and ignore it
       
   174     TRAP_IGNORE( iMruAddressTable->InitializeIfNeededL() );
       
   175 
       
   176 	iContentManager = CContainerStoreContentManager::NewL( *iUtils, *iEncryption );
       
   177 	
       
   178 	// Cleanup any uncommitted containers.
       
   179 	MarkUncommittedContainersForDeleteL();
       
   180 	
       
   181 	// Start the background delete operation.
       
   182 	iDeleteHandler->Start();
       
   183 
       
   184     // Read the total counts.
       
   185 	iTotalCounts.CreateL( iCountsLength );
       
   186 	
       
   187 	__LOG_EXIT
       
   188 	} // end ConstructL
       
   189 		
       
   190 // ==========================================================================
       
   191 // FUNCTION: Destructor
       
   192 // ==========================================================================
       
   193 CContainerStore::~CContainerStore()
       
   194 	{
       
   195 	delete iDeleteHandler;
       
   196 
       
   197     for ( int i = 0 ; i < iSortSessions.Count() ; i++ )
       
   198         {
       
   199         delete iSortSessions[i].iResultRowSet;
       
   200         }
       
   201     iSortSessions.Close();
       
   202     
       
   203     CloseTables();
       
   204 
       
   205     if ( iUtils )
       
   206         {
       
   207         TRAP_IGNORE( iUtils->CloseDatabaseL() );
       
   208         }
       
   209     
       
   210     delete iEncryptHandler;
       
   211     
       
   212 	delete iContentManager;
       
   213 	
       
   214 	delete iEncryption;
       
   215 	
       
   216 	delete iUtils;
       
   217 	
       
   218 	iObservers.Close();
       
   219 	
       
   220 	iHierarchy.Close();
       
   221 	
       
   222 	iQuickProperties.Close();
       
   223 	
       
   224 	iTotalCountsDelta.Close();
       
   225 	
       
   226 	iTotalCounts.Close();
       
   227     
       
   228 	__LOG_DESTRUCT	
       
   229 	} // end destructor
       
   230 	
       
   231 // ==========================================================================
       
   232 // FUNCTION: WipeEverything
       
   233 // ==========================================================================
       
   234 TInt CContainerStore::WipeEverything( const TDesC& aDbFilename,
       
   235 									  TDriveNumber aDriveNumber )
       
   236     {    
       
   237     RFs fs;
       
   238     TInt result = fs.Connect();
       
   239     if( result == KErrNone )
       
   240         {
       
   241         fs.SetSessionToPrivate( aDriveNumber );
       
   242         
       
   243         // Wipe the database file.
       
   244         BaflUtils::DeleteFile( fs, aDbFilename );
       
   245 
       
   246         // Wipe the content files.
       
   247         CContainerStoreContentManager::WipeContentFiles( fs );
       
   248         
       
   249         fs.Close();
       
   250         
       
   251         } // end if	
       
   252         
       
   253     return result;        
       
   254         
       
   255     } // end WipeEverything
       
   256     
       
   257 // ==========================================================================
       
   258 // FUNCTION: CreateTablesL
       
   259 // ==========================================================================
       
   260 void CContainerStore::CreateTablesL()
       
   261 	{
       
   262 	__LOG_ENTER( "CreateTablesL" )
       
   263 	
       
   264 	iUtils->BeginDatabaseTransactionLC();
       
   265 	
       
   266 	delete iGeneralTable;
       
   267 	iGeneralTable = NULL;
       
   268 	
       
   269 	iGeneralTable = CContainerStoreGeneralTable::CreateL( *iUtils );		
       
   270 	
       
   271 	delete iAccountTable;
       
   272 	iAccountTable = NULL;
       
   273 	
       
   274 	iAccountTable = CContainerStoreAccountTable::CreateL( *iUtils, *iEncryption, iCustomBehaviorProvider );		
       
   275 	
       
   276 	delete iContainersTable;
       
   277 	iContainersTable = NULL;
       
   278 
       
   279 	iContainersTable = CContainerStoreContainersTable::CreateL( *iUtils, iCustomBehaviorProvider, iCountsLength, *iEncryption );
       
   280 	
       
   281 	delete iSortingTable;
       
   282 	iSortingTable = NULL;
       
   283 	
       
   284 	iSortingTable = CContainerStoreSortingTable::CreateL( *iUtils, *iEncryption, *this );
       
   285     
       
   286     delete iSearchResultTable;
       
   287     iSearchResultTable = NULL;
       
   288     
       
   289     iSearchResultTable = CContainerStoreSearchResultTable::CreateL( *iUtils );
       
   290     
       
   291     delete iMruAddressTable;
       
   292     iMruAddressTable = NULL;
       
   293     
       
   294     iMruAddressTable = CContainerStoreMruAddressTable::CreateL( *iUtils, *iEncryption, *iGeneralTable, *iAccountTable );
       
   295 	
       
   296 	iUtils->CommitDatabaseTransactionL();
       
   297 	
       
   298 	__LOG_EXIT
       
   299 	} // end CreateTablesL
       
   300 	
       
   301 // ==========================================================================
       
   302 // FUNCTION: OpenTablesL
       
   303 // ==========================================================================
       
   304 void CContainerStore::OpenTablesL()
       
   305 	{
       
   306 	__LOG_ENTER( "OpenTablesL" )
       
   307 	
       
   308 	delete iGeneralTable;
       
   309     iGeneralTable = NULL;
       
   310     
       
   311 	iGeneralTable = CContainerStoreGeneralTable::OpenL( *iUtils );		
       
   312 	
       
   313 	delete iAccountTable;
       
   314 	iAccountTable = NULL;
       
   315     
       
   316 	iAccountTable = CContainerStoreAccountTable::OpenL( *iUtils, *iEncryption, iCustomBehaviorProvider );		
       
   317 	
       
   318 	delete iContainersTable;
       
   319 	iContainersTable = NULL;
       
   320 	
       
   321 	iContainersTable = CContainerStoreContainersTable::OpenL( *iUtils, iCustomBehaviorProvider, iCountsLength, *iEncryption );
       
   322 	
       
   323 	delete iSortingTable;
       
   324 	iSortingTable = NULL;
       
   325 	
       
   326 	iSortingTable = CContainerStoreSortingTable::OpenL( *iUtils, *iEncryption, *this );
       
   327     
       
   328     delete iSearchResultTable;
       
   329     iSearchResultTable = NULL;
       
   330     
       
   331     iSearchResultTable = CContainerStoreSearchResultTable::OpenL( *iUtils );
       
   332     
       
   333     delete iMruAddressTable;
       
   334     iMruAddressTable = NULL;
       
   335     
       
   336     iMruAddressTable = CContainerStoreMruAddressTable::OpenL( *iUtils, *iEncryption, *iGeneralTable, *iAccountTable );
       
   337 	
       
   338 	__LOG_EXIT
       
   339 	} // end OpenTablesL
       
   340 
       
   341 // ==========================================================================
       
   342 // FUNCTION: CloseTables
       
   343 // ==========================================================================
       
   344 void CContainerStore::CloseTables()
       
   345 	{
       
   346 	__LOG_ENTER( "CloseTables" )
       
   347 	
       
   348 	delete iAccountTable;
       
   349 	iAccountTable = NULL;
       
   350 
       
   351 	delete iGeneralTable;
       
   352 	iGeneralTable = NULL;
       
   353 	
       
   354 	delete iContainersTable;
       
   355 	iContainersTable = NULL;
       
   356 	
       
   357 	delete iSortingTable;
       
   358 	iSortingTable = NULL;
       
   359     
       
   360     delete iSearchResultTable;
       
   361     iSearchResultTable = NULL;
       
   362     
       
   363     delete iMruAddressTable;
       
   364     iMruAddressTable = NULL;
       
   365     
       
   366 	__LOG_EXIT
       
   367 	} // end CloseTables
       
   368 
       
   369 // ==========================================================================
       
   370 // FUNCTION: ObserveL
       
   371 // ==========================================================================
       
   372 void CContainerStore::ObserveL( MContainerStoreObserver* aObserver )
       
   373 	{
       
   374 	__LOG_ENTER( "ObserverL" )
       
   375 	
       
   376 	iObservers.AppendL( aObserver );
       
   377 	
       
   378 	__LOG_EXIT
       
   379 	} // end ObserveL
       
   380 
       
   381 // ==========================================================================
       
   382 // FUNCTION: StopObserving
       
   383 // ==========================================================================
       
   384 void CContainerStore::StopObserving( MContainerStoreObserver* aObserver )
       
   385 	{
       
   386 	__LOG_ENTER( "StopObserving" )
       
   387 	
       
   388 	TBool found = EFalse;
       
   389 	
       
   390 	TInt index = 0;
       
   391 	
       
   392 	while( !found && index < iObservers.Count() )
       
   393 		{
       
   394 		if( iObservers[index] == aObserver )
       
   395 			{
       
   396 			found = ETrue;
       
   397 			iObservers.Remove( index );
       
   398 			}
       
   399 		else
       
   400 			{
       
   401 			index++;
       
   402 			} // end if		
       
   403 				
       
   404 		} // end while
       
   405 		
       
   406     __LOG_EXIT		
       
   407 	} // end StopObservingL
       
   408 
       
   409 // ==========================================================================
       
   410 // FUNCTION: NotifyObservers
       
   411 // ==========================================================================
       
   412 void CContainerStore::NotifyObservers( MContainerStoreObserver::TOperation aOperation,
       
   413 									   const RArray<TContainerId>&         aHierarchy,
       
   414 									   const TDesC8&                       aQuickProperties,
       
   415 									   MContainerStoreObserver* 		   aDoNotNotify,
       
   416 									   TContainerId                        aOtherId )		
       
   417 	{
       
   418 	__LOG_ENTER_SUPPRESS( "NotifyObservers" )
       
   419 	if ( aHierarchy.Count() > 1 )
       
   420 	    {
       
   421 	__LOG_WRITE8_FORMAT4_INFO( "op=%i id=%x pid=%x otherid=%x", aOperation, aHierarchy[0], aHierarchy[1], aOtherId );
       
   422 	    }
       
   423 	
       
   424 	// if aDoNotNotify is NULL or if the operation was for an uncommitted object then suppress this
       
   425 	// notification entirely.
       
   426 	
       
   427 	if( aDoNotNotify && aHierarchy[aHierarchy.Count()-1] != KUncommittedContainers )
       
   428 	    {	    
       
   429     	for( TInt index = 0; index < iObservers.Count(); index++ )
       
   430     		{
       
   431     		if( iObservers[index] != aDoNotNotify )
       
   432     			{
       
   433     			__LOG_WRITE8_FORMAT1_INFO( "Notifying observer %i", index );
       
   434     			iObservers[index]->ContainerModified( aOperation, aHierarchy, aOtherId, aQuickProperties );			
       
   435     			} // end if
       
   436     			
       
   437     		} // end for
       
   438 	    } // end if
       
   439 	    
       
   440     __LOG_EXIT	    
       
   441 	} // end NotifyObservers
       
   442 	
       
   443 // ==========================================================================
       
   444 // FUNCTION: NotifyObservers
       
   445 // ==========================================================================
       
   446 void CContainerStore::NotifyObservers( TBool aAuthenticated )
       
   447     {
       
   448 	__LOG_ENTER_SUPPRESS( "NotifyObservers" )
       
   449     __LOG_WRITE8_FORMAT1_INFO( "authenticated=%i", aAuthenticated )
       
   450     
       
   451 	for( TInt index = 0; index < iObservers.Count(); index++ )
       
   452 		{
       
   453 		iObservers[index]->AuthenticationChanged( aAuthenticated );
       
   454 		} // end for
       
   455 		
       
   456     __LOG_EXIT		
       
   457     } // end NotifyObservers
       
   458 
       
   459 void CContainerStore::NotifyObservers( MContainerStoreObserver::TOperation aOperation,
       
   460 									   TInt32 aOwnerId,
       
   461 									   const TDesC8& aName,
       
   462 									   const TDesC8& aNewName,
       
   463                                        TContainerId  aMailboxId,
       
   464 									   MContainerStoreObserver* aDoNotNotify )
       
   465 	{
       
   466 	__LOG_ENTER_SUPPRESS( "NotifyObservers" )
       
   467 	__LOG_WRITE8_FORMAT4_INFO( "op=%i id=%x name=%S newName=%S", aOperation, aOwnerId, &aName, &aNewName );
       
   468     
       
   469 	if( aDoNotNotify )
       
   470 		{
       
   471 		for( TInt index = 0; index < iObservers.Count(); index++ )
       
   472 			{
       
   473     		if( iObservers[index] != aDoNotNotify )
       
   474     			{
       
   475     			__LOG_WRITE8_FORMAT1_INFO( "Notifying observer %i", index );
       
   476     			iObservers[index]->AccountModified(  aOperation, aOwnerId, aName, aNewName, aMailboxId );
       
   477     			}
       
   478 			} // end for
       
   479 		}
       
   480 	
       
   481     __LOG_EXIT		
       
   482 	}
       
   483 	
       
   484 // ==========================================================================
       
   485 // FUNCTION: CreatePredefinedContainerIfNeededL
       
   486 // ==========================================================================
       
   487 void CContainerStore::CreatePredefinedContainerIfNeededL( TContainerId  aId,
       
   488 														  TContainerId  aType,
       
   489 														  TContainerId  aParentId, 
       
   490 														  const TDesC8& aProperties )
       
   491 	{
       
   492 	__LOG_ENTER_SUPPRESS( "CreatePredefinedContainerIfNeededL" )
       
   493 	__LOG_WRITE8_FORMAT3_INFO( "id=%x type=%x pid=%x", aId, aType, aParentId )
       
   494 	
       
   495 	TRAPD( result, iContainersTable->SeekL( aId ) );
       
   496 
       
   497 	if( result == KErrNotFound )
       
   498 		{
       
   499 		aId = aId | aType;
       
   500 
       
   501 		iUtils->BeginDatabaseTransactionLC();	
       
   502 		iContainersTable->CreateContainerL( aId, aParentId, aProperties, iQuickProperties );		
       
   503 		iUtils->CommitDatabaseTransactionL();
       
   504 				
       
   505 		} // end if
       
   506 	
       
   507 	__LOG_EXIT
       
   508 	} // end CreatePredefinedContainerIfNeededL
       
   509 
       
   510 // ==========================================================================
       
   511 // FUNCTION: Authenticated
       
   512 // ==========================================================================
       
   513 TBool CContainerStore::Authenticated()
       
   514     {
       
   515     return iEncryption->Authenticated();
       
   516     } // end Authenticated
       
   517 	
       
   518 // ==========================================================================
       
   519 // FUNCTION: AuthenticateL
       
   520 // ==========================================================================
       
   521 TBool CContainerStore::AuthenticateL( const TDesC& aPassword )
       
   522 	{
       
   523 	__LOG_ENTER( "AuthenticateL" )
       
   524 	
       
   525 	CContainerStoreUtils::LeaveIfFalse( iEncryption->IsAuthenticationRequired(), KErrNotSupported );
       
   526     
       
   527     RBuf8 buffer;
       
   528     CleanupClosePushL( buffer );
       
   529     
       
   530 	iGeneralTable->GetAuthenticationDataL( buffer );
       
   531 
       
   532     TBool oldAuthenticated = iEncryption->Authenticated();
       
   533     	
       
   534 	TBool returnValue = iEncryption->AuthenticateL( aPassword, buffer );
       
   535 	
       
   536 	TBool newAuthenticated = iEncryption->Authenticated();
       
   537 	
       
   538 	CleanupStack::PopAndDestroy( &buffer );
       
   539 
       
   540     if( oldAuthenticated != newAuthenticated )
       
   541         {
       
   542         NotifyObservers( newAuthenticated );
       
   543         } // end if
       
   544 	
       
   545 	__LOG_EXIT8_FORMAT1( "returnValue=%i", returnValue )
       
   546 	return returnValue;	
       
   547 	
       
   548 	} // end AuthenticateL
       
   549 
       
   550 // ==========================================================================
       
   551 // FUNCTION: ClearAuthentication
       
   552 // ==========================================================================
       
   553 void CContainerStore::ClearAuthentication()
       
   554 	{
       
   555 	__LOG_ENTER( "ClearAuthentication" )
       
   556 	
       
   557     TBool oldAuthenticated = iEncryption->Authenticated();
       
   558 
       
   559     iEncryption->ClearAuthentication();
       
   560         	
       
   561     if( oldAuthenticated )
       
   562         {
       
   563         NotifyObservers( EFalse );
       
   564         } // end if
       
   565 	
       
   566 	__LOG_EXIT
       
   567 	} // end ClearAuthenticationL
       
   568 
       
   569 // ==========================================================================
       
   570 // FUNCTION: HasPasswordL
       
   571 // ==========================================================================
       
   572 TBool CContainerStore::HasPasswordL()
       
   573     {
       
   574     return iGeneralTable->AuthenticationDataPresentL();
       
   575     } // end HasPasswordL
       
   576 
       
   577 
       
   578 
       
   579 // ==========================================================================
       
   580 // FUNCTION: SetPasswordL
       
   581 // ==========================================================================
       
   582 void CContainerStore::SetPasswordL( const TDesC& aPassword )
       
   583 	{
       
   584 	__LOG_ENTER( "SetPasswordL" )
       
   585 	
       
   586 	if ( iGeneralTable->AuthenticationDataPresentL() )
       
   587         {
       
   588         User::Leave( KErrAlreadyExists );
       
   589         }
       
   590 	
       
   591     RBuf8 buffer;
       
   592     CleanupClosePushL( buffer );
       
   593 
       
   594     iEncryption->CreateAuthenticationBufferL( aPassword, buffer );    
       
   595         
       
   596 	iUtils->BeginDatabaseTransactionLC();	
       
   597     iGeneralTable->SetAuthenticationDataL( buffer );
       
   598     
       
   599     //Enable the authentication required flag. 
       
   600     //From this point on, authentication is required
       
   601     iGeneralTable->SetAuthenticationRequiredL( ETrue );
       
   602     iEncryption->SetAuthenticationRequired( ETrue );
       
   603     
       
   604     iUtils->CommitDatabaseTransactionL();
       
   605     
       
   606     CleanupStack::PopAndDestroy( &buffer );
       
   607 	
       
   608     NotifyObservers( ETrue );
       
   609 	
       
   610 	__LOG_EXIT         
       
   611 	} // end SetPasswordL
       
   612 
       
   613 // ==========================================================================
       
   614 // FUNCTION: ChangePasswordL
       
   615 // ==========================================================================
       
   616 TBool CContainerStore::ChangePasswordL( const TDesC& aOldPassword, const TDesC& aNewPassword )
       
   617 	{
       
   618 	__LOG_ENTER( "ChangePasswordL" )
       
   619 	
       
   620 	CContainerStoreUtils::LeaveIfFalse( iEncryption->IsAuthenticationRequired(), KErrNotSupported );
       
   621 	
       
   622     RBuf8 buffer;
       
   623     CleanupClosePushL( buffer );
       
   624 
       
   625     TBool oldAuthenticated = iEncryption->Authenticated();
       
   626     	
       
   627 	iGeneralTable->GetAuthenticationDataL( buffer );
       
   628 
       
   629 	TBool oldPasswordOk = iEncryption->AuthenticateL( aOldPassword, buffer );
       
   630 	
       
   631     if( oldPasswordOk )
       
   632         {
       
   633         buffer.Close();
       
   634         
       
   635         iEncryption->CreateAuthenticationBufferL( aNewPassword, buffer );    
       
   636         
       
   637     	iUtils->BeginDatabaseTransactionLC();	
       
   638         iGeneralTable->SetAuthenticationDataL( buffer );
       
   639         iUtils->CommitDatabaseTransactionL();
       
   640         
       
   641         } // end if
       
   642 
       
   643 	CleanupStack::PopAndDestroy( &buffer );
       
   644 
       
   645     if( oldAuthenticated != iEncryption->Authenticated() )
       
   646         {
       
   647         NotifyObservers( iEncryption->Authenticated() );
       
   648         } // end if
       
   649 	
       
   650 	__LOG_EXIT8_FORMAT1( "oldPasswordOk=%i", oldPasswordOk )
       
   651 	return oldPasswordOk;	
       
   652 
       
   653 	} // end ChangePasswordL
       
   654 
       
   655 // ==========================================================================
       
   656 // FUNCTION: EnableEncryptionL
       
   657 // ==========================================================================
       
   658 void CContainerStore::EnableEncryptionL()
       
   659     {
       
   660     __LOG_ENTER( "EnableEncryptionL" );
       
   661 
       
   662     //leave if password has not been set, or
       
   663     // client has not authenticated with the store yet
       
   664     if ( !iGeneralTable->AuthenticationDataPresentL() ||
       
   665          !iEncryption->Authenticated()                   )
       
   666         {
       
   667         User::Leave( KErrNotReady );
       
   668         }
       
   669     //leave if authentication is already on
       
   670     else if ( iGeneralTable->IsEncryptionOnL() )
       
   671         {
       
   672         User::Leave( KErrAlreadyExists );
       
   673         }
       
   674     
       
   675     iUtils->BeginDatabaseTransactionLC();
       
   676     
       
   677     iGeneralTable->SetEncryptionFlagL( ETrue );
       
   678     iEncryption->SetEncryptionFlag( ETrue );
       
   679     
       
   680     iEncryptHandler->EncryptL();
       
   681     
       
   682     iUtils->CommitDatabaseTransactionL();
       
   683     
       
   684     __LOG_EXIT
       
   685     }
       
   686 
       
   687 // ==========================================================================
       
   688 // FUNCTION: DisableEncryptionL
       
   689 // ==========================================================================
       
   690 void CContainerStore::DisableEncryptionL()
       
   691     {
       
   692     __LOG_ENTER( "DisableEncryptionL" );
       
   693     
       
   694     //leave if password has not been set, or
       
   695     // client has not authenticated with the store yet
       
   696     if ( !iGeneralTable->AuthenticationDataPresentL() ||
       
   697          !iEncryption->Authenticated()                   )
       
   698            {
       
   699            User::Leave( KErrNotReady );
       
   700            }
       
   701     //leave if authenticaion is NOT on
       
   702     else if ( !iGeneralTable->IsEncryptionOnL() )
       
   703         {
       
   704         User::Leave( KErrAlreadyExists );
       
   705         }
       
   706     
       
   707     iUtils->BeginDatabaseTransactionLC();
       
   708     
       
   709     iGeneralTable->SetEncryptionFlagL( EFalse );
       
   710     iEncryption->SetEncryptionFlag( EFalse );
       
   711     
       
   712     iEncryptHandler->DecryptL();
       
   713     
       
   714     iUtils->CommitDatabaseTransactionL();
       
   715 
       
   716     __LOG_EXIT
       
   717     }
       
   718 
       
   719 // ==========================================================================
       
   720 // FUNCTION: CreateAccountL
       
   721 // ==========================================================================
       
   722 TContainerId CContainerStore::CreateAccountL( TInt32 aOwnerId, const TDesC& aName, MContainerStoreObserver* aDoNotNotify, const TDesC8& aProperties )
       
   723 	{
       
   724 	__LOG_ENTER_SUPPRESS( "CreateAccountL" );
       
   725 	__LOG_WRITE_FORMAT2_INFO( "ownerId=%i name=%S", aOwnerId, &aName );
       
   726 	
       
   727 	//convert name to 8 bits
       
   728 	TPtrC8 name8;
       
   729 	const TUint8* valuePtr8 = reinterpret_cast<const TUint8*>( aName.Ptr() );
       
   730 	name8.Set( valuePtr8, aName.Length() * 2 );
       
   731 	
       
   732 	TContainerId mailboxId = KMsgStoreInvalidId;
       
   733 	
       
   734 	TRAPD(err, mailboxId = iAccountTable->FindAccountL( aOwnerId, name8 ) )
       
   735 	if ( err == KErrNone )
       
   736 		{
       
   737 		User::Leave( KErrAlreadyExists );
       
   738 		}
       
   739 	else if ( err != KErrNotFound )
       
   740 		{
       
   741 		User::Leave( err );
       
   742 		}
       
   743 	
       
   744 	iUtils->BeginDatabaseTransactionLC();	
       
   745 	
       
   746 	mailboxId = CreateContainerL( EMsgStoreMailBoxBits, KMsgStoreRootMailBoxId, KMsgStoreInvalidId, aProperties );
       
   747 		
       
   748 	iAccountTable->AddAccountL( mailboxId, aOwnerId, name8 );
       
   749     
       
   750     iMruAddressTable->AddMailboxL( mailboxId );
       
   751 	
       
   752 	CommitContainerL( mailboxId, KMsgStoreRootMailBoxId, mailboxId, NULL );
       
   753 	
       
   754 	//create system folders, do not leave
       
   755 	TRAP_IGNORE( CreateSystemFoldersL( mailboxId ) );
       
   756 	
       
   757     iUtils->CommitDatabaseTransactionL();
       
   758     
       
   759     NotifyObservers( MContainerStoreObserver::EAdd, aOwnerId, name8, KNullDesC8, mailboxId, aDoNotNotify );
       
   760 	
       
   761     return mailboxId;
       
   762 	}
       
   763 
       
   764 // ==========================================================================
       
   765 // FUNCTION: OpenAccountL
       
   766 // ==========================================================================
       
   767 TContainerId CContainerStore::OpenAccountL( TInt32 aOwnerId, const TDesC& aName, RBuf8& aProperties )
       
   768 	{
       
   769 	__LOG_ENTER_SUPPRESS( "OpenAccountL" );
       
   770 	__LOG_WRITE_FORMAT2_INFO( "ownerId=%i name=%S", aOwnerId, &aName );
       
   771 	
       
   772 	//convert name to 8 bits
       
   773 	TPtrC8 name8;
       
   774 	const TUint8* valuePtr8 = reinterpret_cast<const TUint8*>( aName.Ptr() );
       
   775 	name8.Set( valuePtr8, aName.Length() * 2 );
       
   776 	
       
   777 	TContainerId mailboxId = iAccountTable->FindAccountL( aOwnerId, name8 );
       
   778 	
       
   779 	TContainerId parentId = KMsgStoreRootMailBoxId;
       
   780 	FetchPropertiesL( mailboxId, parentId, KMsgStoreInvalidId, aProperties );
       
   781 	
       
   782     return mailboxId;
       
   783 	}
       
   784 
       
   785 // ==========================================================================
       
   786 // FUNCTION: RenameAccountL
       
   787 // ==========================================================================
       
   788 void CContainerStore::RenameAccountL( TInt32 aOwnerId, const TDesC& aOldName, const TDesC& aNewName, MContainerStoreObserver* aDoNotNotify )
       
   789 	{
       
   790 	__LOG_ENTER_SUPPRESS( "RenameAccountL" );
       
   791 	__LOG_WRITE_FORMAT3_INFO( "ownerId=%i oldName=%S newName=%S", aOwnerId, &aOldName, &aNewName );
       
   792 	
       
   793 	//convert names to 8 bits
       
   794 	TPtrC8 oldName8;
       
   795 	const TUint8* oldValPtr8 = reinterpret_cast<const TUint8*>( aOldName.Ptr() );
       
   796 	oldName8.Set( oldValPtr8, aOldName.Length() * 2 );
       
   797 	
       
   798 	TPtrC8 newName8;
       
   799 	const TUint8* newValPtr8 = reinterpret_cast<const TUint8*>( aNewName.Ptr() );
       
   800 	newName8.Set( newValPtr8, aNewName.Length() * 2 );
       
   801 	
       
   802 	iAccountTable->RenameAccountL( aOwnerId, oldName8, newName8 );
       
   803     
       
   804     TContainerId mailboxId = iAccountTable->FindAccountL( aOwnerId, newName8 );
       
   805 	
       
   806     NotifyObservers( MContainerStoreObserver::ERenameAccount, aOwnerId, oldName8, newName8, mailboxId, aDoNotNotify );	
       
   807 	}
       
   808 
       
   809 // ==========================================================================
       
   810 // FUNCTION: DeleteAccountL
       
   811 // ==========================================================================
       
   812 void CContainerStore::DeleteAccountL( TInt32 aOwnerId, const TDesC& aName, MContainerStoreObserver* aDoNotNotify )
       
   813 	{
       
   814 	__LOG_ENTER_SUPPRESS( "DeleteAccountL" );
       
   815 	__LOG_WRITE_FORMAT2_INFO( "ownerId=%i name=%S", aOwnerId, &aName );
       
   816 	
       
   817 	//convert name to 8 bits
       
   818 	TPtrC8 name8;
       
   819 	const TUint8* valuePtr8 = reinterpret_cast<const TUint8*>( aName.Ptr() );
       
   820 	name8.Set( valuePtr8, aName.Length() * 2 );
       
   821 	
       
   822 	TContainerId mailboxId = iAccountTable->FindAccountL( aOwnerId, name8 );
       
   823 	
       
   824 	iUtils->BeginDatabaseTransactionLC();	
       
   825 	
       
   826 	//NOTE: must delete it from container table BEFORE deleting it from account table
       
   827 	//otherwise accountTable->UpdateTotalCounts() will leave.
       
   828 	DeleteContainerL( mailboxId, KMsgStoreInvalidId, KMsgStoreInvalidId, mailboxId, NULL );
       
   829 	iAccountTable->DeleteAccountL( aOwnerId, name8 );
       
   830     
       
   831     iMruAddressTable->DeleteMailboxL( mailboxId );
       
   832 	
       
   833     iUtils->CommitDatabaseTransactionL();
       
   834     
       
   835     NotifyObservers( MContainerStoreObserver::EDelete, aOwnerId, name8, KNullDesC8, mailboxId, aDoNotNotify );
       
   836 	}
       
   837 
       
   838 // ==========================================================================
       
   839 // FUNCTION: ListAccountsL
       
   840 // ==========================================================================
       
   841 void CContainerStore::ListAccountsL( TDes8& aBuf )
       
   842 	{
       
   843 	iAccountTable->AccountsL( aBuf );
       
   844 	}
       
   845 
       
   846 
       
   847 // ==========================================================================
       
   848 // FUNCTION: CreateContainerL
       
   849 // ==========================================================================
       
   850 TContainerId CContainerStore::CreateContainerL(
       
   851     TContainerId  aType,
       
   852     TContainerId  aParentId, 
       
   853     TContainerId  aGrandparentId, 
       
   854     const TDesC8& aProperties,
       
   855     TContainerId  aId /*= KMsgStoreInvalidId*/ )
       
   856 	{
       
   857 	__LOG_ENTER_SUPPRESS( "CreateContainerL" );
       
   858 	__LOG_WRITE8_FORMAT3_INFO( "type=%x pid=%x gpid=%x", aType, aParentId, aGrandparentId )
       
   859 
       
   860 	iContainersTable->HierarchyL( aParentId, iHierarchy );
       
   861 	ValidateParentL( aGrandparentId, iHierarchy, EFalse );  // allow parent or grandparent to be uncommitted.	
       
   862 	
       
   863 	//check if we are already in a DB Transaction
       
   864 	TBool weStartedDBTransaction = EFalse;
       
   865 	if ( !iUtils->InTransaction() )
       
   866 		{
       
   867 		iUtils->BeginDatabaseTransactionLC();
       
   868 		weStartedDBTransaction = ETrue;
       
   869 		}
       
   870 	
       
   871 	TContainerId id;
       
   872 	if ( KMsgStoreInvalidId == aId )
       
   873 	    {
       
   874         id = iGeneralTable->AssignNextIdL();
       
   875         id = id | aType;
       
   876 	    }
       
   877 	else
       
   878 	    {
       
   879         id = aId;
       
   880 	    }	
       
   881 
       
   882 	// Add a row to the containers table.
       
   883 	iContainersTable->CreateContainerL( id, KUncommittedContainers, aProperties, iQuickProperties );
       
   884 			
       
   885 	if ( weStartedDBTransaction )
       
   886 		{
       
   887 		iUtils->CommitDatabaseTransactionL();
       
   888 		}
       
   889 
       
   890 	__LOG_EXIT8_FORMAT1( "id=%x", id );
       
   891 	return id;								  			
       
   892 		
       
   893 	} // end CreateContainerL
       
   894 
       
   895 
       
   896 /**
       
   897  * 
       
   898  */
       
   899 void CContainerStore::AllocateIdsBlockL(
       
   900     RArray<TContainerId>& aIds, TInt aBlockSize /*= 4*/ )
       
   901     {
       
   902     //check if we are already in a DB Transaction
       
   903     TBool weStartedDBTransaction = EFalse;
       
   904     if ( !iUtils->InTransaction() )
       
   905         {
       
   906         iUtils->BeginDatabaseTransactionLC();
       
   907         weStartedDBTransaction = ETrue;
       
   908         }
       
   909     
       
   910     for ( TInt i = 0; i < aBlockSize; i++ )
       
   911         {
       
   912         TContainerId id = iGeneralTable->AssignNextIdL();
       
   913         aIds.AppendL( id );
       
   914         }
       
   915     
       
   916     if ( weStartedDBTransaction )
       
   917         {
       
   918         iUtils->CommitDatabaseTransactionL();
       
   919         }
       
   920     }
       
   921 
       
   922 // ==========================================================================
       
   923 // FUNCTION: AbandonContainerL
       
   924 // ==========================================================================
       
   925 void CContainerStore::AbandonContainerL( TContainerId aId )
       
   926     {
       
   927     __LOG_ENTER_SUPPRESS( "AbandonContainerL" )
       
   928     __LOG_WRITE8_FORMAT1_INFO( "id=%x", aId )
       
   929     
       
   930     iContainersTable->SeekL( aId, iHierarchy );
       
   931     ValidateParentL( KUncommittedContainers, iHierarchy );
       
   932 
       
   933     DoAbandonContainerL( aId );
       
   934     
       
   935     __LOG_EXIT
       
   936     } // end AbandonContainerL
       
   937 
       
   938 // ==========================================================================
       
   939 // FUNCTION: DoAbandonContainerL
       
   940 // ==========================================================================
       
   941 void CContainerStore::DoAbandonContainerL( TContainerId aId )
       
   942     {	         
       
   943     iContainersTable->SeekL( aId );
       
   944 
       
   945 	iUtils->BeginDatabaseTransactionLC();	
       
   946     iContainersTable->MoveL( KToBeDeletedContainers, iTotalCountsDelta );
       
   947 	iUtils->CommitDatabaseTransactionL();	
       
   948 
       
   949     // No need to update the total counts since uncommitted containers do not
       
   950     // affect the total counts.
       
   951     
       
   952     } // end AbandonContainerL
       
   953     
       
   954 // ==========================================================================
       
   955 // FUNCTION: MarkUncommittedContainersForDeleteL
       
   956 // ==========================================================================
       
   957 void CContainerStore::MarkUncommittedContainersForDeleteL()
       
   958     {
       
   959     __LOG_ENTER( "MarkUncommittedContainersForDeleteL" )
       
   960     
       
   961     RArray<TContainerId> children;
       
   962     CleanupClosePushL( children );
       
   963 
       
   964     // Abandon all of the uncommitted containers.
       
   965     iContainersTable->ListChildrenL( children, KUncommittedContainers );
       
   966     
       
   967     for( TInt i = 0; i < children.Count(); i++ )
       
   968         {
       
   969        	__LOG_WRITE8_FORMAT1_INFO( "abandoning %x", children[i] )
       
   970         TRAP_IGNORE( DoAbandonContainerL( children[i] ) );
       
   971         } // end for
       
   972     
       
   973     CleanupStack::PopAndDestroy( &children );   
       
   974     
       
   975     __LOG_EXIT        
       
   976     } // end MarkUncommittedContainersForDeleteL
       
   977 
       
   978 // ==========================================================================
       
   979 // FUNCTION: CommitContainerL
       
   980 // ==========================================================================
       
   981 void CContainerStore::CommitContainerL( TContainerId aId, 
       
   982                                         TContainerId aParentId, 
       
   983                                         TContainerId aMailBoxId, 
       
   984                                         MContainerStoreObserver* aObserver,
       
   985                                         TContainerId aCopiedFromOriginalMsgId )
       
   986     {
       
   987     __LOG_ENTER_SUPPRESS( "CommitContainerL" )
       
   988     __LOG_WRITE8_FORMAT2_INFO( "id=%x parentId=%x", aId, aParentId )
       
   989     
       
   990     iContainersTable->SeekL( aId, iHierarchy );
       
   991     ValidateParentL( KUncommittedContainers, iHierarchy );
       
   992 
       
   993 	iContainersTable->QuickPropertiesL( iQuickProperties );
       
   994 	
       
   995 	//get the total counts for the mailbox
       
   996 	iAccountTable->TotalCountsL( aMailBoxId, iTotalCounts );
       
   997 	
       
   998 	//check if we are already in a DB Transaction
       
   999 	TBool weStartedDBTransaction = EFalse;
       
  1000 	if ( !iUtils->InTransaction() )
       
  1001 		{
       
  1002 		iUtils->BeginDatabaseTransactionLC();	
       
  1003 		weStartedDBTransaction = ETrue;
       
  1004 		}
       
  1005 	
       
  1006 	// Move the message.
       
  1007 	iContainersTable->MoveL( aParentId, iTotalCountsDelta );
       
  1008 	
       
  1009 	// Update the total counts.
       
  1010 	iCustomBehaviorProvider.IncrementParentCounts( iTotalCounts, iTotalCountsDelta );
       
  1011 	iAccountTable->UpdateTotalCountsL( aMailBoxId, iTotalCounts );
       
  1012 	
       
  1013     //update the sorting table if this container is a message
       
  1014     if ( ( aId & EMsgStoreContainerMask ) == EMsgStoreMessageBits )
       
  1015         {
       
  1016         RMsgStoreSortableFields sortableFields;
       
  1017         CleanupClosePushL( sortableFields );
       
  1018         
       
  1019         GetSortableFieldsL( aId, sortableFields );
       
  1020         iSortingTable->AddMessageL( aId, aParentId, aMailBoxId, sortableFields ); 
       
  1021         
       
  1022         CleanupStack::PopAndDestroy( &sortableFields );
       
  1023         }
       
  1024     
       
  1025 	if ( weStartedDBTransaction )
       
  1026 		{
       
  1027 		iUtils->CommitDatabaseTransactionL();      
       
  1028 		}
       
  1029 
       
  1030     iContainersTable->HierarchyL( aId, iHierarchy );
       
  1031 	
       
  1032 	NotifyObservers( MContainerStoreObserver::EAdd, iHierarchy, iQuickProperties, aObserver, aCopiedFromOriginalMsgId );
       
  1033 	
       
  1034 	__LOG_EXIT
       
  1035     } // end CommitContainerL
       
  1036 
       
  1037 // ==========================================================================
       
  1038 // FUNCTION: DeleteContainerL
       
  1039 // ==========================================================================
       
  1040 void CContainerStore::DeleteContainerL( TContainerId             aId,
       
  1041        				                    TContainerId             aParentId,						
       
  1042                 				        TContainerId             aGrandparentId,
       
  1043                 				        TContainerId             aMailBoxId,
       
  1044                                         MContainerStoreObserver* aObserver )
       
  1045     {
       
  1046     __LOG_ENTER_SUPPRESS( "DeleteContainerL" )
       
  1047 	__LOG_WRITE8_FORMAT3_INFO( "id=%x pid=%x gpid=%x", aId, aParentId, aGrandparentId )
       
  1048     
       
  1049 	if(	aId < KLowestUserCreatedContainerId )
       
  1050 		{
       
  1051 		__LOG_WRITE_ERROR( "Attempted to delete predefined container" )		
       
  1052 		User::Leave( KErrArgument );
       
  1053 		} // end if	
       
  1054     
       
  1055     // Check for authentication, even though no encryption/decryption will be performed.
       
  1056     iEncryption->CheckForAuthenticationL();
       
  1057     
       
  1058     iContainersTable->SeekL( aId, iHierarchy );
       
  1059     
       
  1060     ValidateParentAndGrandparentL( aParentId, aGrandparentId, iHierarchy );
       
  1061     
       
  1062 	iContainersTable->QuickPropertiesL( iQuickProperties );
       
  1063 	
       
  1064 	//get the current total counts for the mailbox
       
  1065 	iAccountTable->TotalCountsL( aMailBoxId, iTotalCounts );	
       
  1066 	//check if we are already in a DB Transaction
       
  1067 	TBool weStartedDBTransaction = EFalse;
       
  1068 	if ( !iUtils->InTransaction() )
       
  1069 		{
       
  1070 		iUtils->BeginDatabaseTransactionLC();
       
  1071 		weStartedDBTransaction = ETrue;
       
  1072 		}
       
  1073 	
       
  1074 	// Move the message to the ToBeDeletedContainers folder	
       
  1075 	iContainersTable->MoveL( KToBeDeletedContainers, iTotalCountsDelta );
       
  1076 	
       
  1077 	// Update the total counts.
       
  1078 	iCustomBehaviorProvider.IncrementParentCounts( iTotalCounts, iTotalCountsDelta );
       
  1079 	iAccountTable->UpdateTotalCountsL( aMailBoxId, iTotalCounts );	
       
  1080     
       
  1081     //update the sorting table if necessary
       
  1082     TMsgStoreId type = aId & EMsgStoreContainerMask;
       
  1083     if ( type == EMsgStoreMessageBits )
       
  1084         {
       
  1085         //need to get the size
       
  1086         TRAP_IGNORE( iSortingTable->DeleteMessageL( aId ) );
       
  1087         }
       
  1088     else if ( type == EMsgStoreFolderBits )
       
  1089         {
       
  1090         //need to get the size
       
  1091         TRAP_IGNORE( iSortingTable->DeleteMessagesByFolderIdL( aId ) );
       
  1092         }
       
  1093     else if ( type == EMsgStoreMailBoxBits )
       
  1094         {
       
  1095         //need to get the size
       
  1096         TRAP_IGNORE( iSortingTable->DeleteMessagesByMailBoxIdL( aId ) );
       
  1097         }
       
  1098 	
       
  1099 	if ( weStartedDBTransaction )
       
  1100 		{
       
  1101 		iUtils->CommitDatabaseTransactionL();
       
  1102 		}
       
  1103 	
       
  1104     iDeleteHandler->Start();
       
  1105 
       
  1106     // Only send a notification for the parent object.
       
  1107     NotifyObservers( MContainerStoreObserver::EDelete, iHierarchy, iQuickProperties, aObserver );    
       
  1108     
       
  1109     __LOG_EXIT
       
  1110     } // end DeleteContainerL					  
       
  1111 
       
  1112 // ==========================================================================
       
  1113 // FUNCTION: MoveContainerL
       
  1114 // ==========================================================================
       
  1115 void CContainerStore::MoveContainerL( TContainerId             aId, 
       
  1116 			 						  TContainerId             aOldParentId,
       
  1117 								 	  TContainerId             aNewParentId, 
       
  1118 									  MContainerStoreObserver* aObserver )
       
  1119 	{
       
  1120 	__LOG_ENTER_SUPPRESS( "MoveContainerL" )
       
  1121 	__LOG_WRITE8_FORMAT3_INFO( "%x from %x to %x", aId, aOldParentId, aNewParentId )
       
  1122 	
       
  1123 	if(	aId < KLowestUserCreatedContainerId )
       
  1124 		{
       
  1125 		__LOG_WRITE_ERROR( "Attempted to move predefined container" )		
       
  1126 		User::Leave( KErrArgument );
       
  1127 		} // end if	
       
  1128 
       
  1129     // Check for authentication, even though no encryption/decryption will be performed.
       
  1130     iEncryption->CheckForAuthenticationL();
       
  1131     
       
  1132     iContainersTable->HierarchyL( aNewParentId, iHierarchy );
       
  1133     
       
  1134 	iContainersTable->SeekL( aId, iHierarchy );
       
  1135 	ValidateParentL( aOldParentId, iHierarchy );
       
  1136 	
       
  1137 	iContainersTable->QuickPropertiesL( iQuickProperties );
       
  1138 	
       
  1139 	iUtils->BeginDatabaseTransactionLC();	
       
  1140 
       
  1141 	iContainersTable->MoveL( aNewParentId, iTotalCountsDelta );
       
  1142     
       
  1143     //update the sorting table if necessary
       
  1144     if ( ( aId & EMsgStoreContainerMask ) == EMsgStoreMessageBits )
       
  1145         {
       
  1146         iSortingTable->UpdateMessageFolderL( aId, aNewParentId );    
       
  1147         }
       
  1148 
       
  1149     // No need to update the total counts since moves don't affect the total counts except in the
       
  1150     // case of Commit and Delete, which are not handled by this function.
       
  1151 	
       
  1152 	iUtils->CommitDatabaseTransactionL();
       
  1153 
       
  1154     NotifyObservers( MContainerStoreObserver::EMove, iHierarchy, iQuickProperties, aObserver, aNewParentId );	    
       
  1155 	
       
  1156 	__LOG_EXIT
       
  1157 	} // end MoveContainerL
       
  1158 				
       
  1159 // ==========================================================================
       
  1160 // FUNCTION: CopyContainerL
       
  1161 // ==========================================================================
       
  1162 TContainerId CContainerStore::CopyContainerL( TContainerId             aId, 
       
  1163         								 	  TContainerId             aSourceId, 
       
  1164         								 	  TContainerId             aSourceParentId, 
       
  1165         								 	  TContainerId             aDestinationId, 
       
  1166         								 	  TContainerId             aDestinationParentId, 
       
  1167         								 	  TContainerId             aMailBoxId, 
       
  1168         									  MContainerStoreObserver* aObserver )
       
  1169     {
       
  1170     __LOG_ENTER_SUPPRESS( "CopyContainerL" )
       
  1171 	__LOG_WRITE8_FORMAT3_INFO( "id=%x source=%x destination=%x", aId, aSourceId, aDestinationId )
       
  1172 
       
  1173     // Verify the hierarchy of the destination.
       
  1174 	iContainersTable->HierarchyL( aDestinationId, iHierarchy );
       
  1175 	ValidateParentL( aDestinationParentId, iHierarchy );
       
  1176 
       
  1177 	// Verify the hierarchy of the source.
       
  1178 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1179 	ValidateParentAndGrandparentL( aSourceId, aSourceParentId, iHierarchy );
       
  1180     
       
  1181 	iUtils->BeginDatabaseTransactionLC();
       
  1182 	iContentManager->StartCopyTransaction();
       
  1183         
       
  1184 	TContainerId newId = 0;
       
  1185 	TRAPD( err, newId = RecursiveCopyL( 0, aId, KUncommittedContainers ) );
       
  1186 	if ( KErrNone == err )
       
  1187 	    {
       
  1188         iUtils->CommitDatabaseTransactionL();
       
  1189 
       
  1190         //Per Gypsy UI's request, when copying messages, we now send the original message id
       
  1191         // in the aOtherId field of the notification ( MotificationNotify() ). 
       
  1192         if ( ( aId & EMsgStoreContainerMask ) == EMsgStoreMessageBits )
       
  1193             {
       
  1194             CommitContainerL( newId, aDestinationId, aMailBoxId, aObserver, aId );
       
  1195             }
       
  1196         else
       
  1197             {
       
  1198             CommitContainerL( newId, aDestinationId, aMailBoxId, aObserver );
       
  1199             }
       
  1200 	    }
       
  1201 	else
       
  1202 	    {
       
  1203         iContentManager->RollbackCopyTransaction();
       
  1204 
       
  1205         //will automatically rollback the transaction.
       
  1206         CleanupStack::PopAndDestroy( iUtils );
       
  1207         
       
  1208         //if there was a rollback and the recover call detected recovering is
       
  1209         //necessary (happens in one of the unit tests) then all of the open
       
  1210         //tables will be closed; so reopening the tables is necessary; not
       
  1211         //confident enough whether this is not a very specific case so making
       
  1212         //this change only here; technically tables must always be reopened
       
  1213         //after a call to Recover because they could definitely get closed 
       
  1214         //although the documentation doesn't say anything.
       
  1215         
       
  1216         CloseTables();
       
  1217         OpenTablesL();
       
  1218         
       
  1219         User::Leave( err );
       
  1220 	    }
       
  1221 	
       
  1222 	__LOG_EXIT8_FORMAT1( "id=%x", newId )
       
  1223 	return newId;
       
  1224 	
       
  1225 	} // end CopyContainerL
       
  1226 
       
  1227 // ==========================================================================
       
  1228 // FUNCTION: RecursiveCopyL
       
  1229 //
       
  1230 // Recursion notes:
       
  1231 //
       
  1232 // Each recursive call pushes these variables on the stack: 
       
  1233 //
       
  1234 // children (RArray has 8 32-bit values, actual elements are allocated from the heap)
       
  1235 // newId
       
  1236 // aDepth
       
  1237 // aId
       
  1238 // aDestinationId
       
  1239 //
       
  1240 // This is approximately 48 bytes per invocation (plus any additional runtime overhead like
       
  1241 // return addresses, etc.).  Assuming 80 bytes per invocation, and an 8K Symbian stack, a
       
  1242 // recursion depth of up to 100 should be acceptable.
       
  1243 // ==========================================================================
       
  1244 TContainerId CContainerStore::RecursiveCopyL( TUint         aDepth,
       
  1245                                               TContainerId  aId, 
       
  1246         							          TContainerId  aDestinationId )
       
  1247 	{
       
  1248 	__LOG_ENTER_SUPPRESS( "RecursiveCopyL" )
       
  1249 	
       
  1250     if( aDepth > KMaxRecursionDepth )
       
  1251 	    {
       
  1252 	    __LOG_WRITE_ERROR( "Maximum recursion depth exceeded" );
       
  1253 	    User::Leave( KErrOverflow );
       
  1254 	    } // end if
       
  1255 	
       
  1256 	iContainersTable->SeekL( aId );
       
  1257 
       
  1258 	// Generate a new ID, with the same type as the entry being copied.
       
  1259 	TContainerId newId = iGeneralTable->AssignNextIdL() | (aId & KContainerTypeMask);
       
  1260 	
       
  1261 	// Copy current row.
       
  1262 	iContainersTable->CopyL( newId, aDestinationId, iQuickProperties );
       
  1263 
       
  1264     // Copy content and children.
       
  1265     RArray<TContainerId> children;
       
  1266     CleanupClosePushL( children );
       
  1267 	
       
  1268     TRAPD( result, iContentManager->CopyContentL( aId, newId );		
       
  1269     	
       
  1270                    iContainersTable->ListChildrenL( children, aId );
       
  1271 	
       
  1272                    for( TInt i = 0; i < children.Count(); i++ )
       
  1273                        {
       
  1274                        RecursiveCopyL( aDepth+1, children[i], newId );
       
  1275                   	   }
       
  1276          );                  	   
       
  1277 
       
  1278     User::LeaveIfError( result );
       
  1279  	
       
  1280 	CleanupStack::PopAndDestroy( &children );
       
  1281     
       
  1282 	return newId;
       
  1283 	
       
  1284 	} // end RecursiveCopyL
       
  1285 
       
  1286 // ==========================================================================
       
  1287 // FUNCTION: ChildrenCountsL
       
  1288 // ==========================================================================
       
  1289 void CContainerStore::ChildrenCountsL( TContainerId aId, TDes8& aCounts )
       
  1290 	{
       
  1291 	__LOG_ENTER_SUPPRESS( "ChildrenCountsL" )
       
  1292 	__LOG_WRITE8_FORMAT1_INFO( "id=%x", aId )
       
  1293 	
       
  1294 	iContainersTable->SeekL( aId, iHierarchy );
       
  1295 	iContainersTable->ChildrenCountsL( aCounts );
       
  1296 	
       
  1297 	__LOG_EXIT
       
  1298 	} // end ChildrenCountsL
       
  1299 	
       
  1300 // ==========================================================================
       
  1301 // FUNCTION: TotalCountsL
       
  1302 // ==========================================================================
       
  1303 void CContainerStore::TotalCountsL( TContainerId aMailBoxId, TDes8& aCounts )
       
  1304 	{
       
  1305 	__LOG_ENTER( "TotalCountsL" )
       
  1306 	
       
  1307 	iAccountTable->TotalCountsL( aMailBoxId, aCounts );
       
  1308     	
       
  1309 	__LOG_EXIT
       
  1310 	} // end TotalCountsL
       
  1311 	
       
  1312 // ==========================================================================
       
  1313 // FUNCTION: UpdatePropertiesL
       
  1314 // ==========================================================================
       
  1315 void CContainerStore::UpdatePropertiesL( TContainerId             aId,
       
  1316 									     TContainerId             aParentId,
       
  1317 									     TContainerId             aMailBoxId,
       
  1318 									     const TDesC8&            aProperties,
       
  1319 				                         MContainerStoreObserver* aObserver )
       
  1320 	{
       
  1321 	__LOG_ENTER_SUPPRESS( "UpdatePropertiesL" )
       
  1322 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1323 
       
  1324     iContainersTable->SeekL( aId, iHierarchy );
       
  1325     ValidateParentL( aParentId, iHierarchy );
       
  1326     
       
  1327     //gets the total counts for the mailbox
       
  1328 	iAccountTable->TotalCountsL( aMailBoxId, iTotalCounts );
       
  1329     
       
  1330 	iUtils->BeginDatabaseTransactionLC();
       
  1331     
       
  1332     TContainerId realParentId;
       
  1333 	
       
  1334 	// Update the properties.
       
  1335 	iContainersTable->UpdatePropertiesL( aProperties, iQuickProperties, iTotalCountsDelta, realParentId );
       
  1336 	
       
  1337 	// Update the total counts if the parent is not uncommitted.
       
  1338     if( realParentId != KUncommittedContainers )
       
  1339         {        
       
  1340         iCustomBehaviorProvider.IncrementParentCounts( iTotalCounts, iTotalCountsDelta );
       
  1341         iAccountTable->UpdateTotalCountsL( aMailBoxId, iTotalCounts );	
       
  1342         }
       
  1343     
       
  1344     //update the sorting table if necessary
       
  1345     if ( ( aId & EMsgStoreContainerMask ) == EMsgStoreMessageBits )
       
  1346         {
       
  1347         RMsgStoreSortableFields sortableFields;
       
  1348         CleanupClosePushL( sortableFields );
       
  1349         
       
  1350         GetSortableFieldsL( aId, sortableFields );
       
  1351         //need to get the size
       
  1352         TRAPD( err, iSortingTable->UpdateMessageL( aId, sortableFields ) );
       
  1353         if ( err != KErrNone && err != KErrNotFound )
       
  1354             {
       
  1355             //if err==KErrNotFound, it just means that the message has been created 
       
  1356             // but not committed yet, in this case, the message will be added to the
       
  1357             // sorting table when it is committed.  So ignore KErrNotFound
       
  1358             User::Leave( err );
       
  1359             }
       
  1360         
       
  1361         CleanupStack::PopAndDestroy( &sortableFields );
       
  1362         }
       
  1363     
       
  1364 	iUtils->CommitDatabaseTransactionL();
       
  1365 	
       
  1366 	NotifyObservers( MContainerStoreObserver::EUpdateProperties, iHierarchy, iQuickProperties, aObserver );
       
  1367 	
       
  1368 	__LOG_EXIT
       
  1369 	} // end UpdatePropertiesL
       
  1370 
       
  1371 // ==========================================================================
       
  1372 // FUNCTION: UpdatePropertyL
       
  1373 // ==========================================================================
       
  1374 void CContainerStore::UpdatePropertyL( TContainerId             aId,
       
  1375 									   TContainerId             aParentId,
       
  1376 									   TContainerId             aMailBoxId,
       
  1377 									   const TDesC8&            aName,
       
  1378 									   TUint8                   aType,
       
  1379 									   const TDesC8&            aValue,
       
  1380 				                       MContainerStoreObserver* aObserver )
       
  1381 	{
       
  1382 	__LOG_ENTER_SUPPRESS( "UpdatePropertyL" )
       
  1383 	__LOG_WRITE8_FORMAT4_INFO( "id=%x pid=%x name=%S type=%i", aId, aParentId, &aName, aType )
       
  1384 
       
  1385     iContainersTable->SeekL( aId, iHierarchy );
       
  1386     ValidateParentL( aParentId, iHierarchy );
       
  1387     
       
  1388     //gets the total counts for the mailbox
       
  1389 	iAccountTable->TotalCountsL( aMailBoxId, iTotalCounts );
       
  1390     
       
  1391 	iUtils->BeginDatabaseTransactionLC();	
       
  1392 
       
  1393     TContainerId realParentId;
       
  1394 	
       
  1395 	// Update the property.
       
  1396 	iContainersTable->UpdatePropertyL( aName, aType, aValue, iQuickProperties, iTotalCountsDelta, realParentId );
       
  1397 	
       
  1398 	// Update the total counts.
       
  1399     if( realParentId != KUncommittedContainers )
       
  1400         {        
       
  1401     	iCustomBehaviorProvider.IncrementParentCounts( iTotalCounts, iTotalCountsDelta );
       
  1402     	iAccountTable->UpdateTotalCountsL( aMailBoxId, iTotalCounts );	
       
  1403         }
       
  1404     
       
  1405     //update the sorting table if necessary
       
  1406     if ( ( aId & EMsgStoreContainerMask ) == EMsgStoreMessageBits )
       
  1407         {
       
  1408         RMsgStoreSortableFields sortableFields;
       
  1409         CleanupClosePushL( sortableFields );
       
  1410         
       
  1411         GetSortableFieldsL( aId, sortableFields );
       
  1412         //need to get the size
       
  1413         TRAPD( err, iSortingTable->UpdateMessageL( aId, sortableFields ) );
       
  1414         if ( err != KErrNone && err != KErrNotFound )
       
  1415             {
       
  1416             //if err==KErrNotFound, it just means that the message has been created 
       
  1417             // but not committed yet, in this case, the message will be added to the
       
  1418             // sorting table when it is committed.  So ignore KErrNotFound
       
  1419             User::Leave( err );
       
  1420             }
       
  1421         
       
  1422         CleanupStack::PopAndDestroy( &sortableFields );
       
  1423         }
       
  1424 		
       
  1425 	iUtils->CommitDatabaseTransactionL();
       
  1426 	
       
  1427 	NotifyObservers( MContainerStoreObserver::EUpdateProperties, iHierarchy, iQuickProperties, aObserver );
       
  1428 	
       
  1429 	__LOG_EXIT
       
  1430 	} // end UpdatePropertyL
       
  1431 
       
  1432 // ==========================================================================
       
  1433 // FUNCTION: ReplaceContentL
       
  1434 // ==========================================================================
       
  1435 void CContainerStore::ReplaceContentL( TContainerId             aId, 
       
  1436 									   TContainerId             aParentId, 
       
  1437 									   const TDesC8&            aContent, 
       
  1438 									   MContainerStoreObserver* aObserver )
       
  1439 	{
       
  1440 	__LOG_ENTER_SUPPRESS( "ReplaceContentL" )
       
  1441 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1442 
       
  1443 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1444 	ValidateParentL( aParentId, iHierarchy, EFalse );
       
  1445     
       
  1446 	TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1447     
       
  1448 	iContentManager->ReplaceContentL( aId, aContent, isRowEncrypted );
       
  1449 	
       
  1450 	NotifyObservers( MContainerStoreObserver::EUpdateContent, iHierarchy, KNullDes, aObserver );
       
  1451 		
       
  1452     __LOG_EXIT		
       
  1453 	} // end ReplaceContentL
       
  1454 
       
  1455 // ==========================================================================
       
  1456 // FUNCTION: ReplaceContentL
       
  1457 // ==========================================================================
       
  1458 void CContainerStore::ReplaceContentL( TContainerId             aId, 
       
  1459 								       TContainerId             aParentId, 
       
  1460 								       RFile&                   aContentFile,
       
  1461                       				   MContainerStoreObserver* aObserver )
       
  1462 	{
       
  1463 	__LOG_ENTER_SUPPRESS( "ReplaceContentL" )
       
  1464 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1465 
       
  1466 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1467 	ValidateParentL( aParentId, iHierarchy, EFalse );
       
  1468 		
       
  1469     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1470     
       
  1471     iContentManager->ReplaceContentL( aId, aContentFile, isRowEncrypted );		
       
  1472 	
       
  1473 	NotifyObservers( MContainerStoreObserver::EUpdateContent, iHierarchy, KNullDes, aObserver );
       
  1474 		
       
  1475     __LOG_EXIT		
       
  1476 	} // end ReplaceContentL
       
  1477 
       
  1478 // ==========================================================================
       
  1479 // FUNCTION: AppendContentL
       
  1480 // ==========================================================================
       
  1481 void CContainerStore::AppendContentL( TContainerId aId, TContainerId aParentId, const TDesC8& aContent, MContainerStoreObserver* aObserver )
       
  1482 	{
       
  1483 	__LOG_ENTER_SUPPRESS( "AppendContentL" )
       
  1484 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1485 
       
  1486 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1487 	ValidateParentL( aParentId, iHierarchy, EFalse );
       
  1488 
       
  1489     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1490     
       
  1491     iContentManager->AppendContentL( aId, aContent, isRowEncrypted );		
       
  1492 	
       
  1493 	NotifyObservers( MContainerStoreObserver::EUpdateContent, iHierarchy, KNullDes, aObserver );
       
  1494 		
       
  1495     __LOG_EXIT		
       
  1496 	} // end AppendContentL
       
  1497 	
       
  1498 // ==========================================================================
       
  1499 // FUNCTION: PrependContentL
       
  1500 // ==========================================================================
       
  1501 void CContainerStore::PrependContentL(
       
  1502     TContainerId aId,
       
  1503     TContainerId aParentId,
       
  1504     const TDesC8& aContent,
       
  1505     MContainerStoreObserver* aObserver )
       
  1506     {
       
  1507     __LOG_ENTER_SUPPRESS( "PrependContentL" )
       
  1508     __LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1509 
       
  1510     iContainersTable->HierarchyL( aId, iHierarchy );
       
  1511     ValidateParentL( aParentId, iHierarchy, EFalse );
       
  1512 
       
  1513     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1514     
       
  1515     iContentManager->PrependContentL( aId, aContent, isRowEncrypted );       
       
  1516     
       
  1517     NotifyObservers( MContainerStoreObserver::EUpdateContent, iHierarchy, KNullDes, aObserver );
       
  1518         
       
  1519     __LOG_EXIT      
       
  1520     } // end PrependContentL
       
  1521 
       
  1522 // ==========================================================================
       
  1523 // FUNCTION: RemoveContentL 
       
  1524 // ==========================================================================
       
  1525 void CContainerStore::RemoveContentL( TContainerId aId, TContainerId aParentId, MContainerStoreObserver* aObserver )
       
  1526 	{
       
  1527 	__LOG_ENTER_SUPPRESS( "RemoveContentL" )
       
  1528 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1529 
       
  1530 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1531 	ValidateParentL( aParentId, iHierarchy, EFalse );
       
  1532 	
       
  1533 	iContentManager->RemoveContentL( aId );	
       
  1534 
       
  1535 	NotifyObservers( MContainerStoreObserver::ERemoveContent, iHierarchy, KNullDes, aObserver );
       
  1536 
       
  1537     __LOG_EXIT		
       
  1538 	} // end RemoveContentL
       
  1539 
       
  1540 // ==========================================================================
       
  1541 // FUNCTION: FetchPropertiesL
       
  1542 // ==========================================================================
       
  1543 void CContainerStore::FetchPropertiesL( TContainerId  aId, 
       
  1544 										TContainerId& aParentId,
       
  1545 										TContainerId  aGrandparentId, 
       
  1546 										RBuf8&        aProperties,
       
  1547 										TContainerId  aMailboxId )
       
  1548 	{
       
  1549 	__LOG_ENTER_SUPPRESS( "FetchPropertiesL" )
       
  1550 	__LOG_WRITE8_FORMAT3_INFO( "id=%x pid=%x gpid=%x", aId, aParentId, aGrandparentId )
       
  1551 	
       
  1552 	iContainersTable->SeekL( aId, iHierarchy );
       
  1553 	ValidateParentAndGrandparentL( aParentId, aGrandparentId, iHierarchy );
       
  1554 	
       
  1555 	//check the mailbox id if specified
       
  1556 	if ( aMailboxId != KContainerInvalidId )
       
  1557 	    {
       
  1558 	    if ( iHierarchy.Find( aMailboxId ) < 0 )
       
  1559 	        {
       
  1560 	        User::Leave( KErrNotFound );
       
  1561 	        }
       
  1562 	    }
       
  1563 	
       
  1564 	if( iHierarchy.Count() > 1 )
       
  1565 	    {	    
       
  1566 	    aParentId = iHierarchy[1];
       
  1567 	    } // end if
       
  1568 	
       
  1569     iContainersTable->PropertiesL( aProperties );	    
       
  1570 	
       
  1571 	__LOG_EXIT
       
  1572 	} // end FetchPropertiesL
       
  1573 
       
  1574 // ==========================================================================
       
  1575 // FUNCTION: FastFetchPropertiesL
       
  1576 // ==========================================================================
       
  1577 void CContainerStore::FastFetchPropertiesL( TContainerId  aId, 
       
  1578                                             TBool         aQuickProperties,
       
  1579          		                            TContainerId& aParentId,
       
  1580 								            RBuf8&        aProperties )
       
  1581 	{
       
  1582 	__LOG_ENTER_SUPPRESS( "FastFetchPropertiesL" )
       
  1583 	__LOG_WRITE8_FORMAT2_DEBUG3( "id=%x pid=%x", aId, aParentId )
       
  1584 	
       
  1585 	iContainersTable->SeekL( aId );
       
  1586 	
       
  1587 	aParentId = iContainersTable->ParentId();
       
  1588 	
       
  1589     if( aQuickProperties )
       
  1590         {        
       
  1591         iContainersTable->QuickPropertiesL( aProperties );
       
  1592         }
       
  1593     else
       
  1594         {
       
  1595         iContainersTable->PropertiesL( aProperties );	    
       
  1596         } // end if
       
  1597 	
       
  1598 	} // end FastFetchPropertiesL
       
  1599 
       
  1600 // ==========================================================================
       
  1601 // FUNCTION: FetchContentL
       
  1602 // ==========================================================================
       
  1603 void CContainerStore::FetchContentL( TContainerId aId,
       
  1604                                      TContainerId aParentId,					
       
  1605 								     TDes8&       aContent,
       
  1606 				 				     TUint        aStartPosition )
       
  1607 	{
       
  1608 	__LOG_ENTER_SUPPRESS( "FetchContentL(1)" )
       
  1609 	__LOG_WRITE8_FORMAT3_INFO( "id=%x pid=%x spos=%i", aId, aParentId, aStartPosition )
       
  1610 	
       
  1611     // Make sure that the message has not been deleted, otherwise generate KErrNotFound.
       
  1612     iContainersTable->HierarchyL( aId, iHierarchy );
       
  1613     ValidateParentL( aParentId, iHierarchy );
       
  1614     
       
  1615     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1616     
       
  1617     iContentManager->FetchContentL( aId, aContent, isRowEncrypted, aStartPosition );
       
  1618 
       
  1619     __LOG_EXIT
       
  1620 	} // end FetchContentL
       
  1621 	
       
  1622 // ==========================================================================
       
  1623 // FUNCTION: FetchContentL
       
  1624 // ==========================================================================
       
  1625 void CContainerStore::FetchContentL( TContainerId aId,					
       
  1626                                      TContainerId aParentId,					
       
  1627 								     RFile&       aDestinationFile )
       
  1628 	{ 
       
  1629 	__LOG_ENTER_SUPPRESS( "FetchContentL(2)" )
       
  1630 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1631 	
       
  1632     // Make sure that the message has not been deleted, otherwise generate KErrNotFound.
       
  1633     iContainersTable->HierarchyL( aId, iHierarchy );  
       
  1634     ValidateParentL( aParentId, iHierarchy );
       
  1635     
       
  1636     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1637     
       
  1638     iContentManager->FetchContentL( aId, aDestinationFile, isRowEncrypted );
       
  1639 	
       
  1640 	__LOG_EXIT		
       
  1641 	} // end FetchContentL
       
  1642 	
       
  1643 // ==========================================================================
       
  1644 // FUNCTION: ContentLengthL
       
  1645 // ==========================================================================
       
  1646 TUint CContainerStore::ContentLengthL( TContainerId aId,
       
  1647                                        TContainerId aParentId )	
       
  1648 	{
       
  1649 	__LOG_ENTER_SUPPRESS( "ContentLengthL" )
       
  1650 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1651 	
       
  1652     // Make sure that the message has not been deleted, otherwise generate KErrNotFound.
       
  1653 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1654     ValidateParentL( aParentId, iHierarchy );
       
  1655     
       
  1656     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1657     
       
  1658     TUint returnValue = iContentManager->ContentLengthL( aId, isRowEncrypted );
       
  1659     
       
  1660     __LOG_EXIT8_FORMAT1( "length=%i", returnValue )
       
  1661     return returnValue;
       
  1662 	} // end ContentLengthL
       
  1663 
       
  1664 
       
  1665 // ==========================================================================
       
  1666 // FUNCTION: OpenContentFileL
       
  1667 // ==========================================================================
       
  1668 void CContainerStore::OpenContentFileL( TContainerId aId, TContainerId aParentId, RFs& aFs, RFile& aFile )
       
  1669     {
       
  1670     __LOG_ENTER_SUPPRESS( "OpenContentFileL" )
       
  1671     __LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1672     
       
  1673     // Make sure that the message has not been deleted, otherwise generate KErrNotFound.
       
  1674     iContainersTable->HierarchyL( aId, iHierarchy );
       
  1675     ValidateParentL( aParentId, iHierarchy );
       
  1676     
       
  1677     TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  1678     
       
  1679     iContentManager->OpenContentFileL( aId, aFs, aFile, isRowEncrypted );
       
  1680     }
       
  1681 
       
  1682 // ==========================================================================
       
  1683 // FUNCTION: ListChildrenL
       
  1684 // ==========================================================================
       
  1685 void CContainerStore::ListChildrenL( RArray<TContainerId>& aChildren, TContainerId aId, TContainerId aParentId, TContainerId aType, TBool aRecursive )
       
  1686 	{
       
  1687 	__LOG_ENTER_SUPPRESS( "ListChildrenL" )
       
  1688 	__LOG_WRITE8_FORMAT2_INFO( "id=%x pid=%x", aId, aParentId )
       
  1689 	
       
  1690 	iContainersTable->HierarchyL( aId, iHierarchy );
       
  1691 	ValidateParentL( aParentId, iHierarchy );
       
  1692 	
       
  1693 	iContainersTable->ListChildrenL( aChildren, aId, aType, aRecursive );
       
  1694 	
       
  1695 	__LOG_EXIT
       
  1696 	} // end ListChildrenL
       
  1697 	
       
  1698 // ==========================================================================
       
  1699 // FUNCTION: FirstChildL
       
  1700 // ==========================================================================
       
  1701 TContainerId CContainerStore::FirstChildL( TContainerId aId )
       
  1702     {
       
  1703     __LOG_ENTER_SUPPRESS( "FirstChildL" )
       
  1704 	__LOG_WRITE8_FORMAT1_INFO( "id=%x", aId )
       
  1705     
       
  1706 	const TUint bufSize = 60;
       
  1707     TBuf<bufSize> queryString;
       
  1708     
       
  1709     _LIT( KEquals, "=" );
       
  1710     
       
  1711 	queryString.Copy( KContainersTableParentIdCol );
       
  1712 	queryString.Append( KEquals );
       
  1713     queryString.AppendNum( aId );
       
  1714 
       
  1715     TContainerId returnValue = iContainersTable->FindL( queryString );
       
  1716     
       
  1717     __LOG_EXIT
       
  1718     return returnValue;
       
  1719     
       
  1720     } // end FirstChildL
       
  1721 
       
  1722 TContainerId CContainerStore::FirstChildL( TContainerId aId, TBool& aIsChildEncrypted )
       
  1723     {
       
  1724     TContainerId firstChildId = FirstChildL( aId );
       
  1725     
       
  1726     if( firstChildId != KContainerInvalidId )
       
  1727         {
       
  1728         aIsChildEncrypted = iContainersTable->IsEncrypted();
       
  1729         } // end if
       
  1730     return firstChildId;
       
  1731     }
       
  1732 
       
  1733 // ==========================================================================
       
  1734 // FUNCTION: FirstChildL
       
  1735 // ==========================================================================
       
  1736 void CContainerStore::FirstChildL( TContainerId aId, TContainerId& aFirstChildId, TDbBookmark& aBookmark )
       
  1737     {
       
  1738     aFirstChildId = FirstChildL( aId );
       
  1739     
       
  1740     if( aFirstChildId != KContainerInvalidId )
       
  1741         {
       
  1742         aBookmark = iContainersTable->Bookmark();
       
  1743         } // end if
       
  1744         
       
  1745      } // end FirstChildL
       
  1746 		
       
  1747 // ==========================================================================
       
  1748 // FUNCTION: SearchL
       
  1749 // ==========================================================================
       
  1750 CContainerStoreSearchHandler* CContainerStore::SearchL( TContainerId                 aType,  
       
  1751                                                         TMsgStoreSearchCmdParams&    aCmdParam,
       
  1752                                                         RPointerArray<HBufC>&        aSearchStrings, 
       
  1753                                                         RArray<TContainerId>&        aFolderIds,
       
  1754                                                         RPointerArray<HBufC8>&       aPropertyNames,
       
  1755                                                         MContainerStoreSearchClient& aSearchClient )
       
  1756     {
       
  1757     __LOG_ENTER_SUPPRESS( "SearchL" )
       
  1758     
       
  1759 	CContainerStoreSearchHandler* handler = new(ELeave) CContainerStoreSearchHandler( *this,
       
  1760 	                                                                                  *iContentManager,
       
  1761                                                                                       *iSearchResultTable,
       
  1762                                                                                       *iSortingTable,
       
  1763 	                                                                                  aType, 
       
  1764 	                                                                                  aSearchClient, 
       
  1765 	                                                                                  iBasePriority + KSearchPriorityOffset );
       
  1766     CleanupStack::PushL( handler );
       
  1767     handler->ConstructL( aSearchStrings, aCmdParam, aFolderIds, aPropertyNames );
       
  1768     CleanupStack::Pop( handler );
       
  1769     
       
  1770     return handler;
       
  1771     
       
  1772     } // end SearchL
       
  1773 
       
  1774 // ==========================================================================
       
  1775 // FUNCTION: StartSortingL
       
  1776 // ==========================================================================
       
  1777 TContainerId CContainerStore::StartSortingL( TMsgStoreSortCriteria& aSortCriteria, 
       
  1778                                              RPointerArray<HBufC8>& aPropertyNames,
       
  1779                                              TBool                  aInMemorySort )
       
  1780     {
       
  1781     __LOG_ENTER_SUPPRESS( "StartSortingL" )
       
  1782     __LOG_WRITE_FORMAT4_INFO( "folder=%x sortField=%d order=%d, aInMemorySort=%d", aSortCriteria.iFolderId, aSortCriteria.iSortBy, aSortCriteria.iSortOrder, aInMemorySort )
       
  1783 
       
  1784     CMsgStoreSortResultRowSet* resultRowSet = iSortingTable->SortL( aSortCriteria, aInMemorySort );
       
  1785     CleanupStack::PushL( resultRowSet );
       
  1786     
       
  1787     //the property names will be used by GetSortedRows, and only the properties specified in aPropertyNames
       
  1788     //will be returned to the client
       
  1789     resultRowSet->SetPropertyNamesL( aPropertyNames );
       
  1790     
       
  1791     //the "subject prefixes to be ignored" is used when sorting subjects
       
  1792     //subject prefixes like: "RE:", "FW:" will be ignored
       
  1793     //resultRowSet->SetSubjectPrefixToIgnoreL( aSubjectPrefixToIgnore );
       
  1794     
       
  1795     TSortSession session;
       
  1796     
       
  1797     session.iSessionId = iNextSortSessionId++;
       
  1798     session.iResultRowSet = resultRowSet ;
       
  1799     
       
  1800     iSortSessions.Append( session );
       
  1801     
       
  1802     CleanupStack::Pop( resultRowSet );
       
  1803     
       
  1804     return session.iSessionId;
       
  1805     }
       
  1806 
       
  1807 // ==========================================================================
       
  1808 // FUNCTION: EndSortingL
       
  1809 // ==========================================================================
       
  1810 void CContainerStore::EndSortingL( TContainerId aSessionId )
       
  1811     {
       
  1812     __LOG_ENTER_SUPPRESS( "EndSortingL" )
       
  1813     __LOG_WRITE_FORMAT1_INFO( "session=%d", aSessionId )
       
  1814     
       
  1815     //find the session;
       
  1816     TUint index = FindSortingSessionL( aSessionId );
       
  1817     if ( index < iSortSessions.Count() ) 
       
  1818         {
       
  1819         delete iSortSessions[index].iResultRowSet;
       
  1820         iSortSessions.Remove(index);
       
  1821         }
       
  1822     }
       
  1823 
       
  1824 // ==========================================================================
       
  1825 // FUNCTION: GetSortedRowsL
       
  1826 // ==========================================================================
       
  1827 TBool CContainerStore::GetSortedRowsL( TMsgStoreGetSortedRowsCmdParams aParams, RBuf8& aPropertiesBuf, const TDesC& aStartWith )
       
  1828     {
       
  1829     __LOG_ENTER_SUPPRESS( "GetSortedRowsL" )
       
  1830     __LOG_WRITE_FORMAT4_INFO( "session=%d from msg=%x direction=%d rows=%d", aParams.iSortSessionId, 
       
  1831                                                                              aParams.iStartingMessageId, 
       
  1832                                                                              aParams.iDirection, 
       
  1833                                                                              aParams.iRowsToRetrieve );
       
  1834     
       
  1835     iUtils->SuspendCompactionLC();
       
  1836    
       
  1837     //find the session;
       
  1838     TUint index = FindSortingSessionL( aParams.iSortSessionId );
       
  1839     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  1840     if ( index < iSortSessions.Count() ) 
       
  1841          {
       
  1842          rowSet = iSortSessions[index].iResultRowSet;
       
  1843          }
       
  1844     else
       
  1845         {
       
  1846         User::Leave( KErrNotFound );
       
  1847         }
       
  1848     
       
  1849     
       
  1850     const RPointerArray<HBufC8>& propertyNames = rowSet->PropertyNames();
       
  1851     
       
  1852     TMsgStoreId msgId;
       
  1853     TPckg<TContainerId> idPckg( msgId );
       
  1854     
       
  1855     TContainerId folderId = rowSet->FolderId();
       
  1856     TPckg<TContainerId> folderIdPckg( folderId );
       
  1857     
       
  1858     TUint32 length32;
       
  1859     TPckg<TUint32> length32Pckg( length32 );    
       
  1860 
       
  1861     const TUint overhead  = idPckg.Length() + folderIdPckg.Length() + length32Pckg.Length();
       
  1862     
       
  1863     TMsgStoreIteratorDirection direction = aParams.iDirection;
       
  1864     TUint rowsToGet = aParams.iRowsToRetrieve;
       
  1865     
       
  1866     TBool hasMore = ETrue;
       
  1867     TInt  err = KErrNone;
       
  1868 
       
  1869     RBuf8 curPropertiesBuf;
       
  1870     CleanupClosePushL( curPropertiesBuf );
       
  1871     
       
  1872     //position the starting point (put the cursor to the desired place)
       
  1873     if ( aStartWith == KNullDesC )
       
  1874         {
       
  1875         if ( aParams.iStartingMessageId == KMsgStoreSortResultTop )
       
  1876             {
       
  1877             rowSet->ToTopL();
       
  1878             }
       
  1879         else if ( aParams.iStartingMessageId == KMsgStoreSortResultBottom )
       
  1880             {
       
  1881             rowSet->ToEndL();
       
  1882             }
       
  1883         else
       
  1884             {
       
  1885             rowSet->GotoL( aParams.iStartingMessageId );
       
  1886             }
       
  1887         }
       
  1888     else
       
  1889         {
       
  1890         rowSet->GotoL( aStartWith, direction );
       
  1891         }
       
  1892     
       
  1893     //for "Group" support in UI
       
  1894     //check if we need to skip the current group
       
  1895     if ( aParams.iSkipCurrentGroup )
       
  1896         {
       
  1897         TUint itemsInGroup;
       
  1898         hasMore = rowSet->SkipCurrentGroupL( direction, itemsInGroup );
       
  1899         }
       
  1900     
       
  1901     //start retrieving rows
       
  1902     for ( TUint i = 0 ; hasMore && i < rowsToGet ; i++ )
       
  1903         {
       
  1904         if ( direction == EMsgStoreIteratorForward )
       
  1905             {
       
  1906             TRAP( err, msgId = rowSet->NextL() );
       
  1907             }
       
  1908         else
       
  1909             {
       
  1910             TRAP( err, msgId = rowSet->PreviousL() );
       
  1911             }
       
  1912         
       
  1913         if ( err == KErrOverflow || err == KErrUnderflow )
       
  1914             {
       
  1915             hasMore = EFalse;
       
  1916             }
       
  1917         else if ( err != KErrNone )
       
  1918             {
       
  1919             User::Leave( err );
       
  1920             }
       
  1921         else
       
  1922             {
       
  1923             //got a valid row, get it's properties
       
  1924             curPropertiesBuf.SetLength( 0 );
       
  1925             
       
  1926             FastFetchPropertiesL( msgId, EFalse, folderId, curPropertiesBuf );
       
  1927             
       
  1928             //filter out the properties that are not specified in the propertyNames
       
  1929             if( propertyNames.Count() > 0 )
       
  1930                 {
       
  1931                 // Remove the properties that are not needed.
       
  1932                 TPropertiesSerializer serializer( curPropertiesBuf );        
       
  1933                 TBool moreProperties = serializer.First();        
       
  1934                 while( moreProperties )        
       
  1935                     {
       
  1936                     TBool found = EFalse;            
       
  1937                     for( TInt i = 0; !found && (i < propertyNames.Count()); i++ )
       
  1938                         {
       
  1939                         found = (propertyNames[i]->Compare( serializer.Name() ) == 0);
       
  1940                         } // end for                               
       
  1941                     if( found )
       
  1942                         {
       
  1943                         moreProperties = serializer.Next();
       
  1944                         }
       
  1945                     else
       
  1946                         {
       
  1947                         moreProperties = serializer.RemovePropertyL();
       
  1948                         } // end if                
       
  1949                     } // end while   
       
  1950                 } // end if
       
  1951             
       
  1952             aPropertiesBuf.ReAllocL( aPropertiesBuf.Length() + curPropertiesBuf.Length() + overhead );  //msgId + parentId + length32 = 12 bytes
       
  1953             
       
  1954             aPropertiesBuf.Append( idPckg );     
       
  1955             aPropertiesBuf.Append( folderIdPckg );
       
  1956 
       
  1957             length32 = curPropertiesBuf.Length();
       
  1958             aPropertiesBuf.Append( length32Pckg );
       
  1959 
       
  1960             aPropertiesBuf.Append( curPropertiesBuf );              
       
  1961             }
       
  1962         }
       
  1963     
       
  1964         CleanupStack::PopAndDestroy( &curPropertiesBuf );
       
  1965         
       
  1966         //check if there are more rows left
       
  1967         if ( hasMore )
       
  1968             {
       
  1969             if ( direction == EMsgStoreIteratorForward )
       
  1970                 {
       
  1971                 hasMore = rowSet->HasMoreNextL();
       
  1972                 }
       
  1973             else
       
  1974                 {
       
  1975                 hasMore = rowSet->HasMorePreviousL();
       
  1976                 }
       
  1977             }
       
  1978         
       
  1979         iUtils->ResumeCompaction();
       
  1980         
       
  1981         return hasMore;
       
  1982  
       
  1983     }
       
  1984 
       
  1985 // ==========================================================================
       
  1986 // FUNCTION: IteratorGroupCountL
       
  1987 // ==========================================================================
       
  1988 TInt CContainerStore::IteratorGroupCountL( TContainerId aSessionId,  RArray<TUint>& aItemsInGroup )
       
  1989     {
       
  1990     //find the session;
       
  1991     TUint index = FindSortingSessionL( aSessionId );
       
  1992     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  1993     if ( index < iSortSessions.Count() )  
       
  1994         {
       
  1995         rowSet = iSortSessions[index].iResultRowSet;
       
  1996         }
       
  1997     else
       
  1998         {
       
  1999         User::Leave( KErrNotFound );
       
  2000         }
       
  2001     return rowSet->GroupCountL( aItemsInGroup );
       
  2002     }
       
  2003 
       
  2004 // ==========================================================================
       
  2005 // FUNCTION: SortedIdsAndFlagsL
       
  2006 // ==========================================================================
       
  2007 void CContainerStore::SortedIdsAndFlagsL( TContainerId aSessionId, RArray<TContainerId>& aIdArray, RArray<TUint32>& aFlagArray )
       
  2008 	{
       
  2009     __LOG_ENTER_SUPPRESS( "SortedIdsAndFlagsL" )
       
  2010     //find the session;
       
  2011     TUint index = FindSortingSessionL( aSessionId );
       
  2012     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  2013     if ( index < iSortSessions.Count() ) 
       
  2014         {
       
  2015         rowSet = iSortSessions[index].iResultRowSet;
       
  2016         }
       
  2017     else
       
  2018         {
       
  2019         User::Leave( KErrNotFound );
       
  2020         }
       
  2021     TContainerId folderId = rowSet->FolderId();
       
  2022 	
       
  2023     __LOG_WRITE_INFO("Before Calling SortedIdsL()")
       
  2024     rowSet->SortedIdsL( aIdArray );
       
  2025     __LOG_WRITE_INFO("After Calling SortedIdsL()")
       
  2026     
       
  2027     TPckgBuf<TUint32> flagsPckg;
       
  2028     
       
  2029     for ( TInt i = 0 ; i < aIdArray.Count() ; i++ )
       
  2030     	{
       
  2031     	iContainersTable->SeekL( aIdArray[i] );
       
  2032     	iContainersTable->QuickPropertiesL( iQuickProperties );
       
  2033     	
       
  2034         TPropertiesSerializer serializer( iQuickProperties );        
       
  2035         
       
  2036         if ( !serializer.Find( KMsgStorePropertyFlags ) )
       
  2037         	{
       
  2038         	User::Leave( KErrCorrupt );
       
  2039         	}
       
  2040         
       
  2041         flagsPckg.Copy( serializer.Value() );
       
  2042         aFlagArray.Append( flagsPckg() );
       
  2043     	}
       
  2044     
       
  2045     __LOG_WRITE_INFO("After Getting all flags")
       
  2046     
       
  2047 	}
       
  2048 
       
  2049 
       
  2050 // ==========================================================================
       
  2051 // FUNCTION: SortedIndexOfL
       
  2052 // ==========================================================================
       
  2053 TInt CContainerStore::SortedIndexOfL( TContainerId aSessionId, TContainerId aMessageId )
       
  2054     {
       
  2055     //find the session;
       
  2056     TUint index = FindSortingSessionL( aSessionId );
       
  2057     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  2058     if ( index < iSortSessions.Count() ) 
       
  2059         {
       
  2060         rowSet = iSortSessions[index].iResultRowSet;
       
  2061         }
       
  2062     else
       
  2063         {
       
  2064         User::Leave( KErrNotFound );
       
  2065         }
       
  2066     return rowSet->IndexOfL( aMessageId );
       
  2067     }
       
  2068 
       
  2069 // ==========================================================================
       
  2070 // FUNCTION: SortedIdsL
       
  2071 // ==========================================================================
       
  2072 void CContainerStore::SortedIdsL( TContainerId aSessionId, RArray<TContainerId>& aIdArray )
       
  2073 	{
       
  2074     //find the session;
       
  2075     TUint index = FindSortingSessionL( aSessionId );
       
  2076     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  2077     if ( index < iSortSessions.Count() ) 
       
  2078         {
       
  2079         rowSet = iSortSessions[index].iResultRowSet;
       
  2080         }
       
  2081     else
       
  2082         {
       
  2083         User::Leave( KErrNotFound );
       
  2084         }
       
  2085     rowSet->SortedIdsL( aIdArray );
       
  2086 	}
       
  2087 
       
  2088 // ==========================================================================
       
  2089 // FUNCTION: SortedIdsAndGroupCountL
       
  2090 // ==========================================================================
       
  2091 void CContainerStore::SortedIdsAndGroupCountL( TContainerId aSessionId, 
       
  2092                                                RArray<TContainerId>& aIdArray, 
       
  2093                                                RArray<TUint>& aItemsInGroup )
       
  2094     {
       
  2095     //find the session;
       
  2096     TUint index = FindSortingSessionL( aSessionId );
       
  2097     CMsgStoreSortResultRowSet* rowSet = NULL;
       
  2098     if ( index < iSortSessions.Count() ) 
       
  2099         {
       
  2100         rowSet = iSortSessions[index].iResultRowSet;
       
  2101         }
       
  2102     else
       
  2103         {
       
  2104         User::Leave( KErrNotFound );
       
  2105         }
       
  2106     rowSet->SortedIdsAndGroupCountL( aIdArray, aItemsInGroup );
       
  2107     }
       
  2108 
       
  2109 // ==========================================================================
       
  2110 // FUNCTION: FindSortingSessionL
       
  2111 // ==========================================================================
       
  2112 TUint CContainerStore::FindSortingSessionL( TContainerId aSessionId )
       
  2113     {
       
  2114     __LOG_ENTER_SUPPRESS( "FindSortingSessionL" )
       
  2115     
       
  2116     TBool found = EFalse;
       
  2117     TUint i = 0;
       
  2118     for ( ; !found && i < iSortSessions.Count() ; i++ )
       
  2119         {
       
  2120         if ( iSortSessions[i].iSessionId == aSessionId )
       
  2121             {
       
  2122             found = ETrue;
       
  2123             break;
       
  2124             }
       
  2125         }
       
  2126     
       
  2127     if ( !found )
       
  2128         {
       
  2129         __LOG_WRITE_ERROR( "ERR: session not found!" )
       
  2130         User::Leave( KErrNotFound );
       
  2131         }
       
  2132     
       
  2133     return i;
       
  2134     }
       
  2135 
       
  2136 // ==========================================================================
       
  2137 // FUNCTION: SetMaxMruCountL
       
  2138 // ==========================================================================
       
  2139 void CContainerStore::SetMaxMruCountL( TInt aMaxCount )
       
  2140     {
       
  2141     iMruAddressTable->SetMaxMruCountL( aMaxCount );
       
  2142     }
       
  2143 
       
  2144 // ==========================================================================
       
  2145 // FUNCTION: SetMruAddressListL
       
  2146 // ==========================================================================
       
  2147 void CContainerStore::SetMruAddressListL( TContainerId aMailboxId, RPointerArray<CMruAddress>& aMruAddressArray )
       
  2148     {
       
  2149     iMruAddressTable->SetMruAddressListL( aMailboxId, aMruAddressArray );
       
  2150     } 
       
  2151 
       
  2152 // ==========================================================================
       
  2153 // FUNCTION: MruAddressListL
       
  2154 // ==========================================================================
       
  2155 const RPointerArray<CMruAddress>& CContainerStore::MruAddressListL( TContainerId aMailboxId )
       
  2156     {
       
  2157     return iMruAddressTable->MruAddressListL( aMailboxId );
       
  2158     }
       
  2159 
       
  2160 // ==========================================================================
       
  2161 // FUNCTION: EncryptFirstL
       
  2162 // ==========================================================================
       
  2163 TBool CContainerStore::EncryptFirstL( TDbBookmark& aNextRow )
       
  2164     {
       
  2165     __LOG_ENTER( "EncryptFirstL" )
       
  2166     
       
  2167     TBool hasMore = iContainersTable->EncryptFirstL( aNextRow );
       
  2168     
       
  2169     __LOG_EXIT
       
  2170     
       
  2171     return hasMore;
       
  2172     }
       
  2173 
       
  2174 // ==========================================================================
       
  2175 // FUNCTION: EncryptNextL
       
  2176 // ==========================================================================
       
  2177 TBool CContainerStore::EncryptNextL( TDbBookmark& aNextRow )
       
  2178     {
       
  2179     __LOG_ENTER( "EncryptNextL" )
       
  2180     
       
  2181     TContainerId containerId = KContainerInvalidId;
       
  2182    
       
  2183     TBool hasMore = iContainersTable->EncryptNextL( aNextRow, containerId );
       
  2184         
       
  2185     if ( containerId != KContainerInvalidId )
       
  2186         {
       
  2187         TRAP_IGNORE( iContentManager->EncryptL( containerId ) );
       
  2188         }
       
  2189     
       
  2190     __LOG_EXIT
       
  2191     
       
  2192     return hasMore;
       
  2193     }
       
  2194 
       
  2195 // ==========================================================================
       
  2196 // FUNCTION: EncryptNextL
       
  2197 // ==========================================================================
       
  2198 TBool CContainerStore::DecryptFirstL( TDbBookmark& aNextRow )
       
  2199     {
       
  2200     __LOG_ENTER( "DecryptFirstL" )
       
  2201     
       
  2202     TBool hasMore = iContainersTable->DecryptFirstL( aNextRow );
       
  2203     
       
  2204     __LOG_EXIT
       
  2205     
       
  2206     return hasMore;
       
  2207     }
       
  2208 
       
  2209 // ==========================================================================
       
  2210 // FUNCTION: EncryptNextL
       
  2211 // ==========================================================================
       
  2212 TBool CContainerStore::DecryptNextL( TDbBookmark& aNextRow )
       
  2213     {
       
  2214     __LOG_ENTER( "DecryptNextL" )
       
  2215     
       
  2216     TContainerId containerId = KContainerInvalidId;
       
  2217     
       
  2218     TBool hasMore = iContainersTable->DecryptNextL( aNextRow, containerId );
       
  2219         
       
  2220     if ( containerId != KContainerInvalidId )
       
  2221         {
       
  2222         TRAP_IGNORE( iContentManager->DecryptL( containerId ) );
       
  2223         }
       
  2224     
       
  2225     __LOG_EXIT
       
  2226     
       
  2227     return hasMore;
       
  2228     }
       
  2229 
       
  2230 // ==========================================================================
       
  2231 // FUNCTION: ValidateParentL
       
  2232 // ==========================================================================
       
  2233 void CContainerStore::ValidateParentL( TContainerId                aParentId, 
       
  2234                                        const RArray<TContainerId>& aHierarchy, 
       
  2235                                        TBool                       aStrictComparison )
       
  2236     {
       
  2237     __LOG_ENTER_SUPPRESS( "ValidateParentL" )
       
  2238     
       
  2239     TBool matches = (aParentId == KContainerInvalidId) ||
       
  2240                     ((aHierarchy.Count() > 1) &&
       
  2241                         (aHierarchy[1] == aParentId) ||
       
  2242                         ((aHierarchy[1] == KUncommittedContainers) && !aStrictComparison ));
       
  2243                                 
       
  2244     if( !matches )
       
  2245         {
       
  2246         __LOG_WRITE_ERROR( "parent does not match" )
       
  2247         
       
  2248         User::Leave( KErrNotFound );
       
  2249         } // end if
       
  2250     
       
  2251     } // end ValidateParentL
       
  2252                       
       
  2253 // ==========================================================================
       
  2254 // FUNCTION: ValidateParentAndGrandparentL
       
  2255 // ==========================================================================
       
  2256 void CContainerStore::ValidateParentAndGrandparentL( TContainerId                aParentId, 
       
  2257                                                      TContainerId                aGrandparentId, 		                                    		    
       
  2258                                                      const RArray<TContainerId>& aHierarchy,
       
  2259                                                      TBool                       aStrictComparison )
       
  2260     {
       
  2261     __LOG_ENTER_SUPPRESS( "ValidateParentAndGrandparentL" )
       
  2262     
       
  2263     ValidateParentL( aParentId, aHierarchy, aStrictComparison );    
       
  2264     
       
  2265     TBool matches = (aGrandparentId == KContainerInvalidId) ||
       
  2266                     ((aHierarchy.Count() == 2) &&
       
  2267                          ((aHierarchy[1] == KUncommittedContainers) && !aStrictComparison )) ||
       
  2268                     ((aHierarchy.Count() > 2) &&
       
  2269                           ((aHierarchy[2] == aGrandparentId) ||
       
  2270                           ((aHierarchy[2] == KUncommittedContainers) && !aStrictComparison )));
       
  2271                                 
       
  2272     if( !matches )
       
  2273         {
       
  2274         __LOG_WRITE_ERROR( "grandparent does not match" )
       
  2275         
       
  2276         User::Leave( KErrNotFound );
       
  2277         } // end if        
       
  2278     
       
  2279     } // end ValidateParentAndGrandparentL
       
  2280 
       
  2281 // ==========================================================================
       
  2282 // FUNCTION: DeleteIndividualContainerL
       
  2283 // ==========================================================================
       
  2284 TBool CContainerStore::DeleteIndividualContainerL( TDbBookmark aBookmark )
       
  2285     {
       
  2286     __LOG_ENTER( "DeleteIndividualContainerL" )
       
  2287     
       
  2288     TBool result = ETrue;
       
  2289     
       
  2290     TContainerId id = iContainersTable->GotoL( aBookmark );
       
  2291 
       
  2292     TRAPD( err, iContentManager->RemoveContentL( id ) );
       
  2293     if ( err == KErrInUse )
       
  2294         {
       
  2295         __LOG_WRITE_INFO("Content file still open, mark for delete again.")
       
  2296         iUtils->BeginDatabaseTransactionLC();
       
  2297         iContainersTable->MarkAsDeleteRetryL();
       
  2298         iUtils->CommitDatabaseTransactionL();
       
  2299         result = EFalse;
       
  2300         }
       
  2301     else
       
  2302         {
       
  2303         iUtils->BeginDatabaseTransactionLC();
       
  2304         iContainersTable->DeleteL();
       
  2305         iUtils->CommitDatabaseTransactionL();
       
  2306         }
       
  2307     
       
  2308     __LOG_EXIT
       
  2309     
       
  2310     return result;
       
  2311     } // end DeleteIndividualContainerL
       
  2312 
       
  2313 // ==========================================================================
       
  2314 // FUNCTION: SuspendCompaction
       
  2315 // ==========================================================================
       
  2316 void CContainerStore::SuspendCompactionLC()
       
  2317 	{
       
  2318 	iUtils->SuspendCompactionLC();
       
  2319 	} // end SuspendCompaction
       
  2320 
       
  2321 // ==========================================================================
       
  2322 // FUNCTION: ResumeCompaction
       
  2323 // ==========================================================================
       
  2324 void CContainerStore::ResumeCompaction()
       
  2325 	{
       
  2326 	iUtils->ResumeCompaction();
       
  2327 	} // end ResumeCompaction
       
  2328 
       
  2329 // ==========================================================================
       
  2330 // FUNCTION: GetSortableFieldsL
       
  2331 // ==========================================================================
       
  2332 void CContainerStore::GetSortableFieldsL( TContainerId aMessageId, RMsgStoreSortableFields& aSortableFields )
       
  2333     {
       
  2334     RBuf8 propertiesBuf;
       
  2335     CleanupClosePushL( propertiesBuf );
       
  2336     
       
  2337     iContainersTable->SeekL( aMessageId );
       
  2338     
       
  2339     iContainersTable->PropertiesL( propertiesBuf );
       
  2340     
       
  2341     iCustomBehaviorProvider.SortableFieldsL( iQuickProperties, propertiesBuf, aSortableFields );
       
  2342 
       
  2343     CleanupStack::PopAndDestroy( &propertiesBuf );
       
  2344     
       
  2345     //need to get the size
       
  2346     if ( aSortableFields.iSizeOnServer == 0 )
       
  2347         {
       
  2348         //get the size on client
       
  2349         //first get the proerty size of the message itself
       
  2350         TUint size = iContainersTable->PropertiesSizeL( aMessageId );
       
  2351         
       
  2352         RArray<TContainerId> children;
       
  2353         CleanupClosePushL( children );
       
  2354     
       
  2355         // Abandon all of the uncommitted containers.
       
  2356         iContainersTable->ListChildrenL( children, aMessageId );  //non-recursive, assuming the UI will not build an recursive attachment.
       
  2357         for ( int i = 0 ; i < children.Count() ; i++ )
       
  2358             {
       
  2359             //get the property size
       
  2360             size += iContainersTable->PropertiesSizeL( children[i] );
       
  2361             TBool isRowEncrypted = iContainersTable->IsEncrypted();
       
  2362             //get the content size
       
  2363             size += iContentManager->ContentLengthL( children[i], isRowEncrypted );
       
  2364             }
       
  2365         
       
  2366         CleanupStack::PopAndDestroy( &children );
       
  2367         
       
  2368         aSortableFields.iSizeOnClient = size;
       
  2369         }
       
  2370     }
       
  2371 
       
  2372 
       
  2373 // ==========================================================================
       
  2374 // FUNCTION: CreateSystemFoldersL
       
  2375 // ==========================================================================
       
  2376 void CContainerStore::CreateSystemFoldersL( TContainerId aMailboxId )
       
  2377     {
       
  2378     TPckg<TBool> boolPckg( ETrue );
       
  2379     TPckg<TUint> intPckg( aMailboxId );
       
  2380     TInt totalLength = TPropertiesSerializer::EFixedOverhead;
       
  2381     totalLength += KMsgStorePropertyFolderType().Length() + intPckg.Length() + TPropertiesSerializer::EPerNodeOverhead;
       
  2382     totalLength += KMsgStorePropertyLocal().Length() + boolPckg.Length() + TPropertiesSerializer::EPerNodeOverhead;
       
  2383     
       
  2384     RBuf8 properties;
       
  2385     properties.Create( totalLength );
       
  2386     CleanupClosePushL( properties );
       
  2387     
       
  2388     for ( TUint32 i = EMsgStoreInbox; i <= EMsgStoreDeleted; i++ )
       
  2389         {
       
  2390         properties.SetLength( 0 );
       
  2391         TPropertiesSerializer serializer( properties );
       
  2392         
       
  2393         TPckg<TUint> typePkg( i );
       
  2394         serializer.AddPropertyL( KMsgStorePropertyFolderType, EMsgStoreTypeUint32, typePkg );
       
  2395         
       
  2396         TBool isLocal = ( i == EMsgStoreDeleted );
       
  2397         TPckg<TBool> isLocalPkg( isLocal );
       
  2398         serializer.AddPropertyL( KMsgStorePropertyLocal, EMsgStoreTypeBool, isLocalPkg );
       
  2399         
       
  2400         TContainerId folderId = CreateContainerL( EMsgStoreFolderBits, aMailboxId, KMsgStoreInvalidId, properties );
       
  2401         
       
  2402         CommitContainerL( folderId, aMailboxId, aMailboxId, NULL );        
       
  2403         }
       
  2404     
       
  2405     CleanupStack::PopAndDestroy( &properties );
       
  2406     }
       
  2407 
       
  2408 // ==========================================================================
       
  2409 // FUNCTION: GetSortableFields
       
  2410 // ==========================================================================
       
  2411 void CContainerStore::MessageUpdate( TContainerId       aMessageId, 
       
  2412                                      TContainerId       aFolderId, 
       
  2413                                      TMsgStoreOperation aOperation, 
       
  2414                                      TUint              aFieldsChanged,
       
  2415                                      const TDesC&       aFrom, 
       
  2416                                      const TDesC&       aTo, 
       
  2417                                      const TDesC&       aSubject,
       
  2418                                      TInt64             aDate)
       
  2419     {
       
  2420     for ( TInt i = 0 ; i < iSortSessions.Count() ; i++ )
       
  2421         {
       
  2422         iSortSessions[i].iResultRowSet->MessageUpdate( aMessageId, aFolderId, aOperation, aFieldsChanged, aFrom, aTo, aSubject, aDate );
       
  2423         }
       
  2424     }
       
  2425 
       
  2426 // ==========================================================================
       
  2427 // FUNCTION: FolderDeleted
       
  2428 // ==========================================================================
       
  2429 void CContainerStore::FolderDeleted( TContainerId aFolderId )
       
  2430     {
       
  2431     for ( TInt i = 0 ; i < iSortSessions.Count() ; i++ )
       
  2432         {
       
  2433         iSortSessions[i].iResultRowSet->FolderDeleted( aFolderId );
       
  2434         }
       
  2435     }
       
  2436 
       
  2437 // ==========================================================================
       
  2438 // FUNCTION: MailBoxDeleted
       
  2439 // ==========================================================================
       
  2440 void CContainerStore::MailBoxDeleted( TContainerId aMailBoxId )
       
  2441     {
       
  2442     for ( TInt i = 0 ; i < iSortSessions.Count() ; i++ )
       
  2443         {
       
  2444         iSortSessions[i].iResultRowSet->MailBoxDeleted( aMailBoxId );
       
  2445         }
       
  2446     }
       
  2447 
       
  2448 /**
       
  2449  * 
       
  2450  */
       
  2451 /*public*/ CContainerStoreUtils& CContainerStore::StoreUtils()
       
  2452     {
       
  2453     return *iUtils;
       
  2454     }
       
  2455 
       
  2456 /**
       
  2457  * 
       
  2458  */
       
  2459 /*public*/ CContainerStoreContentManager& CContainerStore::ContentManager()
       
  2460     {
       
  2461     //guaranteed that cannot be NULL by ConstructL.
       
  2462     return *iContentManager;
       
  2463     }
       
  2464 
       
  2465 /**
       
  2466  * 
       
  2467  */
       
  2468 /*public*/ TBool CContainerStore::IsEncryptionEnabled()
       
  2469     {
       
  2470     return iEncryption->IsEncryptionOn();
       
  2471     }
       
  2472 
       
  2473 /**
       
  2474  * 
       
  2475  */
       
  2476 /*public*/
       
  2477 void CContainerStore::BeginDatabaseTransactionLC()
       
  2478     {
       
  2479     iUtils->BeginDatabaseTransactionLC();
       
  2480     }
       
  2481 
       
  2482 /**
       
  2483  * 
       
  2484  */
       
  2485 /*public*/
       
  2486 void CContainerStore::CommitDatabaseTransactionL()
       
  2487     {
       
  2488     iUtils->CommitDatabaseTransactionL();
       
  2489     }
       
  2490 
       
  2491 /**
       
  2492  * 
       
  2493  */
       
  2494 /*public*/ const TDesC& CContainerStore::PrivatePath()
       
  2495     {
       
  2496     return iUtils->PrivatePath();
       
  2497     }
       
  2498 
       
  2499 // ---------------
       
  2500 // DEBUG FUNCTIONS
       
  2501 // ---------------
       
  2502 
       
  2503 #ifdef _DEBUG                                 	
       
  2504 
       
  2505 void CContainerStore::SimulateLowDiskSpace( TInt aLatency )
       
  2506     {
       
  2507     iUtils->SimulateLowDiskSpace( aLatency );
       
  2508     }
       
  2509 
       
  2510 TInt CContainerStore::GetEncryptionStateL()
       
  2511     {
       
  2512     return iGeneralTable->EncryptionStateL();
       
  2513     }
       
  2514 
       
  2515 #endif    
       
  2516