|
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 } |