--- /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) );
+ }
+