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