commsfwtools/preparedefaultcommsdatabase/src/CommsDatSessionImpl.cpp
changeset 0 dfb7c4ff071f
child 25 9d7ce34704c8
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     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