omads/omadsextensions/adapters/mms/src/changefinder.cpp
changeset 40 b63e67867dcd
parent 0 dab8a81a92de
equal deleted inserted replaced
39:9905f7d46607 40:b63e67867dcd
       
     1 /*
       
     2 * Copyright (c) 2005-2009 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:  Part of SyncML Data Synchronization Plug In Adapter
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "changefinder.h"
       
    20 #include "logger.h"
       
    21 
       
    22 const TUint KSnapshotFormatVersion ( 0xf0000001 ); // format version
       
    23 
       
    24 // -----------------------------------------------------------------------------
       
    25 // CChangeFinder::NewL
       
    26 // Static function to create CChangeFider object(s)
       
    27 // -----------------------------------------------------------------------------
       
    28 CChangeFinder* CChangeFinder::NewL( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey,
       
    29         TBool& aHasHistory, TInt aStreamUid )
       
    30     {
       
    31     CChangeFinder* self = new (ELeave) CChangeFinder( aSyncRelationship, aKey, aStreamUid );
       
    32     CleanupStack::PushL( self );
       
    33     self->ConstructL( aHasHistory );
       
    34     CleanupStack::Pop( self );
       
    35     return self;
       
    36     }
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CChangeFinder::CChangeFinder
       
    40 // Constructor for the class
       
    41 // -----------------------------------------------------------------------------
       
    42 CChangeFinder::CChangeFinder( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey, TInt aStreamUid ) :
       
    43 iSyncRelationship( aSyncRelationship ),
       
    44 iKey( aKey ),
       
    45 iStreamUid( aStreamUid ),
       
    46 iDataStoreUid( KErrNotFound )
       
    47     {
       
    48         
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CChangeFinder::~CChangeFinder
       
    53 // Destructor for the class, closes the ChangeFinder and writes snapshot to stream
       
    54 // -----------------------------------------------------------------------------
       
    55 CChangeFinder::~CChangeFinder()
       
    56     {
       
    57     LOGGER_ENTERFN( "CChangeFinder::~CChangeFinder" );
       
    58     TInt error;
       
    59     TRAP( error, CloseL() );
       
    60     if ( error != KErrNone )
       
    61         {
       
    62         LOGGER_WRITE( "CChangeFinder::~CChangeFinder, CloseL failed." );
       
    63         }
       
    64     
       
    65     delete iCurrentSnapshot;
       
    66     delete iOldSnapshot;
       
    67     
       
    68     LOGGER_LEAVEFN( "CChangeFinder::~CChangeFinder" );
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CChangeFinder::ConstructL
       
    73 // 2nd phase constructor for the class, reads snapshot from stream
       
    74 // -----------------------------------------------------------------------------
       
    75 void CChangeFinder::ConstructL( TBool& aHasHistory )
       
    76     {
       
    77     LOGGER_ENTERFN( "CChangeFinder::ConstructL" );
       
    78         
       
    79     aHasHistory = EFalse;
       
    80     RReadStream readStream;
       
    81     
       
    82     TUid streamId;
       
    83     streamId.iUid = iStreamUid;
       
    84     
       
    85     aHasHistory = iSyncRelationship.IsStreamPresentL(streamId);
       
    86     
       
    87     if (aHasHistory)
       
    88         {
       
    89         iSyncRelationship.OpenReadStreamLC(readStream, streamId);
       
    90         
       
    91         // Read the index, first create snapshot array
       
    92         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
    93         
       
    94         // Read used format version
       
    95         TUint formatVer = readStream.ReadUint32L();
       
    96         if ( formatVer != KSnapshotFormatVersion )
       
    97             {
       
    98             // Wrong version, do not try to import data
       
    99             LOGGER_WRITE("CChangeFinder::ConstructL, Wrong format version -> no history");
       
   100             aHasHistory = EFalse;
       
   101             CleanupStack::PopAndDestroy(); // readStream
       
   102             LOGGER_LEAVEFN("CChangeFinder::ConstructL");
       
   103             return;
       
   104             }
       
   105         
       
   106         // Read item count
       
   107         TInt count = readStream.ReadUint32L();
       
   108         
       
   109         // Read items
       
   110         for ( TInt i=0; i<count; i++ )
       
   111             {
       
   112             TSnapshotItem item;
       
   113             item.InternalizeL( readStream );
       
   114             iOldSnapshot->InsertIsqL( item, iKey );
       
   115             }
       
   116 
       
   117         readStream.Close();
       
   118         readStream.Pop();
       
   119         }
       
   120     else
       
   121         {
       
   122         LOGGER_WRITE("CChangeFinder::ConstructL, no sync history.");
       
   123         }
       
   124         
       
   125     LOGGER_LEAVEFN("CChangeFinder::ConstructL");
       
   126     }
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // CChangeFinder::CloseL
       
   130 // Closes ChangeFinder object and writes snapshot to stream
       
   131 // -----------------------------------------------------------------------------
       
   132 void CChangeFinder::CloseL()
       
   133     {
       
   134     LOGGER_ENTERFN( "CChangeFinder::CloseL" );
       
   135     
       
   136     // Write to stream
       
   137     RWriteStream writeStream;
       
   138     
       
   139     TUid streamId;
       
   140     streamId.iUid = iStreamUid; 
       
   141 
       
   142     // Open write stream
       
   143     iSyncRelationship.OpenWriteStreamLC( writeStream, streamId );
       
   144     
       
   145     // Write used format version
       
   146     writeStream.WriteUint32L( KSnapshotFormatVersion );
       
   147 
       
   148     // Write item count
       
   149     TInt count(0);
       
   150     if ( iOldSnapshot )
       
   151         {
       
   152         count = iOldSnapshot->Count();
       
   153         }
       
   154     writeStream.WriteUint32L(count);
       
   155     
       
   156     // Write items
       
   157     for (TInt i=0; i<count; i++)
       
   158         {
       
   159         const TSnapshotItem& item = iOldSnapshot->At( i );
       
   160         item.ExternalizeL( writeStream );
       
   161         }
       
   162 
       
   163     writeStream.CommitL();
       
   164     writeStream.Close();
       
   165     writeStream.Pop();
       
   166     
       
   167     LOGGER_LEAVEFN( "CChangeFinder::CloseL" );
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CChangeFinder::ResetL
       
   172 // Resets synchronization history, all contetn is considered new after this call
       
   173 // -----------------------------------------------------------------------------
       
   174 void CChangeFinder::ResetL()
       
   175     {
       
   176     LOGGER_ENTERFN( "CChangeFinder::ResetL" );
       
   177     // Delete old change information
       
   178     if ( iOldSnapshot )
       
   179         {
       
   180         LOGGER_WRITE("iOldSnapshot->Reset()");
       
   181         iOldSnapshot->Reset();
       
   182         }
       
   183     
       
   184     // Write 'null' data to file, 
       
   185     // this removes change history from the file
       
   186     CloseL();
       
   187     
       
   188     LOGGER_LEAVEFN( "CChangeFinder::ResetL" );
       
   189     }
       
   190 
       
   191 // -----------------------------------------------------------------------------
       
   192 // CChangeFinder::FindChangedItemsL
       
   193 // Compares snapshots, finds changed items
       
   194 // -----------------------------------------------------------------------------
       
   195 void CChangeFinder::FindChangedItemsL( CNSmlDataItemUidSet& aChangedUids )
       
   196     {   
       
   197     LOGGER_ENTERFN( "CChangeFinder::FindChangedItemsL" );
       
   198     
       
   199     if ( !iCurrentSnapshot )
       
   200         {
       
   201         LOGGER_WRITE( "CChangeFinder::FindChangedItemsL leaved, no current snapshot." );
       
   202         User::Leave( KErrNotFound );
       
   203         }
       
   204 
       
   205     if ( !iOldSnapshot )
       
   206         {
       
   207         LOGGER_WRITE( "CChangeFinder::FindChangedItemsL leaved, no old snapshot." );
       
   208         User::Leave( KErrNotFound );
       
   209         }
       
   210         
       
   211     TInt index;
       
   212     TInt count = iCurrentSnapshot->Count();
       
   213     for ( TInt i=0; i < count; i++ )
       
   214         {
       
   215         const TSnapshotItem& currentItem = iCurrentSnapshot->At( i );
       
   216         // Find this entry from the old snapshot
       
   217         if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) == KErrNone)
       
   218             {
       
   219             // This is the old item
       
   220             TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   221             // Compare times to see whether this was changed or item was read
       
   222             if ( ( oldItem.LastChangedDate() != currentItem.LastChangedDate() )
       
   223                 || ( oldItem.Unread() && !currentItem.Unread() )
       
   224                 || ( !oldItem.Unread() && currentItem.Unread() )
       
   225                 || ( oldItem.FolderName().Compare( currentItem.FolderName() ) != 0 ) )
       
   226                 {
       
   227                 aChangedUids.AddItem( currentItem.ItemId() );
       
   228                 LOGGER_WRITE_1( "Item %d was changed.", currentItem.ItemId() );  
       
   229                 }
       
   230             }
       
   231         }
       
   232     
       
   233     LOGGER_LEAVEFN( "CChangeFinder::FindChangedItemsL" );
       
   234     }
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CChangeFinder::FindDeletedItemsL
       
   238 // Compares snapshots, finds deleted items
       
   239 // -----------------------------------------------------------------------------
       
   240 void CChangeFinder::FindDeletedItemsL( CNSmlDataItemUidSet& aDeletedUids )
       
   241     {
       
   242     LOGGER_ENTERFN( "CChangeFinder::FindDeletedItemsL" );
       
   243     
       
   244     if ( !iOldSnapshot )
       
   245         {
       
   246         LOGGER_LEAVEFN( "CChangeFinder::FindDeletedItemsL leaved, no old snapshot." );
       
   247         User::Leave( KErrNotFound );
       
   248         }
       
   249         
       
   250     TInt index;
       
   251     TInt count = iOldSnapshot->Count();
       
   252     for ( TInt i=0; i < count; i++ )
       
   253         {
       
   254         const TSnapshotItem& currentItem = iOldSnapshot->At( i );
       
   255         
       
   256         // If there's no current snapshot, this definately is deleted item
       
   257         if ( !iCurrentSnapshot )
       
   258             {
       
   259             aDeletedUids.AddItem( currentItem.ItemId() );
       
   260             LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() );
       
   261             }
       
   262         // It is also new if it doesn't exist int the current snapshot.
       
   263         else if ( iCurrentSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone )
       
   264             {
       
   265             aDeletedUids.AddItem( currentItem.ItemId() );
       
   266             LOGGER_WRITE_1( "Item %d was deleted.", currentItem.ItemId() );
       
   267             }       
       
   268         }
       
   269         
       
   270     LOGGER_LEAVEFN( "CChangeFinder::FindDeletedItemsL" );
       
   271     }
       
   272 
       
   273 // -----------------------------------------------------------------------------
       
   274 // CChangeFinder::FindNewItemsL
       
   275 // Compares snapshots, finds new items
       
   276 // -----------------------------------------------------------------------------
       
   277 void CChangeFinder::FindNewItemsL( CNSmlDataItemUidSet& aNewUids )
       
   278     {
       
   279     LOGGER_ENTERFN( "CChangeFinder::FindNewItemsL" );
       
   280     
       
   281     if ( !iCurrentSnapshot )
       
   282         {
       
   283         LOGGER_WRITE( "CChangeFinder::FindNewItemsL leaved, no current snapshot." );
       
   284         User::Leave( KErrNotFound );
       
   285         }
       
   286 
       
   287     TInt index;
       
   288     TInt count = iCurrentSnapshot->Count();
       
   289     for ( TInt i=0; i < count; i++ )
       
   290         {
       
   291         const TSnapshotItem& currentItem = iCurrentSnapshot->At( i );
       
   292         
       
   293         // If there's no old snapshot, all items are new
       
   294         if ( !iOldSnapshot )
       
   295             {
       
   296             aNewUids.AddItem( currentItem.ItemId() );
       
   297             LOGGER_WRITE_1( "Item %d was new.", currentItem.ItemId() );
       
   298             }
       
   299         // It is also new if it doesn't exist int the old snapshot.
       
   300         else if ( iOldSnapshot->FindIsq( currentItem, iKey, index ) != KErrNone )
       
   301             {
       
   302             aNewUids.AddItem( currentItem.ItemId() );
       
   303             LOGGER_WRITE_1( "Item %d was new.", currentItem.ItemId() );
       
   304             }       
       
   305         }
       
   306         
       
   307     LOGGER_LEAVEFN( "CChangeFinder::FindNewItemsL" );
       
   308     }
       
   309 
       
   310 // -----------------------------------------------------------------------------
       
   311 // CChangeFinder::FindMovedItemsL
       
   312 // Compares snapshots, finds moved items
       
   313 // -----------------------------------------------------------------------------
       
   314 void CChangeFinder::FindMovedItemsL( CNSmlDataItemUidSet& aMovedUids )
       
   315     {
       
   316     LOGGER_ENTERFN( "CChangeFinder::FindMovedItemsL" );
       
   317     
       
   318     if ( !iCurrentSnapshot )
       
   319         {
       
   320         LOGGER_WRITE( "CChangeFinder::FindMovedItemsL leaved, no current snapshot." );
       
   321         User::Leave( KErrNotFound );
       
   322         }
       
   323         
       
   324     if ( !iOldSnapshot )
       
   325         {
       
   326         LOGGER_WRITE( "CChangeFinder::FindMovedItemsL leaved, no old snapshot." );
       
   327         User::Leave( KErrNotFound );
       
   328         }
       
   329         
       
   330     TInt index;
       
   331     TInt count = iCurrentSnapshot->Count();
       
   332     for ( TInt i=0; i < count; i++ )
       
   333         {
       
   334         const TSnapshotItem& currentItem = iCurrentSnapshot->At( i );
       
   335         
       
   336         // Find this entry from the old snapshot
       
   337         if(iOldSnapshot->FindIsq( currentItem, iKey, index ) == KErrNone)
       
   338             {
       
   339             // This is the old item
       
   340             TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   341             
       
   342             // Report only moved items in which only parent id has been changed
       
   343             if ( oldItem.ParentId() != currentItem.ParentId()
       
   344                 && oldItem.LastChangedDate() == currentItem.LastChangedDate()
       
   345                 && !(oldItem.Unread() && !currentItem.Unread() )
       
   346                 && !(!oldItem.Unread() && currentItem.Unread() ) )
       
   347                 {
       
   348                 aMovedUids.AddItem( currentItem.ItemId() );
       
   349                 LOGGER_WRITE_1( "Item %d was moved.", currentItem.ItemId() );
       
   350                 }
       
   351             }       
       
   352         }
       
   353     
       
   354     LOGGER_LEAVEFN( "CChangeFinder::FindMovedItemsL" );     
       
   355     }
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // CChangeFinder::ItemAddedL
       
   359 // Adds item to snapshot, this item is no longer considered new
       
   360 // -----------------------------------------------------------------------------
       
   361 void CChangeFinder::ItemAddedL( const TSnapshotItem& aItem )
       
   362     {
       
   363     LOGGER_ENTERFN( "CChangeFinder::ItemAddedL" );
       
   364     
       
   365     // Add this to old snapshot, if there's no old snapshot it must be created
       
   366     if ( !iOldSnapshot )
       
   367         {
       
   368         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
   369         }
       
   370         
       
   371     LOGGER_WRITE_1( "Adding item %d.", aItem.ItemId() );
       
   372     
       
   373     TRAPD( error, iOldSnapshot->InsertIsqL( aItem, iKey ) );
       
   374     if ( error == KErrAlreadyExists )
       
   375         {
       
   376         // It was already committed, no actions required
       
   377         LOGGER_WRITE( "iOldSnapshot->InsertIsqL leaved with KErrAlreadyExists" );
       
   378         }
       
   379     else if ( error != KErrNone )
       
   380         {
       
   381         LOGGER_WRITE_1( "iOldSnapshot->InsertIsqL leaved with %d.", error );
       
   382         User::Leave( error );
       
   383         }
       
   384         
       
   385     LOGGER_LEAVEFN( "CChangeFinder::ItemAddedL" );
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CChangeFinder::ItemDeletedL
       
   390 // Removes item to snapshot, this item is no longer considered deleted
       
   391 // -----------------------------------------------------------------------------
       
   392 void CChangeFinder::ItemDeletedL( const TSnapshotItem& aItem )
       
   393     {
       
   394     LOGGER_ENTERFN( "CChangeFinder::ItemDeleted" );
       
   395     
       
   396     LOGGER_WRITE_1( "deleting item %d.", aItem.ItemId() );
       
   397     
       
   398     if ( !iOldSnapshot )
       
   399         {
       
   400         LOGGER_WRITE( "CChangeFinder::ItemDeleted leaved, no old snapshot." );
       
   401         User::Leave( KErrNotFound );
       
   402         }
       
   403 
       
   404     // Delete item from the old snapshot
       
   405     TInt index;
       
   406     if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone )
       
   407         {
       
   408         iOldSnapshot->Delete( index );
       
   409         }
       
   410     else // Skip, there wasn't such entry
       
   411         {
       
   412         LOGGER_WRITE( "iOldSnapshot->FindIsq, item was not found." );
       
   413         }  
       
   414     
       
   415     LOGGER_LEAVEFN( "CChangeFinder::ItemDeleted" );
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // CChangeFinder::ItemUpdatedL
       
   420 // Updates item to snapshot, this item is no longer considered changed
       
   421 // -----------------------------------------------------------------------------
       
   422 void CChangeFinder::ItemUpdatedL( const TSnapshotItem& aItem )
       
   423     {
       
   424     LOGGER_ENTERFN( "CChangeFinder::ItemUpdatedL" );
       
   425 
       
   426     LOGGER_WRITE_1( "Updating item %d.", aItem.ItemId() );
       
   427     
       
   428     // There must be such entry in the snapshot after this
       
   429     // If there isn't old snapshot, we'll create it and add the item
       
   430     if ( !iOldSnapshot )
       
   431         {
       
   432         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
   433         ItemAddedL( aItem );
       
   434         }
       
   435     else
       
   436         {
       
   437         // Update item in the old snapshot
       
   438         TInt index;
       
   439         if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone )
       
   440             {
       
   441             TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   442             oldItem = aItem;
       
   443             }
       
   444         else 
       
   445             {
       
   446             // There was old snapshot but no such item. Let's add it
       
   447             ItemAddedL( aItem );
       
   448             }
       
   449         
       
   450         }
       
   451         
       
   452     LOGGER_LEAVEFN( "CChangeFinder::ItemUpdatedL" );
       
   453     }
       
   454 
       
   455 // -----------------------------------------------------------------------------
       
   456 // CChangeFinder::ItemMovedL
       
   457 // Moves item within snapshot, this item is no longer considered moved
       
   458 // -----------------------------------------------------------------------------
       
   459 void CChangeFinder::ItemMovedL( const TSnapshotItem& aItem )
       
   460     {
       
   461     LOGGER_ENTERFN( "CChangeFinder::ItemMovedL" );
       
   462     
       
   463     LOGGER_WRITE_1( "Moving item %d.", aItem.ItemId() );
       
   464             
       
   465     // There must be such entry in the snapshot after this
       
   466     // If there isn't old snapshot, we'll create it and add the item
       
   467     if ( !iOldSnapshot )
       
   468         {
       
   469         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
   470         ItemAddedL( aItem );
       
   471         }
       
   472     else
       
   473         {
       
   474         // Update item's parent in the old snapshot
       
   475         TInt index;
       
   476         if ( iOldSnapshot->FindIsq( aItem, iKey, index ) == KErrNone )
       
   477             {
       
   478             TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   479             oldItem.SetParentId( aItem.ParentId() );
       
   480             }
       
   481         else 
       
   482             {
       
   483             // There was old snapshot but no such item. Let's add it
       
   484             ItemAddedL( aItem );
       
   485             }   
       
   486         }
       
   487     
       
   488     LOGGER_LEAVEFN("CChangeFinder::ItemMovedL");    
       
   489     }
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // CChangeFinder::CommitChangesL
       
   493 // Commits current changes to snapshot
       
   494 // -----------------------------------------------------------------------------
       
   495 void CChangeFinder::CommitChangesL()
       
   496     {
       
   497     LOGGER_ENTERFN( "CChangeFinder::CommitChangesL" );
       
   498     
       
   499     if ( !iCurrentSnapshot )
       
   500         {
       
   501         LOGGER_WRITE( "CChangeFinder::CommitChangesL leaved, current snapshot missing." );
       
   502         User::Leave( KErrNotFound );
       
   503         }
       
   504         
       
   505     if ( !iOldSnapshot )
       
   506         {
       
   507         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
   508         }
       
   509         
       
   510     // Delete everything from the old snapshot
       
   511     iOldSnapshot->Reset();
       
   512     
       
   513     // Loop through all the items in current snapshot
       
   514     TInt count = iCurrentSnapshot->Count();
       
   515     
       
   516     // Copy everything from current to old snapshot
       
   517     for ( TInt i=0; i < count; i++ )
       
   518         {   
       
   519         const TSnapshotItem& newItem = iCurrentSnapshot->At( i );
       
   520 
       
   521         // Commit it to the old array.
       
   522         TRAPD( error, iOldSnapshot->InsertIsqL( newItem, iKey ) );
       
   523         if ( error == KErrAlreadyExists )
       
   524             {
       
   525             // It was already committed, this is an internal error of change finder
       
   526             LOGGER_WRITE( "iOldSnapshot->InsertIsqL leaved with KErrAlreadyExists." );
       
   527             User::Leave( error );
       
   528             }
       
   529         else if ( error != KErrNone )
       
   530             {
       
   531             LOGGER_WRITE_1( "iOldSnapshot->InsertIsqL leaved with %d.", error );
       
   532             User::Leave( error );
       
   533             }
       
   534         }
       
   535     LOGGER_LEAVEFN( "CChangeFinder::CommitChangesL" );
       
   536     }
       
   537 
       
   538 // -----------------------------------------------------------------------------
       
   539 // CChangeFinder::CommitChangesL
       
   540 // Commits current changes to snapshot, affects only a specified group of items
       
   541 // -----------------------------------------------------------------------------
       
   542 void CChangeFinder::CommitChangesL( const MSmlDataItemUidSet& aUids )
       
   543     {
       
   544     LOGGER_ENTERFN( "CChangeFinder::CommitChangesL" );
       
   545     
       
   546     // This function commits changes from current snapshot to old snapshot
       
   547     // But commits only the entries in the parameter array
       
   548     if ( !iCurrentSnapshot )
       
   549         {
       
   550         LOGGER_WRITE( "CChangeFinder::CommitChangesL leaved, current snapshot missing." );
       
   551         User::Leave( KErrNotFound );
       
   552         }
       
   553         
       
   554     if ( !iOldSnapshot )
       
   555         {
       
   556         iOldSnapshot = new (ELeave) CSnapshotArray( KSnapshotGranularity );
       
   557         }
       
   558         
       
   559     // Use only these uid values
       
   560     TInt index;
       
   561     TInt count = aUids.ItemCount();
       
   562     
       
   563     for ( TInt i=0; i < count; i++ )
       
   564         {
       
   565         TSmlDbItemUid uid = aUids.ItemAt( i );
       
   566         TSnapshotItem item( uid );
       
   567         // Let's see if this uid exists in the current snapshot
       
   568         if ( iCurrentSnapshot->FindIsq( item, iKey, index ) == KErrNone )
       
   569             {
       
   570             // This is the new item
       
   571             const TSnapshotItem& newItem = iCurrentSnapshot->At( index );
       
   572             
       
   573             // Let's see if we can find the old one
       
   574             if ( iOldSnapshot->FindIsq( item, iKey, index ) == KErrNone )
       
   575                 {
       
   576                 // This is the old item
       
   577                 TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   578                 
       
   579                 // Copy new item over the old one, this'll commit the change
       
   580                 oldItem = newItem;
       
   581                 }
       
   582             else // This entry was not found. It means that it is new one
       
   583                 {
       
   584                 // Commit it to the old array.
       
   585                 ItemAddedL( newItem );
       
   586                 }
       
   587             }
       
   588         else 
       
   589             {
       
   590             // This item was deleted from the current snapshot.
       
   591             TSnapshotItem toDelete( item );
       
   592             ItemDeletedL( toDelete );
       
   593             } 
       
   594         }
       
   595     
       
   596     LOGGER_LEAVEFN( "CChangeFinder::CommitChangesL" );
       
   597     }
       
   598 
       
   599 // -----------------------------------------------------------------------------
       
   600 // CChangeFinder::SetNewSnapshot
       
   601 // Sets new snapshot (to be compared against), ChangeFinder takes ownership
       
   602 // -----------------------------------------------------------------------------
       
   603 void CChangeFinder::SetNewSnapshot( CSnapshotArray* aNewSnapshot )
       
   604     {
       
   605     LOGGER_ENTERFN( "CChangeFinder::SetNewSnapshot" );
       
   606     
       
   607     // Delete existing snapshot
       
   608     delete iCurrentSnapshot;
       
   609     
       
   610     // Set submitted snapshot as active
       
   611     iCurrentSnapshot = aNewSnapshot;
       
   612     LOGGER_LEAVEFN( "CChangeFinder::SetNewSnapshot" );
       
   613     }
       
   614 
       
   615 // -----------------------------------------------------------------------------
       
   616 // CChangeFinder::DataStoreUid
       
   617 // returns stored data store id number
       
   618 // -----------------------------------------------------------------------------
       
   619 TInt64 CChangeFinder::DataStoreUid() const
       
   620     {
       
   621     LOGGER_ENTERFN( "CChangeFinder::DataStoreUid" );
       
   622     LOGGER_LEAVEFN( "CChangeFinder::DataStoreUid" );
       
   623     return iDataStoreUid;
       
   624     }
       
   625 
       
   626 // -----------------------------------------------------------------------------
       
   627 // CChangeFinder::SetDataStoreUid
       
   628 // Sets data store id number
       
   629 // -----------------------------------------------------------------------------
       
   630 void CChangeFinder::SetDataStoreUid( TInt64 aUid )
       
   631     {
       
   632     LOGGER_ENTERFN( "CChangeFinder::SetDataStoreUid" );
       
   633     iDataStoreUid = aUid;
       
   634     LOGGER_LEAVEFN( "CChangeFinder::SetDataStoreUid" );
       
   635     }
       
   636 
       
   637 // -----------------------------------------------------------------------------
       
   638 // CChangeFinder::UpdatePartialL
       
   639 // Returns ETrue if item can be updated partially (only status bits are changed)
       
   640 // -----------------------------------------------------------------------------
       
   641 TBool CChangeFinder::UpdatePartialL( TSmlDbItemUid& aUid )
       
   642     {
       
   643     LOGGER_ENTERFN( "CChangeFinder::UpdatePartialL" );
       
   644     
       
   645     if ( !iCurrentSnapshot )
       
   646         {
       
   647         LOGGER_WRITE( "CChangeFinder::UpdatePartialL leaved, current snapshot missing." );
       
   648         User::Leave( KErrNotFound );
       
   649         }
       
   650 
       
   651     if ( !iOldSnapshot )
       
   652         {
       
   653         LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   654         return EFalse;
       
   655         }
       
   656         
       
   657     TInt index;
       
   658     TSnapshotItem item( aUid );
       
   659     // Find from current snapshot, if not found -> deleted
       
   660     if ( iCurrentSnapshot->FindIsq( item, iKey, index ) != KErrNone )
       
   661         {
       
   662         LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   663         return EFalse;
       
   664         }   
       
   665         
       
   666     // Current item 
       
   667     const TSnapshotItem& currentItem = iCurrentSnapshot->At( index );
       
   668     
       
   669     // Old item, if not found -> added
       
   670     if ( iOldSnapshot->FindIsq( item, iKey, index ) != KErrNone )
       
   671         {
       
   672         LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   673         return EFalse;
       
   674         }
       
   675     else
       
   676         {
       
   677         // This is the old item
       
   678         TSnapshotItem& oldItem = iOldSnapshot->At( index );
       
   679         
       
   680         // Status bits must have been changed to allow partial update
       
   681         if ( oldItem.Unread() == currentItem.Unread() )
       
   682             {
       
   683             LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   684             return EFalse;
       
   685             }
       
   686             
       
   687         // Date should be same, otherwise 'just' changed item
       
   688         if ( oldItem.LastChangedDate() == currentItem.LastChangedDate() )
       
   689             {
       
   690             LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   691             return ETrue;
       
   692             }
       
   693         
       
   694         LOGGER_LEAVEFN( "CChangeFinder::UpdatePartialL" );
       
   695         return EFalse;
       
   696         }
       
   697     }