emailservices/emailstore/message_store/server/src/ContainerStoreAccountTable.cpp
changeset 0 8466d47a6819
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailservices/emailstore/message_store/server/src/ContainerStoreAccountTable.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,629 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Container store account table implementation.
+*
+*/
+
+
+
+// ========
+// INCLUDES
+// ========
+
+#include "ContainerStoreAccountTable.h"
+#include "ContainerStoreDefs.h"
+#include "ContainerStoreUtils.h"
+#include "MessageStoreClientServer.h"
+#include "ContainerStoreEncryption.h"
+#include "AccountsSerializer.h"
+
+// =========
+// CONSTANTS
+// =========
+
+// ======================
+// METHOD IMPLEMENTATIONS
+// ======================
+
+// ==========================================================================
+// FUNCTION: OpenL
+// ==========================================================================
+CContainerStoreAccountTable* CContainerStoreAccountTable::OpenL( CContainerStoreUtils&      aUtils, 
+																 CContainerStoreEncryption& aEncryption,
+																 MCustomBehaviorProvider&   aCustomBehaviorProvider )
+	{
+	CContainerStoreAccountTable* self = new(ELeave) CContainerStoreAccountTable( aUtils, aEncryption, aCustomBehaviorProvider );
+	CleanupStack::PushL( self );
+	self->OpenTableL();
+	CleanupStack::Pop( self );
+	return self;
+	} // end OpenL
+
+// ==========================================================================
+// FUNCTION: CreateL
+// ==========================================================================
+CContainerStoreAccountTable* CContainerStoreAccountTable::CreateL( CContainerStoreUtils&      aUtils, 
+																   CContainerStoreEncryption& aEncryption,
+																   MCustomBehaviorProvider&   aCustomBehaviorProvider )
+	{
+	CContainerStoreAccountTable* self = new(ELeave) CContainerStoreAccountTable( aUtils, aEncryption, aCustomBehaviorProvider );
+	CleanupStack::PushL( self );
+	self->CreateTableL();
+	CleanupStack::Pop( self );
+	return self;
+	} // end CreateL
+
+// ==========================================================================
+// FUNCTION: Constructor
+// ==========================================================================
+CContainerStoreAccountTable::CContainerStoreAccountTable( CContainerStoreUtils&      aUtils, 
+														  CContainerStoreEncryption& aEncryption,
+														  MCustomBehaviorProvider&   aCustomBehaviorProvider ) :
+    CContainerStoreTable( aUtils ), iEncryption(aEncryption), iCustomBehaviorProvider(aCustomBehaviorProvider)
+	{
+	__LOG_CONSTRUCT( "msg", "CContainerStoreAccountTable" )
+	__LOG_CLOSE_BETWEEN_WRITES
+	} // end constructor
+
+// ==========================================================================
+// FUNCTION: Destructor
+// ==========================================================================
+CContainerStoreAccountTable::~CContainerStoreAccountTable()
+	{
+	iUtils.CloseTable( iTable );
+
+	__LOG_DESTRUCT	
+	} // end destructor
+	
+// ==========================================================================
+// FUNCTION: OpenTableL
+// ==========================================================================
+void CContainerStoreAccountTable::OpenTableL()
+	{
+	__LOG_ENTER( "OpenTableL" )
+
+	iUtils.OpenTableL( iTable, KAccountTableName );
+	
+	// Get the column numbers for the containers table.
+	CDbColSet* colSet = iTable.ColSetL();
+	CleanupStack::PushL( colSet );
+	
+	iOwnerIdColNum       = colSet->ColNo( KAccountTableOwnerIdCol );
+	iAccountNameColNum   = colSet->ColNo( KAccountTableAccountNameCol );
+	iMailBoxIdColNum     = colSet->ColNo( KAccountTableMailBoxIdCol );
+	iTotalCountsColNum   = colSet->ColNo( KAccountTableTotalCountsCol );
+	iIsEncryptedColNum   = colSet->ColNo( KAccountTableIsEncryptedCol );
+	
+	CleanupStack::PopAndDestroy( colSet );
+
+	//initialize the iCountsLength
+    TUint quickPropertiesLength;  //don't care
+    iCustomBehaviorProvider.LengthsL( iCountsLength, quickPropertiesLength );
+	
+	// Set the table's index to the ID index.
+	User::LeaveIfError( iTable.SetIndex( KAccountTableMailBoxIdIndex ) );
+
+	__LOG_EXIT	
+	} // end OpenTableL
+	
+// ==========================================================================
+// FUNCTION: CreateTableL
+// ==========================================================================
+void CContainerStoreAccountTable::CreateTableL()
+	{
+	__LOG_ENTER( "CreateTableL" )
+	
+	// Create table columns
+	
+	CDbColSet* colSet = CDbColSet::NewLC();
+	
+	TDbCol ownerIdCol( KAccountTableOwnerIdCol, EDbColInt32 );
+	colSet->AddL( ownerIdCol );	
+	
+	TDbCol accNameCol( KAccountTableAccountNameCol, EDbColLongBinary );
+	colSet->AddL( accNameCol );	
+	
+	TDbCol mailBoxIdCol( KAccountTableMailBoxIdCol, EDbColUint32 );
+	colSet->AddL( mailBoxIdCol );	
+	
+	TDbCol totalCountsCol( KAccountTableTotalCountsCol, EDbColBinary );
+	colSet->AddL( totalCountsCol );	
+	
+	TDbCol isEncryptedCol( KAccountTableIsEncryptedCol, EDbColUint8 );
+	colSet->AddL( isEncryptedCol );	
+		
+	// Create table.
+	iUtils.CreateTableL( KAccountTableName, *colSet );
+	
+	CleanupStack::PopAndDestroy( colSet );
+	
+	// Create table index.
+    CreateIndexL( KAccountTableName, KAccountTableMailBoxIdIndex, KAccountTableMailBoxIdCol );
+    
+	OpenTableL();
+			
+	__LOG_EXIT
+	} // end CreateTableL
+	
+
+// ==========================================================================
+// FUNCTION: AddAccountL
+// ==========================================================================
+void CContainerStoreAccountTable::AddAccountL( TContainerId aMailboxId, TInt32 aOwnerId, const TDesC8& aName )
+	{
+	__LOG_ENTER_SUPPRESS( "AddAccountL" )
+	
+	__LOG_WRITE8_FORMAT3_INFO( "mbId=%x, ownerId=%i, name=%S", aMailboxId, aOwnerId, &aName )
+	
+	//initialize to total counts
+	RBuf8 totalCounts;
+	CleanupClosePushL( totalCounts );
+
+	//now we can add the new account
+	
+	iTable.LastL();
+	
+	InsertRowLC();
+	 
+	iTable.SetColL( iOwnerIdColNum,        aOwnerId );
+	iTable.SetColL( iMailBoxIdColNum,      aMailboxId );
+	
+	totalCounts.Create( iCountsLength );
+    iCustomBehaviorProvider.InitializeCounts( totalCounts );
+	iTable.SetColL( iTotalCountsColNum, totalCounts );
+    
+    TBool isEncryptionOn = iEncryption.IsEncryptionOn();
+    
+    iTable.SetColL( iIsEncryptedColNum, static_cast<TUint8>( isEncryptionOn ) );
+	
+	WriteNameL( aName, isEncryptionOn );
+	
+	PutRowUpdatesL();
+	
+	CleanupStack::PopAndDestroy( &totalCounts );
+	
+	}
+
+// ==========================================================================
+// FUNCTION: FindAccountL
+// ==========================================================================
+TContainerId CContainerStoreAccountTable::FindAccountL( TInt32 aOwnerId, const TDesC8& aName )
+	{
+	__LOG_ENTER_SUPPRESS( "FindAccountL" )
+	__LOG_WRITE8_FORMAT2_INFO( "ownerId=%i, name=%S", aOwnerId, &aName )
+
+	RBuf8 accName;
+	CleanupClosePushL( accName );
+	
+	TContainerId mbId = KMsgStoreInvalidId;
+	
+	iTable.FirstL();
+	
+	while( !iTable.AtEnd() )
+		{
+		iTable.GetL();
+		TInt32 ownerId = iTable.ColInt32( iOwnerIdColNum );
+		if ( ownerId == aOwnerId )
+			{
+			ReadNameL( accName );
+			if ( accName.CompareC( aName ) == 0 )
+				{
+				//we have found the matching account, get it's mailbox id
+				mbId = iTable.ColUint32( iMailBoxIdColNum );
+				break;
+				}
+			}
+		
+		iTable.NextL();
+		}
+	
+	if ( mbId == KMsgStoreInvalidId )
+		{
+		User::Leave( KErrNotFound );
+		}
+	
+	CleanupStack::PopAndDestroy( &accName );
+		
+	return mbId;
+	}
+
+// ==========================================================================
+// FUNCTION: DeleteAccountL
+// ==========================================================================
+TContainerId CContainerStoreAccountTable::DeleteAccountL( TInt32 aOwnerId, const TDesC8& aName )
+	{
+	__LOG_ENTER_SUPPRESS( "DeleteAccountL" )
+	__LOG_WRITE8_FORMAT2_INFO( "ownerId=%i, name=%S", aOwnerId, &aName )
+	
+	TContainerId mbId = FindAccountL(aOwnerId, aName);
+	
+	//delete the account
+	SeekL( mbId );
+	
+	iTable.DeleteL();
+	 
+	return mbId;
+	}
+
+// ==========================================================================
+// FUNCTION: RenameAccountL
+// ==========================================================================
+void CContainerStoreAccountTable::RenameAccountL( TInt32 aOwnerId, const TDesC8& aOldName, const TDesC8& aNewName )
+	{
+	__LOG_ENTER_SUPPRESS( "RenameAccountL" )
+	__LOG_WRITE8_FORMAT3_INFO( "ownerId=%i, oleName=%S newName=%S", aOwnerId, &aOldName, &aNewName )
+	
+	TContainerId mbId = FindAccountL( aOwnerId, aOldName );
+	
+	TRAPD( err, FindAccountL( aOwnerId, aNewName ) );
+	if ( err == KErrNone )
+		{
+		//new account name already exists
+		User::Leave( KErrAlreadyExists );
+		}
+	else if ( err != KErrNotFound )
+		{
+		User::Leave( err );
+		}
+	
+	//rename the account
+	SeekL( mbId );
+	
+	PrepareRowForUpdateLC();
+	
+	WriteNameL( aNewName, iEncryption.IsEncryptionOn() );
+	
+	PutRowUpdatesL();
+	}
+
+// ==========================================================================
+// FUNCTION: RenameAccountL
+// ==========================================================================
+void CContainerStoreAccountTable::AccountsL( TDes8& aAccountsBuf )
+	{
+	__LOG_ENTER( "AccountsL" )
+	
+	RBuf8 accName;
+	CleanupClosePushL( accName );
+	
+	CAccountsSerializer* serializer = new (ELeave) CAccountsSerializer();
+	CleanupStack::PushL( serializer );
+
+	iTable.FirstL();
+	
+	while( !iTable.AtEnd() )
+		{
+		iTable.GetL();
+		TInt32 ownerId = iTable.ColInt32( iOwnerIdColNum );
+		ReadNameL( accName );
+		
+		//convert name to 16 bits
+		TPtrC16 name16;
+		
+		const TUint16* valuePtr16 = reinterpret_cast<const TUint16*>( accName.Ptr() );
+		
+		name16.Set( valuePtr16, accName.Length() / 2 );
+		
+		__LOG_WRITE_FORMAT2_INFO( "ownerId=%i, name=%S", ownerId, &name16 )
+		
+		serializer->AddAccountL( ownerId, name16 );
+		
+		iTable.NextL();
+		}
+	
+	serializer->SerializeL( aAccountsBuf );
+	
+	CleanupStack::PopAndDestroy( serializer );
+	CleanupStack::PopAndDestroy( &accName );
+
+	__LOG_EXIT
+	}
+
+// ==========================================================================
+// FUNCTION: MailboxIdsL
+// ==========================================================================
+void CContainerStoreAccountTable::MailboxIdsL( RArray<TContainerId>& aMailboxIds )
+    {
+    __LOG_ENTER( "MailboxIdsL" )
+    
+    if ( iTable.IsEmptyL() )
+        {
+        __LOG_WRITE_INFO( "Table is empty!" )
+        __LOG_EXIT
+        return;
+        }    
+    
+    for( TBool hasMore = iTable.FirstL() ; hasMore ; hasMore = iTable.NextL() )
+        {
+        iTable.GetL();
+        TContainerId mailboxId = iTable.ColUint32( iMailBoxIdColNum );
+        aMailboxIds.Append( mailboxId );
+        }
+    
+    __LOG_EXIT
+    }
+
+// ==========================================================================
+// FUNCTION: EncryptFirstL
+// ==========================================================================
+TBool CContainerStoreAccountTable::EncryptFirstL( TDbBookmark& aNextRow )
+    {
+    __LOG_ENTER( "EncryptFirstL" )
+    
+    TBool found = iUtils.FindFirstEncryptedOrUnencryptedL( iTable, KAccountTableIsEncryptedCol, EFalse, aNextRow );
+    
+    __LOG_EXIT
+    
+    return found;
+    }
+
+// ==========================================================================
+// FUNCTION: EncryptNextL
+// ==========================================================================
+TBool CContainerStoreAccountTable::EncryptNextL( TDbBookmark& aNextRow )
+    {
+    __LOG_ENTER( "EncryptNextL" )
+    
+    TBool hasMore = EFalse;
+    
+    TRAPD( err, iTable.GotoL( aNextRow ) );
+    if ( err == KErrNotFound )
+        {
+        hasMore = EncryptFirstL( aNextRow );
+        }
+    else if ( err != KErrNone )
+        {
+        User::Leave( err );        
+        }
+    else
+        {
+        iTable.GetL();
+        if ( !IsEncrypted() )
+            {
+            RBuf8 nameBuf;
+            CleanupClosePushL( nameBuf );
+            
+            ReadNameL( nameBuf );
+            
+            PrepareRowForUpdateLC();
+            
+            WriteNameL( nameBuf, ETrue );  //encrypt before write
+            
+            //update the isEncrypted column
+            SetEncryptedL( ETrue );
+            
+            PutRowUpdatesL();
+            
+            CleanupStack::PopAndDestroy( &nameBuf );
+            }
+        
+        hasMore = iTable.NextL();
+        if ( hasMore )
+            {
+            __LOG_WRITE_INFO("hasMore is TRUE")
+            aNextRow = iTable.Bookmark();
+            }
+        }
+
+    __LOG_EXIT
+    
+    return hasMore;
+    }
+
+// ==========================================================================
+// FUNCTION: DecryptFirstL
+// ==========================================================================
+TBool CContainerStoreAccountTable::DecryptFirstL( TDbBookmark& aNextRow )
+    {
+    __LOG_ENTER( "DecryptFirstL" )
+    
+    TBool found = iUtils.FindFirstEncryptedOrUnencryptedL( iTable, KAccountTableIsEncryptedCol, ETrue, aNextRow );
+    
+    __LOG_EXIT
+    
+    return found;
+    }
+
+// ==========================================================================
+// FUNCTION: DecryptNextL
+// ==========================================================================
+TBool CContainerStoreAccountTable::DecryptNextL( TDbBookmark& aNextRow )
+    {
+    __LOG_ENTER( "DecryptNextL" )
+    
+    TBool hasMore = EFalse;
+    
+    TRAPD( err, iTable.GotoL( aNextRow ) );
+    if ( err == KErrNotFound )
+        {
+        hasMore = DecryptFirstL( aNextRow );
+        }
+    else if ( err != KErrNone )
+        {
+        User::Leave( err );        
+        }
+    else
+        {
+        iTable.GetL();
+        if ( IsEncrypted() )
+            {
+            RBuf8 nameBuf;
+            CleanupClosePushL( nameBuf ); 
+            
+            ReadNameL( nameBuf );
+            
+            PrepareRowForUpdateLC();
+            
+            WriteNameL( nameBuf, EFalse );  //do not encrypt before write
+            
+            //update the isEncrypted column
+            SetEncryptedL( EFalse );
+            
+            PutRowUpdatesL();
+            
+            CleanupStack::PopAndDestroy( &nameBuf );
+            }
+        
+        hasMore = iTable.NextL();
+        if ( hasMore )
+            {
+            __LOG_WRITE_INFO("hasMore is TRUE")
+            aNextRow = iTable.Bookmark();
+            }
+        }
+
+    __LOG_EXIT
+    
+    return hasMore;
+    }
+
+// ==========================================================================
+// FUNCTION: SeekL
+// ==========================================================================
+void CContainerStoreAccountTable::SeekL( TContainerId aMailBoxId )
+    {
+    __LOG_ENTER_SUPPRESS("SeekL")
+    if ( !iTable.SeekL( aMailBoxId ) )
+        {
+        __LOG_WRITE8_FORMAT1_ERROR( "MailBox id %x not found", aMailBoxId )
+        User::Leave( KErrNotFound );
+        }
+    }
+
+// ==========================================================================
+// FUNCTION: WriteNameL
+// ==========================================================================
+void CContainerStoreAccountTable::WriteNameL( const TDesC8& aName, TBool aEncryptBeforeWrite )
+	{
+	__LOG_ENTER_SUPPRESS( "WriteNameL" )
+	__LOG_WRITE8_FORMAT1_INFO( "name=%S", &aName )
+    
+    if ( aEncryptBeforeWrite && aName.Length() > 0 )
+        {
+        RBuf8 encryptedBuffer;
+        encryptedBuffer.CreateL( aName.Length() + iEncryption.BlockSizeL() );
+        CleanupClosePushL( encryptedBuffer );
+        
+        RBuf8 paddedBuffer;
+        paddedBuffer.CreateL( aName.Length() + iEncryption.BlockSizeL() );       
+        CleanupClosePushL( paddedBuffer );
+    
+        paddedBuffer.Copy( aName );
+        iEncryption.AddPaddingL( paddedBuffer, iEncryption.BlockSizeL() );
+    
+        iEncryption.EncryptL( paddedBuffer, encryptedBuffer );
+    
+    	CleanupStack::PopAndDestroy( &paddedBuffer );
+    
+        iUtils.WriteLongColumnL( iTable, iAccountNameColNum, encryptedBuffer );
+        
+    	CleanupStack::PopAndDestroy( &encryptedBuffer );
+        }
+    else
+        {
+        iUtils.WriteLongColumnL( iTable, iAccountNameColNum, aName );
+        }
+	
+	__LOG_EXIT
+	}
+
+
+// ==========================================================================
+// FUNCTION: ReadNameL
+// ==========================================================================
+void CContainerStoreAccountTable::ReadNameL( RBuf8& aName )
+	{
+	__LOG_ENTER_SUPPRESS( "ReadNameL" )
+    
+    if ( IsEncrypted() )
+        {
+        aName.SetLength( 0 );
+	
+    	RBuf8 encryptedBuffer;
+    	CleanupClosePushL( encryptedBuffer );
+    	
+    	iUtils.ReadLongColumnL( iTable, iAccountNameColNum, encryptedBuffer );
+    	
+    	if( aName.Size() < encryptedBuffer.Length() )
+    	    {        
+    	    aName.ReAllocL( encryptedBuffer.Length() );
+    	    } // end if
+    	
+    	if( encryptedBuffer.Length() > 0 )
+    	    {        
+    	    iEncryption.DecryptL( encryptedBuffer, aName );        
+    	    iEncryption.RemovePaddingL( aName );
+    	    } // end if
+    	
+    	CleanupStack::PopAndDestroy( &encryptedBuffer );
+        }
+    else
+        {
+        iUtils.ReadLongColumnL( iTable, iAccountNameColNum, aName );
+        }
+	
+	__LOG_WRITE8_FORMAT1_INFO( "name=%S", &aName )
+	
+	}
+
+// ==========================================================================
+// FUNCTION: TotalCountsL
+// ==========================================================================
+void CContainerStoreAccountTable::TotalCountsL( TContainerId aMailBoxId, TDes8& aTotalCounts )
+{
+	__LOG_ENTER( "TotalCountsL" )
+	
+	SeekL( aMailBoxId );
+  	iTable.GetL();
+
+    aTotalCounts.Copy( iTable.ColDes8( iTotalCountsColNum ) );
+        
+	__LOG_EXIT
+} // end TotalCountsL
+
+// ==========================================================================
+// FUNCTION: UpdateTotalCountsL
+// ==========================================================================
+void CContainerStoreAccountTable::UpdateTotalCountsL( TContainerId aMailBoxId, const TDesC8& aTotalCounts )
+{
+	__LOG_ENTER( "UpdateTotalCountsL" )
+
+	SeekL( aMailBoxId );
+	
+	PrepareRowForUpdateLC();
+    
+	iTable.SetColL( iTotalCountsColNum, aTotalCounts );
+
+	PutRowUpdatesL();
+	
+	__LOG_EXIT
+    
+} // end UpdateTotalCountsL
+
+// ==========================================================================
+// FUNCTION: IsEncrypted
+// ==========================================================================
+TBool CContainerStoreAccountTable::IsEncrypted()
+    {
+    return static_cast<TBool>( iTable.ColUint8( iIsEncryptedColNum ) );
+    }
+
+// ==========================================================================
+// FUNCTION: SetEncryptedL
+// ==========================================================================
+void CContainerStoreAccountTable::SetEncryptedL( TBool aIsEncrypted )
+    {
+    iTable.SetColL( iIsEncryptedColNum, static_cast<TUint8>(aIsEncrypted) );
+    }
+