diff -r 8e7494275d3a -r 4f0867e42d62 omads/omadsextensions/adapters/contactsgroup/src/contactsgrpdatastore.cpp --- 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 -#include - -#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& /*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(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 - (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; iAddContactToGroupL( 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 - (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(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; iContainsItem( 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; iCount(); 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 - (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(item); - CContactIdArray* contactArr = groupItem->ItemsContainedLC(); - if ( contactArr ) - { - TTime lastMod; - lastMod.UniversalTime(); - for ( TInt i=0; iCount(); 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; iCount(); i++ ) - { - // check that item type is ContactGroup - CContactItem* item = iContactsDb->ReadContactLC( (*groups)[i] ); - - // Update all contacts in group - CContactGroup* groupItem = static_cast(item); - CContactIdArray* contactArr = groupItem->ItemsContainedLC(); - if ( contactArr ) - { - for ( TInt i=0; iCount(); 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* snapshot = - new ( ELeave ) CArrayFixSeg( 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; iCount(); i++ ) - { - CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]); - CContactGroup* groupItem = static_cast(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; iCount() && !duplicateFound; i++ ) - { - CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]); - CContactGroup* groupItem = static_cast(item); - - if ( groupItem->HasItemLabelField() ) - { - TPtrC label = groupItem->GetGroupLabelL(); - if ( aLabel.Compare( label ) == 0 ) - { - duplicateFound = ETrue; - } - } - CleanupStack::PopAndDestroy( item ); - } - CleanupStack::PopAndDestroy( groups ); - } - - return duplicateFound; - }