phonebookengines/VirtualPhonebook/VPbkCntModel/src/CDeleteContactsOperation.cpp
changeset 0 e686773b3f54
child 8 5586b4d2ec3e
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  An operation object to delete contacts from contacts database
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CDeleteContactsOperation.h"
       
    20 
       
    21 // VPbkCntModel
       
    22 #include "CContactLink.h"
       
    23 #include "CContactStore.h"
       
    24 #include "CVPbkDiskSpaceCheck.h"
       
    25 #include "CContact.h"
       
    26 
       
    27 // Virtual Phonebook engine
       
    28 #include <MVPbkBatchOperationObserver.h>
       
    29 
       
    30 // Contact Model
       
    31 #include <cntdef.h>
       
    32 #include <cntdb.h>
       
    33 #include <cntitem.h>
       
    34 
       
    35 
       
    36 namespace VPbkCntModel {
       
    37 
       
    38 // Definition for delete array size
       
    39 const TInt KDeleteArraySize = 3;
       
    40 
       
    41 // Definition for FreeDiskSpaceRequest towards DOSSERVER
       
    42 const TInt KFreeSpaceRequiredInKB = 140 * 1024; // 140 kB
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CDeleteContactsOperation::CDeleteContactsOperation
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 CDeleteContactsOperation::CDeleteContactsOperation(
       
    49         CContactStore& aContactStore,
       
    50         MVPbkBatchOperationObserver& aObserver,
       
    51         RSharedDataClient* aSharedDataClient,
       
    52         VPbkEngUtils::CVPbkDiskSpaceCheck& aDiskSpaceChecker ) :
       
    53     CActive( CActive::EPriorityIdle ),
       
    54     iContactStore( aContactStore ),
       
    55     iObserver( aObserver ),
       
    56     iState( EDelete ),
       
    57     iSharedDataClient( aSharedDataClient ),
       
    58     iDiskSpaceChecker( aDiskSpaceChecker )
       
    59     {
       
    60     CActiveScheduler::Add(this);
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CDeleteContactsOperation::~CDeleteContactsOperation
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 CDeleteContactsOperation::~CDeleteContactsOperation()
       
    68     {
       
    69     Cancel();
       
    70     delete iRemainingContactIds;
       
    71     delete iCurrentContactIds;
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CDeleteContactsOperation::NewL
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CDeleteContactsOperation* CDeleteContactsOperation::NewL(
       
    79         CContactStore& aContactStore,
       
    80         const MVPbkContactLinkArray& aLinks,
       
    81         MVPbkBatchOperationObserver& aObserver,
       
    82         RSharedDataClient* aSharedDataClient,
       
    83         VPbkEngUtils::CVPbkDiskSpaceCheck& aDiskSpaceChecker )
       
    84     {
       
    85     CDeleteContactsOperation* self =
       
    86         new( ELeave ) CDeleteContactsOperation( aContactStore, aObserver,
       
    87                                                 aSharedDataClient, aDiskSpaceChecker );
       
    88     CleanupStack::PushL( self );
       
    89     self->ConstructL( aLinks );
       
    90     CleanupStack::Pop( self );
       
    91     return self;
       
    92     }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CDeleteContactsOperation::ConstructL
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 inline void CDeleteContactsOperation::ConstructL
       
    99         (const MVPbkContactLinkArray& aLinks)
       
   100     {
       
   101     iRemainingContactIds = CContactIdArray::NewL();
       
   102     iCurrentContactIds = CContactIdArray::NewL();
       
   103     
       
   104     iGroupCount = iContactStore.NativeDatabase().GroupCount();
       
   105     
       
   106     const TInt count = aLinks.Count();
       
   107     for ( TInt i=0 ; i < count; ++i )
       
   108         {
       
   109         const CContactLink& link =
       
   110             static_cast<const CContactLink&>( aLinks.At( i ) );
       
   111         iRemainingContactIds->AddL( link.ContactId() );
       
   112         }
       
   113     PrepareNextDelete();
       
   114     }
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CDeleteContactsOperation::DoCancel
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 void CDeleteContactsOperation::DoCancel()
       
   121     {
       
   122     // Do nothing
       
   123     }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 // CDeleteContactsOperation::RunL
       
   127 // -----------------------------------------------------------------------------
       
   128 //
       
   129 void CDeleteContactsOperation::RunL()
       
   130     {
       
   131     switch ( iState )
       
   132         {
       
   133         case EDelete:
       
   134             {
       
   135             RunDeleteL();
       
   136             IssueRequest();
       
   137             break;
       
   138             }
       
   139         case EComplete:
       
   140             {
       
   141             iObserver.OperationComplete( *this );
       
   142             break;
       
   143             }
       
   144         }
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CDeleteContactsOperation::RunError
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 TInt CDeleteContactsOperation::RunError(TInt aError)
       
   152     {    
       
   153     if ( iFreeDiskSpaceRequired )
       
   154         {
       
   155         // Notify shared data that we do not need free space anymore
       
   156         DoCancelFreeDiskSpaceRequest();
       
   157         iFreeDiskSpaceRequired = EFalse;
       
   158         }
       
   159 
       
   160     // if iCurrentContactIndex is valid, than it's delete error
       
   161     // otherwise, RunDeleteL leaved outside the delete loop
       
   162     TBool deleteError = iCurrentContactIndex >= 0 &&
       
   163     					iCurrentContactIndex < iCurrentContactIds->Count();
       
   164 
       
   165     // if error outside the delete loop, than skip all current contacts,
       
   166     // otherwise, remove failed contact and try again
       
   167     TInt stepSize = iCurrentContactIds->Count();
       
   168     if ( deleteError )
       
   169     	{
       
   170     	stepSize = 1;
       
   171     	}
       
   172     
       
   173     if ( iObserver.StepFailed( *this, stepSize, aError ) )
       
   174         {
       
   175         if ( iCurrentContactIds->Count() > 1 && deleteError )
       
   176         	{
       
   177         	//remove failed contact and try without it again
       
   178         	iCurrentContactIds->Remove( iCurrentContactIndex );
       
   179         	iState = EDelete;
       
   180         	}
       
   181         else
       
   182         	{
       
   183         	//skip iCurrentContactIds, try remaining
       
   184         	PrepareNextDelete();
       
   185         	}
       
   186         IssueRequest();
       
   187         }
       
   188  
       
   189     return KErrNone;
       
   190     }
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // CDeleteContactsOperation::StartL
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 void CDeleteContactsOperation::StartL()
       
   197     {   
       
   198     IssueRequest();
       
   199     }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // CDeleteContactsOperation::Cancel
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 void CDeleteContactsOperation::Cancel()
       
   206     {
       
   207     CActive::Cancel();
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CDeleteContactsOperation::IssueRequest
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 void CDeleteContactsOperation::IssueRequest()
       
   215     {
       
   216     TRequestStatus* status = &iStatus;
       
   217     User::RequestComplete( status, KErrNone );
       
   218     SetActive();
       
   219     }
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // CDeleteContactsOperation::UpdateTimeStampOfAllContactsInGroupL
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 void CDeleteContactsOperation::UpdateTimeStampOfAllContactsInGroupL()
       
   226     {
       
   227     CContactItem* groupItem = iContactStore.NativeDatabase().
       
   228                                 ReadContactLC( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   229     
       
   230     CContact* group = CContact::NewL( iContactStore, groupItem );
       
   231     CleanupStack::Pop(groupItem);
       
   232     CleanupStack::PushL( group );
       
   233    
       
   234     group->UpdateTimeStampOfAllContactsInGroupL();
       
   235     
       
   236     CleanupStack::PopAndDestroy( group ); 
       
   237     }
       
   238 
       
   239 // -----------------------------------------------------------------------------
       
   240 // CDeleteContactsOperation::CurrentItemIsGroupL
       
   241 // -----------------------------------------------------------------------------
       
   242 //
       
   243 TBool CDeleteContactsOperation::CurrentItemIsGroupL()
       
   244     {
       
   245     TBool isGroup = EFalse;
       
   246     
       
   247     // If groups exists, we need to read a minimal contact to get it's type
       
   248     if (iGroupCount > 0)
       
   249         {
       
   250         CContactItem* item = iContactStore.NativeDatabase().
       
   251             ReadMinimalContactLC( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   252                    
       
   253         if (item->Type() == KUidContactGroup)
       
   254             {
       
   255             isGroup = ETrue;
       
   256             }
       
   257         
       
   258         CleanupStack::PopAndDestroy(item); 
       
   259         }
       
   260     
       
   261     return isGroup;
       
   262     }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // CDeleteContactsOperation::RunDeleteL
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 inline void CDeleteContactsOperation::RunDeleteL()
       
   269     {
       
   270     StartTransactionLC();
       
   271 
       
   272     TInt stepSize = iCurrentContactIds->Count();
       
   273     for ( iCurrentContactIndex = 0;
       
   274     	  iCurrentContactIndex < stepSize;
       
   275       	  ++iCurrentContactIndex )
       
   276         {
       
   277         DoRequestFreeDiskSpaceLC();        
       
   278         
       
   279         // If contact item is a group, we need to update the timestamps 
       
   280         // of the contacts in the group before deleting the group.
       
   281         // This is needed for sync services.
       
   282         if ( CurrentItemIsGroupL() )
       
   283             {
       
   284             UpdateTimeStampOfAllContactsInGroupL();
       
   285             }
       
   286       
       
   287         // Cannot use DeleteContactsL here, since it does not
       
   288         // send contact removed events
       
   289         iContactStore.NativeDatabase().
       
   290             DeleteContactL( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   291         
       
   292         CleanupStack::PopAndDestroy();  // RequestFreeDiskSpaceLC            
       
   293 
       
   294         RunCompressL(EFalse);
       
   295         }
       
   296     
       
   297     // Commit database transaction
       
   298     CommitTransactionLP();
       
   299     
       
   300     iObserver.StepComplete( *this, stepSize );
       
   301     RunCompressL(ETrue);
       
   302     PrepareNextDelete();
       
   303     }
       
   304 
       
   305 void CDeleteContactsOperation::PrepareNextDelete()
       
   306 	{
       
   307     iCurrentContactIds->Reset();
       
   308     for ( TInt i = Min(iRemainingContactIds->Count(), KDeleteArraySize) - 1;
       
   309     	  i >= 0;
       
   310     	  --i )
       
   311         {
       
   312         iCurrentContactIds->AddL( ( *iRemainingContactIds )[i] );
       
   313         iRemainingContactIds->Remove( i );
       
   314         }
       
   315     
       
   316     iState = EDelete;
       
   317     iCurrentContactIndex = -1; //make index invalid, it's checked in RunError
       
   318     						   //to detect StartTransactionLC leave
       
   319     if ( iCurrentContactIds->Count() == 0 )
       
   320         {
       
   321         // No more contacts to delete
       
   322         iState = EComplete;
       
   323         }
       
   324 	}
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // CDeleteContactsOperation::RunCompressL
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 inline void CDeleteContactsOperation::RunCompressL(TBool aForce)
       
   331     {
       
   332     if ( aForce || iContactStore.NativeDatabase().CompressRequired() )
       
   333         {
       
   334         DoRequestFreeDiskSpaceLC();        
       
   335         // Compress database
       
   336         iContactStore.NativeDatabase().CompactL();
       
   337         CleanupStack::PopAndDestroy();  // RequestFreeDiskSpaceLC        
       
   338         }    
       
   339     }
       
   340 
       
   341 // -----------------------------------------------------------------------------
       
   342 // CDeleteContactsOperation::StartTransactionLC
       
   343 // -----------------------------------------------------------------------------
       
   344 //
       
   345 inline void CDeleteContactsOperation::StartTransactionLC()
       
   346     {
       
   347     // If database transaction starting leaves --> 
       
   348     // Reserved disk space if freed in CDeleteContactsOperation::RunError
       
   349     DoRequestFreeDiskSpace();
       
   350     iFreeDiskSpaceRequired = ETrue;
       
   351     
       
   352     iContactStore.NativeDatabase().DatabaseBeginLC( EFalse );
       
   353     
       
   354     DoCancelFreeDiskSpaceRequest();
       
   355     iFreeDiskSpaceRequired = EFalse;
       
   356     }
       
   357     
       
   358 // -----------------------------------------------------------------------------
       
   359 // CDeleteContactsOperation::CommitTransactionLC
       
   360 // -----------------------------------------------------------------------------
       
   361 //
       
   362 inline void CDeleteContactsOperation::CommitTransactionLP()
       
   363     {
       
   364     // If database commit leaves --> Reserved disk space if freeed in
       
   365     // CDeleteContactsOperation::RunError
       
   366     DoRequestFreeDiskSpace();
       
   367     iFreeDiskSpaceRequired = ETrue;
       
   368     
       
   369     iContactStore.NativeDatabase().DatabaseCommitLP( EFalse );
       
   370     
       
   371     DoCancelFreeDiskSpaceRequest();
       
   372     iFreeDiskSpaceRequired = EFalse;  
       
   373     }
       
   374 
       
   375 // -----------------------------------------------------------------------------
       
   376 // CDeleteContactsOperation::DoRequestFreeDiskSpace
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CDeleteContactsOperation::DoRequestFreeDiskSpace()
       
   380     {
       
   381     if ( iSharedDataClient )
       
   382         {
       
   383         iSharedDataClient->RequestFreeDiskSpace(KFreeSpaceRequiredInKB);
       
   384         }
       
   385     }
       
   386 
       
   387 // -----------------------------------------------------------------------------
       
   388 // CDeleteContactsOperation::DoRequestFreeDiskSpaceLC
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 void CDeleteContactsOperation::DoRequestFreeDiskSpaceLC()
       
   392     {
       
   393     if ( iSharedDataClient )
       
   394         {
       
   395         iSharedDataClient->RequestFreeDiskSpaceLC(KFreeSpaceRequiredInKB);        
       
   396         }
       
   397     else
       
   398         {
       
   399         // place token in cleanup stack
       
   400         TAny* const nop = NULL;
       
   401         CleanupStack::PushL(nop);
       
   402         }
       
   403     }
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CDeleteContactsOperation::CancelFreeDiskSpaceRequest
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 void CDeleteContactsOperation::DoCancelFreeDiskSpaceRequest()
       
   410     {
       
   411     if ( iSharedDataClient )
       
   412         {
       
   413         iSharedDataClient->CancelFreeDiskSpaceRequest();
       
   414         }
       
   415     }
       
   416 
       
   417 } // namespace VPbkCntModel
       
   418 
       
   419 // End of File