|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Implementation of comms database session functions |
|
15 // dealing with : |
|
16 // session creation and destruction |
|
17 // data version checking |
|
18 // transaction management |
|
19 // containment of helper classes for notification, mapping, database interaction etc |
|
20 // |
|
21 // |
|
22 |
|
23 /** |
|
24 @file |
|
25 @internalComponent |
|
26 */ |
|
27 |
|
28 |
|
29 #include "CommsDatInternalDefs.h" |
|
30 //#include <commsdattypeinfov1_1.h> |
|
31 #include <comms-infras/commsdatschema.h> |
|
32 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
33 #include <commsdat_partner.h> |
|
34 #endif |
|
35 |
|
36 /** |
|
37 Last 4 digits of binary UID. This number has no meaning, |
|
38 but must be something that is very unlikely to be used by real |
|
39 fields in a database. |
|
40 */ |
|
41 #define MEANINGLESS_NUMBER 0x4DDB |
|
42 |
|
43 using namespace CommsDat; |
|
44 using namespace CommsDatInternal; |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 // |
|
50 // Utilities for comparing items in arrays |
|
51 |
|
52 TInt InsertNode(const TUint32& aFirst, const TUint32& aSecond) |
|
53 /* |
|
54 Utility function to find node in array |
|
55 @internalComponent |
|
56 */ |
|
57 { |
|
58 TUint mask = KCDMaskShowField | KCDUtilityFlag; |
|
59 |
|
60 if ((aFirst & mask ) == (aSecond & mask)) |
|
61 return 0; |
|
62 |
|
63 if ((aFirst & mask) < (aSecond & mask)) |
|
64 return -1; |
|
65 |
|
66 return 1; |
|
67 } |
|
68 |
|
69 TBool FindNode(const TUint32& aFirst, const TUint32& aSecond) |
|
70 /* |
|
71 Utility function to find node in array |
|
72 @internalComponent |
|
73 */ |
|
74 { |
|
75 TUint mask = KCDMaskShowField | KCDUtilityFlag; |
|
76 return (aFirst & mask ) == (aSecond & mask); |
|
77 } |
|
78 |
|
79 |
|
80 TBool CompareElements(const CMDBElement& aFirst, const CMDBElement& aSecond) |
|
81 /* |
|
82 Utility function to compare elements in array |
|
83 @internalComponent |
|
84 */ |
|
85 { |
|
86 return &aFirst == &aSecond; |
|
87 } |
|
88 |
|
89 |
|
90 TInt InsertElements(const CMDBElement& aFirst, const CMDBElement& aSecond) |
|
91 /* |
|
92 Utility function to allow insertion of elements in array |
|
93 @internalComponent |
|
94 */ |
|
95 { |
|
96 if (&aFirst == &aSecond) |
|
97 return 0; |
|
98 if (&aFirst < &aSecond) |
|
99 return -1; |
|
100 return 1; |
|
101 } |
|
102 |
|
103 TBool CompareElementsById(const CMDBElement& aFirst, const CMDBElement& aSecond) |
|
104 /* |
|
105 Utility function to compare elements in array by matching Table, Column and RecordId |
|
106 @internalComponent |
|
107 */ |
|
108 { |
|
109 return (aFirst.ElementId() & KCDMaskShowField) == (aSecond.ElementId() & KCDMaskShowField); |
|
110 } |
|
111 |
|
112 |
|
113 |
|
114 // |
|
115 |
|
116 |
|
117 |
|
118 CMDBSessionImpl::CMDBSessionImpl(CMDBSession& aOwner) |
|
119 /* |
|
120 Constructor |
|
121 @internalComponent |
|
122 */ |
|
123 : iOwner(aOwner), |
|
124 iReadAttributeMask(KCDMaskShowReadAttributes), |
|
125 iWriteAttributeMask(KCDMaskShowReadWriteAttributes) |
|
126 { |
|
127 } |
|
128 |
|
129 |
|
130 CMDBSessionImpl::~CMDBSessionImpl() |
|
131 /* |
|
132 Destructor |
|
133 |
|
134 @internalComponent |
|
135 */ |
|
136 { |
|
137 Close(); |
|
138 } |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 TInt CMDBSessionImpl::ConstructL( TVersion aRequiredVersion ) |
|
144 /* |
|
145 Open a session with the storage server and compare data versions |
|
146 |
|
147 The MetaDatabase always attempts to support the required version. If the versions match, |
|
148 KErrNone will be returned. If the versions are not the same, but the requested version |
|
149 is supported, a warning code will be returned. Otherwise an error will be |
|
150 returned. The latest version is returned in the aLatestVersion parameter for information |
|
151 |
|
152 @internalComponent |
|
153 */ |
|
154 { |
|
155 if (iCommsStorage) |
|
156 { |
|
157 return KErrNone; |
|
158 } |
|
159 |
|
160 __FLOG_STATIC1(KLogComponent, KCDInfoLog, _L("*** CMDBSessionImpl::ConstructL() constructing session object object <%08x>"), this); |
|
161 |
|
162 EstablishVersionL(aRequiredVersion); |
|
163 |
|
164 // Connect to the repository |
|
165 iCommsStorage = ::CRepository::NewL(KCDCommsRepositoryId); |
|
166 |
|
167 // register for events |
|
168 #ifndef __TOOLS2__ |
|
169 TInt err = iCommitSeqProperty.Attach(KUidCommsDatStatusEvent, KCommsDatStatusEventCommitSeq); |
|
170 |
|
171 if (err != KErrNone) |
|
172 { |
|
173 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::ConstructL() failed with error <%d>"), err); |
|
174 User::Leave(err); |
|
175 } |
|
176 #endif |
|
177 |
|
178 return KErrNone; |
|
179 } |
|
180 |
|
181 |
|
182 void CMDBSessionImpl::Close() |
|
183 /* |
|
184 Close session with storage server. |
|
185 No session required with Central repository |
|
186 |
|
187 @internalComponent |
|
188 */ |
|
189 { |
|
190 #ifndef __TOOLS2__ |
|
191 TRAPD( |
|
192 err, |
|
193 |
|
194 // Don't signal any roll-back, the reason we're performing a roll-back is because |
|
195 // the session is being CLOSED. |
|
196 NotifierL()->SuppressRollBackEvents(); |
|
197 |
|
198 RollbackTransactionL(); |
|
199 |
|
200 NotifierL()->NotifyClients(TCDNotifiableEvent::EClose); |
|
201 ); |
|
202 err = err; // suppress "unused-var" warning |
|
203 |
|
204 delete iNotifier; |
|
205 iNotifier=NULL; |
|
206 #endif |
|
207 |
|
208 #ifdef __TOOLS2__ |
|
209 if (iCommsStorage) |
|
210 { |
|
211 iCommsStorage->Flush(); |
|
212 } |
|
213 #endif |
|
214 delete iCommsStorage; |
|
215 iCommsStorage=NULL; |
|
216 |
|
217 iCommitSeqProperty.Close(); |
|
218 } |
|
219 |
|
220 |
|
221 |
|
222 TBool CMDBSessionImpl::UsingLatestVersion() |
|
223 /* |
|
224 Check the flag that indicates whether using latest version |
|
225 |
|
226 @internalComponent |
|
227 */ |
|
228 { |
|
229 return iUsingLatestVersion; |
|
230 } |
|
231 |
|
232 |
|
233 |
|
234 void CMDBSessionImpl::EstablishVersionL(TVersion aRequiredVersion) |
|
235 /* |
|
236 Check the version in use at the moment and set a flag if using latest version |
|
237 Return an error code KErrDeprecated if version is deprecated |
|
238 Return KErrNone if the version is current |
|
239 |
|
240 MAINTENANCE - this function needs updating whenever the latest version changes |
|
241 |
|
242 @internalComponent |
|
243 */ |
|
244 { |
|
245 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
246 if ( aRequiredVersion.iMajor == KCDVersion1_2.iMajor && |
|
247 aRequiredVersion.iMinor == KCDVersion1_2.iMinor && |
|
248 aRequiredVersion.iBuild == KCDVersion1_2.iBuild ) |
|
249 { |
|
250 iClientsDataSetVersion = aRequiredVersion; |
|
251 iUsingLatestVersion = ETrue; |
|
252 |
|
253 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::EstablishVersionL() Current dataset version <%d.%d.%d> in use. Mapping disabled"), KCDVersion1_2.iMajor, KCDVersion1_2.iMinor, KCDVersion1_2.iBuild); |
|
254 |
|
255 return; |
|
256 } |
|
257 else if( (aRequiredVersion.iMajor == KCDVersion1_1.iMajor && |
|
258 aRequiredVersion.iMinor == KCDVersion1_1.iMinor && |
|
259 aRequiredVersion.iBuild == KCDVersion1_1.iBuild) || |
|
260 //the orig KCDLatesVersion was (0,0,0) |
|
261 (aRequiredVersion.iMajor == 0 && |
|
262 aRequiredVersion.iMinor == 0 && |
|
263 aRequiredVersion.iBuild == 0) ) |
|
264 { |
|
265 iClientsDataSetVersion = KCDVersion1_1; |
|
266 iUsingLatestVersion = EFalse; |
|
267 |
|
268 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::EstablishVersionL() Deprecated dataset version <%d.%d.%d> in use. Mapping enabled"), aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild); |
|
269 |
|
270 return; |
|
271 } |
|
272 #else |
|
273 if( (aRequiredVersion.iMajor == KCDVersion1_1.iMajor && |
|
274 aRequiredVersion.iMinor == KCDVersion1_1.iMinor && |
|
275 aRequiredVersion.iBuild == KCDVersion1_1.iBuild) || |
|
276 //the orig KCDLatesVersion was (0,0,0) |
|
277 (aRequiredVersion.iMajor == 0 && |
|
278 aRequiredVersion.iMinor == 0 && |
|
279 aRequiredVersion.iBuild == 0) ) |
|
280 { |
|
281 iClientsDataSetVersion = KCDVersion1_1; |
|
282 iUsingLatestVersion = ETrue; |
|
283 |
|
284 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::EstablishVersionL() Current dataset version <%d.%d.%d> in use. Mapping disabled"), aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild); |
|
285 |
|
286 return; |
|
287 } |
|
288 #endif |
|
289 |
|
290 // MAINTENANCE - as versions are deprecated, allow them to still be used and return KCDDeprecatedVersion here. |
|
291 |
|
292 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("*** CMDBSessionImpl::EstablishVersionL() Requested dataset version <%d.%d.%d> not supported"), aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild); |
|
293 |
|
294 User::Leave(KErrNotSupported); |
|
295 |
|
296 return; |
|
297 } |
|
298 |
|
299 |
|
300 // |
|
301 // Accessors |
|
302 |
|
303 TVersion CMDBSessionImpl::LatestVersion() |
|
304 /* |
|
305 Lookup latest data format version |
|
306 |
|
307 @Deprecated |
|
308 @internalComponent |
|
309 */ |
|
310 { |
|
311 return KCDCurrentVersion; |
|
312 } |
|
313 |
|
314 |
|
315 TVersion CMDBSessionImpl::VersionInUse() |
|
316 /* |
|
317 Lookup data format version currently in use by client |
|
318 |
|
319 @internalComponent |
|
320 */ |
|
321 { |
|
322 return iClientsDataSetVersion; |
|
323 } |
|
324 |
|
325 |
|
326 CRepository* CMDBSessionImpl::StorageL() |
|
327 /* |
|
328 Return Storage class for Comms data |
|
329 |
|
330 @internalComponent |
|
331 */ |
|
332 { |
|
333 if (! iCommsStorage) |
|
334 { |
|
335 iCommsStorage = ::CRepository::NewL(KCDCommsRepositoryId); |
|
336 } |
|
337 return iCommsStorage; |
|
338 } |
|
339 |
|
340 |
|
341 #ifndef __TOOLS2__ |
|
342 CCDNotifier* CMDBSessionImpl::NotifierL() |
|
343 /* |
|
344 return notifier object, creating it if necessary. |
|
345 |
|
346 @internalComponent |
|
347 */ |
|
348 { |
|
349 if (! iNotifier) |
|
350 { |
|
351 iNotifier = ::CCDNotifier::NewL(*this); |
|
352 } |
|
353 return iNotifier; |
|
354 } |
|
355 #endif |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 // |
|
361 // TRANSACTIONS WITH THE DATABASE SERVER |
|
362 // |
|
363 |
|
364 TBool CMDBSessionImpl::MaybeOpenTransactionL() |
|
365 /* |
|
366 Start transaction with storage server if available |
|
367 |
|
368 Returns ETrue if opens transaction |
|
369 Returns EFalse if already in transaction |
|
370 |
|
371 @internalComponent |
|
372 */ |
|
373 { |
|
374 TBool ownTransaction = EFalse; |
|
375 |
|
376 if ( ! iInTransaction ) |
|
377 { |
|
378 TInt err = StorageL()->StartTransaction(CRepository::EReadWriteTransaction); |
|
379 |
|
380 if (err != KErrNone) |
|
381 { |
|
382 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeOpenTransactionL() - CentralRepository::StartTransactionL() failed with err = %d"), err); |
|
383 User::Leave(err); |
|
384 } |
|
385 else |
|
386 { |
|
387 iInTransaction = ETrue; |
|
388 ownTransaction = ETrue; |
|
389 } |
|
390 } |
|
391 |
|
392 return ownTransaction; |
|
393 } |
|
394 |
|
395 |
|
396 |
|
397 |
|
398 void CMDBSessionImpl::RollbackTransactionL() |
|
399 /* |
|
400 Explicitly request rollback of transaction restoring database state to before transaction started. |
|
401 |
|
402 @internalComponent |
|
403 */ |
|
404 { |
|
405 if (iInTransaction) |
|
406 { |
|
407 StorageL()->RollbackTransaction(); |
|
408 |
|
409 __FLOG_STATIC(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::RollbackTransactionL() Has rolled back storage server Transaction ")); |
|
410 |
|
411 iInTransaction = EFalse; |
|
412 |
|
413 #ifndef __TOOLS2__ |
|
414 //delete notifications if there are any |
|
415 NotifierL()->ClearPubSubNotifications(); |
|
416 |
|
417 // Notify any clients. |
|
418 NotifierL()->NotifyClients(TCDNotifiableEvent::ERollback); |
|
419 #endif |
|
420 } |
|
421 } |
|
422 |
|
423 |
|
424 TInt CMDBSessionImpl::MaybeCommitTransactionL(TBool aOwnTransaction, CMDBElement* aElement, TInt aErr) |
|
425 /* |
|
426 |
|
427 Commit transaction if outstanding and owned by caller |
|
428 |
|
429 Rollback transaction if an error has occurred |
|
430 |
|
431 Mapping and notification tasks may be required after commit |
|
432 |
|
433 Load/Find -> map & sync |
|
434 Update -> map |
|
435 Store/Modify -> sync & notify |
|
436 Delete -> notify |
|
437 |
|
438 @internalComponent |
|
439 */ |
|
440 { |
|
441 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::MaybeCommitTransactionL() aOwnTransaction = %b, aElementId = %08x, Err = %d"), aOwnTransaction, aElement ? aElement->ElementId() : 0, aErr); |
|
442 |
|
443 // Stop compiler complaining abot unused variables in UREL builds. |
|
444 (void)aElement; |
|
445 |
|
446 if (aErr != KErrNone) |
|
447 { |
|
448 __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeCommitTransactionL() Commit transaction for element <%08x> failed with error <%d>. The transaction will be rolled back"), aElement ? aElement->ElementId() : 0, aErr); |
|
449 RollbackTransactionL(); |
|
450 User::Leave(aErr); |
|
451 } |
|
452 |
|
453 TInt err(KErrNone); |
|
454 |
|
455 if ( aOwnTransaction && iInTransaction ) |
|
456 { |
|
457 TUint32 errLoc; |
|
458 |
|
459 #ifndef __TOOLS2__ |
|
460 // Update the global commit sequence. If we can't fetch the current one then we set it to the FastCounter() as a best effort |
|
461 // signal of change to observers |
|
462 TInt currCommitSeq; |
|
463 if(iCommitSeqProperty.Get(currCommitSeq) != KErrNone) |
|
464 { |
|
465 currCommitSeq = User::FastCounter(); |
|
466 } |
|
467 iCommitSeqProperty.Set(currCommitSeq + 1); |
|
468 #endif |
|
469 |
|
470 err = StorageL()->CommitTransaction(errLoc); |
|
471 |
|
472 if (err != KErrNone) |
|
473 { |
|
474 __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeCommitTransactionL() CentralRepository::CommitTransaction failed with err = %d at %08x"), err, errLoc); |
|
475 |
|
476 RollbackTransactionL(); |
|
477 |
|
478 User::Leave(err); |
|
479 } |
|
480 |
|
481 |
|
482 |
|
483 #ifndef __TOOLS2__ |
|
484 //notify any changes via pubsub if necessary |
|
485 NotifierL()->NotifyAllChanges(); |
|
486 |
|
487 // Notify any clients. |
|
488 |
|
489 /* |
|
490 NOTE: Documented or not, our Licensees expect EUnlock notification to be returned if |
|
491 CommitTransaction didn't have anything to commit (probably because user container remained unchanged or |
|
492 the user used it as a read transaction). So we are to notify with ECommit, if and only the database actually changed. |
|
493 |
|
494 This behaviour SHOULD not be changed without a BC break. Death, Destruction, rage, pillage and horror will follow if not.. |
|
495 */ |
|
496 if(errLoc > 0) |
|
497 { |
|
498 NotifierL()->NotifyClients(TCDNotifiableEvent::ECommit); |
|
499 } |
|
500 else |
|
501 { |
|
502 //errLoc will be 0 if the db wasn't changed.. |
|
503 NotifierL()->NotifyClients(TCDNotifiableEvent::EUnlock); |
|
504 } |
|
505 #endif |
|
506 |
|
507 iInTransaction = EFalse; |
|
508 } |
|
509 |
|
510 return aErr; |
|
511 } |
|
512 |
|
513 |
|
514 TBool CMDBSessionImpl::IsInTransaction() |
|
515 /* |
|
516 Query if transaction is already underway in this session |
|
517 |
|
518 @internalComponent |
|
519 */ |
|
520 { |
|
521 //__FLOG_STATIC1(KLogComponent, KCDInfoLog, _L("IsInTransaction - returning = %b "), iInTransaction ); |
|
522 |
|
523 return iInTransaction; |
|
524 } |
|
525 |
|
526 |
|
527 void CMDBSessionImpl::SetAttributeMask(TMDBAttributeFlags aAttributeMask) |
|
528 /* |
|
529 CLEAR flags from read and write attribute masks so that attributes are ignored |
|
530 |
|
531 @internalComponent |
|
532 */ |
|
533 { |
|
534 TUint32 tmpWrite = (~aAttributeMask & KCDMaskShowReadWriteAttributes); |
|
535 iWriteAttributeMask &= tmpWrite; |
|
536 |
|
537 TUint32 tmpRead = (~aAttributeMask & KCDMaskShowReadAttributes); |
|
538 iReadAttributeMask &= tmpRead; |
|
539 |
|
540 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::SetAttributeMask() aAttributeMask = %08x, iReadAttributeMask now = %08x. iWriteAttributeMask now = %08x"), aAttributeMask, iReadAttributeMask, iWriteAttributeMask); |
|
541 } |
|
542 |
|
543 |
|
544 TBool CMDBSessionImpl::IsSetAttributeMask(TMDBAttributeFlags aAttributeMask) |
|
545 /* |
|
546 Check flags in read and write attribute masks as requested |
|
547 |
|
548 @internalComponent |
|
549 */ |
|
550 { |
|
551 TUint32 currentMask = (iWriteAttributeMask | iReadAttributeMask); |
|
552 TBool retval = ((currentMask & (~aAttributeMask & KCDMaskShowAttributes)) == currentMask); |
|
553 return retval; |
|
554 } |
|
555 |
|
556 |
|
557 |
|
558 void CMDBSessionImpl::ClearAttributeMask(TMDBAttributeFlags aAttributeMask) |
|
559 /* |
|
560 SET flags in read and write attribute masks so that attributes are obeyed |
|
561 |
|
562 @internalComponent |
|
563 */ |
|
564 { |
|
565 TUint32 tmpWrite = (aAttributeMask & KCDMaskShowReadWriteAttributes); |
|
566 iWriteAttributeMask |= tmpWrite; |
|
567 |
|
568 TUint32 tmpRead = (aAttributeMask & KCDMaskShowReadAttributes); |
|
569 iReadAttributeMask |= tmpRead; |
|
570 |
|
571 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::ClearAttributeMask() aAttributeMask = %08x, iReadAttributeMask now = %08x. iWriteAttributeMask now = %08x"), aAttributeMask, iReadAttributeMask, iWriteAttributeMask); |
|
572 } |
|
573 |
|
574 |
|
575 TMDBAttributeFlags CMDBSessionImpl::GetWriteAttributeMask() |
|
576 /* |
|
577 Return current write attribute mask |
|
578 |
|
579 @internalComponent |
|
580 */ |
|
581 { |
|
582 return iWriteAttributeMask; |
|
583 } |
|
584 |
|
585 |
|
586 TMDBAttributeFlags CMDBSessionImpl::GetReadAttributeMask() |
|
587 /* |
|
588 Return current read attribute mask |
|
589 |
|
590 @internalComponent |
|
591 */ |
|
592 { |
|
593 return iReadAttributeMask; |
|
594 } |
|
595 |
|
596 |
|
597 void CMDBSessionImpl::ReadAllowedL(TMDBElementId aElementId) |
|
598 /* |
|
599 If one or more read attributes are SET in the aElementId and in the write attribute mask, |
|
600 the session does not have permission to read this element. |
|
601 */ |
|
602 { |
|
603 if ( (iReadAttributeMask & (aElementId & KCDMaskShowReadAttributes) ) ) |
|
604 { |
|
605 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::ReadAllowed() This client does not have the correct access attributes to view Element <%08x>"), aElementId); |
|
606 User::Leave(KErrPermissionDenied); |
|
607 } |
|
608 } |
|
609 |
|
610 void CMDBSessionImpl::WriteAllowedL(TMDBElementId aElementId) |
|
611 /* |
|
612 If one or more write attributes are SET in the aElementId and in the write attribute mask, |
|
613 the session does not have permission to write or update this element. |
|
614 */ |
|
615 { |
|
616 if ( (iWriteAttributeMask & (aElementId & KCDMaskShowReadWriteAttributes) ) ) |
|
617 { |
|
618 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::WriteAllowed() This client does not have the correct access attributes to write Element <%08x>"), aElementId); |
|
619 User::Leave(KErrPermissionDenied); |
|
620 } |
|
621 } |
|
622 |
|
623 void CMDBSessionImpl::DeleteAllowedL(TMDBElementId aElementId) |
|
624 /* |
|
625 If one or more write attributes are SET in the aElementId and in the write attribute mask, |
|
626 the session does not have permission to delete this element. |
|
627 |
|
628 However ECDNoWriteButDelete must be ignored in the writeAttributeMask as it is anomalous |
|
629 for BC reasons |
|
630 */ |
|
631 { |
|
632 if ( iWriteAttributeMask & (aElementId & (KCDMaskShowReadWriteAttributes & ~ECDNoWriteButDelete)) ) |
|
633 { |
|
634 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::DeleteAllowed() This client does not have the correct access attributes to delete Element <%08x>"), aElementId); |
|
635 User::Leave(KErrPermissionDenied); |
|
636 } |
|
637 } |
|
638 TInt CMDBSessionImpl::LoadNodeAttributesL(TMDBElementId& aElementId) |
|
639 /* |
|
640 Find out appropriate attributes for this node id by checking specified node |
|
641 and gathering attributes from parent nodes if aElementId does not exist in the database. |
|
642 |
|
643 Return KErrNone if the node does exist and gather attributes from the existing node into aElementId |
|
644 Return KErrNotFound if node does not exist, but gather attributes from parent nodes anyway (if they exist) |
|
645 |
|
646 Leave with KErrPermissionDenied if database forbids access to any element. |
|
647 |
|
648 @internalComponent |
|
649 */ |
|
650 { |
|
651 ASSERT(aElementId); |
|
652 |
|
653 TInt retval(KErrNotFound); |
|
654 |
|
655 if(!(CommsDatSchema::IsNewRecordRequest(aElementId) || CommsDatSchema::IsNewColumnRequest(aElementId))) |
|
656 { |
|
657 retval = FindElementInDatabaseL(aElementId); |
|
658 } |
|
659 |
|
660 if ( retval == KErrNotFound && ! CommsDatSchema::IsTable(aElementId) ) |
|
661 { |
|
662 // This must be a new field or node so gather attributes from parent nodes, |
|
663 // Report if don't find parent Record or Table nodes, |
|
664 TInt err(GatherParentAttributesL(aElementId)); |
|
665 |
|
666 if ( err != KErrNone ) |
|
667 { |
|
668 // don't worry about this, but just log it as might be of interest |
|
669 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::LoadNodeAttributes for id %08x. GatherParentAttributesL returned err %d"), aElementId, err); |
|
670 } |
|
671 } |
|
672 |
|
673 return retval; |
|
674 } |
|
675 |
|
676 |
|
677 TInt CMDBSessionImpl::GatherParentAttributesL(TMDBElementId& aElementId) |
|
678 // Get table attributes for any record or column node |
|
679 // Get Record and Column attributes for any field |
|
680 |
|
681 // Do not call this function to find a Table placeholder and element directly |
|
682 |
|
683 // Leave with KErrAccessDenied if cannot access a node. |
|
684 // return with KErrNotFound if expected parent node is not present |
|
685 |
|
686 // May leave with other errors from repository |
|
687 // May return with other error codes from repository |
|
688 { |
|
689 ASSERT(aElementId); |
|
690 |
|
691 TInt retval(KErrNotFound); |
|
692 TMDBElementId id(aElementId); |
|
693 |
|
694 if ( CommsDatSchema::IsNode(aElementId) ) |
|
695 { |
|
696 // element is a record or column, or table, so load Table attributes |
|
697 id |= (KCDMaskShowRecordId | KCDMaskShowFieldType); |
|
698 |
|
699 retval = FindElementInDatabaseL(id); |
|
700 |
|
701 aElementId |= (id & KCDMaskShowAttributes); |
|
702 } |
|
703 else |
|
704 { |
|
705 // Element is a field so get attributes from the parent record |
|
706 id = aElementId | KCDMaskShowFieldType; |
|
707 |
|
708 retval = FindElementInDatabaseL(id); |
|
709 |
|
710 aElementId |= (id & KCDMaskShowAttributes); |
|
711 |
|
712 // Finally, get extra attributes from parent column node if the node exists (it may not) |
|
713 id = aElementId | KCDMaskShowRecordId; |
|
714 |
|
715 if ( KErrNone == FindElementInDatabaseL(id) ) |
|
716 { |
|
717 aElementId |= (id & KCDMaskShowAttributes); |
|
718 } |
|
719 } |
|
720 return retval; |
|
721 } |
|
722 |
|
723 |
|
724 // |
|
725 // NODE MANAGEMENT FUNCTIONS ... |
|
726 // |
|
727 |
|
728 TInt CMDBSessionImpl::FindElementInDatabaseL(TMDBElementId& aElementId) |
|
729 /* |
|
730 Locates a single element in the database, retrieving the full id of the element including its attributes |
|
731 |
|
732 Only locates one field, node or placeholder |
|
733 |
|
734 returns EFalse if the element is not found |
|
735 returns ETrue if the element is found |
|
736 |
|
737 If the client process does not have the capabilities to read this element |
|
738 this function will leave with KErrPermissionDenied |
|
739 |
|
740 */ |
|
741 { |
|
742 ASSERT(aElementId); |
|
743 |
|
744 // Find this element with any attributes so only specify the <T><C><R>, |
|
745 // but don't want placeholder.as well as node so pay attention to the utility flag |
|
746 TUint32 mask(KCDUtilityFlag | KCDMaskShowField); |
|
747 |
|
748 //__FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::LocateElementInDatabaseL for id %08x. CRepository::FindL using mask %08x"), aElementId, mask); |
|
749 |
|
750 RArray<TUint32> ids; |
|
751 CleanupClosePushL(ids); |
|
752 |
|
753 // set the utility flag so don't find placeholder. Will leave if permission denied |
|
754 TInt retval = StorageL()->FindL((aElementId & ~KCDUtilityFlag), mask, ids); |
|
755 |
|
756 if (ids.Count()) |
|
757 { |
|
758 // element already exists in database so set attributes |
|
759 aElementId = (aElementId & ~KCDMaskShowAttrAndRes) | (ids[0] & KCDMaskShowAttributes); |
|
760 |
|
761 #ifdef __DEBUG |
|
762 if (ids.Count() > 1) |
|
763 { |
|
764 // Must not find more than one this would be a fundamental error! |
|
765 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::LocateElementInDatabase() for id <%08x>. CRepository::FindL with mask %08x returned %d entries. Should only be 1"), aElementId, mask, ids.Count()); |
|
766 } |
|
767 #endif |
|
768 } |
|
769 |
|
770 CleanupStack::PopAndDestroy(&ids); |
|
771 |
|
772 if ( retval != KErrNone && retval != KErrNotFound ) |
|
773 { |
|
774 __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::LocateElementInDatabase() for id <%08x>. CRepository::FindL. Returned err was %d"), aElementId, retval); |
|
775 } |
|
776 |
|
777 return retval; |
|
778 } |
|
779 |
|
780 |
|
781 TInt CMDBSessionImpl::LoadElementAttributesL(TMDBElementId& aElementId) |
|
782 /* |
|
783 Find out appropriate attributes for this element id by checking nodes |
|
784 |
|
785 If element is table just look for corresponding table node |
|
786 If element is record, get attributes from existing record node or from table node if record doesn't yet exist |
|
787 If element is column, get attributes from existing column node or from table node if column doesn't yet exist |
|
788 |
|
789 If element is field, get attributes from existing record and column too, where that has been set. |
|
790 |
|
791 If node does not exist, return KErrNotFound |
|
792 |
|
793 But if element is single field and does not exist set attributes from the node and return KErrNone unless parent |
|
794 node doesn't exist in which case return KErrNotFound |
|
795 |
|
796 In non-user-defined record types, column nodes are only set when attributes differ from general table attributes. |
|
797 In user defined record types, column nodes are always set. |
|
798 |
|
799 @internalComponent |
|
800 */ |
|
801 { |
|
802 TInt retval(KErrNotFound); |
|
803 |
|
804 if( aElementId ) |
|
805 { |
|
806 RArray<TUint32> ids; |
|
807 CleanupClosePushL(ids); |
|
808 |
|
809 // first look for the element itself directly... |
|
810 |
|
811 // find this element with any attributes, but don't find placeholders. |
|
812 TUint32 mask(KCDUtilityFlag | KCDMaskShowField); |
|
813 |
|
814 // __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::LoadElementAttributes for id %08x. CRepository::FindL using mask %08x"), aElementId, mask); |
|
815 |
|
816 retval = StorageL()->FindL((aElementId & ~KCDUtilityFlag), mask, ids); |
|
817 |
|
818 if (ids.Count() > 1) |
|
819 { |
|
820 // don't expect to find more than one !! |
|
821 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::LoadElementAttributes() for id <%08x>. CRepository::FindL() with mask <%08x> returned %d entries. Should only be 1"), aElementId, mask, ids.Count()); |
|
822 } |
|
823 |
|
824 |
|
825 if ( retval != KErrNone && CommsDatSchema::IsNode(aElementId)) |
|
826 { |
|
827 if (retval != KErrNotFound) |
|
828 { |
|
829 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::LoadElementAttributes for id %08x. CRepository::FindL. mask %08x Returned err was %d"), aElementId, mask, retval); |
|
830 } |
|
831 } |
|
832 else |
|
833 { |
|
834 retval = KErrNotFound; |
|
835 |
|
836 if (ids.Count()) |
|
837 { |
|
838 // node already exists so set attributes |
|
839 aElementId = (aElementId & ~KCDMaskShowAttrAndRes) | (ids[0] & KCDMaskShowAttributes); |
|
840 retval = KErrNone; |
|
841 } |
|
842 else |
|
843 { |
|
844 // Need to gather attributes from parent nodes to ensure new element is created appropriately |
|
845 // but error is still KErrNotFound |
|
846 |
|
847 // __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::LoadElementAttributes for id %08x. CRepository::FindL with mask %08x returned no entries. Checking parent nodes"), aElementId, mask); |
|
848 |
|
849 TMDBElementId id(aElementId); |
|
850 |
|
851 if ( CommsDatSchema::IsRecord(aElementId) || CommsDatSchema::IsColumn(aElementId) ) |
|
852 { |
|
853 // Get attributes from parent table |
|
854 |
|
855 id |= (KCDMaskShowRecordId | KCDMaskShowFieldType); |
|
856 |
|
857 // Last step in (potentially) recursive call chain (note we deliberately drop the KErrNone return value). |
|
858 if (LoadElementAttributesL(id) == KErrNone) |
|
859 { |
|
860 aElementId |= (id & KCDMaskShowAttributes); |
|
861 } |
|
862 } |
|
863 else if ( !CommsDatSchema::IsTable(aElementId) ) |
|
864 { |
|
865 // This is a single field. |
|
866 // Get attributes from the parent record... |
|
867 |
|
868 id = aElementId | KCDMaskShowFieldType; |
|
869 |
|
870 if ( LoadElementAttributesL(id) == KErrNone ) |
|
871 { |
|
872 aElementId |= (id & KCDMaskShowAttributes); |
|
873 |
|
874 // ...and might need to get attributes from the column node too..., |
|
875 id = aElementId | KCDMaskShowRecordId; |
|
876 if ((retval = LoadElementAttributesL(id)) == KErrNone) |
|
877 { |
|
878 aElementId |= (id & KCDMaskShowAttributes); |
|
879 } |
|
880 } |
|
881 } |
|
882 } |
|
883 } |
|
884 |
|
885 if ( retval != KErrNone && retval != KErrNotFound ) |
|
886 { |
|
887 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::LoadElementAttributesL() for id <%08x> CRepository::FindL with mask %08x returned err %d"), aElementId, mask, retval); |
|
888 } |
|
889 |
|
890 CleanupStack::PopAndDestroy(&ids); |
|
891 } |
|
892 |
|
893 return retval; |
|
894 } |
|
895 |
|
896 void CMDBSessionImpl::SetNodeIdL(TMDBElementId& aElementId, TMDBElementId aNodeTypeMask, TMDBElementId aInitialId, TMDBElementId aMaxId, TInt aMaxVal) |
|
897 /* |
|
898 Set id to a new node in the database recording the item's attributes etc. |
|
899 Will leave with KErrOverflow if there is no more space to create a new item |
|
900 */ |
|
901 { |
|
902 // First see which placeholder nodes already exist at this level |
|
903 // placeholder nodes will never have any attributes set and will always be readable by those who can write to central repository |
|
904 |
|
905 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::SetNodeIdL() for id <%08x> CRepository::FindL using mask <%08x>"), aElementId, aNodeTypeMask); |
|
906 |
|
907 RArray<TUint32> ids; |
|
908 CleanupClosePushL(ids); |
|
909 |
|
910 TInt err = StorageL()->FindL(aElementId, aNodeTypeMask, ids); |
|
911 |
|
912 |
|
913 //Ids now contains all the nodes for all the tables, Filter out those only for generic tables |
|
914 if(aMaxVal == KCDMaxUserDefTables) |
|
915 { |
|
916 TInt i(ids.Count()); |
|
917 while ( i > 0 ) |
|
918 { |
|
919 i--; |
|
920 if((ids[i] & KCDMaskShowRecordType) < KCDInitialUDefRecordType) |
|
921 { |
|
922 ids.Remove(i); |
|
923 } |
|
924 } |
|
925 ids.Compress(); |
|
926 } |
|
927 |
|
928 if (ids.Count() >= aMaxVal) |
|
929 { |
|
930 err = KErrOverflow; |
|
931 } |
|
932 |
|
933 if (err != KErrNone && err != KErrNotFound) |
|
934 { |
|
935 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::SetNodeIdL for id %08x. CRepository::FindL returned no entries. Should have found 1"), aElementId); |
|
936 |
|
937 CleanupStack::PopAndDestroy(&ids); |
|
938 User::Leave(err); |
|
939 } |
|
940 else |
|
941 { |
|
942 while ( ids.Count() > 0 && (ids[ids.Count() - 1] & aMaxId) == aMaxId ) |
|
943 { |
|
944 ids.Remove(ids.Count() - 1); |
|
945 ids.Compress(); |
|
946 } |
|
947 |
|
948 |
|
949 if( ids.Count() == 0 || |
|
950 ( ids.Count() == 1 && (ids[0] & aMaxId) == 0 ) ) // just default entry |
|
951 { |
|
952 if(aMaxVal == KCDMaxUserDefTables) |
|
953 { |
|
954 //if for generic table request |
|
955 aElementId |= KCDInitialUDefRecordType; |
|
956 } |
|
957 else |
|
958 { |
|
959 aElementId |= aInitialId; |
|
960 } |
|
961 } |
|
962 else if (ids.Count() == 1) |
|
963 { |
|
964 TUint32 temp = (ids[0] & aMaxId); |
|
965 temp += aInitialId; |
|
966 /** |
|
967 if the remaining recordId is FE (AccessPointPrioritySelectionPolicy record) then the new record id |
|
968 should be 1 and not FF. |
|
969 */ |
|
970 if (temp == aMaxId) |
|
971 { |
|
972 temp = KCDInitialRecordId; |
|
973 } |
|
974 aElementId |= temp; |
|
975 } |
|
976 else |
|
977 { |
|
978 TMDBElementId testId = (ids[ids.Count() - 1] & aMaxId) + aInitialId; |
|
979 |
|
980 if ( testId < aMaxId ) |
|
981 { |
|
982 // assign next free id at end of list |
|
983 aElementId |= testId; |
|
984 } |
|
985 else |
|
986 { |
|
987 testId = ids[0] & aMaxId; |
|
988 |
|
989 if ( testId > aInitialId ) |
|
990 { |
|
991 // assign free id from the beginning of the list |
|
992 aElementId |= aInitialId; |
|
993 } |
|
994 else |
|
995 { |
|
996 // assign first free id found in the list |
|
997 for (TInt i = 0; i < ids.Count() -1; i++) |
|
998 { |
|
999 testId = (ids[i] & aMaxId) + aInitialId; |
|
1000 |
|
1001 if ( (ids[i+1] & aMaxId) > testId ) |
|
1002 { |
|
1003 aElementId |= testId; |
|
1004 break; |
|
1005 } |
|
1006 } |
|
1007 } |
|
1008 } |
|
1009 } |
|
1010 |
|
1011 __FLOG_STATIC1(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::SetNodeIdL() successfully set aElementId to <%08x>"), aElementId); |
|
1012 |
|
1013 CleanupStack::PopAndDestroy(&ids); |
|
1014 } |
|
1015 } |
|
1016 |
|
1017 |
|
1018 void CMDBSessionImpl::CreatePlaceholderL(TMDBElementId& aElementId, TMDBElementId aNodeTypeMask, TDesC& aTableName) |
|
1019 /* |
|
1020 Create placeholdertype info node which must never have any attributes set |
|
1021 |
|
1022 Table <U><T><ef><ff><0> Int |
|
1023 Record <U><T><ef><R><0> Int |
|
1024 Column <U><T><C><ff><0> Int |
|
1025 */ |
|
1026 { |
|
1027 TInt err(KErrNone); |
|
1028 // always might need to create a table placeholder - create one if client is storing |
|
1029 // first record or column in a table as well as explicitly creating the table |
|
1030 TUint32 id = (aElementId & KCDMaskShowRecordType) | (KCDNewTableRequest & ~KCDChangedFlag) | KCDUtilityFlag ; |
|
1031 |
|
1032 RArray<TUint32>ids; |
|
1033 CleanupClosePushL(ids); |
|
1034 |
|
1035 TUint32 tablePlaceholder = id | KCDMaskShowFieldType | KCDMaskShowRecordId | KCDUtilityFlag; |
|
1036 if (KErrNotFound == StorageL()->FindL(tablePlaceholder, KCDCenRepNoMask, ids)) |
|
1037 { |
|
1038 err = StorageL()->Create(tablePlaceholder, MEANINGLESS_NUMBER); |
|
1039 if (err != KErrNone) |
|
1040 { |
|
1041 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() for id <%08x>, prepared id <%08x> CRepository::Create() for missing table returned %d"), aElementId, tablePlaceholder, err); |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 if (aNodeTypeMask != KCDMaskShowRecordType) |
|
1046 { |
|
1047 TUint32 tableNode = tablePlaceholder & ~KCDUtilityFlag; |
|
1048 |
|
1049 /* if (CommsDatSchema::IsGenericRecord(aElementId)) |
|
1050 { |
|
1051 // Not using dynamic_cast<>() here. RTTI is disabled (winscw). |
|
1052 // |
|
1053 // Presumably this works OK if the iRecordType is "null". |
|
1054 err = StorageL()->Create(tableNode, static_cast<CMDBGenericRecord*>(iCurrentRecord)->iRecordType); |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 // and now create a node too, but without any attributes and without a table name |
|
1059 // because don't know what these should be as just storing first record or column |
|
1060 */ err = StorageL()->Create(tableNode, aTableName); |
|
1061 // } |
|
1062 |
|
1063 if (err != KErrNone) |
|
1064 { |
|
1065 // unexpected error that should be logged and passed back to caller |
|
1066 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() creating Node for id <%08x>, prepared id <%08x> CRepository::Create() returned %d"), aElementId, tableNode & ~KCDUtilityFlag, err); |
|
1067 } |
|
1068 } |
|
1069 } |
|
1070 } |
|
1071 CleanupStack::PopAndDestroy(&ids); |
|
1072 |
|
1073 if (aNodeTypeMask != KCDMaskShowRecordType) |
|
1074 { |
|
1075 // create the other node types as required |
|
1076 |
|
1077 switch(aNodeTypeMask) |
|
1078 { |
|
1079 case KCDMaskShowRecordId : |
|
1080 { |
|
1081 id = (aElementId & (KCDMaskShowRecordId | KCDMaskShowRecordType)) | (KCDNewRecordRequest & KCDMaskHideRes) | KCDUtilityFlag; |
|
1082 break; |
|
1083 } |
|
1084 case KCDMaskShowFieldType : |
|
1085 { |
|
1086 id = (aElementId & (KCDMaskShowFieldType | KCDMaskShowRecordType)) | (KCDNewColumnRequest & KCDMaskHideRes) | KCDUtilityFlag; |
|
1087 break; |
|
1088 } |
|
1089 }; |
|
1090 |
|
1091 err = StorageL()->Create(id, MEANINGLESS_NUMBER); |
|
1092 |
|
1093 if (err != KErrNone) |
|
1094 { |
|
1095 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() for id <%08x> CRepository::Create() used id <%08x> and returned %d"), aElementId, id, err); |
|
1096 } |
|
1097 } |
|
1098 } |
|
1099 |
|
1100 void CMDBSessionImpl::CreatePlaceholderL(TMDBElementId& aElementId, TMDBElementId aNodeTypeMask, CMDBElement& aElement) |
|
1101 /* |
|
1102 Create placeholdertype info node which must never have any attributes set |
|
1103 |
|
1104 Table <U><T><ef><ff><0> Int |
|
1105 Record <U><T><ef><R><0> Int |
|
1106 Column <U><T><C><ff><0> Int |
|
1107 */ |
|
1108 { |
|
1109 TInt err(KErrNone); |
|
1110 // always might need to create a table placeholder - create one if client is storing |
|
1111 // first record or column in a table as well as explicitly creating the table |
|
1112 TUint32 id = (aElementId & KCDMaskShowRecordType) | (KCDNewTableRequest & ~KCDChangedFlag) | KCDUtilityFlag ; |
|
1113 |
|
1114 RArray<TUint32>ids; |
|
1115 CleanupClosePushL(ids); |
|
1116 |
|
1117 TUint32 tablePlaceholder = id | KCDMaskShowFieldType | KCDMaskShowRecordId | KCDUtilityFlag; |
|
1118 if (KErrNotFound == StorageL()->FindL(tablePlaceholder, KCDCenRepNoMask, ids)) |
|
1119 { |
|
1120 err = StorageL()->Create(tablePlaceholder, MEANINGLESS_NUMBER); |
|
1121 if (err != KErrNone) |
|
1122 { |
|
1123 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() for id <%08x>, prepared id <%08x> CRepository::Create() for missing table returned %d"), aElementId, tablePlaceholder, err); |
|
1124 } |
|
1125 else |
|
1126 { |
|
1127 if (aNodeTypeMask != KCDMaskShowRecordType) |
|
1128 { |
|
1129 TUint32 tableNode = tablePlaceholder & ~KCDUtilityFlag; |
|
1130 |
|
1131 if (CommsDatSchema::IsGenericRecord(aElementId)) |
|
1132 { |
|
1133 // Not using dynamic_cast<>() here. RTTI is disabled (winscw). |
|
1134 // |
|
1135 // Presumably this works OK if the iRecordType is "null". |
|
1136 err = StorageL()->Create(tableNode, static_cast<CMDBGenericRecord*>(&aElement)->iRecordType); |
|
1137 } |
|
1138 else |
|
1139 { |
|
1140 // and now create a node too, but without any attributes and without a table name |
|
1141 // because don't know what these should be as just storing first record or column |
|
1142 err = StorageL()->Create(tableNode, KNullDesC); |
|
1143 } |
|
1144 |
|
1145 if (err != KErrNone) |
|
1146 { |
|
1147 // unexpected error that should be logged and passed back to caller |
|
1148 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() creating Node for id <%08x>, prepared id <%08x> CRepository::Create() returned %d"), aElementId, tableNode & ~KCDUtilityFlag, err); |
|
1149 } |
|
1150 } |
|
1151 } |
|
1152 } |
|
1153 CleanupStack::PopAndDestroy(&ids); |
|
1154 |
|
1155 if (aNodeTypeMask != KCDMaskShowRecordType) |
|
1156 { |
|
1157 // create the other node types as required |
|
1158 |
|
1159 switch(aNodeTypeMask) |
|
1160 { |
|
1161 case KCDMaskShowRecordId : |
|
1162 { |
|
1163 id = (aElementId & (KCDMaskShowRecordId | KCDMaskShowRecordType)) | (KCDNewRecordRequest & KCDMaskHideRes) | KCDUtilityFlag; |
|
1164 break; |
|
1165 } |
|
1166 case KCDMaskShowFieldType : |
|
1167 { |
|
1168 id = (aElementId & (KCDMaskShowFieldType | KCDMaskShowRecordType)) | (KCDNewColumnRequest & KCDMaskHideRes) | KCDUtilityFlag; |
|
1169 break; |
|
1170 } |
|
1171 }; |
|
1172 |
|
1173 err = StorageL()->Create(id, MEANINGLESS_NUMBER); |
|
1174 |
|
1175 if (err != KErrNone) |
|
1176 { |
|
1177 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreatePlaceholderL() for id <%08x> CRepository::Create() used id <%08x> and returned %d"), aElementId, id, err); |
|
1178 } |
|
1179 } |
|
1180 } |
|
1181 |
|
1182 |
|
1183 void CMDBSessionImpl::CreateNodeL(TMDBElementId& aElementId, TMDBElementId aNodeTypeMask, CMDBElement& aElement, SGenericRecordTypeInfo* aFieldTypeInfo) |
|
1184 /* |
|
1185 Create a new node that shows the appropriate attributes and stores type information |
|
1186 given in the element passed in to the function |
|
1187 Table <T><ef><ff><0> Text |
|
1188 Record <T><ef><R><0> Int |
|
1189 Column <T><C><ff><0> Bin |
|
1190 */ |
|
1191 { |
|
1192 TInt err(KErrNone); |
|
1193 TUint32 id = aElementId; |
|
1194 switch(aNodeTypeMask) |
|
1195 { |
|
1196 case KCDMaskShowRecordType : |
|
1197 { |
|
1198 CMDBTextFieldBase& ref = static_cast<CMDBTextFieldBase&>(aElement); |
|
1199 id = (aElementId & (KCDMaskShowRecordType | iWriteAttributeMask)) | KCDNewTableRequest; |
|
1200 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::CreateNodeL() for id <%08x> prepared id is <%08x>"), aElementId, id); |
|
1201 if (aElement.IsNull()) |
|
1202 { |
|
1203 TPtrC nothing(_L("_")); |
|
1204 err = StorageL()->Create(id, nothing); |
|
1205 } |
|
1206 else |
|
1207 err = StorageL()->Create(id, (TDesC&)ref); |
|
1208 break; |
|
1209 } |
|
1210 case KCDMaskShowRecordId : |
|
1211 { |
|
1212 id = (aElementId & (KCDMaskShowRecordId | KCDMaskShowRecordType | (~iWriteAttributeMask & KCDMaskShowAttributes))); |
|
1213 id |= (KCDNewRecordRequest & KCDMaskShowFieldType); |
|
1214 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::CreateNodeL() for id <%08x> prepared id is <%08x>"), aElementId, id); |
|
1215 err = StorageL()->Create(id, MEANINGLESS_NUMBER); |
|
1216 break; |
|
1217 } |
|
1218 case KCDMaskShowFieldType : |
|
1219 { |
|
1220 // CMDBBinFieldBase& ref = static_cast<CMDBBinFieldBase&>(aElement); |
|
1221 id = (aElementId & (KCDMaskShowFieldType | KCDMaskShowRecordType | iWriteAttributeMask)) | (KCDNewColumnRequest & KCDMaskShowRecordId); |
|
1222 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::CreateNodeL() for id <%08x> prepared id is <%08x>"), aElementId, id); |
|
1223 if (aFieldTypeInfo) |
|
1224 { |
|
1225 // Serialize to a binary "stream" the field info. |
|
1226 TPckg<SGenericRecordTypeInfo> serializedTypeInfo(*aFieldTypeInfo); |
|
1227 err = StorageL()->Create(id, serializedTypeInfo); |
|
1228 } |
|
1229 break; |
|
1230 } |
|
1231 }; |
|
1232 |
|
1233 |
|
1234 if (err != KErrNone) |
|
1235 { |
|
1236 __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::CreateNodeL() for id %08x, prepared id %08x CRepository::Create() returned %d"), aElementId, id, err); |
|
1237 } |
|
1238 |
|
1239 } |
|
1240 |
|
1241 |
|
1242 |
|
1243 void CMDBSessionImpl::MaybeCreateNodeL(CMDBElement& aElement) |
|
1244 /* |
|
1245 Check to see if a new node needs to be created and if so, create it. |
|
1246 Never allows creation of deprecated record types |
|
1247 |
|
1248 else lookup attributes |
|
1249 |
|
1250 Will leave with |
|
1251 KErrAlreadyExists if requested node already exists. |
|
1252 KErrOverflow if no space to store a new node |
|
1253 KErrNotSupported if client asks to create deprecated record (will only get here |
|
1254 if mapping turned off because current version of session chosen by client) |
|
1255 @internalComponent |
|
1256 */ |
|
1257 { |
|
1258 TMDBElementId elementId = aElement.ElementId(); |
|
1259 |
|
1260 // Checking for nodes the user has asked to be created |
|
1261 |
|
1262 if ( (elementId & KCDMaskHideAttrAndRes) == KCDNewTableRequest ) |
|
1263 { |
|
1264 //Not supported at the moment |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 TInt err(KErrNotFound); |
|
1269 TPtrC tableName(KNullDesC); |
|
1270 |
|
1271 if (CommsDatSchema::IsNode(elementId)) |
|
1272 { |
|
1273 if (CommsDatSchema::IsDeprecatedRecord( |
|
1274 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1275 elementId |
|
1276 #endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY |
|
1277 )) |
|
1278 { |
|
1279 // Client is using a deprecated record in the 'latest' session |
|
1280 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeCreateNode() this client has chosen not to use an old data schema version, but is accessing a deprecated node <%08x>"), aElement.ElementId()); |
|
1281 ASSERT(KErrNotSupported); |
|
1282 User::Leave(KErrNotSupported); |
|
1283 } |
|
1284 |
|
1285 /* if (CommsDatSchema::IsGenericRecord(elementId) ) |
|
1286 { |
|
1287 CMDBGenericRecord* genRec = static_cast<CMDBGenericRecord*>(&aElement); |
|
1288 if (NULL != genRec->iRecordType.Ptr()) |
|
1289 { |
|
1290 __FLOG_STATIC0(KLogComponent, KCDInfoLog,_L("janos: genRec.iRecordType is not NULL")); |
|
1291 tableName.Set(genRec->iRecordType); |
|
1292 } |
|
1293 }*/ |
|
1294 |
|
1295 // check if the node exists and find out the attributes the element should have |
|
1296 err = LoadNodeAttributesL(elementId); |
|
1297 } |
|
1298 else |
|
1299 { |
|
1300 // First check if the node exists and find out the attributes the element should have |
|
1301 err = LoadElementAttributesL(elementId); |
|
1302 } |
|
1303 |
|
1304 // Don't need to do anything more if element already exists |
|
1305 // or if element is a field |
|
1306 if (err == KErrNotFound) |
|
1307 { |
|
1308 WriteAllowedL(elementId); |
|
1309 |
|
1310 if ( CommsDatSchema::IsNewRecordRequest(elementId) ) |
|
1311 { |
|
1312 // assign new record id and create node |
|
1313 SetNodeIdL(elementId, KCDUtilityFlag | KCDMaskShowType, KCDInitialRecordId, KCDMaxRecordId, KCDMaxRecords); |
|
1314 elementId &= ~KCDUtilityFlag; |
|
1315 // CreatePlaceholderL(elementId, KCDMaskShowRecordId, tableName); |
|
1316 CreatePlaceholderL(elementId, KCDMaskShowRecordId, aElement); |
|
1317 CreateNodeL(elementId, KCDMaskShowRecordId, aElement); |
|
1318 } |
|
1319 else if ( CommsDatSchema::IsNewColumnRequest(elementId) ) |
|
1320 { |
|
1321 elementId &= ~KCDUtilityFlag; |
|
1322 // assign new column id and create node |
|
1323 SetNodeIdL(elementId, KCDMaskShowFieldType, KCDInitialColumnId, KCDMaxColumnId, KCDMaxColumns); |
|
1324 // CreatePlaceholderL(elementId, KCDMaskShowFieldType, tableName); |
|
1325 CreatePlaceholderL(elementId, KCDMaskShowFieldType, aElement); |
|
1326 CreateNodeL(elementId, KCDMaskShowFieldType, aElement); |
|
1327 } |
|
1328 else if ( (elementId & KCDMaskShowRecordType) != 0 ) |
|
1329 { |
|
1330 // Is an element where the id has already been set by caller |
|
1331 if ( CommsDatSchema::IsRecord(elementId) ) |
|
1332 { |
|
1333 // create new record |
|
1334 // CreatePlaceholderL(elementId, KCDMaskShowRecordId, tableName); |
|
1335 CreatePlaceholderL(elementId, KCDMaskShowRecordId, aElement); |
|
1336 if ( CommsDatSchema::IsTemplate(elementId) ) |
|
1337 { |
|
1338 // Template records must be hidden |
|
1339 elementId |= ECDHidden; |
|
1340 } |
|
1341 CreateNodeL(elementId, KCDMaskShowRecordId, aElement); |
|
1342 } |
|
1343 // columns shouldn't be set by user.explicitly - new column request should be used |
|
1344 // other entries would be individual fields and wouldn't get here because |
|
1345 // LoadElementAttributes would have returned KErrNone. |
|
1346 } |
|
1347 else |
|
1348 { |
|
1349 // user has set an invalid id |
|
1350 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeCreateNode() Element <%08x> is not a valid element id"), aElement.ElementId()); |
|
1351 User::Leave(KErrNotFound); |
|
1352 } |
|
1353 } |
|
1354 } |
|
1355 //pass back new node id or set of appropriate attributes |
|
1356 aElement.SetElementId(elementId); |
|
1357 } |
|
1358 |
|
1359 |
|
1360 |
|
1361 TInt CMDBSessionImpl::MaybeModifyNodeL(TMDBElementId& aElementId) |
|
1362 /* |
|
1363 */ |
|
1364 { |
|
1365 TBool retval(0); |
|
1366 if (! iInModification) |
|
1367 { |
|
1368 TMDBElementId storedId(aElementId & KCDMaskHideRes); |
|
1369 TMDBElementId mask = ~(KCDMaskShowAttributes | KCDChangedFlag); |
|
1370 |
|
1371 TInt err = LoadElementAttributesL(storedId); |
|
1372 |
|
1373 if ( err == KErrNotFound && |
|
1374 ( ( (storedId & KCDMaskShowFieldType) != KCDMaskShowFieldType ) || |
|
1375 ( (storedId & KCDMaskShowRecordId) != KCDMaskShowRecordId ) ) ) |
|
1376 { |
|
1377 err = KErrNone; |
|
1378 } |
|
1379 |
|
1380 if ( (aElementId & KCDMaskShowAttributes) != (storedId & KCDMaskShowAttributes) ) |
|
1381 { |
|
1382 // this means the element was found but didn't have these attributes. |
|
1383 // So need to move it and all linked elements. |
|
1384 |
|
1385 TUint32 partialSourceId(storedId); |
|
1386 TUint32 partialTargetId(aElementId); |
|
1387 TUint32 targetAttributes = (aElementId ^ storedId) & KCDMaskShowAttributes; |
|
1388 |
|
1389 if ( CommsDatSchema::IsTable(aElementId) ) |
|
1390 { |
|
1391 // move all records, columns and fields in this table |
|
1392 mask = KCDMaskShowRecordType | targetAttributes; |
|
1393 partialSourceId &= (KCDMaskShowRecordType | KCDMaskShowAttributes); |
|
1394 partialTargetId &= (KCDMaskShowRecordType | KCDMaskShowAttributes); |
|
1395 } |
|
1396 else if ( CommsDatSchema::IsRecord(aElementId) ) |
|
1397 { |
|
1398 // move all fields in this record |
|
1399 mask = KCDMaskShowRecordType | KCDMaskShowRecordId | targetAttributes; |
|
1400 partialSourceId &= (KCDMaskShowRecordType | KCDMaskShowRecordId | KCDMaskShowAttributes); |
|
1401 partialTargetId &= (KCDMaskShowRecordType | KCDMaskShowRecordId | KCDMaskShowAttributes); |
|
1402 } |
|
1403 else if ( CommsDatSchema::IsColumn(aElementId) ) |
|
1404 { |
|
1405 // move all fields in this column |
|
1406 mask = KCDMaskShowRecordType | KCDMaskShowFieldType | targetAttributes; |
|
1407 partialSourceId &= (KCDMaskShowRecordType | KCDMaskShowFieldType | KCDMaskShowAttributes); |
|
1408 partialTargetId &= (KCDMaskShowRecordType | KCDMaskShowFieldType | KCDMaskShowAttributes); |
|
1409 } |
|
1410 else |
|
1411 { |
|
1412 // this element is not a node, but a field and yet was not found with expected set of attributes. |
|
1413 // Can't change attributes of single fields so in error situation. |
|
1414 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeModifyNodeL() for id <%08x> being asked to change attributes on single field which is an error"), partialSourceId ); |
|
1415 User::Leave(KErrNotFound); |
|
1416 } |
|
1417 |
|
1418 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::MaybeModifyNodeL() About to call CRepository::MoveL() to move everything at id %08x to %08x using the mask %08x."), partialSourceId, partialTargetId, mask); |
|
1419 |
|
1420 TUint32 errorId(0); |
|
1421 err = StorageL()->Move(partialSourceId, partialTargetId, mask, errorId); |
|
1422 |
|
1423 if (err != KErrNone) |
|
1424 { |
|
1425 __FLOG_STATIC5(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeModifyNodeL() for id %08x, moving to <%08x> with the mask <%08x>. CRepository::MoveL() returned %d and failed at <%08x>"), partialSourceId, partialTargetId, mask, retval, errorId); |
|
1426 } |
|
1427 else |
|
1428 { |
|
1429 iInModification = ETrue; |
|
1430 retval = ETrue; |
|
1431 } |
|
1432 } |
|
1433 } |
|
1434 |
|
1435 return retval; |
|
1436 } |
|
1437 |
|
1438 |
|
1439 TBool CompareInstance(const TUint32& aFirst, const TUint32& aSecond) |
|
1440 { |
|
1441 return( (aFirst & KCDMaskShowRecordId) == (aSecond & KCDMaskShowRecordId)); |
|
1442 } |
|
1443 |
|
1444 |
|
1445 TInt CMDBSessionImpl::MaybeDeleteNodeL(CMDBElement* /* aElement */, TMDBElementId& aElementId) |
|
1446 { |
|
1447 TMDBElementId id(aElementId); |
|
1448 |
|
1449 // check element id exists |
|
1450 TInt err = LoadElementAttributesL(id); |
|
1451 |
|
1452 if (err == KErrNone) |
|
1453 { |
|
1454 RArray<TUint32> ids; |
|
1455 CleanupClosePushL(ids); |
|
1456 |
|
1457 // set mask |
|
1458 TUint32 mask(KCDMaskHideRes); |
|
1459 TUint32 nodemask(KCDMaskHideRes); |
|
1460 |
|
1461 // if is table |
|
1462 if ( CommsDatSchema::IsTable(id) ) |
|
1463 { |
|
1464 mask = KCDMaskShowRecordType | KCDUtilityFlag; |
|
1465 nodemask = mask | KCDMaskShowFieldType | iWriteAttributeMask; // will find records and table. Not enough - need to do two finds |
|
1466 } |
|
1467 // if is record |
|
1468 else if ( CommsDatSchema::IsRecord(id) ) |
|
1469 { |
|
1470 mask = KCDMaskShowRecordType | KCDMaskShowRecordId | KCDUtilityFlag; |
|
1471 nodemask = mask | KCDMaskShowFieldType | iWriteAttributeMask; |
|
1472 } |
|
1473 // if is column |
|
1474 else if ( CommsDatSchema::IsColumn(id) ) |
|
1475 { |
|
1476 mask = KCDMaskShowRecordType | KCDMaskShowFieldType | KCDUtilityFlag; |
|
1477 nodemask = mask | KCDMaskShowRecordId | iWriteAttributeMask; |
|
1478 } |
|
1479 |
|
1480 // otherwise just delete single field with no mask |
|
1481 |
|
1482 __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::MaybeDeleteNode() for id <%08x> CRepository::FindL using mask <%08x>"), aElementId, mask); |
|
1483 |
|
1484 |
|
1485 if ( mask != KCDMaskHideRes ) |
|
1486 { |
|
1487 RArray<TUint32> placeholders; |
|
1488 CleanupClosePushL(placeholders); |
|
1489 // find all relevant placeholders |
|
1490 err = StorageL()->FindL((aElementId & ~iWriteAttributeMask) | KCDUtilityFlag, mask, placeholders); |
|
1491 |
|
1492 if (placeholders.Count() > 0) |
|
1493 { |
|
1494 RArray<TUint32> nodes; |
|
1495 CleanupClosePushL(nodes); |
|
1496 |
|
1497 err = StorageL()->FindL(aElementId & ~iWriteAttributeMask, nodemask, nodes); |
|
1498 |
|
1499 if(CommsDatSchema::IsGenericRecord(aElementId)) |
|
1500 { |
|
1501 TUint32 checkid = KCDMaskShowRecordId; |
|
1502 TInt instanceid; |
|
1503 while((instanceid = nodes.Find(checkid,TIdentityRelation<TUint32>(CompareInstance))) != KErrNotFound) |
|
1504 { |
|
1505 nodes.Remove(instanceid); |
|
1506 } |
|
1507 while((instanceid = placeholders.Find(checkid,TIdentityRelation<TUint32>(CompareInstance))) != KErrNotFound) |
|
1508 { |
|
1509 placeholders.Remove(instanceid); |
|
1510 } |
|
1511 placeholders.Compress(); |
|
1512 nodes.Compress(); |
|
1513 } |
|
1514 |
|
1515 |
|
1516 if (nodes.Count() == placeholders.Count() ) |
|
1517 { |
|
1518 // delete the placeholders in a batch |
|
1519 for (TInt i = 0; i < placeholders.Count(); i++) |
|
1520 { |
|
1521 err = StorageL()->Delete(placeholders[i]); |
|
1522 if( err != KErrNone) |
|
1523 { |
|
1524 __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeDeleteNode() failed to delete a placeholder <%08x> with error %d"), placeholders[i], err); |
|
1525 User::Leave(err); |
|
1526 } |
|
1527 } |
|
1528 |
|
1529 if(nodes.Count()) |
|
1530 { |
|
1531 #ifndef __TOOLS2__ |
|
1532 TBool modemBearerDeleted = ((nodes[0] & KCDMaskShowRecordType) == KCDTIdModemBearerRecord); |
|
1533 NotifierL()->MaybeNotifyChangeForDelete(nodes[0], modemBearerDeleted); |
|
1534 #endif |
|
1535 } |
|
1536 } |
|
1537 else |
|
1538 { |
|
1539 // place holders have no attributes, but nodes do. |
|
1540 // if cannot see same number of nodes and placeholders this indicates |
|
1541 // client may need extra capabilities to see or manipulate all nodes |
|
1542 __FLOG_STATIC1(KLogComponent, KCDErrLog, _L("CMDBSessionImpl::MaybeDeleteNode() client does not have permission to delete all elements in this node <%08x>"), aElementId); |
|
1543 User::Leave(KErrPermissionDenied); |
|
1544 } |
|
1545 |
|
1546 CleanupStack::PopAndDestroy(&nodes); |
|
1547 } |
|
1548 |
|
1549 CleanupStack::PopAndDestroy(&placeholders); |
|
1550 } |
|
1551 |
|
1552 // find all relevant items |
|
1553 err = StorageL()->FindL(aElementId & ~iWriteAttributeMask, mask, ids); |
|
1554 |
|
1555 if(CommsDatSchema::IsGenericRecord(aElementId)) |
|
1556 { |
|
1557 TUint32 checkid = KCDMaskShowRecordId; |
|
1558 TInt instanceid; |
|
1559 while((instanceid = ids.Find(checkid,TIdentityRelation<TUint32>(CompareInstance))) != KErrNotFound) |
|
1560 { |
|
1561 ids.Remove(instanceid); |
|
1562 } |
|
1563 ids.Compress(); |
|
1564 } |
|
1565 |
|
1566 |
|
1567 if (ids.Count() > 0) |
|
1568 { |
|
1569 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::MaybeDeleteNode() for id <%08x> CRepository::FindL() with mask <%08x> returned %d entries"), aElementId, mask, ids.Count()); |
|
1570 // delete everything in a batch |
|
1571 for (TInt i = 0; i < ids.Count(); i++) |
|
1572 { |
|
1573 err = StorageL()->Delete(ids[i]); |
|
1574 #ifndef __TOOLS2__ |
|
1575 NotifierL()->MaybeNotifyChangeForDelete(ids[i], 0); |
|
1576 #endif |
|
1577 } |
|
1578 // reset NotNull flag |
|
1579 aElementId &= ~KCDNotNullFlag; |
|
1580 } |
|
1581 else |
|
1582 { |
|
1583 __FLOG_STATIC3(KLogComponent, KCDInfoLog, _L("CMDBSessionImpl::MaybeDeleteNode() for id <%08x> CRepository::FindL() with mask <%08x> returned err %d"), aElementId, mask, err); |
|
1584 } |
|
1585 |
|
1586 CleanupStack::PopAndDestroy(&ids); |
|
1587 } |
|
1588 |
|
1589 return err; |
|
1590 } |
|
1591 |
|
1592 |
|
1593 |
|
1594 |
|
1595 TInt CMDBSessionImpl::FindMatchL(RArray<TUint32>& aCandidates, RArray<TUint32>& aMatches, TUint32 aIdMask) |
|
1596 /* |
|
1597 Utility function to match a CMDBElement with a list of possible candidates by id. |
|
1598 |
|
1599 @internalComponent |
|
1600 */ |
|
1601 { |
|
1602 |
|
1603 TInt retval = KErrNotFound; |
|
1604 |
|
1605 //ignore template record |
|
1606 if ( aCandidates.Count() ) |
|
1607 { |
|
1608 if ( (aCandidates[0] & KCDMaskShowRecordId) == KCDDefaultRecord ) |
|
1609 { |
|
1610 aCandidates.Remove(0); |
|
1611 } |
|
1612 } |
|
1613 |
|
1614 if ( aCandidates.Count() && aMatches.Count()) |
|
1615 { |
|
1616 TInt count(aMatches.Count()); |
|
1617 while(count--) |
|
1618 { |
|
1619 if(KErrNotFound == aCandidates.Find(aMatches[count],TIdentityRelation<TUint32>(CompareInstance))) |
|
1620 { |
|
1621 aMatches.Remove(count); |
|
1622 } |
|
1623 } |
|
1624 aMatches.Compress(); |
|
1625 } |
|
1626 else if ( aCandidates.Count()) |
|
1627 { |
|
1628 for (TInt i = 0; i < aCandidates.Count(); i++) |
|
1629 { |
|
1630 retval = aMatches.Append(aCandidates[i] | aIdMask); |
|
1631 |
|
1632 if (retval != KErrNone) |
|
1633 { |
|
1634 aMatches.Close(); |
|
1635 if (retval == KErrNoMemory) |
|
1636 { |
|
1637 User::Leave(KErrNoMemory); |
|
1638 } |
|
1639 } |
|
1640 } |
|
1641 } |
|
1642 |
|
1643 if ( aMatches.Count() ) |
|
1644 { |
|
1645 retval = KErrNone; |
|
1646 } |
|
1647 |
|
1648 return retval; |
|
1649 |
|
1650 } |
|
1651 |
|
1652 |
|
1653 |
|
1654 //EOF |