|
1 /* |
|
2 * Copyright (c) 2009-2010 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 <sysutil.h> |
|
20 #include <cntfldst.h> |
|
21 |
|
22 #include "contactsgrpdatastore.h" |
|
23 #include "contactsgrpconverter.h" |
|
24 #include "changefinder.h" |
|
25 #include "contactsgrpdataproviderdefs.h" |
|
26 #include "logger.h" |
|
27 |
|
28 const TInt KDefaultBufferSize = 1024; |
|
29 const TInt KDataBufferNotReady = -1; |
|
30 // ----------------------------------------------------------------------------- |
|
31 // CContactsGrpDataStore::CContactsGrpDataStore |
|
32 // C++ default constructor can NOT contain any code, that might leave. |
|
33 // ----------------------------------------------------------------------------- |
|
34 CContactsGrpDataStore::CContactsGrpDataStore() : |
|
35 iKey( TKeyArrayFix( _FOFF( TNSmlSnapshotItem, ItemId() ), ECmpTInt ) ) |
|
36 { |
|
37 TRACE_FUNC; |
|
38 } |
|
39 |
|
40 // ----------------------------------------------------------------------------- |
|
41 // CContactsGrpDataStore::ConstructL |
|
42 // Symbian 2nd phase constructor, can leave. |
|
43 // ----------------------------------------------------------------------------- |
|
44 void CContactsGrpDataStore::ConstructL() |
|
45 { |
|
46 TRACE_FUNC_ENTRY; |
|
47 |
|
48 User::LeaveIfError( iFs.Connect() ); |
|
49 |
|
50 iNewItems = new ( ELeave ) CNSmlDataItemUidSet; |
|
51 iDeletedItems = new ( ELeave ) CNSmlDataItemUidSet; |
|
52 iUpdatedItems = new ( ELeave ) CNSmlDataItemUidSet; |
|
53 iEmptyList = new ( ELeave ) CNSmlDataItemUidSet; |
|
54 |
|
55 iConverter = CContactsGrpConverter::NewL(); |
|
56 |
|
57 TRACE_FUNC_EXIT; |
|
58 } |
|
59 |
|
60 // ----------------------------------------------------------------------------- |
|
61 // CContactsGrpDataStore::~CContactsGrpDataStore |
|
62 // Destructor |
|
63 // ----------------------------------------------------------------------------- |
|
64 CContactsGrpDataStore::~CContactsGrpDataStore() |
|
65 { |
|
66 TRACE_FUNC_ENTRY; |
|
67 |
|
68 delete iDataBuffer; |
|
69 delete iNewItems; |
|
70 delete iDeletedItems; |
|
71 delete iUpdatedItems; |
|
72 delete iEmptyList; |
|
73 |
|
74 if ( iChangeFinder ) |
|
75 { |
|
76 TRAPD( error, iChangeFinder->CloseL() ); |
|
77 if ( error != KErrNone ) |
|
78 { |
|
79 LOGGER_WRITE_1( "iChangeFinder->CloseL() leaved with %d", error ); |
|
80 } |
|
81 } |
|
82 delete iChangeFinder; |
|
83 |
|
84 delete iConverter; |
|
85 |
|
86 delete iContactsDb; |
|
87 |
|
88 iFs.Close(); |
|
89 TRACE_FUNC_EXIT; |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // CContactsGrpDataStore::NewL |
|
94 // Two-phased constructor. |
|
95 // ----------------------------------------------------------------------------- |
|
96 CContactsGrpDataStore* CContactsGrpDataStore::NewL() |
|
97 { |
|
98 TRACE_FUNC_ENTRY; |
|
99 CContactsGrpDataStore* self = CContactsGrpDataStore::NewLC(); |
|
100 CleanupStack::Pop( self ); |
|
101 TRACE_FUNC_EXIT; |
|
102 return self; |
|
103 } |
|
104 |
|
105 // ----------------------------------------------------------------------------- |
|
106 // CContactsGrpDataStore::NewLC |
|
107 // Two-phased constructor. |
|
108 // ----------------------------------------------------------------------------- |
|
109 CContactsGrpDataStore* CContactsGrpDataStore::NewLC() |
|
110 { |
|
111 TRACE_FUNC_ENTRY; |
|
112 CContactsGrpDataStore* self = new ( ELeave ) CContactsGrpDataStore(); |
|
113 CleanupStack::PushL( self ); |
|
114 self->ConstructL(); |
|
115 TRACE_FUNC_EXIT; |
|
116 return self; |
|
117 } |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // CContactsGrpDataStore::DoOpenL |
|
121 // Opens database. |
|
122 // ----------------------------------------------------------------------------- |
|
123 void CContactsGrpDataStore::DoOpenL( const TDesC& /*aStoreName*/, |
|
124 MSmlSyncRelationship& aContext, TRequestStatus& aStatus ) |
|
125 { |
|
126 TRACE_FUNC_ENTRY; |
|
127 |
|
128 iCallerStatus = &aStatus; |
|
129 *iCallerStatus = KRequestPending; |
|
130 |
|
131 if ( iContactsDb ) |
|
132 { |
|
133 // already opened |
|
134 User::RequestComplete( iCallerStatus, KErrInUse ); |
|
135 LOGGER_WRITE( "CContactsGrpDataStore::DoOpenL failed with KErrInUse." ); |
|
136 return; |
|
137 } |
|
138 |
|
139 // Create ChangeFinder |
|
140 if ( iChangeFinder ) |
|
141 { |
|
142 delete iChangeFinder; |
|
143 iChangeFinder = NULL; |
|
144 } |
|
145 iChangeFinder = CChangeFinder::NewL( aContext, iKey, iHasHistory ); |
|
146 |
|
147 iContactsDb = CContactDatabase::OpenL(); |
|
148 |
|
149 RegisterSnapshotL(); |
|
150 |
|
151 User::RequestComplete( iCallerStatus, KErrNone ); |
|
152 TRACE_FUNC_EXIT; |
|
153 } |
|
154 |
|
155 |
|
156 // ----------------------------------------------------------------------------- |
|
157 // CContactsGrpDataStore::DoCancelRequest |
|
158 // Not supported, does nothing. |
|
159 // ----------------------------------------------------------------------------- |
|
160 void CContactsGrpDataStore::DoCancelRequest() |
|
161 { |
|
162 TRACE_FUNC; |
|
163 } |
|
164 |
|
165 // ----------------------------------------------------------------------------- |
|
166 // CContactsGrpDataStore::DoStoreName |
|
167 // Returns the name of the DataStore |
|
168 // ----------------------------------------------------------------------------- |
|
169 const TDesC& CContactsGrpDataStore::DoStoreName() const |
|
170 { |
|
171 TRACE_FUNC; |
|
172 |
|
173 if ( iContactsDb ) |
|
174 { |
|
175 return KContactsGrpStoreName; |
|
176 } |
|
177 else |
|
178 { |
|
179 return KNullDesC; |
|
180 } |
|
181 } |
|
182 |
|
183 // ----------------------------------------------------------------------------- |
|
184 // CContactsGrpDataStore::DoBeginTransactionL |
|
185 // Transactions are not supported. |
|
186 // ----------------------------------------------------------------------------- |
|
187 void CContactsGrpDataStore::DoBeginTransactionL() |
|
188 { |
|
189 TRACE_FUNC; |
|
190 User::Leave( KErrNotSupported ); |
|
191 } |
|
192 |
|
193 // ----------------------------------------------------------------------------- |
|
194 // CContactsGrpDataStore::DoCommitTransactionL |
|
195 // Transactions are not supported. |
|
196 // ----------------------------------------------------------------------------- |
|
197 void CContactsGrpDataStore::DoCommitTransactionL( TRequestStatus& aStatus ) |
|
198 { |
|
199 TRACE_FUNC; |
|
200 iCallerStatus = &aStatus; |
|
201 User::RequestComplete( iCallerStatus, KErrNotSupported ); |
|
202 } |
|
203 |
|
204 // ----------------------------------------------------------------------------- |
|
205 // CContactsGrpDataStore::DoRevertTransaction |
|
206 // Transactions are not supported. |
|
207 // ----------------------------------------------------------------------------- |
|
208 void CContactsGrpDataStore::DoRevertTransaction( TRequestStatus& aStatus ) |
|
209 { |
|
210 TRACE_FUNC; |
|
211 iCallerStatus = &aStatus; |
|
212 User::RequestComplete( iCallerStatus, KErrNotSupported ); |
|
213 } |
|
214 |
|
215 // ----------------------------------------------------------------------------- |
|
216 // CContactsGrpDataStore::DoBeginBatchL |
|
217 // Batching is not supported. |
|
218 // ----------------------------------------------------------------------------- |
|
219 void CContactsGrpDataStore::DoBeginBatchL() |
|
220 { |
|
221 TRACE_FUNC; |
|
222 User::Leave( KErrNotSupported ); |
|
223 } |
|
224 |
|
225 // ----------------------------------------------------------------------------- |
|
226 // CContactsGrpDataStore::DoCommitBatchL |
|
227 // Batching is not supported |
|
228 // ----------------------------------------------------------------------------- |
|
229 void CContactsGrpDataStore::DoCommitBatchL( RArray<TInt>& /*aResultArray*/, TRequestStatus& aStatus ) |
|
230 { |
|
231 TRACE_FUNC; |
|
232 iCallerStatus = &aStatus; |
|
233 User::RequestComplete( iCallerStatus, KErrNotSupported ); |
|
234 } |
|
235 |
|
236 // ----------------------------------------------------------------------------- |
|
237 // CContactsGrpDataStore::DoCancelBatch |
|
238 // Batching is not supported |
|
239 // ----------------------------------------------------------------------------- |
|
240 void CContactsGrpDataStore::DoCancelBatch() |
|
241 { |
|
242 TRACE_FUNC; |
|
243 } |
|
244 |
|
245 // ----------------------------------------------------------------------------- |
|
246 // CContactsGrpDataStore::DoSetRemoteStoreFormatL |
|
247 // Not supported |
|
248 // ----------------------------------------------------------------------------- |
|
249 void CContactsGrpDataStore::DoSetRemoteStoreFormatL( const CSmlDataStoreFormat& /*aServerDataStoreFormat*/ ) |
|
250 { |
|
251 TRACE_FUNC; |
|
252 } |
|
253 |
|
254 // ----------------------------------------------------------------------------- |
|
255 // CContactsGrpDataStore::DoSetRemoteMaxObjectSize |
|
256 // Not supported |
|
257 // ----------------------------------------------------------------------------- |
|
258 void CContactsGrpDataStore::DoSetRemoteMaxObjectSize( TInt /*aServerMaxObjectSize*/ ) |
|
259 { |
|
260 TRACE_FUNC; |
|
261 } |
|
262 |
|
263 |
|
264 // ----------------------------------------------------------------------------- |
|
265 // CContactsGrpDataStore::DoMaxObjectSize |
|
266 // Reads the maximum object size from the central repository |
|
267 // ----------------------------------------------------------------------------- |
|
268 TInt CContactsGrpDataStore::DoMaxObjectSize() const |
|
269 { |
|
270 TRACE_FUNC; |
|
271 return 0; // no limit |
|
272 } |
|
273 |
|
274 // ----------------------------------------------------------------------------- |
|
275 // CContactsGrpDataStore::DoOpenItemL |
|
276 // Opens item in the DataStore, reads it (either completely or partially) |
|
277 // to the temporary buffer where it can be later read to the remote database. |
|
278 // ----------------------------------------------------------------------------- |
|
279 void CContactsGrpDataStore::DoOpenItemL( |
|
280 TSmlDbItemUid aUid, |
|
281 TBool& aFieldChange, |
|
282 TInt& aSize, |
|
283 TSmlDbItemUid& aParent, |
|
284 TDes8& aMimeType, |
|
285 TDes8& aMimeVer, |
|
286 TRequestStatus& aStatus ) |
|
287 { |
|
288 TRACE_FUNC_ENTRY; |
|
289 LOGGER_WRITE_1( "aUid: %d", aUid ); |
|
290 |
|
291 iCallerStatus = &aStatus; |
|
292 *iCallerStatus = KRequestPending; |
|
293 |
|
294 aFieldChange = EFalse; |
|
295 aParent = KErrNotFound; |
|
296 |
|
297 delete iDataBuffer; |
|
298 iDataBuffer = NULL; |
|
299 |
|
300 if ( !iContactsDb ) |
|
301 { |
|
302 User::Leave( KErrNotReady ); |
|
303 } |
|
304 |
|
305 iDataBuffer = CBufFlat::NewL( KDefaultBufferSize ); |
|
306 iReaderPosition = 0; |
|
307 |
|
308 CContactItem* item = iContactsDb->ReadContactLC( aUid ); |
|
309 if ( item->Type() != KUidContactGroup ) |
|
310 { |
|
311 CleanupStack::PopAndDestroy( item ); |
|
312 User::Leave( KErrNotFound ); |
|
313 } |
|
314 |
|
315 iConverter->ImportDbItemL( *static_cast<CContactGroup*>(item) ); |
|
316 |
|
317 CleanupStack::PopAndDestroy( item ); |
|
318 |
|
319 iConverter->ExportVCardL( *iDataBuffer ); |
|
320 iConverter->ResetL(); |
|
321 aSize = iDataBuffer->Size(); |
|
322 |
|
323 // Set mime type to correct one |
|
324 AssignString( aMimeType, KContactsGrpItemMimeType ); |
|
325 AssignString( aMimeVer, KContactsGrpItemMimeVersion ); |
|
326 |
|
327 User::RequestComplete( iCallerStatus, KErrNone ); |
|
328 iCurrentState = EContactGrpOpening; |
|
329 |
|
330 TRACE_FUNC_EXIT; |
|
331 } |
|
332 |
|
333 // ----------------------------------------------------------------------------- |
|
334 // CContactsGrpDataStore::DoCreateItemL |
|
335 // Create new item to the message store. |
|
336 // Return the id number of the newly created item |
|
337 // ----------------------------------------------------------------------------- |
|
338 void CContactsGrpDataStore::DoCreateItemL( |
|
339 TSmlDbItemUid& aUid, |
|
340 TInt aSize, |
|
341 TSmlDbItemUid /*aParent*/, |
|
342 const TDesC8& /*aMimeType*/, |
|
343 const TDesC8& /*aMimeVer*/, |
|
344 TRequestStatus& aStatus ) |
|
345 { |
|
346 TRACE_FUNC_ENTRY; |
|
347 iCallerStatus = &aStatus; |
|
348 *iCallerStatus = KRequestPending; |
|
349 |
|
350 // Ensure that we're in a proper state |
|
351 if ( iCurrentState != EOpenAndWaiting ) |
|
352 { |
|
353 LOGGER_WRITE_1( "Warning: Unexpected current state: %d", iCurrentState ); |
|
354 } |
|
355 |
|
356 if ( !iContactsDb ) |
|
357 { |
|
358 LOGGER_WRITE( "iContactsDb not ready" ); |
|
359 User::Leave( KErrNotReady ); |
|
360 } |
|
361 |
|
362 // Ensure that we've got enough disk space for the item |
|
363 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aSize, EDriveC ) ) |
|
364 { |
|
365 User::RequestComplete( iCallerStatus, KErrDiskFull ); |
|
366 LOGGER_WRITE( "SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull." ); |
|
367 return; |
|
368 } |
|
369 |
|
370 // item uid is updated when groups is saved to db. |
|
371 iCurrentItem = &aUid; |
|
372 // Save current operation-state so we know what operation |
|
373 // is needed to do on DoCommitItemL |
|
374 iCurrentState = EContactGrpCreating; |
|
375 |
|
376 delete iDataBuffer; |
|
377 iDataBuffer = NULL; |
|
378 iDataBuffer = CBufFlat::NewL( KDefaultBufferSize ); |
|
379 iWriterPosition = 0; |
|
380 |
|
381 User::RequestComplete( iCallerStatus, KErrNone ); |
|
382 TRACE_FUNC_EXIT; |
|
383 } |
|
384 |
|
385 // ----------------------------------------------------------------------------- |
|
386 // CContactsGrpDataStore::DoReplaceItemL |
|
387 // Begin the replace operation, ensure that the item really exists |
|
388 // ----------------------------------------------------------------------------- |
|
389 void CContactsGrpDataStore::DoReplaceItemL( |
|
390 TSmlDbItemUid aUid, |
|
391 TInt aSize, |
|
392 TSmlDbItemUid /*aParent*/, |
|
393 TBool /*aFieldChange*/, |
|
394 TRequestStatus& aStatus ) |
|
395 { |
|
396 TRACE_FUNC_ENTRY; |
|
397 LOGGER_WRITE_1("aUid: %d", aUid); |
|
398 |
|
399 iCallerStatus = &aStatus; |
|
400 *iCallerStatus = KRequestPending; |
|
401 |
|
402 if ( !iContactsDb ) |
|
403 { |
|
404 LOGGER_WRITE( "iContactsDb not ready" ); |
|
405 User::Leave( KErrNotReady ); |
|
406 } |
|
407 |
|
408 // Ensure that we've got enough disk space for the item |
|
409 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, aSize, EDriveC ) ) |
|
410 { |
|
411 User::RequestComplete( iCallerStatus, KErrDiskFull ); |
|
412 LOGGER_WRITE( "SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull." ); |
|
413 return; |
|
414 } |
|
415 |
|
416 // check that item exist and is Group-type |
|
417 CContactItem* item = iContactsDb->ReadContactLC( aUid ); |
|
418 if ( item->Type() != KUidContactGroup ) |
|
419 { |
|
420 CleanupStack::PopAndDestroy( item ); |
|
421 User::Leave( KErrNotFound ); |
|
422 } |
|
423 CleanupStack::PopAndDestroy( item ); |
|
424 |
|
425 // init databuffer |
|
426 delete iDataBuffer; |
|
427 iDataBuffer = NULL; |
|
428 iDataBuffer = CBufFlat::NewL( KDefaultBufferSize ); |
|
429 iWriterPosition = 0; |
|
430 |
|
431 // Save current item, so we know what item needs to be replaced |
|
432 iItemToBeReplaced = aUid; |
|
433 // Save current operation-state so we know what operation |
|
434 // is needed to do on DoCommitItemL |
|
435 iCurrentState = EContactGrpUpdating; |
|
436 |
|
437 User::RequestComplete( iCallerStatus, KErrNone ); |
|
438 |
|
439 TRACE_FUNC_EXIT; |
|
440 } |
|
441 |
|
442 // ----------------------------------------------------------------------------- |
|
443 // CContactsGrpDataStore::DoReadItemL |
|
444 // Read specified amount of data from the temporary buffer |
|
445 // ----------------------------------------------------------------------------- |
|
446 void CContactsGrpDataStore::DoReadItemL( TDes8& aBuffer ) |
|
447 { |
|
448 TRACE_FUNC_ENTRY; |
|
449 |
|
450 if ( iCurrentState != EContactGrpOpening || !iDataBuffer ) |
|
451 { |
|
452 LOGGER_WRITE_1( "Unexpected state %d", iCurrentState ); |
|
453 User::Leave( KErrNotReady ); |
|
454 } |
|
455 |
|
456 if ( iReaderPosition == KDataBufferNotReady ) |
|
457 { |
|
458 LOGGER_WRITE( "No data to read" ); |
|
459 User::Leave( KErrEof ); |
|
460 } |
|
461 |
|
462 // Thiw is how much data there is left in the buffer |
|
463 TInt left = iDataBuffer->Size() - iReaderPosition; |
|
464 |
|
465 if ( left > 0 ) |
|
466 { |
|
467 // This is how much there's space in the destination buffer |
|
468 TInt destSize = aBuffer.MaxSize(); |
|
469 |
|
470 // This is how much we can read |
|
471 TInt toRead = destSize < left ? destSize : left; |
|
472 |
|
473 // Read the data from the buffer, then update the position |
|
474 iDataBuffer->Read( iReaderPosition, aBuffer, toRead ); |
|
475 iReaderPosition += toRead; |
|
476 } |
|
477 else |
|
478 { |
|
479 iReaderPosition = KDataBufferNotReady; |
|
480 LOGGER_WRITE( "No data to read" ); |
|
481 User::Leave( KErrEof ); |
|
482 } |
|
483 |
|
484 TRACE_FUNC_EXIT; |
|
485 } |
|
486 |
|
487 // ----------------------------------------------------------------------------- |
|
488 // CContactsGrpDataStore::DoWriteItemL |
|
489 // Write specified amount of data to the temporary buffer |
|
490 // ----------------------------------------------------------------------------- |
|
491 void CContactsGrpDataStore::DoWriteItemL( const TDesC8& aData ) |
|
492 { |
|
493 TRACE_FUNC_ENTRY; |
|
494 |
|
495 if ( iCurrentState != EContactGrpCreating && iCurrentState != EContactGrpUpdating ) |
|
496 { |
|
497 LOGGER_WRITE_1( "Unexpected current state: %d", iCurrentState ); |
|
498 User::Leave( KErrNotReady ); |
|
499 } |
|
500 |
|
501 // Calculate total size |
|
502 TInt totalSize = aData.Size() + iDataBuffer->Size(); |
|
503 |
|
504 // Ensure that we've got enough disk space for the item |
|
505 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFs, totalSize, EDriveC ) ) |
|
506 { |
|
507 User::RequestComplete( iCallerStatus, KErrDiskFull ); |
|
508 LOGGER_WRITE("SysUtil::DiskSpaceBelowCriticalLevelL failed with KErrDiskFull."); |
|
509 return; |
|
510 } |
|
511 |
|
512 // Add data to buffer |
|
513 iDataBuffer->InsertL( iWriterPosition, aData ); |
|
514 iWriterPosition += aData.Size(); |
|
515 |
|
516 TRACE_FUNC_EXIT; |
|
517 } |
|
518 |
|
519 // ----------------------------------------------------------------------------- |
|
520 // CContactsGrpDataStore::DoCommitItemL |
|
521 // Commits item from temporary buffer to the message store |
|
522 // ----------------------------------------------------------------------------- |
|
523 void CContactsGrpDataStore::DoCommitItemL( TRequestStatus& aStatus ) |
|
524 { |
|
525 TRACE_FUNC_ENTRY; |
|
526 iCallerStatus = &aStatus; |
|
527 *iCallerStatus = KRequestPending; |
|
528 |
|
529 // Check that we're in proper state |
|
530 if ( iCurrentState != EContactGrpCreating && iCurrentState != EContactGrpUpdating ) |
|
531 { |
|
532 User::RequestComplete( iCallerStatus, KErrNotReady ); |
|
533 LOGGER_WRITE_1( "Unexpected current state: %d", iCurrentState ); |
|
534 return; |
|
535 } |
|
536 |
|
537 if ( iDataBuffer->Size() <= 0 ) |
|
538 { |
|
539 User::RequestComplete( iCallerStatus, KErrNotReady ); |
|
540 LOGGER_WRITE_1( "Data buffer has no data (%d)", iDataBuffer->Size() ); |
|
541 return; |
|
542 } |
|
543 |
|
544 if ( !iContactsDb ) |
|
545 { |
|
546 LOGGER_WRITE( "iContactsDb not ready" ); |
|
547 User::Leave( KErrNotReady ); |
|
548 } |
|
549 |
|
550 iDataBuffer->Compress(); |
|
551 iConverter->ImportVCardL( iDataBuffer->Ptr(0) ); |
|
552 |
|
553 const CContactIdArray& contactArr = iConverter->ItemsContained(); |
|
554 |
|
555 if ( iCurrentState == EContactGrpCreating ) |
|
556 { |
|
557 *iCurrentItem = CreateNewGroupL( iConverter->GroupLabel(), contactArr ); |
|
558 } |
|
559 else |
|
560 { |
|
561 ReplaceGroupL( iItemToBeReplaced, iConverter->GroupLabel(), contactArr); |
|
562 } |
|
563 iConverter->ResetL(); |
|
564 |
|
565 // Destroy buffer |
|
566 delete iDataBuffer; |
|
567 iDataBuffer = NULL; |
|
568 iWriterPosition = 0; |
|
569 |
|
570 // Restore state and signal we're done |
|
571 iCurrentState = EOpenAndWaiting; |
|
572 User::RequestComplete( iCallerStatus, KErrNone ); |
|
573 |
|
574 TRACE_FUNC_EXIT; |
|
575 } |
|
576 |
|
577 // ----------------------------------------------------------------------------- |
|
578 // CContactsGrpDataStore::CreateNewGroupL |
|
579 // Creates new groupd to db. |
|
580 // ----------------------------------------------------------------------------- |
|
581 TContactItemId CContactsGrpDataStore::CreateNewGroupL( const TDesC& aLabel, |
|
582 const CContactIdArray& aContactArray ) |
|
583 { |
|
584 TRACE_FUNC_ENTRY; |
|
585 LOGGER_WRITE_1("aLabel: %S", &aLabel ); |
|
586 |
|
587 // Check for duplicates |
|
588 if ( GroupNameExistsL( aLabel ) ) |
|
589 { |
|
590 LOGGER_WRITE("Duplicate group name found, leave KErrAlreadyExists"); |
|
591 User::Leave( KErrAlreadyExists ); |
|
592 } |
|
593 |
|
594 CContactGroup* group = |
|
595 static_cast<CContactGroup*> |
|
596 (iContactsDb->CreateContactGroupLC( aLabel )); |
|
597 |
|
598 // Create new contact group |
|
599 |
|
600 TContactItemId groupId = group->Id(); |
|
601 LOGGER_WRITE_1("new group id: %d", groupId); |
|
602 |
|
603 TBool partiallyUpdated(EFalse); |
|
604 TTime lastMod; |
|
605 lastMod.UniversalTime(); |
|
606 TInt err(KErrNone); |
|
607 for ( TInt i=0; i<aContactArray.Count(); i++ ) |
|
608 { |
|
609 LOGGER_WRITE_1("Add contact: %d", aContactArray[i] ); |
|
610 TRAP( err, iContactsDb->AddContactToGroupL( aContactArray[i], groupId )); |
|
611 if ( err ) |
|
612 { |
|
613 LOGGER_WRITE_2("Warning: AddContactToGroupL, contact: %d, err: %d", aContactArray[i], err); |
|
614 partiallyUpdated = ETrue; |
|
615 } |
|
616 else |
|
617 { |
|
618 // If succesfully added, update contact timestamp so contact sync sees those |
|
619 // contacts as changed ones. |
|
620 UpdateContactLastMod( aContactArray[i], lastMod ); |
|
621 } |
|
622 } |
|
623 |
|
624 CleanupStack::PopAndDestroy( group ); |
|
625 group = NULL; |
|
626 |
|
627 // if item was only partially updated, do not register to snapshot |
|
628 // --> on next sync item is marked as updated |
|
629 if ( !partiallyUpdated ) |
|
630 { |
|
631 // reload group |
|
632 group = static_cast<CContactGroup*> |
|
633 (iContactsDb->ReadContactLC( groupId )); |
|
634 // Inform ChangeFinder of new item |
|
635 TSnapshotItem snapshotItem( groupId ); |
|
636 snapshotItem.CreateHashL( *group ); |
|
637 iChangeFinder->ItemAddedL( snapshotItem ); |
|
638 |
|
639 CleanupStack::PopAndDestroy( group ); |
|
640 } |
|
641 |
|
642 |
|
643 |
|
644 TRACE_FUNC_EXIT; |
|
645 return groupId; |
|
646 } |
|
647 |
|
648 // ----------------------------------------------------------------------------- |
|
649 // CContactsGrpDataStore::ReplaceGroupL |
|
650 // Replaces existing group on db |
|
651 // ----------------------------------------------------------------------------- |
|
652 void CContactsGrpDataStore::ReplaceGroupL( TContactItemId aGroupId, const TDesC& aLabel, |
|
653 const CContactIdArray& aContactArray ) |
|
654 { |
|
655 TRACE_FUNC_ENTRY; |
|
656 LOGGER_WRITE_1("aGroupId: %d", aGroupId); |
|
657 LOGGER_WRITE_1("aLabel: %S", &aLabel); |
|
658 TBool partiallyUpdated(EFalse); |
|
659 // check that item exist and is Group-type |
|
660 // The LX suffix means that the lock record of the contact item is left on the cleanup stack. |
|
661 CContactItem* item = iContactsDb->OpenContactLX( aGroupId ); |
|
662 CleanupStack::PushL( item ); |
|
663 if ( item->Type() != KUidContactGroup ) |
|
664 { |
|
665 LOGGER_WRITE("Type was not KUidContactGroup, leaving KErrNotFound"); |
|
666 User::Leave( KErrNotFound ); |
|
667 } |
|
668 |
|
669 // cast item to CContactGroup type |
|
670 CContactGroup* groupItem = static_cast<CContactGroup*>(item); |
|
671 TContactItemId groupId = groupItem->Id(); |
|
672 |
|
673 TBool labelUpdated(EFalse); |
|
674 // Check is group label changed |
|
675 if ( groupItem->HasItemLabelField() ) |
|
676 { |
|
677 TPtrC dbLabel = groupItem->GetGroupLabelL(); |
|
678 if ( aLabel.Compare( dbLabel ) != 0 ) |
|
679 { |
|
680 // didn't match, update label. |
|
681 // Check that new name does not already exist |
|
682 if ( GroupNameExistsL( aLabel ) ) |
|
683 { |
|
684 LOGGER_WRITE("Name already exists, leave KErrAlreadyExists"); |
|
685 User::Leave( KErrAlreadyExists ); |
|
686 } |
|
687 LOGGER_WRITE("Update label" ); |
|
688 groupItem->SetGroupLabelL( aLabel ); |
|
689 iContactsDb->CommitContactL( *item ); |
|
690 labelUpdated = ETrue; |
|
691 } |
|
692 } |
|
693 TTime lastMod; |
|
694 lastMod.UniversalTime(); |
|
695 // Update joined contacts |
|
696 TInt err(KErrNone); |
|
697 // add new items to current group |
|
698 for ( TInt i=0; i<aContactArray.Count(); i++ ) |
|
699 { |
|
700 TContactItemId newItem = aContactArray[i]; |
|
701 TBool founded = groupItem->ContainsItem( newItem ); |
|
702 if ( !founded ) |
|
703 { |
|
704 // item does not exist on current group, add it. |
|
705 LOGGER_WRITE_1("Add contact: %d", newItem) |
|
706 TRAP( err, iContactsDb->AddContactToGroupL( newItem, groupId )); |
|
707 if ( err ) |
|
708 { |
|
709 LOGGER_WRITE_2("Warning: Could not add contact: %d, err: %d", newItem, err); |
|
710 partiallyUpdated = ETrue; |
|
711 } |
|
712 else |
|
713 { |
|
714 // Update contact timestamp |
|
715 UpdateContactLastMod( newItem, lastMod ); |
|
716 } |
|
717 } |
|
718 else |
|
719 { |
|
720 LOGGER_WRITE_1("contact( %d ) already exist on group, no need to update", newItem) |
|
721 } |
|
722 } |
|
723 |
|
724 // remove all missing items from group |
|
725 CContactIdArray* oldIdArr = groupItem->ItemsContainedLC(); |
|
726 if ( oldIdArr ) |
|
727 { |
|
728 for ( TInt i=0; i<oldIdArr->Count(); i++ ) |
|
729 { |
|
730 TContactItemId oldItem = (*oldIdArr)[i]; |
|
731 TInt err = aContactArray.Find( oldItem ); |
|
732 if ( err == KErrNotFound ) |
|
733 { |
|
734 LOGGER_WRITE_1("Remove contact: %d", oldItem ); |
|
735 // old item was not found from new item list, remove it. |
|
736 TRAP( err, iContactsDb->RemoveContactFromGroupL(oldItem, groupId)); |
|
737 if ( err ) |
|
738 { |
|
739 LOGGER_WRITE_2("Warning: Could not remove contact: %d, err: ",oldItem, err ); |
|
740 partiallyUpdated = ETrue; |
|
741 } |
|
742 else |
|
743 { |
|
744 UpdateContactLastMod( oldItem, lastMod ); |
|
745 } |
|
746 } |
|
747 // Update all contacts in group if label is changed |
|
748 else if ( labelUpdated ) |
|
749 { |
|
750 UpdateContactLastMod( oldItem, lastMod ); |
|
751 } |
|
752 } |
|
753 } |
|
754 CleanupStack::PopAndDestroy( oldIdArr ); |
|
755 CleanupStack::PopAndDestroy( 2 ); // item, lock object |
|
756 |
|
757 // if item was only partially updated, do not register to snapshot |
|
758 // --> on next sync item is marked as updated |
|
759 if ( !partiallyUpdated ) |
|
760 { |
|
761 // reload group |
|
762 groupItem = NULL; |
|
763 groupItem = static_cast<CContactGroup*> |
|
764 (iContactsDb->ReadContactLC( groupId )); |
|
765 // Inform ChangeFinder of updated item |
|
766 TSnapshotItem snapshotItem( groupId ); |
|
767 snapshotItem.CreateHashL( *groupItem ); |
|
768 iChangeFinder->ItemUpdatedL( snapshotItem ); |
|
769 |
|
770 CleanupStack::PopAndDestroy( groupItem ); |
|
771 } |
|
772 |
|
773 TRACE_FUNC_EXIT; |
|
774 } |
|
775 // ----------------------------------------------------------------------------- |
|
776 // CContactsGrpDataStore::DoCloseItem |
|
777 // Closes open item in the data store |
|
778 // ----------------------------------------------------------------------------- |
|
779 void CContactsGrpDataStore::DoCloseItem() |
|
780 { |
|
781 TRACE_FUNC_ENTRY; |
|
782 // Reset read buffer |
|
783 iReaderPosition = KDataBufferNotReady; |
|
784 delete iDataBuffer; |
|
785 iDataBuffer = NULL; |
|
786 |
|
787 // Make sure that we're opened an item |
|
788 if ( iCurrentState != EContactGrpOpening ) |
|
789 { |
|
790 LOGGER_WRITE_1( "WARNING: Invalid state %d.", iCurrentState ); |
|
791 } |
|
792 // Start to wait for the next operation |
|
793 iCurrentState = EOpenAndWaiting; |
|
794 |
|
795 TRACE_FUNC_EXIT; |
|
796 } |
|
797 |
|
798 // ----------------------------------------------------------------------------- |
|
799 // CContactsGrpDataStore::DoMoveItemL |
|
800 // Not supported. |
|
801 // ----------------------------------------------------------------------------- |
|
802 void CContactsGrpDataStore::DoMoveItemL( TSmlDbItemUid /*aUid*/, |
|
803 TSmlDbItemUid /*aNewParent*/, TRequestStatus& aStatus ) |
|
804 { |
|
805 TRACE_FUNC_ENTRY; |
|
806 |
|
807 iCallerStatus = &aStatus; |
|
808 *iCallerStatus = KRequestPending; |
|
809 |
|
810 // Restore state and signal we're done |
|
811 User::RequestComplete( iCallerStatus, KErrNotSupported ); |
|
812 |
|
813 TRACE_FUNC_EXIT; |
|
814 } |
|
815 |
|
816 // ----------------------------------------------------------------------------- |
|
817 // CContactsGrpDataStore::DoDeleteItemL |
|
818 // Removes item from the message store |
|
819 // ----------------------------------------------------------------------------- |
|
820 void CContactsGrpDataStore::DoDeleteItemL( TSmlDbItemUid aUid, TRequestStatus& aStatus ) |
|
821 { |
|
822 TRACE_FUNC_ENTRY; |
|
823 LOGGER_WRITE_1( "aUid: %d", aUid ); |
|
824 iCallerStatus = &aStatus; |
|
825 *iCallerStatus = KRequestPending; |
|
826 |
|
827 // Check that we're in proper state |
|
828 if ( iCurrentState != EOpenAndWaiting ) |
|
829 { |
|
830 LOGGER_WRITE_1("CContactsGrpDataStore::DoDeleteItemL, Incorrect state: %d", iCurrentState); |
|
831 } |
|
832 |
|
833 if ( !iContactsDb ) |
|
834 { |
|
835 LOGGER_WRITE( "iContactsDb not ready" ); |
|
836 User::Leave( KErrNotReady ); |
|
837 } |
|
838 |
|
839 // check that item type is ContactGroup |
|
840 CContactItem* item = iContactsDb->ReadContactLC( aUid ); |
|
841 if ( item->Type() != KUidContactGroup ) |
|
842 { |
|
843 LOGGER_WRITE("Item was not ContactGroup"); |
|
844 CleanupStack::PopAndDestroy( item ); |
|
845 User::Leave( KErrNotFound ); |
|
846 } |
|
847 |
|
848 // Update all contacts in group |
|
849 CContactGroup* groupItem = static_cast<CContactGroup*>(item); |
|
850 CContactIdArray* contactArr = groupItem->ItemsContainedLC(); |
|
851 if ( contactArr ) |
|
852 { |
|
853 TTime lastMod; |
|
854 lastMod.UniversalTime(); |
|
855 for ( TInt i=0; i<contactArr->Count(); i++ ) |
|
856 { |
|
857 TContactItemId contactId = (*contactArr)[i]; |
|
858 UpdateContactLastMod( contactId, lastMod ); |
|
859 } |
|
860 } |
|
861 CleanupStack::PopAndDestroy( contactArr ); |
|
862 CleanupStack::PopAndDestroy( item ); |
|
863 |
|
864 // delete group |
|
865 iContactsDb->DeleteContactL( aUid ); |
|
866 |
|
867 TSnapshotItem snapshotItem( aUid ); |
|
868 iChangeFinder->ItemDeleted( snapshotItem ); |
|
869 |
|
870 User::RequestComplete( iCallerStatus, KErrNone ); |
|
871 |
|
872 TRACE_FUNC_EXIT; |
|
873 } |
|
874 |
|
875 // ----------------------------------------------------------------------------- |
|
876 // CContactsGrpDataStore::DoSoftDeleteItemL |
|
877 // Soft delete isn't supported. |
|
878 // ----------------------------------------------------------------------------- |
|
879 void CContactsGrpDataStore::DoSoftDeleteItemL(TSmlDbItemUid /*aUid*/, TRequestStatus& aStatus) |
|
880 { |
|
881 TRACE_FUNC_ENTRY; |
|
882 iCallerStatus = &aStatus; |
|
883 *iCallerStatus = KRequestPending; |
|
884 |
|
885 User::RequestComplete(iCallerStatus, KErrNotSupported); |
|
886 TRACE_FUNC_EXIT; |
|
887 } |
|
888 |
|
889 // ----------------------------------------------------------------------------- |
|
890 // CContactsGrpDataStore::DoDeleteAllItemsL |
|
891 // Deletes all items in the standard folders of bookmark store |
|
892 // ----------------------------------------------------------------------------- |
|
893 void CContactsGrpDataStore::DoDeleteAllItemsL( TRequestStatus& aStatus ) |
|
894 { |
|
895 TRACE_FUNC_ENTRY; |
|
896 |
|
897 iCallerStatus = &aStatus; |
|
898 *iCallerStatus = KRequestPending; |
|
899 |
|
900 if ( !iContactsDb ) |
|
901 { |
|
902 LOGGER_WRITE( "iContactsDb is not opened, Leaving KErrNotReady"); |
|
903 User::Leave( KErrNotReady ); |
|
904 } |
|
905 |
|
906 CContactIdArray* groups = iContactsDb->GetGroupIdListL(); |
|
907 if ( groups ) |
|
908 { |
|
909 CleanupStack::PushL( groups ); |
|
910 TTime lastMod; |
|
911 lastMod.UniversalTime(); |
|
912 |
|
913 // update all contacts in all groups |
|
914 for ( TInt i=0; i<groups->Count(); i++ ) |
|
915 { |
|
916 // check that item type is ContactGroup |
|
917 CContactItem* item = iContactsDb->ReadContactLC( (*groups)[i] ); |
|
918 |
|
919 // Update all contacts in group |
|
920 CContactGroup* groupItem = static_cast<CContactGroup*>(item); |
|
921 CContactIdArray* contactArr = groupItem->ItemsContainedLC(); |
|
922 if ( contactArr ) |
|
923 { |
|
924 for ( TInt i=0; i<contactArr->Count(); i++ ) |
|
925 { |
|
926 TContactItemId contactId = (*contactArr)[i]; |
|
927 UpdateContactLastMod( contactId, lastMod ); |
|
928 } |
|
929 } |
|
930 CleanupStack::PopAndDestroy( contactArr ); |
|
931 CleanupStack::PopAndDestroy( item ); |
|
932 } |
|
933 |
|
934 // delete all groups |
|
935 iContactsDb->DeleteContactsL( *groups ); |
|
936 CleanupStack::PopAndDestroy( groups ); |
|
937 } |
|
938 |
|
939 // Reset the whole change finder |
|
940 iChangeFinder->ResetL(); |
|
941 |
|
942 User::RequestComplete( iCallerStatus, KErrNone ); |
|
943 |
|
944 TRACE_FUNC_EXIT; |
|
945 } |
|
946 |
|
947 // ----------------------------------------------------------------------------- |
|
948 // CContactsGrpDataStore::DoHasSyncHistory |
|
949 // This method returns ETrue if Data Store has history information. |
|
950 // Slow-sync will be used if Data Store does not have history information. |
|
951 // ----------------------------------------------------------------------------- |
|
952 TBool CContactsGrpDataStore::DoHasSyncHistory() const |
|
953 { |
|
954 TRACE_FUNC_ENTRY; |
|
955 LOGGER_WRITE_1( "iHasHistory: %d", iHasHistory ); |
|
956 TRACE_FUNC_EXIT; |
|
957 return iHasHistory; |
|
958 } |
|
959 |
|
960 // ----------------------------------------------------------------------------- |
|
961 // CContactsGrpDataStore::DoAddedItems |
|
962 // This method returns UIDs of added items. Those items are added after previous |
|
963 // synchronization with current synchronization relationship. |
|
964 // ----------------------------------------------------------------------------- |
|
965 const MSmlDataItemUidSet& CContactsGrpDataStore::DoAddedItems() const |
|
966 { |
|
967 TRACE_FUNC_ENTRY; |
|
968 |
|
969 // Clear new-items array |
|
970 iNewItems->Reset(); |
|
971 if ( !iChangeFinder ) |
|
972 { |
|
973 LOGGER_WRITE( "WARNING: Not ready, returns empty item list" ); |
|
974 return *iNewItems; |
|
975 } |
|
976 |
|
977 // Search for new items |
|
978 TRAPD( error, iChangeFinder->FindNewItemsL( *iNewItems ) ) |
|
979 if ( error != KErrNone ) |
|
980 { |
|
981 LOGGER_WRITE_1( "CContactsGrpDataStore::DoAddedItems, iChangeFinder->FindNewItemsL leaved with %d.", error ); |
|
982 } |
|
983 |
|
984 LOGGER_WRITE_1( "New item count: %d.", iNewItems->ItemCount() ); |
|
985 TRACE_FUNC_EXIT; |
|
986 |
|
987 return *iNewItems; |
|
988 } |
|
989 |
|
990 // ----------------------------------------------------------------------------- |
|
991 // CContactsGrpDataStore::DoDeletedItems |
|
992 // Returns ids of items, which are deleted after previous synchronization |
|
993 // ----------------------------------------------------------------------------- |
|
994 const MSmlDataItemUidSet& CContactsGrpDataStore::DoDeletedItems() const |
|
995 { |
|
996 TRACE_FUNC_ENTRY; |
|
997 |
|
998 // Clear deleted-items array |
|
999 iDeletedItems->Reset(); |
|
1000 if ( !iChangeFinder ) |
|
1001 { |
|
1002 LOGGER_WRITE( "WARNING: Not ready, returns empty item list" ); |
|
1003 return *iDeletedItems; |
|
1004 } |
|
1005 |
|
1006 // Search for deleted items |
|
1007 TRAPD( error, iChangeFinder->FindDeletedItemsL( *iDeletedItems ) ); |
|
1008 if ( error != KErrNone ) |
|
1009 { |
|
1010 LOGGER_WRITE_1( "CContactsGrpDataStore::DoDeletedItems, iChangeFinder->FindDeletedItemsL leaved with %d.", error ); |
|
1011 } |
|
1012 |
|
1013 LOGGER_WRITE_1( "Deleted item count: %d.", iDeletedItems->ItemCount() ); |
|
1014 TRACE_FUNC_EXIT; |
|
1015 return *iDeletedItems; |
|
1016 } |
|
1017 |
|
1018 // ----------------------------------------------------------------------------- |
|
1019 // CContactsGrpDataStore::DoSoftDeletedItems |
|
1020 // Not directly supported, empty list returned |
|
1021 // ----------------------------------------------------------------------------- |
|
1022 const MSmlDataItemUidSet& CContactsGrpDataStore::DoSoftDeletedItems() const |
|
1023 { |
|
1024 TRACE_FUNC; |
|
1025 // Return empty array as a result |
|
1026 return *iEmptyList; |
|
1027 } |
|
1028 |
|
1029 // ----------------------------------------------------------------------------- |
|
1030 // CContactsGrpDataStore::DoModifiedItems |
|
1031 // Finds all modified items in the data store |
|
1032 // ----------------------------------------------------------------------------- |
|
1033 const MSmlDataItemUidSet& CContactsGrpDataStore::DoModifiedItems() const |
|
1034 { |
|
1035 TRACE_FUNC_ENTRY; |
|
1036 |
|
1037 // Clear updated-items array |
|
1038 iUpdatedItems->Reset(); |
|
1039 if ( !iChangeFinder ) |
|
1040 { |
|
1041 LOGGER_WRITE( "WARNING: Not ready, returns empty item list" ); |
|
1042 return *iUpdatedItems; |
|
1043 } |
|
1044 |
|
1045 // Search for updated items |
|
1046 TRAPD( error, iChangeFinder->FindChangedItemsL( *iUpdatedItems ) ) |
|
1047 if ( error != KErrNone ) |
|
1048 { |
|
1049 LOGGER_WRITE_1( "CContactsGrpDataStore::DoModifiedItems, iChangeFinder->FindChangedItemsL leaved with %d.", error ); |
|
1050 } |
|
1051 |
|
1052 LOGGER_WRITE_1( "Modified item count: %d.", iUpdatedItems->ItemCount() ); |
|
1053 TRACE_FUNC_EXIT; |
|
1054 return *iUpdatedItems; |
|
1055 } |
|
1056 |
|
1057 // ----------------------------------------------------------------------------- |
|
1058 // CContactsGrpDataStore::DoMovedItems |
|
1059 // Finds all moved items in the data store |
|
1060 // ----------------------------------------------------------------------------- |
|
1061 const MSmlDataItemUidSet& CContactsGrpDataStore::DoMovedItems() const |
|
1062 { |
|
1063 TRACE_FUNC; |
|
1064 // Moved items are not supported |
|
1065 // Return empty array as a result |
|
1066 return *iEmptyList; |
|
1067 } |
|
1068 |
|
1069 // ----------------------------------------------------------------------------- |
|
1070 // CContactsGrpDataStore::DoResetChangeInfoL |
|
1071 // Resets change history in the data store. All content is considered |
|
1072 // new in the data store point of view. |
|
1073 // ----------------------------------------------------------------------------- |
|
1074 void CContactsGrpDataStore::DoResetChangeInfoL( TRequestStatus& aStatus ) |
|
1075 { |
|
1076 TRACE_FUNC_ENTRY; |
|
1077 |
|
1078 iCallerStatus = &aStatus; |
|
1079 *iCallerStatus = KRequestPending; |
|
1080 |
|
1081 // Check that we're in proper state |
|
1082 if ( iCurrentState != EOpenAndWaiting ) |
|
1083 { |
|
1084 LOGGER_WRITE_1( "CContactsGrpDataStore::DoResetChangeInfoL, invalid state %d.", iCurrentState ); |
|
1085 } |
|
1086 |
|
1087 // Reset change info in ChangeFinder |
|
1088 iChangeFinder->ResetL(); |
|
1089 iHasHistory = EFalse; |
|
1090 |
|
1091 // Signal we're done |
|
1092 User::RequestComplete( iCallerStatus, KErrNone ); |
|
1093 |
|
1094 TRACE_FUNC_EXIT; |
|
1095 } |
|
1096 |
|
1097 // ----------------------------------------------------------------------------- |
|
1098 // CContactsGrpDataStore::DoCommitChangeInfoL |
|
1099 // Commits change info. These items are no longer reported, when change |
|
1100 // information is being queried. |
|
1101 // ----------------------------------------------------------------------------- |
|
1102 void CContactsGrpDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus, |
|
1103 const MSmlDataItemUidSet& aItems ) |
|
1104 { |
|
1105 TRACE_FUNC_ENTRY; |
|
1106 |
|
1107 iCallerStatus = &aStatus; |
|
1108 *iCallerStatus = KRequestPending; |
|
1109 |
|
1110 // Ensure that we're in a proper state |
|
1111 if ( iCurrentState != EOpenAndWaiting ) |
|
1112 { |
|
1113 LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState ); |
|
1114 } |
|
1115 |
|
1116 // Notify ChangeFinder |
|
1117 LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, item count %d.", aItems.ItemCount() ); |
|
1118 iChangeFinder->CommitChangesL( aItems ); |
|
1119 iHasHistory = ETrue; |
|
1120 |
|
1121 // Signal we're done |
|
1122 User::RequestComplete( iCallerStatus, KErrNone ); |
|
1123 |
|
1124 TRACE_FUNC_EXIT; |
|
1125 } |
|
1126 |
|
1127 // ----------------------------------------------------------------------------- |
|
1128 // CContactsGrpDataStore::DoCommitChangeInfoL |
|
1129 // Commits change info. There is no more nothing to report when change |
|
1130 // information is being queried. |
|
1131 // ----------------------------------------------------------------------------- |
|
1132 void CContactsGrpDataStore::DoCommitChangeInfoL( TRequestStatus& aStatus ) |
|
1133 { |
|
1134 TRACE_FUNC_ENTRY; |
|
1135 |
|
1136 iCallerStatus = &aStatus; |
|
1137 *iCallerStatus = KRequestPending; |
|
1138 |
|
1139 // Ensure that we're in a proper state |
|
1140 if ( iCurrentState != EOpenAndWaiting ) |
|
1141 { |
|
1142 LOGGER_WRITE_1( "CContactsGrpDataStore::DoCommitChangeInfoL, invalid state %d.", iCurrentState ); |
|
1143 } |
|
1144 |
|
1145 // Notify ChangeFinder |
|
1146 iChangeFinder->CommitChangesL(); |
|
1147 iHasHistory = ETrue; |
|
1148 |
|
1149 // Signal we're done |
|
1150 User::RequestComplete( iCallerStatus, KErrNone ); |
|
1151 |
|
1152 TRACE_FUNC_EXIT; |
|
1153 } |
|
1154 |
|
1155 // ----------------------------------------------------------------------------- |
|
1156 // CContactsGrpDataStore::RegisterSnapshotL |
|
1157 // Sets Changefinder to compare against current message store content |
|
1158 // ----------------------------------------------------------------------------- |
|
1159 void CContactsGrpDataStore::RegisterSnapshotL() |
|
1160 { |
|
1161 TRACE_FUNC_ENTRY; |
|
1162 |
|
1163 CArrayFixSeg<TSnapshotItem>* snapshot = |
|
1164 new ( ELeave ) CArrayFixSeg<TSnapshotItem>( KSnapshotGranularity ); |
|
1165 CleanupStack::PushL( snapshot ); |
|
1166 |
|
1167 // Add everything to snapshot |
|
1168 |
|
1169 // GetGroupIdListL returns NULL if there are no groups in the database. |
|
1170 CContactIdArray* groups = iContactsDb->GetGroupIdListL(); |
|
1171 if ( groups ) |
|
1172 { |
|
1173 TKeyArrayFix key( iKey ); |
|
1174 CleanupStack::PushL( groups ); |
|
1175 for ( TInt i=0; i<groups->Count(); i++ ) |
|
1176 { |
|
1177 CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]); |
|
1178 CContactGroup* groupItem = static_cast<CContactGroup*>(item); |
|
1179 |
|
1180 LOGGER_WRITE_1( "Add group to snatshot, group id: %d",groupItem->Id() ); |
|
1181 |
|
1182 TSnapshotItem snapshotItem( groupItem->Id() ); |
|
1183 snapshotItem.CreateHashL( *groupItem ); |
|
1184 |
|
1185 snapshot->InsertIsqL( snapshotItem, key ); |
|
1186 |
|
1187 CleanupStack::PopAndDestroy( item ); |
|
1188 } |
|
1189 CleanupStack::PopAndDestroy( groups ); |
|
1190 } |
|
1191 |
|
1192 // Set new snapshot to compare against |
|
1193 iChangeFinder->SetNewSnapshot( snapshot ); |
|
1194 |
|
1195 // Changefinder takes ownership of the snapshot |
|
1196 CleanupStack::Pop( snapshot ); |
|
1197 |
|
1198 TRACE_FUNC_EXIT; |
|
1199 } |
|
1200 |
|
1201 // ----------------------------------------------------------------------------- |
|
1202 // CContactsGrpDataStore::AssignString |
|
1203 // Assigns data from one descriptor into another, truncates if too long |
|
1204 // ----------------------------------------------------------------------------- |
|
1205 void CContactsGrpDataStore::AssignString( TDes8& aDestination, const TDesC8& aSource ) |
|
1206 { |
|
1207 TInt targetLength = aSource.Length(); |
|
1208 if ( aDestination.MaxLength() < targetLength ) |
|
1209 { |
|
1210 targetLength = aDestination.MaxLength(); |
|
1211 } |
|
1212 |
|
1213 aDestination.Copy( aSource.Ptr(), targetLength ); |
|
1214 } |
|
1215 |
|
1216 // ----------------------------------------------------------------------------- |
|
1217 // CContactsGrpDataStore::UpdateContactLastMod |
|
1218 // Updates contact item last modified time. Contact sync will see item as changed one. |
|
1219 // ----------------------------------------------------------------------------- |
|
1220 void CContactsGrpDataStore::UpdateContactLastMod( TContactItemId aContactId, |
|
1221 const TTime& aLastModified ) |
|
1222 { |
|
1223 // Ignore errors. |
|
1224 // Cannot update timestamp if contact is already open. However modified time |
|
1225 // is most likely still updated by UI. |
|
1226 TRAP_IGNORE( |
|
1227 // OpenContactLX() places the edit lock on the cleanup stack |
|
1228 CContactItem* contact = iContactsDb->OpenContactLX( aContactId ); |
|
1229 CleanupStack::PushL( contact ); |
|
1230 contact->SetLastModified( aLastModified ); |
|
1231 iContactsDb->CommitContactL( *contact ); |
|
1232 CleanupStack::PopAndDestroy( contact ); |
|
1233 CleanupStack::PopAndDestroy( 1 ); // lock object |
|
1234 ); |
|
1235 } |
|
1236 |
|
1237 // ----------------------------------------------------------------------------- |
|
1238 // CContactsGrpDataStore::GroupNameExistsL |
|
1239 // Checks does group name already exists. |
|
1240 // ----------------------------------------------------------------------------- |
|
1241 TBool CContactsGrpDataStore::GroupNameExistsL( const TDesC& aLabel ) |
|
1242 { |
|
1243 TBool duplicateFound( EFalse ); |
|
1244 // GetGroupIdListL returns NULL if there are no groups in the database. |
|
1245 CContactIdArray* groups = iContactsDb->GetGroupIdListL(); |
|
1246 if ( groups ) |
|
1247 { |
|
1248 CleanupStack::PushL( groups ); |
|
1249 for ( TInt i=0; i<groups->Count() && !duplicateFound; i++ ) |
|
1250 { |
|
1251 CContactItem* item = iContactsDb->ReadContactLC((*groups)[i]); |
|
1252 CContactGroup* groupItem = static_cast<CContactGroup*>(item); |
|
1253 |
|
1254 if ( groupItem->HasItemLabelField() ) |
|
1255 { |
|
1256 TPtrC label = groupItem->GetGroupLabelL(); |
|
1257 if ( aLabel.Compare( label ) == 0 ) |
|
1258 { |
|
1259 duplicateFound = ETrue; |
|
1260 } |
|
1261 } |
|
1262 CleanupStack::PopAndDestroy( item ); |
|
1263 } |
|
1264 CleanupStack::PopAndDestroy( groups ); |
|
1265 } |
|
1266 |
|
1267 return duplicateFound; |
|
1268 } |