commsconfig/commsdatabaseshim/commdbshim/SCDB/commdb_impl.cpp
changeset 0 dfb7c4ff071f
child 48 07656293a99c
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2006-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 // Comms Database Table View defintions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @deprecated since v9.1. Functionality is replaced with commsdat.
       
    21 */
       
    22 
       
    23 #include <cdbtemp.h>
       
    24 #include <commdb.h>
       
    25 #include <cdbpreftable.h>
       
    26 #include <commsdat_partner.h>
       
    27 #include <commsdattypesv1_1_partner.h>
       
    28 
       
    29 #include "commdb_impl.H"
       
    30 #include "Commsdat_Log.h"
       
    31 #include "commsdattypeinfov1_1_internal.h"
       
    32 
       
    33 const TInt KFirstRecord = 0;
       
    34 
       
    35 // Additional funtions to implement Connection Preference table protection - in a separate
       
    36 // class so as not to break BC.
       
    37 CCommDbTableExtension::CCommDbTableExtension()
       
    38 /**
       
    39 Constructor
       
    40 */
       
    41     {
       
    42     }
       
    43 
       
    44 CCommDbTableExtension* CCommDbTableExtension::NewL()
       
    45 	{
       
    46 	CCommDbTableExtension* self = new(ELeave) CCommDbTableExtension;
       
    47 	TInt err = self->iCommitSeqProperty.Attach(KUidCommsDatStatusEvent, KCommsDatStatusEventCommitSeq);
       
    48 	if(err != KErrNone)
       
    49 		{
       
    50 		delete self;
       
    51 		User::Leave(err);
       
    52 		}
       
    53 	return self;
       
    54 	}
       
    55 
       
    56 void CCommDbTableExtension::GetRecordInfoL(const TDesC& aColumn, TDbColType& aColType, TUint32& aAttrib)
       
    57 	{
       
    58 	CMDBRecordSetBase* recSet = GetRecordSetL();
       
    59 	
       
    60 	TBuf<KCommsDbSvrMaxColumnNameLength> buf; // This holds Column name
       
    61 	TBool found(EFalse);
       
    62 	
       
    63 	// create dummy record to read info from it
       
    64 	CMDBRecordBase* dummyRecord = CCDRecordBase::RecordFactoryL(recSet->TypeId());
       
    65 	const SRecordTypeInfo* recordInfo = dummyRecord->GetRecordInfo();
       
    66 
       
    67 	// Loop through all the columns of the record
       
    68 	while(recordInfo->iTypeId != 0 && !found)
       
    69 		{
       
    70 		// Get name of the field into buffer
       
    71 		buf = recordInfo->iTypeName;
       
    72 		
       
    73 		if(buf.CompareF(aColumn) == 0)
       
    74 			{
       
    75 			found = ETrue;
       
    76 			}
       
    77 		else
       
    78 			{
       
    79 			// Switch to Next column
       
    80 			recordInfo++;
       
    81 			}
       
    82 		}
       
    83 	
       
    84 	// check if column is not found
       
    85 	if(!found)
       
    86 		{
       
    87 		delete dummyRecord;
       
    88 		User::Leave(KErrNotFound);
       
    89 		}
       
    90 	else
       
    91 		{
       
    92 		aColType = GetColType(recordInfo->iValType);
       
    93 		recordInfo->iTypeAttr == ENotNull ? aAttrib = TDbCol::ENotNull : aAttrib = 0;
       
    94 		}
       
    95 	
       
    96 	delete dummyRecord;
       
    97 	}
       
    98 
       
    99 TDbColType CCommDbTableExtension::GetColType(TInt aType)
       
   100     {
       
   101     TDbColType ret;
       
   102     switch(aType)
       
   103         {
       
   104         case EText:
       
   105         case EMedText:
       
   106             ret = EDbColText16;
       
   107             break;
       
   108         case ELongText:
       
   109             ret = EDbColLongText;
       
   110             break;
       
   111         case EDesC8:
       
   112             ret = EDbColText8;
       
   113             break;
       
   114         case EUint32:
       
   115             ret = EDbColUint32;
       
   116             break;
       
   117         case EInt:
       
   118             ret = EDbColUint32;
       
   119             break;
       
   120         case EBool:
       
   121             ret = EDbColBit;
       
   122             break;
       
   123         default:
       
   124             ret = EDbColInt32;
       
   125         }
       
   126 
       
   127     return ret;
       
   128     }
       
   129 
       
   130 TInt CCommDbTableExtension::GetMaxTypeLength(TInt aType)
       
   131     {
       
   132     TInt ret;
       
   133 
       
   134     switch(aType)
       
   135         {
       
   136         case EText:
       
   137             ret = KMaxTextLength;
       
   138             break;
       
   139         case EDesC8:
       
   140             ret = KMaxTextLength;
       
   141             break;
       
   142         case EUint32:
       
   143             ret = KMaxNumLength;
       
   144             break;
       
   145         case EInt:
       
   146             ret = KMaxNumLength;
       
   147             break;
       
   148         case EBool:
       
   149             ret = KMaxNumLength;
       
   150             break;
       
   151         case ELongText:
       
   152             ret = KMaxLongTextLength;
       
   153             break;
       
   154         case EMedText:
       
   155             ret = KMaxMedTextLength;
       
   156             break;
       
   157         default:
       
   158             ret = 0;
       
   159         }
       
   160 
       
   161     return ret;
       
   162     }
       
   163 
       
   164 void CCommDbTableExtension::UpdateLastCommitSeq()
       
   165 	{
       
   166 	// Update the global commit sequence, for detecting possible changes when deciding whether to refresh records
       
   167 	TInt currCommitSeq;
       
   168     if(iCommitSeqProperty.Get(currCommitSeq) == KErrNone)
       
   169 		{
       
   170 		iLastCommitSeq = currCommitSeq;
       
   171 		}
       
   172 	}
       
   173 
       
   174 TInt CCommDbTableExtension::MaybeRefreshCurrentRecord(CMDBSession& aDbs)
       
   175 	{
       
   176 	// If the global commit sequence number differs from the last one set or observed by us then we need to refresh to ensure we
       
   177 	// acquire any relevant changes
       
   178 	TInt err = KErrNone;
       
   179 	TInt currCommitSeq = iLastCommitSeq;
       
   180     if(iCommitSeqProperty.Get(currCommitSeq) != KErrNone || currCommitSeq != iLastCommitSeq)
       
   181 		{
       
   182 	    TRAP(err,iCurrentRecord->RefreshL(aDbs));
       
   183 		if(err == KErrNone)
       
   184 			{
       
   185 			iLastCommitSeq = currCommitSeq;
       
   186 			}
       
   187 		}
       
   188 	return err;
       
   189 	}
       
   190 
       
   191 TInt CCommDbTableExtension::GotoFirstRecord(CMDBSession& aDbs)
       
   192     {
       
   193 	TInt err(KErrNotFound);
       
   194 	
       
   195 	TInt countContRec = iRecordSetContainer->iRecords.Count();
       
   196 	
       
   197     if (iRecordSetContainer && countContRec)
       
   198         {
       
   199 		// set up stating point
       
   200 		iCurrentRecord = NULL;
       
   201 		// set up first valid record
       
   202 		TInt valid = FindFirstNextValidRecord(ETrue);
       
   203 
       
   204 		if(valid)
       
   205 			{
       
   206 			// save current record before change
       
   207 			CMDBRecordBase* currRecBackup(iCurrentRecord);
       
   208 
       
   209             if ( iCurrentRecord->RecordId() == KCDDefaultRecord  &&
       
   210                  (iCurrentRecord->Attributes() & ECDHidden ) &&
       
   211                  ! aDbs.IsSetAttributeMask(ECDHidden) )
       
   212                 {
       
   213                 err = GotoNextRecord(aDbs); 
       
   214                 }
       
   215             else 
       
   216                 {
       
   217 			    err = MaybeRefreshCurrentRecord(aDbs);
       
   218 				if (err != KErrNone) 
       
   219 					{
       
   220 					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoFirstRecord failed to Refresh the data Err=%d"),err);
       
   221 					iCurrentRecord = currRecBackup;
       
   222 					}
       
   223                 }
       
   224 			}
       
   225 
       
   226 		iEndOfTableRecordBackup = NULL;
       
   227 		iBeginingOfTableRecordBackup = NULL;
       
   228         }
       
   229 
       
   230     // record set is empty
       
   231     return err;
       
   232     }
       
   233 
       
   234 TInt CCommDbTableExtension::GotoNextRecord(CMDBSession& aDbs)
       
   235     {
       
   236     TInt err(KErrNone);
       
   237 	TInt currIndex(0);
       
   238 	
       
   239 	if (!iRecordSetContainer) 
       
   240 		{
       
   241 		return KErrNotFound;
       
   242 		}
       
   243 	
       
   244     if (iCurrentRecord)
       
   245         {
       
   246         TInt count = iRecordSetContainer->iRecords.Count();
       
   247 		currIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
       
   248         if (currIndex == count-1)
       
   249             {
       
   250             // record set is either empty or going out of scope
       
   251             err = KErrNotFound;
       
   252 			// the marker is going beyond end of the table, so backup last record and use the value as end marker
       
   253 			iEndOfTableRecordBackup = iCurrentRecord;
       
   254 			iCurrentRecord = NULL;
       
   255             }
       
   256         else
       
   257             {
       
   258 			// save current record before change
       
   259 			CMDBRecordBase* currRecBackup(iCurrentRecord);
       
   260 			// set up first next valid record
       
   261 			TInt valid = FindFirstNextValidRecord(EFalse);
       
   262 			if (valid) 
       
   263 				{
       
   264 			    err = MaybeRefreshCurrentRecord(aDbs);
       
   265 				if (err != KErrNone) 
       
   266 					{
       
   267 					// return to status prior to failure
       
   268 					iCurrentRecord = currRecBackup;
       
   269 					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoNextRecord failed to Refresh the data Err=%d"),err);
       
   270 					}
       
   271 				}
       
   272 			else
       
   273 				{
       
   274 				err = KErrNotFound;
       
   275 				}
       
   276             }
       
   277         }
       
   278     else
       
   279     	{
       
   280 		// if position was on the begining of the table then retrieve back first record and set up begining of table marker to null
       
   281         if (iBeginingOfTableRecordBackup)
       
   282 			{
       
   283 			iCurrentRecord = iBeginingOfTableRecordBackup;
       
   284 			iBeginingOfTableRecordBackup = NULL;
       
   285 			}
       
   286 		else
       
   287 	        {
       
   288 	        err = KErrNotFound;
       
   289 	        }
       
   290     	}
       
   291 
       
   292     return err;
       
   293     }
       
   294 
       
   295 TInt CCommDbTableExtension::GotoPreviousRecord(CMDBSession& aDbs)
       
   296     {
       
   297     TInt err = KErrNone;
       
   298 
       
   299 	if (!iRecordSetContainer) 
       
   300 		{
       
   301 		return KErrNotFound;
       
   302 		}
       
   303 	
       
   304     if (iCurrentRecord)
       
   305         {
       
   306         const TInt count = iRecordSetContainer->iRecords.Count();
       
   307 		TInt currIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
       
   308         if (currIndex == 0)
       
   309             {
       
   310             // record set is either empty or going out of scope
       
   311             err = KErrNotFound;
       
   312             }
       
   313         else
       
   314             {
       
   315 			// save current record before change
       
   316 			CMDBRecordBase* currRecBackup(iCurrentRecord);
       
   317 			// set up first prev valid record
       
   318 			TInt valid = FindFirstPrevValidRecord();
       
   319 			if (valid) 
       
   320 				{
       
   321 			    err = MaybeRefreshCurrentRecord(aDbs);
       
   322 				if (err != KErrNone) 
       
   323 					{
       
   324 					// return to status prior to failure
       
   325 					iCurrentRecord = currRecBackup;
       
   326 					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoPreviousRecord failed to Refresh the data Err=%d"),err);
       
   327 					}
       
   328 				}
       
   329 			else
       
   330 				{
       
   331 				err = KErrNotFound;
       
   332 				}
       
   333             }
       
   334         }
       
   335     else
       
   336         {
       
   337 		// if position was on the end of the table then retrieve back last record and set up end of table marker to null
       
   338         if (iEndOfTableRecordBackup) 
       
   339 			{
       
   340 			iCurrentRecord = iEndOfTableRecordBackup;
       
   341 			iEndOfTableRecordBackup = NULL;
       
   342 			}
       
   343 		else
       
   344 			{
       
   345 	        err = KErrNotFound;
       
   346 			}
       
   347         }
       
   348 
       
   349     return err;
       
   350     }
       
   351 
       
   352 void CCommDbTableExtension::InsertConnPrefRecordL(CCDConnectionPrefsRecord* aConnPref, CMDBSession& aDbs)
       
   353 	{
       
   354 	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::InsertConnPrefRecordL -> Entry Point"));
       
   355 
       
   356 	CMDBRecordSetBase* recSet = GetRecordSetL();
       
   357 
       
   358 	// store newly created record
       
   359 	aConnPref->SetRecordId(KCDNewRecordRequest);
       
   360 
       
   361 	aConnPref->StoreL(aDbs);
       
   362 	User::LeaveIfError(recSet->iRecords.Append(aConnPref));
       
   363 	
       
   364 	iCurrentRecord = recSet->iRecords[recSet->iRecords.Count()-1];
       
   365 	iInsertedRecords.Insert(iCurrentRecord->RecordId(), KFirstRecord);
       
   366 	
       
   367 	TInt index = iDeletedRecords.Find(iCurrentRecord->RecordId());
       
   368 	
       
   369 	// check if inserted record has the same record id as previously deleted record	
       
   370 	if(index>=0)
       
   371 		{
       
   372 		iDeletedRecords.Remove(index);
       
   373 		}
       
   374 
       
   375 	SortByRank();
       
   376 	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::InsertConnPrefRecordL -> Record Inserted"));
       
   377 	}
       
   378 
       
   379 
       
   380 TBool CCommDbTableExtension::IsGenericRecord(TMDBElementId aElementId) const
       
   381     {
       
   382     const TMDBElementId tableType = (aElementId & KCDMaskShowRecordType);
       
   383     return (tableType >= KCDInitialUDefRecordType);
       
   384     }
       
   385 
       
   386 void CCommDbTableExtension::InsertRecordL(TBool aCopy, TUint32& aId, CMDBSession& aDbs, TBool aIsTemplate)
       
   387 /**
       
   388 Deletes the current record from commsdat and from queue.
       
   389 Updates the value of record index.
       
   390 */
       
   391     {
       
   392 	CMDBRecordSetBase* recSet = GetRecordSetL();
       
   393 	// storing empty string in order to get RecordId for newly inserted record
       
   394 	CMDBRecordBase* newRecord;
       
   395 	
       
   396 	if(aCopy)
       
   397 		{
       
   398 		CMDBRecordBase* record = GetCurrentRecordL();
       
   399 		newRecord = CCDRecordBase::CreateCopyRecordL(*record);
       
   400 		CleanupStack::PushL(newRecord);
       
   401 		if(IsGenericRecord(newRecord->ElementId()))
       
   402 			{
       
   403 			newRecord->LoadL(aDbs);
       
   404 			}		
       
   405 		}
       
   406 	else
       
   407 		{
       
   408 		newRecord = CCDRecordBase::RecordFactoryL(recSet->TypeId());
       
   409 		CleanupStack::PushL(newRecord);
       
   410 		if(IsGenericRecord(newRecord->ElementId()))
       
   411 			{
       
   412 			newRecord->LoadL(aDbs);
       
   413 			}	
       
   414 		}
       
   415 	
       
   416     TBool removeHiddenMask = EFalse;
       
   417 	if(aIsTemplate)
       
   418 		{
       
   419 		// this will mark record as template record
       
   420 		newRecord->SetRecordId(KCDDefaultRecord);
       
   421         if (! aDbs.IsSetAttributeMask(ECDHidden))
       
   422             {
       
   423             aDbs.SetAttributeMask(ECDHidden);
       
   424             removeHiddenMask = ETrue;
       
   425             }
       
   426 		}
       
   427 	else
       
   428 		{
       
   429 		// this will give next valid record number
       
   430 		newRecord->SetRecordId(KCDNewRecordRequest);		
       
   431 		}
       
   432 	
       
   433 	// create and store record placeholder
       
   434 	newRecord->StoreL(aDbs);
       
   435 
       
   436     if (removeHiddenMask)
       
   437         {
       
   438         aDbs.ClearAttributeMask(ECDHidden);
       
   439         }
       
   440 
       
   441 	// check if inserted record has the same record id as previously deleted record
       
   442 	TInt index = iDeletedRecords.Find(newRecord->RecordId());
       
   443 	
       
   444 	if(index >= 0)
       
   445 		{
       
   446 		iDeletedRecords.Remove(index);
       
   447 		}
       
   448 
       
   449 	// append inserted record
       
   450 	User::LeaveIfError(recSet->iRecords.Append(newRecord));
       
   451 	CleanupStack::Pop(newRecord);
       
   452 	
       
   453 	iCurrentRecord = newRecord;
       
   454 	iInsertedRecords.Insert(iCurrentRecord->RecordId(), KFirstRecord);
       
   455 	SortById();
       
   456 	
       
   457 	aId = newRecord->RecordId();
       
   458 	}
       
   459 
       
   460 TInt CCommDbTableExtension::CancelRecordChanges(CMDBSession& aDbs)
       
   461 	{
       
   462 	TInt err = KErrNone;
       
   463 	if (!iRecordSetContainer)
       
   464 		{
       
   465 		return KErrNotFound;
       
   466 		}
       
   467 	
       
   468 	TRAP(err,iCurrentRecord->LoadL(aDbs));
       
   469 	if (err != KErrNone) 
       
   470 		{
       
   471 		// return to status prior to failure
       
   472 		__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::CancelRecordChanges failed to Refresh the data, Err=%d"),err);
       
   473 		return err;
       
   474 		}
       
   475 	
       
   476 	if (iInsertedRecords.Count()) 
       
   477 		{
       
   478 		TInt index = FindValueInRecSet(iInsertedRecords[KFirstRecord]);
       
   479 		
       
   480 		if(index >= 0)
       
   481 			{
       
   482 			delete iRecordSetContainer->iRecords[index];
       
   483 			iRecordSetContainer->iRecords.Remove(index);
       
   484 			iRecordSetContainer->iRecords.Compress();
       
   485 			// reuse index variable
       
   486 			index = iRecordSetContainer->iRecords.Count();
       
   487 			index ? iCurrentRecord = iRecordSetContainer->iRecords[index-1] : iCurrentRecord = NULL;
       
   488 			}
       
   489 		}
       
   490 
       
   491 	ResetArrays(aDbs);
       
   492 	
       
   493 	return err;
       
   494 	}
       
   495 
       
   496 void CCommDbTableExtension::ResetArrays(CMDBSession& aSession) 
       
   497 	{
       
   498 	if(!aSession.IsInTransaction())
       
   499 		{
       
   500 		iInsertedRecords.Reset();
       
   501 		iDeletedRecords.Reset();
       
   502 		}
       
   503 	// else they will be reseted on Commit or Rolback Transaction
       
   504 	}
       
   505 
       
   506 void CCommDbTableExtension::ResetAndDestroyL() 
       
   507 	{
       
   508 	GetRecordSetL()->iRecords.ResetAndDestroy();
       
   509 	iCurrentRecord = NULL;
       
   510 	}
       
   511 
       
   512 void CCommDbTableExtension::DeleteCurrentRecordL(CMDBSession& aDbs, TBool aContainerOnly)
       
   513 /**
       
   514 Deletes the current record from commsdat and from queue.
       
   515 Updates the value of record index.
       
   516 */
       
   517     {
       
   518     // check for validity of current record through GetCurrentRecord call
       
   519     CMDBRecordBase* currRec = GetCurrentRecordL();
       
   520     /* TODO: Add iShowHidden in conditions. This might not be necessary checking */
       
   521     /*if(iRecordIndex == 0) 
       
   522         {
       
   523         // it is not possible to delete template record
       
   524         User::Leave(KErrNotSupported);
       
   525         }*/
       
   526 	if(!aContainerOnly)
       
   527 		{
       
   528 		if (currRec->IsSetAttribute(ECDProtectedWrite))
       
   529     		{
       
   530     		User::Leave(KErrAccessDenied);
       
   531     		}
       
   532 		
       
   533 		User::LeaveIfError(iDeletedRecords.Append(currRec->RecordId()));
       
   534 		
       
   535 		__FLOG_STMT(TInt count = iDeletedRecords.Count();)
       
   536 		__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::DeleteCurrentRecordL added to deleted record queue, as No:%d"), count);
       
   537     	
       
   538     	currRec->DeleteL(aDbs);
       
   539 		}
       
   540 
       
   541 	TInt currIndex = iRecordSetContainer->iRecords.Find(currRec);
       
   542 
       
   543 	iCurrentRecord = NULL;
       
   544 	
       
   545 	// If we just deleted the last or first non-deleted record then update the appropriate "backup" so that a next/prev
       
   546 	// will work
       
   547 	TInt probeIndex = currIndex;
       
   548 	iBeginingOfTableRecordBackup = NULL;
       
   549 	iEndOfTableRecordBackup = NULL;
       
   550 	if(!AdvanceIndexToPrevValidRecord(probeIndex))
       
   551 		{
       
   552 		// Deleted first record; Next from here should move to first record
       
   553 		probeIndex = currIndex;
       
   554 		if(AdvanceIndexToNextValidRecord(probeIndex))
       
   555 			{
       
   556 			iBeginingOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
       
   557 			}
       
   558 		}
       
   559 	else
       
   560 		{
       
   561 		iBeginingOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
       
   562 		}
       
   563 	probeIndex = currIndex;
       
   564 	if(!AdvanceIndexToNextValidRecord(probeIndex))
       
   565 		{
       
   566 		// Deleted last record; Prev from here should move to last record
       
   567 		probeIndex = currIndex;
       
   568 		if(AdvanceIndexToPrevValidRecord(probeIndex))
       
   569 			{
       
   570 			iEndOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
       
   571 			}
       
   572 		}
       
   573 	else
       
   574 		{
       
   575 		iEndOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
       
   576 		}
       
   577 
       
   578 	if(!aContainerOnly)
       
   579 		{
       
   580 		// remove an entry from container
       
   581 		delete iRecordSetContainer->iRecords[currIndex];
       
   582 		iRecordSetContainer->iRecords.Remove(currIndex);
       
   583 		iRecordSetContainer->iRecords.Compress();
       
   584 		}
       
   585     }
       
   586 
       
   587 void CCommDbTableExtension::SetRecordSet(CMDBRecordSetBase* aRecordSetContainer)
       
   588     {
       
   589     iRecordSetContainer = aRecordSetContainer;
       
   590 	TInt currIndex = iRecordSetContainer->iRecords.Count();
       
   591 
       
   592 	currIndex == 0 ? iCurrentRecord = NULL : iCurrentRecord = iRecordSetContainer->iRecords[0];
       
   593 	
       
   594 	#ifdef _DEBUG
       
   595        	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("Start of Table Contents"));
       
   596 		CCDRecordBase* ptrTemp;
       
   597 		CMDBRecordBase* currRec;
       
   598 		CMDBRecordSetBase* recSet = static_cast<CMDBRecordSetBase*>(iRecordSetContainer);
       
   599 		TInt count = recSet->iRecords.Count();
       
   600 		for(TInt i=0;i<count;++i)
       
   601 			{
       
   602 	        currRec = recSet->iRecords[i];
       
   603 			ptrTemp = static_cast<CCDRecordBase*>(currRec);
       
   604 			const TDesC& field = ptrTemp->iRecordName;
       
   605 			
       
   606 			__FLOG_STATIC3(KLogComponent, KCommDbShim, _L("Record[%d], RecordId:%d, RecordName:%S"),
       
   607 				i, currRec->RecordId(), &field);
       
   608 			}
       
   609        	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("End of Table Contents"));
       
   610 	#endif
       
   611     };
       
   612 
       
   613 CMDBRecordSetBase* CCommDbTableExtension::RecordSetFactoryL(const TDesC& aTableName, TBool preparePriming, CMDBSession& aDbs)
       
   614 	{
       
   615 	TMDBElementId recordSetId = 0;
       
   616 	CMDBRecordSetBase* recordSetContainer = NULL;
       
   617 	
       
   618     if (aTableName.CompareF(TPtrC(KCDTypeNameConnectionPrefs)) == 0)
       
   619         {
       
   620         // connection preferance needs to be created via CommDbConnectionPref class
       
   621         User::Leave(KErrNotSupported);
       
   622         }
       
   623 	else if (aTableName.CompareF(TPtrC(KCDTypeNameGlobalSettings)) == 0)
       
   624         {
       
   625 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDGlobalSettingsRecord>(KCDTIdGlobalSettingsRecord);
       
   626 		recordSetId = KCDTIdGlobalSettingsRecord;
       
   627 		}
       
   628     else if (aTableName.CompareF(TPtrC(KCDTypeNameNetwork)) == 0)
       
   629         {
       
   630 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDNetworkRecord>(KCDTIdNetworkRecord);
       
   631         recordSetId = KCDTIdNetworkRecord;
       
   632         }
       
   633     else if (aTableName.CompareF(TPtrC(KCDTypeNameLocation)) == 0)
       
   634         {
       
   635 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLocationRecord>(KCDTIdLocationRecord);
       
   636         recordSetId = KCDTIdLocationRecord;
       
   637         }
       
   638     else if (aTableName.CompareF(TPtrC(KCDTypeNameIAP)) == 0)
       
   639         {
       
   640 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDIAPRecord>(KCDTIdIAPRecord);
       
   641         recordSetId = KCDTIdIAPRecord;
       
   642         }
       
   643     else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPAccessPoint)) == 0)
       
   644         {
       
   645 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPAccessPointRecord>(KCDTIdWAPAccessPointRecord);
       
   646         recordSetId = KCDTIdWAPAccessPointRecord;
       
   647         }
       
   648     else if (aTableName.CompareF(TPtrC(KCDTypeNameDialOutISP)) == 0)
       
   649         {
       
   650 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDDialOutISPRecord>(KCDTIdDialOutISPRecord);
       
   651         recordSetId = KCDTIdDialOutISPRecord;
       
   652         }
       
   653     else if (aTableName.CompareF(TPtrC(KCDTypeNameDialInISP)) == 0)
       
   654         {
       
   655 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDDialInISPRecord>(KCDTIdDialInISPRecord);
       
   656         recordSetId = KCDTIdDialInISPRecord;
       
   657         }
       
   658     else if (aTableName.CompareF(TPtrC(KCDTypeNameLANService)) == 0)
       
   659         {
       
   660 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLANServiceRecord>(KCDTIdLANServiceRecord);
       
   661         recordSetId = KCDTIdLANServiceRecord;
       
   662         }
       
   663     else if (aTableName.CompareF(TPtrC(KCDTypeNameWLANServiceExt)) == 0)
       
   664         {
       
   665 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWLANServiceExtRecord>(KCDTIdWLANServiceExtRecord);
       
   666         recordSetId = KCDTIdWLANServiceExtRecord;
       
   667         }
       
   668     else if (aTableName.CompareF(TPtrC(KCDTypeNamePANServiceExt)) == 0)
       
   669         {
       
   670 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDPANServiceExtRecord>(KCDTIdPANServiceExtRecord);
       
   671         recordSetId = KCDTIdPANServiceExtRecord;
       
   672         }
       
   673     else if (aTableName.CompareF(TPtrC(KCDTypeNameVPNService)) == 0)
       
   674         {
       
   675 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDVPNServiceRecord>(KCDTIdVPNServiceRecord);
       
   676         recordSetId = KCDTIdVPNServiceRecord;
       
   677         }
       
   678     else if (aTableName.CompareF(TPtrC(KCDTypeNameDefaultWCDMA)) == 0)
       
   679         {
       
   680 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWCDMAPacketServiceRecord>(KCDTIdDefaultWCDMARecord);
       
   681         recordSetId = KCDTIdDefaultWCDMARecord;
       
   682         }
       
   683     else if (aTableName.CompareF(TPtrC(KCDTypeNameIncomingWCDMA)) == 0)
       
   684         {
       
   685 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDIncomingGprsRecord>(KCDTIdIncomingGprsRecord);
       
   686         recordSetId = KCDTIdIncomingGprsRecord;
       
   687         }
       
   688     else if (aTableName.CompareF(TPtrC(KCDTypeNameOutgoingWCDMA)) == 0)
       
   689         {
       
   690 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDOutgoingGprsRecord>(KCDTIdOutgoingGprsRecord);
       
   691         recordSetId = KCDTIdOutgoingGprsRecord;
       
   692         }
       
   693     else if (aTableName.CompareF(TPtrC(KCDTypeNameModemBearer)) == 0 || aTableName.CompareF(TPtrC(OLD_MODEM_TABLE)) == 0)
       
   694         {
       
   695 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDModemBearerRecord>(KCDTIdModemBearerRecord);
       
   696         recordSetId = KCDTIdModemBearerRecord;
       
   697         }
       
   698     else if (aTableName.CompareF(TPtrC(KCDTypeNameLANBearer)) == 0)
       
   699         {
       
   700 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLANBearerRecord>(KCDTIdLANBearerRecord);
       
   701         recordSetId = KCDTIdLANBearerRecord;
       
   702         }
       
   703     else if (aTableName.CompareF(TPtrC(KCDTypeNameVirtualBearer)) == 0)
       
   704         {
       
   705 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDVirtualBearerRecord>(KCDTIdVirtualBearerRecord);
       
   706         recordSetId = KCDTIdVirtualBearerRecord;
       
   707         }
       
   708     else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPSMSBearer)) == 0)
       
   709         {
       
   710 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPSMSBearerRecord>(KCDTIdWAPSMSBearerRecord);
       
   711         recordSetId = KCDTIdWAPSMSBearerRecord;
       
   712         }
       
   713     else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPIPBearer)) == 0)
       
   714         {
       
   715 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPIPBearerRecord>(KCDTIdWAPIPBearerRecord);
       
   716         recordSetId = KCDTIdWAPIPBearerRecord;
       
   717         }
       
   718     else if (aTableName.CompareF(TPtrC(KCDTypeNameChargecard)) == 0)
       
   719         {
       
   720 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDChargecardRecord>(KCDTIdChargecardRecord);
       
   721         recordSetId = KCDTIdChargecardRecord;
       
   722         }
       
   723     else if (aTableName.CompareF(TPtrC(KCDTypeNameProxies)) == 0)
       
   724         {
       
   725 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDProxiesRecord>(KCDTIdProxiesRecord);
       
   726         recordSetId = KCDTIdProxiesRecord;
       
   727         }
       
   728     else if (aTableName.CompareF(TPtrC(KCDTypeNameSSProto)) == 0)
       
   729         {
       
   730 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDSecureSocketRecord>(KCDTIdSSProtoRecord);
       
   731         recordSetId = KCDTIdSSProtoRecord;
       
   732         }
       
   733     else if (aTableName.CompareF(TPtrC(KCDTypeNameAgentLookup)) == 0)
       
   734         {
       
   735 		recordSetContainer = new (ELeave) CMDBRecordSet<CCDAgentLookupRecord>(KCDTIdAgentLookupRecord);
       
   736         recordSetId = KCDTIdAgentLookupRecord;
       
   737         }
       
   738     else
       
   739         {
       
   740         // Create a temporary example of the user defined record, in order to do the lookup by name and get the Id back.
       
   741         
       
   742         CMDBGenericRecord* tempUserDefinedRecord = static_cast<CMDBGenericRecord*>(CCDRecordBase::RecordFactoryL(0));
       
   743         CleanupStack::PushL(tempUserDefinedRecord);
       
   744     	tempUserDefinedRecord->InitializeL(aTableName, NULL);
       
   745         tempUserDefinedRecord->LoadL(aDbs);
       
   746 
       
   747         // Get the Id that we're interested in...
       
   748         recordSetId = tempUserDefinedRecord->TableId();
       
   749 
       
   750         // ..and validate it.
       
   751         if ((recordSetId & KCDMaskShowRecordType) < KCDInitialUDefRecordType)
       
   752             {
       
   753             User::Leave(KErrNotFound);
       
   754             }
       
   755         
       
   756         
       
   757 		recordSetContainer = new (ELeave) CMDBRecordSet<CMDBGenericRecord>(recordSetId);
       
   758 		
       
   759 		if (preparePriming)
       
   760 			{
       
   761 			CleanupStack::PushL(recordSetContainer);
       
   762 			recordSetContainer->iRecords.AppendL(tempUserDefinedRecord);	
       
   763 			CleanupStack::Pop(2);
       
   764 			}
       
   765 		else
       
   766 			{
       
   767 			CleanupStack::PopAndDestroy(tempUserDefinedRecord);
       
   768 			}
       
   769 		return recordSetContainer;			
       
   770         }
       
   771 
       
   772     if (preparePriming)
       
   773         {
       
   774 		CleanupStack::PushL(recordSetContainer);
       
   775 		CMDBRecordBase* record = CCDRecordBase::RecordFactoryL(recordSetId);
       
   776 		TInt err = recordSetContainer->iRecords.Append(record);
       
   777 		if(err != KErrNone)
       
   778 			{
       
   779 			delete record;
       
   780 			User::Leave(err);
       
   781 			}
       
   782 		CleanupStack::Pop(recordSetContainer);
       
   783         }
       
   784     return recordSetContainer;
       
   785 	}
       
   786 
       
   787 void CCommDbTableExtension::SetRecordSetL(const TDesC& aTableName, CMDBSession& aDbs, TBool aPreparePriming, TBool aLoadTable, TBool aTemplate)
       
   788 /**
       
   789 Sets the value of the member iRecordSetContainer
       
   790 */
       
   791     {
       
   792     __FLOG_STATIC1(KLogComponent, KCommDbShim, _L("SetRecordSetL -> TableName=%S"), &aTableName);
       
   793 
       
   794     // delete existing container
       
   795     delete iRecordSetContainer;
       
   796     iCurrentRecord = NULL;
       
   797 	
       
   798     TBool removeHiddenMask = EFalse;
       
   799 	if (aTemplate) 
       
   800 		{
       
   801 		// keeping BC compatibility
       
   802 		TRAPD(err, iRecordSetContainer = RecordSetFactoryL(aTableName, aPreparePriming, aDbs));
       
   803 		if (err == KErrNotFound) 
       
   804 			{
       
   805 			err = KErrArgument;
       
   806 			}
       
   807 		User::LeaveIfError(err);
       
   808         iRecordSetContainer->iRecords[0]->SetAttributes(ECDHidden);
       
   809         if (! aDbs.IsSetAttributeMask(ECDHidden))
       
   810             {
       
   811             aDbs.SetAttributeMask(ECDHidden);
       
   812             removeHiddenMask = ETrue;
       
   813             }
       
   814 		}
       
   815 		else
       
   816 		{
       
   817 		iRecordSetContainer = RecordSetFactoryL(aTableName, aPreparePriming, aDbs);
       
   818 		}
       
   819 	
       
   820     // load data
       
   821     if (aLoadTable)
       
   822         {
       
   823         TRAPD(err, iRecordSetContainer->LoadL(aDbs));
       
   824         // if table is empty don't leave
       
   825         if (err != KErrNone && err != KErrNotFound)
       
   826         	{
       
   827         	User::LeaveIfError(err);
       
   828         	}
       
   829        	#ifdef _DEBUG
       
   830         else
       
   831         	{
       
   832         	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("Start of Table Contents"));
       
   833 			CCDRecordBase* ptrTemp;
       
   834 			CMDBRecordBase* currRec;
       
   835 			CMDBRecordSetBase* recSet = static_cast<CMDBRecordSetBase*>(iRecordSetContainer);
       
   836 			TInt count = recSet->iRecords.Count();
       
   837 			for(TInt i=0;i<count;++i)
       
   838 				{
       
   839 		        currRec = recSet->iRecords[i];
       
   840 				ptrTemp = static_cast<CCDRecordBase*>(currRec);
       
   841 				const TDesC& field = ptrTemp->iRecordName;
       
   842 
       
   843 				__FLOG_STATIC3(KLogComponent, KCommDbShim, _L("Record[%d], RecordId:%d, RecordName:%S"),
       
   844 					i, currRec->RecordId(), &field);
       
   845 				}
       
   846 			__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("End of Table Contents"));
       
   847         	}
       
   848 		#endif
       
   849 
       
   850 		UpdateLastCommitSeq();
       
   851         }
       
   852 
       
   853     if (removeHiddenMask)
       
   854         {
       
   855         aDbs.ClearAttributeMask(ECDHidden);
       
   856         }
       
   857 
       
   858 
       
   859     // reset the index
       
   860 	TInt currIndex = iRecordSetContainer->iRecords.Count();
       
   861 	currIndex ?  iCurrentRecord = iRecordSetContainer->iRecords[0] : iCurrentRecord = NULL;
       
   862     }
       
   863 
       
   864 
       
   865 CMDBRecordSetBase* CCommDbTableExtension::GetRecordSetL()
       
   866 /**
       
   867 Gets the value of the member iRecordIndex
       
   868 
       
   869 @return A wrapper for an SQL string combined with a text comparison mode.
       
   870 */	{
       
   871     if (!iRecordSetContainer)
       
   872         {
       
   873         User::Leave(KErrNotFound);
       
   874         }
       
   875     return iRecordSetContainer;
       
   876     }
       
   877 
       
   878 TInt CCommDbTableExtension::GetRecordSet(CMDBRecordSetBase*& aRecSet)
       
   879     {
       
   880     TInt ret = KErrNone;
       
   881     if (!iRecordSetContainer)
       
   882         {
       
   883         ret = KErrNotFound;
       
   884         }
       
   885     else
       
   886         {
       
   887         aRecSet = iRecordSetContainer;
       
   888         }
       
   889     return ret;
       
   890     }
       
   891 
       
   892 TInt CCommDbTableExtension::GetCurrentRecord(CMDBRecordBase*& aRecord)
       
   893     {
       
   894     TInt index(0);
       
   895     TInt err = GetRecordSetIndex(index);
       
   896 
       
   897     aRecord = 0;
       
   898 
       
   899     if (err == KErrNone)
       
   900         {
       
   901         aRecord = iRecordSetContainer->iRecords[index];
       
   902         err = KErrNone;
       
   903         }
       
   904 
       
   905     return err;
       
   906     }
       
   907 
       
   908 CMDBRecordBase* CCommDbTableExtension::GetCurrentRecordL()
       
   909     {
       
   910     if(iCurrentRecord)
       
   911         {
       
   912         return iCurrentRecord;
       
   913         }
       
   914 
       
   915     User::Leave(KErrNotFound);
       
   916 
       
   917     return NULL;
       
   918     }
       
   919 
       
   920 TInt CCommDbTableExtension::GetRecordSetIndex(TInt &aIndex)
       
   921 /**
       
   922 Gets the value of the member iRecordIndex
       
   923 
       
   924 @return A wrapper for an SQL string combined with a text comparison mode.
       
   925 */
       
   926     {
       
   927     TInt err = KErrNotFound;
       
   928 
       
   929     if(iRecordSetContainer)
       
   930         {
       
   931         if (iCurrentRecord)
       
   932             {
       
   933             aIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
       
   934             err = KErrNone;
       
   935             }
       
   936         }
       
   937 
       
   938     return err;
       
   939     }
       
   940 
       
   941 TInt CCommDbTableExtension::GetRecordSetIndexL()
       
   942 /**
       
   943 Gets the value of the member iRecordIndex
       
   944 
       
   945 @return A wrapper for an SQL string combined with a text comparison mode.
       
   946 */
       
   947     {
       
   948     if (iCurrentRecord)
       
   949         {
       
   950         User::Leave(KErrNotFound);
       
   951         }
       
   952 
       
   953     return iRecordSetContainer->iRecords.Find(iCurrentRecord);
       
   954     }
       
   955 
       
   956 void CCommDbTableExtension::RefreshDatabaseL(CMDBSession& aDbs)
       
   957 /**
       
   958 Refresh the container
       
   959 */
       
   960 	{
       
   961 	if(iRecordSetContainer)
       
   962 		{
       
   963 		iRecordSetContainer->RefreshL(aDbs);
       
   964 		}
       
   965 	}
       
   966 
       
   967 CCommDbTableExtension::~CCommDbTableExtension()
       
   968 /**
       
   969 Deletes the memory allocated to the members iColSet, iQueryText and iAccess
       
   970 */
       
   971     {
       
   972     delete iRecordSetContainer;
       
   973 	iInsertedRecords.Reset();
       
   974 	iDeletedRecords.Reset();
       
   975 	iCommitSeqProperty.Close();
       
   976     }
       
   977 
       
   978 TInt CCommDbTableExtension::CompareRecordsById(const CMDBRecordBase& aLeft, const CMDBRecordBase& aRight)
       
   979 /**
       
   980 
       
   981 @param
       
   982 @return
       
   983 */
       
   984     {
       
   985     //We assume there can't be 2records with same record IDs
       
   986     return (aLeft.RecordId()) < (aRight.RecordId()) ? -1 : 1;
       
   987     }
       
   988 
       
   989 TInt CCommDbTableExtension::CompareRecordsByRank(
       
   990             const CMDBRecordBase& aLeft, const CMDBRecordBase& aRight)
       
   991 /**
       
   992 
       
   993 @param
       
   994 @param
       
   995 @return
       
   996 */
       
   997     {
       
   998     return ( ((CCDConnectionPrefsRecord&)aLeft).iRanking < ((CCDConnectionPrefsRecord&)aRight).iRanking) ? -1 : 1;
       
   999     }
       
  1000 
       
  1001 void CCommDbTableExtension::SortById()
       
  1002 /**
       
  1003     Sorting values in iRecordSetContainer by Id value
       
  1004 */
       
  1005     {
       
  1006     TLinearOrder<CMDBRecordBase> order(CompareRecordsById);
       
  1007 	if(iRecordSetContainer)
       
  1008 		{
       
  1009     	iRecordSetContainer->iRecords.Sort(order);
       
  1010 		}
       
  1011     }
       
  1012 
       
  1013 void CCommDbTableExtension::SortByRank()
       
  1014 /**
       
  1015 
       
  1016 @param
       
  1017 @return
       
  1018 */
       
  1019     {
       
  1020     TLinearOrder<CMDBRecordBase> order(CompareRecordsByRank);
       
  1021 	if(iRecordSetContainer)
       
  1022 		{
       
  1023 	    iRecordSetContainer->iRecords.Sort(order);
       
  1024 		}
       
  1025     }
       
  1026 
       
  1027 TInt CCommDbTableExtension::GetTableAccess(RDbRowSet::TAccess &aAccess)
       
  1028     {
       
  1029     if( ! iRecordSetContainer)
       
  1030         return KErrNotFound;
       
  1031 
       
  1032     if (iRecordSetContainer->IsSetAttribute(ECDProtectedWrite))
       
  1033        {
       
  1034        aAccess = RDbRowSet::EReadOnly;
       
  1035        }
       
  1036     else
       
  1037        {
       
  1038        aAccess = RDbRowSet::EUpdatable;
       
  1039        }
       
  1040     
       
  1041     return KErrNone;
       
  1042     }
       
  1043 
       
  1044 void CCommDbTableExtension::CommitTransaction()
       
  1045 	{
       
  1046 	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::CommitTransaction()"));
       
  1047 	// remove flags since everything is valid
       
  1048 	iInsertedRecords.Reset();
       
  1049 	iDeletedRecords.Reset();
       
  1050 	}
       
  1051 
       
  1052 void CCommDbTableExtension::RollBackTransaction()
       
  1053 	{
       
  1054 	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::RollBackTransaction()"));
       
  1055 
       
  1056  	// we don't need to keep inserted records anymore
       
  1057 	TInt index;
       
  1058 	for (TInt i = 0; i < iInsertedRecords.Count(); ++i) 
       
  1059 		{
       
  1060 		index = FindValueInRecSet(iInsertedRecords[i]);
       
  1061 
       
  1062 		if(index >= 0)
       
  1063 			{
       
  1064 			delete iRecordSetContainer->iRecords[index];
       
  1065 			iRecordSetContainer->iRecords.Remove(index);
       
  1066 			}
       
  1067 		}
       
  1068 	iRecordSetContainer->iRecords.Compress();
       
  1069 	index =	iRecordSetContainer->iRecords.Count();
       
  1070 	index ? iCurrentRecord = iRecordSetContainer->iRecords[index-1] : iCurrentRecord = NULL;
       
  1071 
       
  1072 	// remove flags since everything is returned to begining
       
  1073 	iInsertedRecords.Reset();
       
  1074 	iDeletedRecords.Reset();
       
  1075 	}
       
  1076 
       
  1077 TInt CCommDbTableExtension::GetCurrentRecordIndex() const
       
  1078 	{
       
  1079 	// If iCurrentRecord is valid then start with it, else start with most recently deleted record
       
  1080 	const TInt numRecs = iRecordSetContainer->iRecords.Count();
       
  1081 	TInt idx = -1;
       
  1082 	const TInt numDeleted = iDeletedRecords.Count();
       
  1083 	if(iCurrentRecord)
       
  1084 		{
       
  1085 		ASSERT(iDeletedRecords.Find(iCurrentRecord->RecordId()) == KErrNotFound);	// dbl-check it isn't somehow deleted too
       
  1086 		idx = iRecordSetContainer->iRecords.Find(iCurrentRecord);
       
  1087 		ASSERT(idx >= 0);
       
  1088 		}
       
  1089 	else 
       
  1090 		{
       
  1091 		if(numDeleted > 0)
       
  1092 			{
       
  1093 			idx = FindValueInRecSet(iDeletedRecords[numDeleted - 1]);
       
  1094 			}
       
  1095 		else
       
  1096 			{
       
  1097 			// No deleted records either, special case is going to -1, ie preparatory to advancing to first record
       
  1098 			}
       
  1099 		}
       
  1100 	return idx;
       
  1101 	}
       
  1102 	
       
  1103 TBool CCommDbTableExtension::AdvanceIndexToNextValidRecord(TInt& aIdx) const
       
  1104 	{
       
  1105 	// Advance to the next visible & not deleted in this view; hidden may not be visible
       
  1106 	const TInt numRecs = iRecordSetContainer->iRecords.Count();
       
  1107 	TInt idx;
       
  1108 	for(idx = aIdx + 1; idx < numRecs; ++idx)
       
  1109 		{
       
  1110 		CMDBRecordBase* rec = iRecordSetContainer->iRecords[idx];
       
  1111 		if(iDeletedRecords.Find(rec->RecordId()) >= 0)
       
  1112 			{
       
  1113 			continue;	// deleted are always invisible
       
  1114 			}
       
  1115 		if(iShowHidden || !rec->IsSetAttribute(ECDHidden))
       
  1116 			{
       
  1117 			break;
       
  1118 			}
       
  1119 		}
       
  1120 	if(idx < numRecs)
       
  1121 		{
       
  1122 		aIdx = idx;
       
  1123 		return ETrue;
       
  1124 		}
       
  1125 	return EFalse;
       
  1126 	}
       
  1127 
       
  1128 TBool CCommDbTableExtension::AdvanceIndexToPrevValidRecord(TInt& aIdx) const
       
  1129 	{
       
  1130 	// Advance to the previous visible & not deleted in this view; hidden may not be visible
       
  1131 	TInt idx;
       
  1132 	for(idx = aIdx - 1; idx >= 0; --idx)
       
  1133 		{
       
  1134 		CMDBRecordBase* rec = iRecordSetContainer->iRecords[idx];
       
  1135 		if(iDeletedRecords.Find(rec->RecordId()) >= 0)
       
  1136 			{
       
  1137 			continue;	// deleted are always invisible
       
  1138 			}
       
  1139 		if(iShowHidden || !rec->IsSetAttribute(ECDHidden))
       
  1140 			{
       
  1141 			break;
       
  1142 			}
       
  1143 		}
       
  1144 	if(idx >= 0)
       
  1145 		{
       
  1146 		aIdx = idx;
       
  1147 		return ETrue;
       
  1148 		}
       
  1149 	return EFalse;
       
  1150 	}
       
  1151 
       
  1152 TBool CCommDbTableExtension::FindFirstNextValidRecord(TBool aResetToStart)
       
  1153 	{
       
  1154 	TInt idx;
       
  1155 	if(aResetToStart)
       
  1156 		{
       
  1157 		iCurrentRecord = NULL;
       
  1158 		idx = -1;
       
  1159 		}
       
  1160 	else 
       
  1161 		{
       
  1162 		idx = GetCurrentRecordIndex();
       
  1163 		}
       
  1164 	if(!AdvanceIndexToNextValidRecord(idx))
       
  1165 		{
       
  1166 		return EFalse;
       
  1167 		}
       
  1168 	iCurrentRecord = iRecordSetContainer->iRecords[idx];
       
  1169 	__FLOG_STMT(TInt recNo = iRecordSetContainer->iRecords.Find(iCurrentRecord);)
       
  1170 	__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("GotoNextRecord -> CurrentRecord is RecNo:%d"), recNo);
       
  1171 	return ETrue;
       
  1172 	}
       
  1173 
       
  1174 TBool CCommDbTableExtension::FindFirstPrevValidRecord()
       
  1175 	{
       
  1176 	TInt idx = GetCurrentRecordIndex();
       
  1177 	if(!AdvanceIndexToPrevValidRecord(idx))
       
  1178 		{
       
  1179 		return EFalse;
       
  1180 		}
       
  1181 	iCurrentRecord = iRecordSetContainer->iRecords[idx];
       
  1182 	__FLOG_STMT(TInt recNo = iRecordSetContainer->iRecords.Find(iCurrentRecord);)
       
  1183 	__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("GotoPreviousRecord -> CurrentRecord is RecNo:%d"), recNo);
       
  1184 	return ETrue;
       
  1185 	}
       
  1186 
       
  1187 TInt CCommDbTableExtension::FindValueInRecSet(TInt aValue) const
       
  1188 	{
       
  1189 	// in case of insertion remove inserted record
       
  1190 	for(TInt index=0; index < iRecordSetContainer->iRecords.Count();index++)
       
  1191 		{
       
  1192 		if(iRecordSetContainer->iRecords[index]->RecordId() == aValue)
       
  1193 			{
       
  1194 			return index;
       
  1195 			}
       
  1196 		}
       
  1197 	
       
  1198 	return KErrNotFound;
       
  1199 	}
       
  1200 
       
  1201 //--------------------------------------------------------------------
       
  1202 //	CCommsDatabaseImpl
       
  1203 //--------------------------------------------------------------------
       
  1204 
       
  1205 CCommsDatabaseImpl::CCommsDatabaseImpl()
       
  1206 	:iHaveCheckedGSTableExists(EFalse), iDbs(NULL)
       
  1207 	{
       
  1208 	
       
  1209 	}
       
  1210 CCommsDatabaseImpl::~CCommsDatabaseImpl()
       
  1211 	{
       
  1212 	iTableViews.ResetAndDestroy();
       
  1213 	iConnPrefViews.ResetAndDestroy();
       
  1214 	
       
  1215 	//Cancel any pending notifications
       
  1216 	CancelRequestNotification();
       
  1217 	
       
  1218 	
       
  1219 	// do not delete iDbs before destroying the view arrays above
       
  1220 	delete iDbs;
       
  1221 	}
       
  1222 
       
  1223 void CCommsDatabaseImpl::RegisterViewL(CCommsDbTableView* aTable)
       
  1224 	{
       
  1225 	iTableViews.AppendL(aTable);
       
  1226 	}
       
  1227 
       
  1228 void CCommsDatabaseImpl::UnRegisterView(CCommsDbTableView* aTable)
       
  1229 	{
       
  1230 	TInt index = iTableViews.Find(aTable);
       
  1231 	if (index>=0) 
       
  1232 		{
       
  1233 		iTableViews.Remove(index);
       
  1234 		}
       
  1235 	}
       
  1236 
       
  1237 void CCommsDatabaseImpl::RegisterConnPrefViewL(CCommsDbConnectionPrefTableView* aTable)
       
  1238 	{
       
  1239 	iConnPrefViews.AppendL(aTable);
       
  1240 	}
       
  1241 
       
  1242 void CCommsDatabaseImpl::UnRegisterConnPrefView(CCommsDbConnectionPrefTableView* aTable)
       
  1243 	{
       
  1244 	TInt index = iConnPrefViews.Find(aTable);
       
  1245 	if (index>=0) 
       
  1246 		{
       
  1247 		iConnPrefViews.Remove(index);
       
  1248 		}
       
  1249 	}
       
  1250 
       
  1251 void CCommsDatabaseImpl::CheckGlobalSettingsTableExistsL()
       
  1252 /**
       
  1253     Important, this function requires 'ECapabilityWriteDeviceData' capability.
       
  1254 */
       
  1255     {
       
  1256     // We only need to check that the global settings table exists once, because if it doesn't we'll create a placeholder.
       
  1257     if (!iHaveCheckedGSTableExists)
       
  1258         {
       
  1259         // Ensure that a global record always exists.
       
  1260     
       
  1261         CCDGlobalSettingsRecord* pNewGlobalRecord = static_cast<CCDGlobalSettingsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdGlobalSettingsRecord));
       
  1262         CleanupStack::PushL(pNewGlobalRecord);
       
  1263 
       
  1264         const TInt KGlobalSettingsRecordID = 1;
       
  1265         
       
  1266         pNewGlobalRecord->SetRecordId(KGlobalSettingsRecordID);
       
  1267         
       
  1268         TRAPD(err, pNewGlobalRecord->StoreL(*iDbs));
       
  1269         if (!(err == KErrNone || err == KErrAlreadyExists))
       
  1270             {
       
  1271             User::Leave(err);
       
  1272             }
       
  1273             
       
  1274         iHaveCheckedGSTableExists = ETrue;
       
  1275                 
       
  1276         CleanupStack::PopAndDestroy(pNewGlobalRecord);
       
  1277         }
       
  1278     }
       
  1279 
       
  1280 TInt CCommsDatabaseImpl::RequestNotification(TRequestStatus& aStatus)
       
  1281 	{  
       
  1282         TInt ret(KErrNone);		
       
  1283 	if(!iShimNotifier.Handle())
       
  1284                 {
       
  1285                 ret = iShimNotifier.Connect(); //Also starts the server if not running allready
       
  1286                 }	
       
  1287 	
       
  1288 	if(ret == KErrNone)
       
  1289                {
       
  1290                iShimNotifier.RequestNotification(aStatus);
       
  1291                }
       
  1292                
       
  1293         return ret;
       
  1294 	}
       
  1295 
       
  1296 void CCommsDatabaseImpl::CancelRequestNotification()
       
  1297 	{
       
  1298 	if(iShimNotifier.Handle())
       
  1299 		{
       
  1300 		iShimNotifier.CancelNotification(); 	
       
  1301 		}
       
  1302 	iShimNotifier.Close();	
       
  1303 	}
       
  1304 
       
  1305 
       
  1306 
       
  1307 // ------------------------ CommDb Shim Utils -------------------------
       
  1308 
       
  1309 /**
       
  1310 @internalTechnology
       
  1311 */
       
  1312 typedef struct 
       
  1313 	{
       
  1314 	const TText* iTableName;
       
  1315 	TUint iTableId;
       
  1316 	} TCommDbTableMapping;
       
  1317 		
       
  1318 /**
       
  1319 Number of mappings in the table
       
  1320 @internalTechnology
       
  1321 */
       
  1322 const TInt KTableMappingsCount = 30;
       
  1323 
       
  1324 /**
       
  1325 Mappings between legacy commdb table names and the commsdat table element id's
       
  1326 @internalTechnology
       
  1327 */
       
  1328 const TCommDbTableMapping tableMappings[KTableMappingsCount] = 
       
  1329 	{
       
  1330 		{ KCDTypeNameModemBearer, CommsDat::KCDTIdModemBearerRecord },
       
  1331 		{ KCDTypeNameLANBearer, CommsDat::KCDTIdLANBearerRecord },
       
  1332 		{ KCDTypeNameVirtualBearer, CommsDat::KCDTIdVirtualBearerRecord },
       
  1333 		{ KCDTypeNameWAPSMSBearer, CommsDat::KCDTIdWAPSMSBearerRecord },
       
  1334 		{ KCDTypeNameWAPIPBearer, CommsDat::KCDTIdWAPIPBearerRecord },
       
  1335 		{ KCDTypeNameGlobalSettings, CommsDat::KCDTIdGlobalSettingsRecord },
       
  1336 		{ KCDTypeNameConnectionPrefs, CommsDat::KCDTIdConnectionPrefsRecord },
       
  1337 		{ KCDTypeNameNetwork, CommsDat::KCDTIdNetworkRecord },
       
  1338 		{ KCDTypeNameLocation, CommsDat::KCDTIdLocationRecord },
       
  1339 		{ KCDTypeNameIAP, CommsDat::KCDTIdIAPRecord },
       
  1340 		{ KCDTypeNameWAPAccessPoint, CommsDat::KCDTIdWAPAccessPointRecord },
       
  1341 		{ KCDTypeNameDialOutISP, CommsDat::KCDTIdDialOutISPRecord },
       
  1342 		{ KCDTypeNameDialInISP, CommsDat::KCDTIdDialInISPRecord },
       
  1343 		{ KCDTypeNameLANService, CommsDat::KCDTIdLANServiceRecord },
       
  1344 		{ KCDTypeNameWLANServiceExt, CommsDat::KCDTIdWLANServiceExtRecord },
       
  1345 		{ KCDTypeNameVPNService, CommsDat::KCDTIdVPNServiceRecord },
       
  1346 		{ KCDTypeNameOutgoingWCDMA, CommsDat::KCDTIdOutgoingGprsRecord },
       
  1347 		{ KCDTypeNameIncomingWCDMA, CommsDat::KCDTIdIncomingGprsRecord },
       
  1348 		{ KCDTypeNamePANServiceExt, CommsDat::KCDTIdPANServiceExtRecord },
       
  1349 		{ KCDTypeNameDefaultWCDMA, CommsDat::KCDTIdDefaultWCDMARecord },
       
  1350 		{ KCDTypeNameChargecard, CommsDat::KCDTIdChargecardRecord },
       
  1351 		{ KCDTypeNameProxies, CommsDat::KCDTIdProxiesRecord },
       
  1352 		{ KCDTypeNameSSProto, CommsDat::KCDTIdSSProtoRecord },
       
  1353 		{ KCDTypeNameAgentLookup, CommsDat::KCDTIdAgentLookupRecord },
       
  1354 		{ KCDTTypeNameEAPSec, CommsDat::KCDTIdEAPSecRecord },
       
  1355 		{ KCDTTypeNameTunEAP, CommsDat::KCDTIdTunEAPRecord },
       
  1356 		{ KCDTTypeNameEAPTLS, CommsDat::KCDTIdEAPTLSRecord },
       
  1357 		{ KCDTTypeNameLEAP, CommsDat::KCDTIdLEAPRecord },
       
  1358 
       
  1359 		// These didn't exist in Commdb and don't have textual names
       
  1360 		//		KCDTIdAccessPointRecord
       
  1361 		//		KCDTIdIapPrioritySelectionPolicyRecord
       
  1362 		//		KCDTIdWCDMAPacketServiceRecord
       
  1363 		//		KCDTIdUmtsR99QoSAndOnTableRecord
       
  1364 	};
       
  1365 
       
  1366 
       
  1367 
       
  1368 /**
       
  1369 @internalTechnology
       
  1370 */
       
  1371 EXPORT_C CommsDat::TMDBElementId CommDbShimUtil::GetElementIdFromFieldNameL(const TDesC& aFieldName)
       
  1372 	{
       
  1373 	_LIT(KSlashCharacter, "\\");
       
  1374    	TInt slashPos = aFieldName.Find(KSlashCharacter);
       
  1375    	if(slashPos < 0)
       
  1376    		{
       
  1377    		User::Leave(KErrArgument);
       
  1378    		}
       
  1379    	TPtrC tableName(aFieldName.Ptr(), slashPos);
       
  1380    	TPtrC fieldName(aFieldName.Ptr() + slashPos + 1, aFieldName.Length() - slashPos - 1);
       
  1381 
       
  1382    	CMDBRecordBase* record = NULL;
       
  1383 	TInt i = 0;
       
  1384 	while (record == NULL && i < KTableMappingsCount)
       
  1385 		{
       
  1386 		if (!tableName.CompareF(TPtrC(tableMappings[i].iTableName))) 
       
  1387 			{
       
  1388 			record = CCDRecordBase::RecordFactoryL(tableMappings[i].iTableId);
       
  1389 			CleanupStack::PushL(record);
       
  1390 			break;
       
  1391 			}
       
  1392 		i++;
       
  1393 		}
       
  1394 
       
  1395 	TMDBElementId elementId;
       
  1396 	if (!record)
       
  1397 		{
       
  1398         // Create a temporary example of the user defined record, in order to do the lookup by name and get the Id back.
       
  1399         CMDBGenericRecord* tempUserDefinedRecord = static_cast<CMDBGenericRecord*>(CCDRecordBase::RecordFactoryL(0));
       
  1400         CleanupStack::PushL(tempUserDefinedRecord);
       
  1401         
       
  1402     	tempUserDefinedRecord->InitializeL(tableName, NULL);
       
  1403 
       
  1404     	CMDBSession* dbs = CMDBSession::NewLC(KCDVersion1_1);
       
  1405         tempUserDefinedRecord->LoadL(*dbs);
       
  1406 
       
  1407         // Get the Id that we're interested in...
       
  1408         TUint tableId = tempUserDefinedRecord->TableId();
       
  1409 
       
  1410         CleanupStack::PopAndDestroy(); // dbs
       
  1411         CleanupStack::PopAndDestroy(); // tempUserDefinedRecord
       
  1412         
       
  1413 		record = CCDRecordBase::RecordFactoryL(tableId);
       
  1414 		CleanupStack::PushL(record);	
       
  1415 		}
       
  1416 	
       
  1417 	TInt tempType;
       
  1418 	CMDBElement* field = record->GetFieldByNameL(fieldName, tempType);
       
  1419 	elementId = field->ElementId();
       
  1420 	CleanupStack::PopAndDestroy(); // record
       
  1421 	return elementId;
       
  1422 	}
       
  1423 
       
  1424 //EOF