--- a/omads/omadsextensions/adapters/contactsgroup/src/contactsgrpdatastore.cpp Tue Aug 31 15:05:37 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1268 +0,0 @@
-/*
-* Copyright (c) 2009-2010 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: Part of SyncML Data Synchronization Plug In Adapter
-*
-*/
-
-
-#include <sysutil.h>
-#include <cntfldst.h>
-
-#include "contactsgrpdatastore.h"
-#include "contactsgrpconverter.h"
-#include "changefinder.h"
-#include "contactsgrpdataproviderdefs.h"
-#include "logger.h"
-
-const TInt KDefaultBufferSize = 1024;
-const TInt KDataBufferNotReady = -1;
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::CContactsGrpDataStore
-// C++ default constructor can NOT contain any code, that might leave.
-// -----------------------------------------------------------------------------
-CContactsGrpDataStore::CContactsGrpDataStore() :
- iKey( TKeyArrayFix( _FOFF( TNSmlSnapshotItem, ItemId() ), ECmpTInt ) )
- {
- TRACE_FUNC;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::ConstructL
-// Symbian 2nd phase constructor, can leave.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::ConstructL()
- {
- TRACE_FUNC_ENTRY;
-
- User::LeaveIfError( iFs.Connect() );
-
- iNewItems = new ( ELeave ) CNSmlDataItemUidSet;
- iDeletedItems = new ( ELeave ) CNSmlDataItemUidSet;
- iUpdatedItems = new ( ELeave ) CNSmlDataItemUidSet;
- iEmptyList = new ( ELeave ) CNSmlDataItemUidSet;
-
- iConverter = CContactsGrpConverter::NewL();
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::~CContactsGrpDataStore
-// Destructor
-// -----------------------------------------------------------------------------
-CContactsGrpDataStore::~CContactsGrpDataStore()
- {
- TRACE_FUNC_ENTRY;
-
- delete iDataBuffer;
- delete iNewItems;
- delete iDeletedItems;
- delete iUpdatedItems;
- delete iEmptyList;
-
- if ( iChangeFinder )
- {
- TRAPD( error, iChangeFinder->CloseL() );
- if ( error != KErrNone )
- {
- LOGGER_WRITE_1( "iChangeFinder->CloseL() leaved with %d", error );
- }
- }
- delete iChangeFinder;
-
- delete iConverter;
-
- delete iContactsDb;
-
- iFs.Close();
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::NewL
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-CContactsGrpDataStore* CContactsGrpDataStore::NewL()
- {
- TRACE_FUNC_ENTRY;
- CContactsGrpDataStore* self = CContactsGrpDataStore::NewLC();
- CleanupStack::Pop( self );
- TRACE_FUNC_EXIT;
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::NewLC
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-CContactsGrpDataStore* CContactsGrpDataStore::NewLC()
- {
- TRACE_FUNC_ENTRY;
- CContactsGrpDataStore* self = new ( ELeave ) CContactsGrpDataStore();
- CleanupStack::PushL( self );
- self->ConstructL();
- TRACE_FUNC_EXIT;
- return self;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoOpenL
-// Opens database.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoOpenL( const TDesC& /*aStoreName*/,
- MSmlSyncRelationship& aContext, TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- if ( iContactsDb )
- {
- // already opened
- User::RequestComplete( iCallerStatus, KErrInUse );
- LOGGER_WRITE( "CContactsGrpDataStore::DoOpenL failed with KErrInUse." );
- return;
- }
-
- // Create ChangeFinder
- if ( iChangeFinder )
- {
- delete iChangeFinder;
- iChangeFinder = NULL;
- }
- iChangeFinder = CChangeFinder::NewL( aContext, iKey, iHasHistory );
-
- iContactsDb = CContactDatabase::OpenL();
-
- RegisterSnapshotL();
-
- User::RequestComplete( iCallerStatus, KErrNone );
- TRACE_FUNC_EXIT;
- }
-
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCancelRequest
-// Not supported, does nothing.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCancelRequest()
- {
- TRACE_FUNC;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoStoreName
-// Returns the name of the DataStore
-// -----------------------------------------------------------------------------
-const TDesC& CContactsGrpDataStore::DoStoreName() const
- {
- TRACE_FUNC;
-
- if ( iContactsDb )
- {
- return KContactsGrpStoreName;
- }
- else
- {
- return KNullDesC;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoBeginTransactionL
-// Transactions are not supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoBeginTransactionL()
- {
- TRACE_FUNC;
- User::Leave( KErrNotSupported );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCommitTransactionL
-// Transactions are not supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCommitTransactionL( TRequestStatus& aStatus )
- {
- TRACE_FUNC;
- iCallerStatus = &aStatus;
- User::RequestComplete( iCallerStatus, KErrNotSupported );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoRevertTransaction
-// Transactions are not supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoRevertTransaction( TRequestStatus& aStatus )
- {
- TRACE_FUNC;
- iCallerStatus = &aStatus;
- User::RequestComplete( iCallerStatus, KErrNotSupported );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoBeginBatchL
-// Batching is not supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoBeginBatchL()
- {
- TRACE_FUNC;
- User::Leave( KErrNotSupported );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCommitBatchL
-// Batching is not supported
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/, TRequestStatus& aStatus )
- {
- TRACE_FUNC;
- iCallerStatus = &aStatus;
- User::RequestComplete( iCallerStatus, KErrNotSupported );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCancelBatch
-// Batching is not supported
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCancelBatch()
- {
- TRACE_FUNC;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoSetRemoteStoreFormatL
-// Not supported
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoSetRemoteStoreFormatL( const CSmlDataStoreFormat& /*aServerDataStoreFormat*/ )
- {
- TRACE_FUNC;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoSetRemoteMaxObjectSize
-// Not supported
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoSetRemoteMaxObjectSize( TInt /*aServerMaxObjectSize*/ )
- {
- TRACE_FUNC;
- }
-
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoMaxObjectSize
-// Reads the maximum object size from the central repository
-// -----------------------------------------------------------------------------
-TInt CContactsGrpDataStore::DoMaxObjectSize() const
- {
- TRACE_FUNC;
- return 0; // no limit
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoOpenItemL
-// Opens item in the DataStore, reads it (either completely or partially)
-// to the temporary buffer where it can be later read to the remote database.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoOpenItemL(
- TSmlDbItemUid aUid,
- TBool& aFieldChange,
- TInt& aSize,
- TSmlDbItemUid& aParent,
- TDes8& aMimeType,
- TDes8& aMimeVer,
- TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1( "aUid: %d", aUid );
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- aFieldChange = EFalse;
- aParent = KErrNotFound;
-
- delete iDataBuffer;
- iDataBuffer = NULL;
-
- if ( !iContactsDb )
- {
- User::Leave( KErrNotReady );
- }
-
- iDataBuffer = CBufFlat::NewL( KDefaultBufferSize );
- iReaderPosition = 0;
-
- CContactItem* item = iContactsDb->ReadContactLC( aUid );
- if ( item->Type() != KUidContactGroup )
- {
- CleanupStack::PopAndDestroy( item );
- User::Leave( KErrNotFound );
- }
-
- iConverter->ImportDbItemL( *static_cast<CContactGroup*>(item) );
-
- CleanupStack::PopAndDestroy( item );
-
- iConverter->ExportVCardL( *iDataBuffer );
- iConverter->ResetL();
- aSize = iDataBuffer->Size();
-
- // Set mime type to correct one
- AssignString( aMimeType, KContactsGrpItemMimeType );
- AssignString( aMimeVer, KContactsGrpItemMimeVersion );
-
- User::RequestComplete( iCallerStatus, KErrNone );
- iCurrentState = EContactGrpOpening;
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCreateItemL
-// Create new item to the message store.
-// Return the id number of the newly created item
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCreateItemL(
- TSmlDbItemUid& aUid,
- TInt aSize,
- TSmlDbItemUid /*aParent*/,
- const TDesC8& /*aMimeType*/,
- const TDesC8& /*aMimeVer*/,
- TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Ensure that we're in a proper state
- if ( iCurrentState != EOpenAndWaiting )
- {
- LOGGER_WRITE_1( "Warning: Unexpected current state: %d", iCurrentState );
- }
-
- if ( !iContactsDb )
- {
- LOGGER_WRITE( "iContactsDb not ready" );
- User::Leave( KErrNotReady );
- }
-
- // Ensure that we've got enough disk space for the item
- if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aSize, EDriveC ) )
- {
- User::RequestComplete( iCallerStatus, KErrDiskFull );
- LOGGER_WRITE( "SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull." );
- return;
- }
-
- // item uid is updated when groups is saved to db.
- iCurrentItem = &aUid;
- // Save current operation-state so we know what operation
- // is needed to do on DoCommitItemL
- iCurrentState = EContactGrpCreating;
-
- delete iDataBuffer;
- iDataBuffer = NULL;
- iDataBuffer = CBufFlat::NewL( KDefaultBufferSize );
- iWriterPosition = 0;
-
- User::RequestComplete( iCallerStatus, KErrNone );
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoReplaceItemL
-// Begin the replace operation, ensure that the item really exists
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoReplaceItemL(
- TSmlDbItemUid aUid,
- TInt aSize,
- TSmlDbItemUid /*aParent*/,
- TBool /*aFieldChange*/,
- TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1("aUid: %d", aUid);
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- if ( !iContactsDb )
- {
- LOGGER_WRITE( "iContactsDb not ready" );
- User::Leave( KErrNotReady );
- }
-
- // Ensure that we've got enough disk space for the item
- if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aSize, EDriveC ) )
- {
- User::RequestComplete( iCallerStatus, KErrDiskFull );
- LOGGER_WRITE( "SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull." );
- return;
- }
-
- // check that item exist and is Group-type
- CContactItem* item = iContactsDb->ReadContactLC( aUid );
- if ( item->Type() != KUidContactGroup )
- {
- CleanupStack::PopAndDestroy( item );
- User::Leave( KErrNotFound );
- }
- CleanupStack::PopAndDestroy( item );
-
- // init databuffer
- delete iDataBuffer;
- iDataBuffer = NULL;
- iDataBuffer = CBufFlat::NewL( KDefaultBufferSize );
- iWriterPosition = 0;
-
- // Save current item, so we know what item needs to be replaced
- iItemToBeReplaced = aUid;
- // Save current operation-state so we know what operation
- // is needed to do on DoCommitItemL
- iCurrentState = EContactGrpUpdating;
-
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoReadItemL
-// Read specified amount of data from the temporary buffer
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoReadItemL( TDes8& aBuffer )
- {
- TRACE_FUNC_ENTRY;
-
- if ( iCurrentState != EContactGrpOpening || !iDataBuffer )
- {
- LOGGER_WRITE_1( "Unexpected state %d", iCurrentState );
- User::Leave( KErrNotReady );
- }
-
- if ( iReaderPosition == KDataBufferNotReady )
- {
- LOGGER_WRITE( "No data to read" );
- User::Leave( KErrEof );
- }
-
- // Thiw is how much data there is left in the buffer
- TInt left = iDataBuffer->Size() - iReaderPosition;
-
- if ( left > 0 )
- {
- // This is how much there's space in the destination buffer
- TInt destSize = aBuffer.MaxSize();
-
- // This is how much we can read
- TInt toRead = destSize < left ? destSize : left;
-
- // Read the data from the buffer, then update the position
- iDataBuffer->Read( iReaderPosition, aBuffer, toRead );
- iReaderPosition += toRead;
- }
- else
- {
- iReaderPosition = KDataBufferNotReady;
- LOGGER_WRITE( "No data to read" );
- User::Leave( KErrEof );
- }
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoWriteItemL
-// Write specified amount of data to the temporary buffer
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoWriteItemL( const TDesC8& aData )
- {
- TRACE_FUNC_ENTRY;
-
- if ( iCurrentState != EContactGrpCreating && iCurrentState != EContactGrpUpdating )
- {
- LOGGER_WRITE_1( "Unexpected current state: %d", iCurrentState );
- User::Leave( KErrNotReady );
- }
-
- // Calculate total size
- TInt totalSize = aData.Size() + iDataBuffer->Size();
-
- // Ensure that we've got enough disk space for the item
- if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, totalSize, EDriveC ) )
- {
- User::RequestComplete( iCallerStatus, KErrDiskFull );
- LOGGER_WRITE("SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull.");
- return;
- }
-
- // Add data to buffer
- iDataBuffer->InsertL( iWriterPosition, aData );
- iWriterPosition += aData.Size();
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCommitItemL
-// Commits item from temporary buffer to the message store
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCommitItemL( TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Check that we're in proper state
- if ( iCurrentState != EContactGrpCreating && iCurrentState != EContactGrpUpdating )
- {
- User::RequestComplete( iCallerStatus, KErrNotReady );
- LOGGER_WRITE_1( "Unexpected current state: %d", iCurrentState );
- return;
- }
-
- if ( iDataBuffer->Size() <= 0 )
- {
- User::RequestComplete( iCallerStatus, KErrNotReady );
- LOGGER_WRITE_1( "Data buffer has no data (%d)", iDataBuffer->Size() );
- return;
- }
-
- if ( !iContactsDb )
- {
- LOGGER_WRITE( "iContactsDb not ready" );
- User::Leave( KErrNotReady );
- }
-
- iDataBuffer->Compress();
- iConverter->ImportVCardL( iDataBuffer->Ptr(0) );
-
- const CContactIdArray& contactArr = iConverter->ItemsContained();
-
- if ( iCurrentState == EContactGrpCreating )
- {
- *iCurrentItem = CreateNewGroupL( iConverter->GroupLabel(), contactArr );
- }
- else
- {
- ReplaceGroupL( iItemToBeReplaced, iConverter->GroupLabel(), contactArr);
- }
- iConverter->ResetL();
-
- // Destroy buffer
- delete iDataBuffer;
- iDataBuffer = NULL;
- iWriterPosition = 0;
-
- // Restore state and signal we're done
- iCurrentState = EOpenAndWaiting;
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::CreateNewGroupL
-// Creates new groupd to db.
-// -----------------------------------------------------------------------------
-TContactItemId CContactsGrpDataStore::CreateNewGroupL( const TDesC& aLabel,
- const CContactIdArray& aContactArray )
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1("aLabel: %S", &aLabel );
-
- // Check for duplicates
- if ( GroupNameExistsL( aLabel ) )
- {
- LOGGER_WRITE("Duplicate group name found, leave KErrAlreadyExists");
- User::Leave( KErrAlreadyExists );
- }
-
- CContactGroup* group =
- static_cast<CContactGroup*>
- (iContactsDb->CreateContactGroupLC( aLabel ));
-
- // Create new contact group
-
- TContactItemId groupId = group->Id();
- LOGGER_WRITE_1("new group id: %d", groupId);
-
- TBool partiallyUpdated(EFalse);
- TTime lastMod;
- lastMod.UniversalTime();
- TInt err(KErrNone);
- for ( TInt i=0; i<aContactArray.Count(); i++ )
- {
- LOGGER_WRITE_1("Add contact: %d", aContactArray[i] );
- TRAP( err, iContactsDb->AddContactToGroupL( aContactArray[i], groupId ));
- if ( err )
- {
- LOGGER_WRITE_2("Warning: AddContactToGroupL, contact: %d, err: %d", aContactArray[i], err);
- partiallyUpdated = ETrue;
- }
- else
- {
- // If succesfully added, update contact timestamp so contact sync sees those
- // contacts as changed ones.
- UpdateContactLastMod( aContactArray[i], lastMod );
- }
- }
-
- CleanupStack::PopAndDestroy( group );
- group = NULL;
-
- // if item was only partially updated, do not register to snapshot
- // --> on next sync item is marked as updated
- if ( !partiallyUpdated )
- {
- // reload group
- group = static_cast<CContactGroup*>
- (iContactsDb->ReadContactLC( groupId ));
- // Inform ChangeFinder of new item
- TSnapshotItem snapshotItem( groupId );
- snapshotItem.CreateHashL( *group );
- iChangeFinder->ItemAddedL( snapshotItem );
-
- CleanupStack::PopAndDestroy( group );
- }
-
-
-
- TRACE_FUNC_EXIT;
- return groupId;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::ReplaceGroupL
-// Replaces existing group on db
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::ReplaceGroupL( TContactItemId aGroupId, const TDesC& aLabel,
- const CContactIdArray& aContactArray )
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1("aGroupId: %d", aGroupId);
- LOGGER_WRITE_1("aLabel: %S", &aLabel);
- TBool partiallyUpdated(EFalse);
- // check that item exist and is Group-type
- // The LX suffix means that the lock record of the contact item is left on the cleanup stack.
- CContactItem* item = iContactsDb->OpenContactLX( aGroupId );
- CleanupStack::PushL( item );
- if ( item->Type() != KUidContactGroup )
- {
- LOGGER_WRITE("Type was not KUidContactGroup, leaving KErrNotFound");
- User::Leave( KErrNotFound );
- }
-
- // cast item to CContactGroup type
- CContactGroup* groupItem = static_cast<CContactGroup*>(item);
- TContactItemId groupId = groupItem->Id();
-
- TBool labelUpdated(EFalse);
- // Check is group label changed
- if ( groupItem->HasItemLabelField() )
- {
- TPtrC dbLabel = groupItem->GetGroupLabelL();
- if ( aLabel.Compare( dbLabel ) != 0 )
- {
- // didn't match, update label.
- // Check that new name does not already exist
- if ( GroupNameExistsL( aLabel ) )
- {
- LOGGER_WRITE("Name already exists, leave KErrAlreadyExists");
- User::Leave( KErrAlreadyExists );
- }
- LOGGER_WRITE("Update label" );
- groupItem->SetGroupLabelL( aLabel );
- iContactsDb->CommitContactL( *item );
- labelUpdated = ETrue;
- }
- }
- TTime lastMod;
- lastMod.UniversalTime();
- // Update joined contacts
- TInt err(KErrNone);
- // add new items to current group
- for ( TInt i=0; i<aContactArray.Count(); i++ )
- {
- TContactItemId newItem = aContactArray[i];
- TBool founded = groupItem->ContainsItem( newItem );
- if ( !founded )
- {
- // item does not exist on current group, add it.
- LOGGER_WRITE_1("Add contact: %d", newItem)
- TRAP( err, iContactsDb->AddContactToGroupL( newItem, groupId ));
- if ( err )
- {
- LOGGER_WRITE_2("Warning: Could not add contact: %d, err: %d", newItem, err);
- partiallyUpdated = ETrue;
- }
- else
- {
- // Update contact timestamp
- UpdateContactLastMod( newItem, lastMod );
- }
- }
- else
- {
- LOGGER_WRITE_1("contact( %d ) already exist on group, no need to update", newItem)
- }
- }
-
- // remove all missing items from group
- CContactIdArray* oldIdArr = groupItem->ItemsContainedLC();
- if ( oldIdArr )
- {
- for ( TInt i=0; i<oldIdArr->Count(); i++ )
- {
- TContactItemId oldItem = (*oldIdArr)[i];
- TInt err = aContactArray.Find( oldItem );
- if ( err == KErrNotFound )
- {
- LOGGER_WRITE_1("Remove contact: %d", oldItem );
- // old item was not found from new item list, remove it.
- TRAP( err, iContactsDb->RemoveContactFromGroupL(oldItem, groupId));
- if ( err )
- {
- LOGGER_WRITE_2("Warning: Could not remove contact: %d, err: ",oldItem, err );
- partiallyUpdated = ETrue;
- }
- else
- {
- UpdateContactLastMod( oldItem, lastMod );
- }
- }
- // Update all contacts in group if label is changed
- else if ( labelUpdated )
- {
- UpdateContactLastMod( oldItem, lastMod );
- }
- }
- }
- CleanupStack::PopAndDestroy( oldIdArr );
- CleanupStack::PopAndDestroy( 2 ); // item, lock object
-
- // if item was only partially updated, do not register to snapshot
- // --> on next sync item is marked as updated
- if ( !partiallyUpdated )
- {
- // reload group
- groupItem = NULL;
- groupItem = static_cast<CContactGroup*>
- (iContactsDb->ReadContactLC( groupId ));
- // Inform ChangeFinder of updated item
- TSnapshotItem snapshotItem( groupId );
- snapshotItem.CreateHashL( *groupItem );
- iChangeFinder->ItemUpdatedL( snapshotItem );
-
- CleanupStack::PopAndDestroy( groupItem );
- }
-
- TRACE_FUNC_EXIT;
- }
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCloseItem
-// Closes open item in the data store
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCloseItem()
- {
- TRACE_FUNC_ENTRY;
- // Reset read buffer
- iReaderPosition = KDataBufferNotReady;
- delete iDataBuffer;
- iDataBuffer = NULL;
-
- // Make sure that we're opened an item
- if ( iCurrentState != EContactGrpOpening )
- {
- LOGGER_WRITE_1( "WARNING: Invalid state %d.", iCurrentState );
- }
- // Start to wait for the next operation
- iCurrentState = EOpenAndWaiting;
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoMoveItemL
-// Not supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoMoveItemL( TSmlDbItemUid /*aUid*/,
- TSmlDbItemUid /*aNewParent*/, TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Restore state and signal we're done
- User::RequestComplete( iCallerStatus, KErrNotSupported );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoDeleteItemL
-// Removes item from the message store
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoDeleteItemL( TSmlDbItemUid aUid, TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1( "aUid: %d", aUid );
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Check that we're in proper state
- if ( iCurrentState != EOpenAndWaiting )
- {
- LOGGER_WRITE_1("CContactsGrpDataStore::DoDeleteItemL, Incorrect state: %d", iCurrentState);
- }
-
- if ( !iContactsDb )
- {
- LOGGER_WRITE( "iContactsDb not ready" );
- User::Leave( KErrNotReady );
- }
-
- // check that item type is ContactGroup
- CContactItem* item = iContactsDb->ReadContactLC( aUid );
- if ( item->Type() != KUidContactGroup )
- {
- LOGGER_WRITE("Item was not ContactGroup");
- CleanupStack::PopAndDestroy( item );
- User::Leave( KErrNotFound );
- }
-
- // Update all contacts in group
- CContactGroup* groupItem = static_cast<CContactGroup*>(item);
- CContactIdArray* contactArr = groupItem->ItemsContainedLC();
- if ( contactArr )
- {
- TTime lastMod;
- lastMod.UniversalTime();
- for ( TInt i=0; i<contactArr->Count(); i++ )
- {
- TContactItemId contactId = (*contactArr)[i];
- UpdateContactLastMod( contactId, lastMod );
- }
- }
- CleanupStack::PopAndDestroy( contactArr );
- CleanupStack::PopAndDestroy( item );
-
- // delete group
- iContactsDb->DeleteContactL( aUid );
-
- TSnapshotItem snapshotItem( aUid );
- iChangeFinder->ItemDeleted( snapshotItem );
-
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoSoftDeleteItemL
-// Soft delete isn't supported.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoSoftDeleteItemL(TSmlDbItemUid /*aUid*/, TRequestStatus& aStatus)
- {
- TRACE_FUNC_ENTRY;
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- User::RequestComplete(iCallerStatus, KErrNotSupported);
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoDeleteAllItemsL
-// Deletes all items in the standard folders of bookmark store
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- if ( !iContactsDb )
- {
- LOGGER_WRITE( "iContactsDb is not opened, Leaving KErrNotReady");
- User::Leave( KErrNotReady );
- }
-
- CContactIdArray* groups = iContactsDb->GetGroupIdListL();
- if ( groups )
- {
- CleanupStack::PushL( groups );
- TTime lastMod;
- lastMod.UniversalTime();
-
- // update all contacts in all groups
- for ( TInt i=0; i<groups->Count(); i++ )
- {
- // check that item type is ContactGroup
- CContactItem* item = iContactsDb->ReadContactLC( (*groups)[i] );
-
- // Update all contacts in group
- CContactGroup* groupItem = static_cast<CContactGroup*>(item);
- CContactIdArray* contactArr = groupItem->ItemsContainedLC();
- if ( contactArr )
- {
- for ( TInt i=0; i<contactArr->Count(); i++ )
- {
- TContactItemId contactId = (*contactArr)[i];
- UpdateContactLastMod( contactId, lastMod );
- }
- }
- CleanupStack::PopAndDestroy( contactArr );
- CleanupStack::PopAndDestroy( item );
- }
-
- // delete all groups
- iContactsDb->DeleteContactsL( *groups );
- CleanupStack::PopAndDestroy( groups );
- }
-
- // Reset the whole change finder
- iChangeFinder->ResetL();
-
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoHasSyncHistory
-// This method returns ETrue if Data Store has history information.
-// Slow-sync will be used if Data Store does not have history information.
-// -----------------------------------------------------------------------------
-TBool CContactsGrpDataStore::DoHasSyncHistory() const
- {
- TRACE_FUNC_ENTRY;
- LOGGER_WRITE_1( "iHasHistory: %d", iHasHistory );
- TRACE_FUNC_EXIT;
- return iHasHistory;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoAddedItems
-// This method returns UIDs of added items. Those items are added after previous
-// synchronization with current synchronization relationship.
-// -----------------------------------------------------------------------------
-const MSmlDataItemUidSet& CContactsGrpDataStore::DoAddedItems() const
- {
- TRACE_FUNC_ENTRY;
-
- // Clear new-items array
- iNewItems->Reset();
- if ( !iChangeFinder )
- {
- LOGGER_WRITE( "WARNING: Not ready, returns empty item list" );
- return *iNewItems;
- }
-
- // Search for new items
- TRAPD( error, iChangeFinder->FindNewItemsL( *iNewItems ) )
- if ( error != KErrNone )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoAddedItems, iChangeFinder->FindNewItemsL leaved with %d.", error );
- }
-
- LOGGER_WRITE_1( "New item count: %d.", iNewItems->ItemCount() );
- TRACE_FUNC_EXIT;
-
- return *iNewItems;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoDeletedItems
-// Returns ids of items, which are deleted after previous synchronization
-// -----------------------------------------------------------------------------
-const MSmlDataItemUidSet& CContactsGrpDataStore::DoDeletedItems() const
- {
- TRACE_FUNC_ENTRY;
-
- // Clear deleted-items array
- iDeletedItems->Reset();
- if ( !iChangeFinder )
- {
- LOGGER_WRITE( "WARNING: Not ready, returns empty item list" );
- return *iDeletedItems;
- }
-
- // Search for deleted items
- TRAPD( error, iChangeFinder->FindDeletedItemsL( *iDeletedItems ) );
- if ( error != KErrNone )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoDeletedItems, iChangeFinder->FindDeletedItemsL leaved with %d.", error );
- }
-
- LOGGER_WRITE_1( "Deleted item count: %d.", iDeletedItems->ItemCount() );
- TRACE_FUNC_EXIT;
- return *iDeletedItems;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoSoftDeletedItems
-// Not directly supported, empty list returned
-// -----------------------------------------------------------------------------
-const MSmlDataItemUidSet& CContactsGrpDataStore::DoSoftDeletedItems() const
- {
- TRACE_FUNC;
- // Return empty array as a result
- return *iEmptyList;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoModifiedItems
-// Finds all modified items in the data store
-// -----------------------------------------------------------------------------
-const MSmlDataItemUidSet& CContactsGrpDataStore::DoModifiedItems() const
- {
- TRACE_FUNC_ENTRY;
-
- // Clear updated-items array
- iUpdatedItems->Reset();
- if ( !iChangeFinder )
- {
- LOGGER_WRITE( "WARNING: Not ready, returns empty item list" );
- return *iUpdatedItems;
- }
-
- // Search for updated items
- TRAPD( error, iChangeFinder->FindChangedItemsL( *iUpdatedItems ) )
- if ( error != KErrNone )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoModifiedItems, iChangeFinder->FindChangedItemsL leaved with %d.", error );
- }
-
- LOGGER_WRITE_1( "Modified item count: %d.", iUpdatedItems->ItemCount() );
- TRACE_FUNC_EXIT;
- return *iUpdatedItems;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoMovedItems
-// Finds all moved items in the data store
-// -----------------------------------------------------------------------------
-const MSmlDataItemUidSet& CContactsGrpDataStore::DoMovedItems() const
- {
- TRACE_FUNC;
- // Moved items are not supported
- // Return empty array as a result
- return *iEmptyList;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoResetChangeInfoL
-// Resets change history in the data store. All content is considered
-// new in the data store point of view.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoResetChangeInfoL( TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Check that we're in proper state
- if ( iCurrentState != EOpenAndWaiting )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoResetChangeInfoL, invalid state %d.", iCurrentState );
- }
-
- // Reset change info in ChangeFinder
- iChangeFinder->ResetL();
- iHasHistory = EFalse;
-
- // Signal we're done
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCommitChangeInfoL
-// Commits change info. These items are no longer reported, when change
-// information is being queried.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus,
- const MSmlDataItemUidSet& aItems )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Ensure that we're in a proper state
- if ( iCurrentState != EOpenAndWaiting )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState );
- }
-
- // Notify ChangeFinder
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, item count %d.", aItems.ItemCount() );
- iChangeFinder->CommitChangesL( aItems );
- iHasHistory = ETrue;
-
- // Signal we're done
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::DoCommitChangeInfoL
-// Commits change info. There is no more nothing to report when change
-// information is being queried.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus )
- {
- TRACE_FUNC_ENTRY;
-
- iCallerStatus = &aStatus;
- *iCallerStatus = KRequestPending;
-
- // Ensure that we're in a proper state
- if ( iCurrentState != EOpenAndWaiting )
- {
- LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState );
- }
-
- // Notify ChangeFinder
- iChangeFinder->CommitChangesL();
- iHasHistory = ETrue;
-
- // Signal we're done
- User::RequestComplete( iCallerStatus, KErrNone );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::RegisterSnapshotL
-// Sets Changefinder to compare against current message store content
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::RegisterSnapshotL()
- {
- TRACE_FUNC_ENTRY;
-
- CArrayFixSeg<TSnapshotItem>* snapshot =
- new ( ELeave ) CArrayFixSeg<TSnapshotItem>( KSnapshotGranularity );
- CleanupStack::PushL( snapshot );
-
- // Add everything to snapshot
-
- // GetGroupIdListL returns NULL if there are no groups in the database.
- CContactIdArray* groups = iContactsDb->GetGroupIdListL();
- if ( groups )
- {
- TKeyArrayFix key( iKey );
- CleanupStack::PushL( groups );
- for ( TInt i=0; i<groups->Count(); i++ )
- {
- CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]);
- CContactGroup* groupItem = static_cast<CContactGroup*>(item);
-
- LOGGER_WRITE_1( "Add group to snatshot, group id: %d",groupItem->Id() );
-
- TSnapshotItem snapshotItem( groupItem->Id() );
- snapshotItem.CreateHashL( *groupItem );
-
- snapshot->InsertIsqL( snapshotItem, key );
-
- CleanupStack::PopAndDestroy( item );
- }
- CleanupStack::PopAndDestroy( groups );
- }
-
- // Set new snapshot to compare against
- iChangeFinder->SetNewSnapshot( snapshot );
-
- // Changefinder takes ownership of the snapshot
- CleanupStack::Pop( snapshot );
-
- TRACE_FUNC_EXIT;
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::AssignString
-// Assigns data from one descriptor into another, truncates if too long
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::AssignString( TDes8& aDestination, const TDesC8& aSource )
- {
- TInt targetLength = aSource.Length();
- if ( aDestination.MaxLength() < targetLength )
- {
- targetLength = aDestination.MaxLength();
- }
-
- aDestination.Copy( aSource.Ptr(), targetLength );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::UpdateContactLastMod
-// Updates contact item last modified time. Contact sync will see item as changed one.
-// -----------------------------------------------------------------------------
-void CContactsGrpDataStore::UpdateContactLastMod( TContactItemId aContactId,
- const TTime& aLastModified )
- {
- // Ignore errors.
- // Cannot update timestamp if contact is already open. However modified time
- // is most likely still updated by UI.
- TRAP_IGNORE(
- // OpenContactLX() places the edit lock on the cleanup stack
- CContactItem* contact = iContactsDb->OpenContactLX( aContactId );
- CleanupStack::PushL( contact );
- contact->SetLastModified( aLastModified );
- iContactsDb->CommitContactL( *contact );
- CleanupStack::PopAndDestroy( contact );
- CleanupStack::PopAndDestroy( 1 ); // lock object
- );
- }
-
-// -----------------------------------------------------------------------------
-// CContactsGrpDataStore::GroupNameExistsL
-// Checks does group name already exists.
-// -----------------------------------------------------------------------------
-TBool CContactsGrpDataStore::GroupNameExistsL( const TDesC& aLabel )
- {
- TBool duplicateFound( EFalse );
- // GetGroupIdListL returns NULL if there are no groups in the database.
- CContactIdArray* groups = iContactsDb->GetGroupIdListL();
- if ( groups )
- {
- CleanupStack::PushL( groups );
- for ( TInt i=0; i<groups->Count() && !duplicateFound; i++ )
- {
- CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]);
- CContactGroup* groupItem = static_cast<CContactGroup*>(item);
-
- if ( groupItem->HasItemLabelField() )
- {
- TPtrC label = groupItem->GetGroupLabelL();
- if ( aLabel.Compare( label ) == 0 )
- {
- duplicateFound = ETrue;
- }
- }
- CleanupStack::PopAndDestroy( item );
- }
- CleanupStack::PopAndDestroy( groups );
- }
-
- return duplicateFound;
- }