commsconfig/commsdatabaseshim/commdbshim/SCDB/commdb_impl.cpp
changeset 0 dfb7c4ff071f
child 48 07656293a99c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commsconfig/commsdatabaseshim/commdbshim/SCDB/commdb_impl.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1424 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Comms Database Table View defintions
+// 
+//
+
+/**
+ @file
+ @deprecated since v9.1. Functionality is replaced with commsdat.
+*/
+
+#include <cdbtemp.h>
+#include <commdb.h>
+#include <cdbpreftable.h>
+#include <commsdat_partner.h>
+#include <commsdattypesv1_1_partner.h>
+
+#include "commdb_impl.H"
+#include "Commsdat_Log.h"
+#include "commsdattypeinfov1_1_internal.h"
+
+const TInt KFirstRecord = 0;
+
+// Additional funtions to implement Connection Preference table protection - in a separate
+// class so as not to break BC.
+CCommDbTableExtension::CCommDbTableExtension()
+/**
+Constructor
+*/
+    {
+    }
+
+CCommDbTableExtension* CCommDbTableExtension::NewL()
+	{
+	CCommDbTableExtension* self = new(ELeave) CCommDbTableExtension;
+	TInt err = self->iCommitSeqProperty.Attach(KUidCommsDatStatusEvent, KCommsDatStatusEventCommitSeq);
+	if(err != KErrNone)
+		{
+		delete self;
+		User::Leave(err);
+		}
+	return self;
+	}
+
+void CCommDbTableExtension::GetRecordInfoL(const TDesC& aColumn, TDbColType& aColType, TUint32& aAttrib)
+	{
+	CMDBRecordSetBase* recSet = GetRecordSetL();
+	
+	TBuf<KCommsDbSvrMaxColumnNameLength> buf; // This holds Column name
+	TBool found(EFalse);
+	
+	// create dummy record to read info from it
+	CMDBRecordBase* dummyRecord = CCDRecordBase::RecordFactoryL(recSet->TypeId());
+	const SRecordTypeInfo* recordInfo = dummyRecord->GetRecordInfo();
+
+	// Loop through all the columns of the record
+	while(recordInfo->iTypeId != 0 && !found)
+		{
+		// Get name of the field into buffer
+		buf = recordInfo->iTypeName;
+		
+		if(buf.CompareF(aColumn) == 0)
+			{
+			found = ETrue;
+			}
+		else
+			{
+			// Switch to Next column
+			recordInfo++;
+			}
+		}
+	
+	// check if column is not found
+	if(!found)
+		{
+		delete dummyRecord;
+		User::Leave(KErrNotFound);
+		}
+	else
+		{
+		aColType = GetColType(recordInfo->iValType);
+		recordInfo->iTypeAttr == ENotNull ? aAttrib = TDbCol::ENotNull : aAttrib = 0;
+		}
+	
+	delete dummyRecord;
+	}
+
+TDbColType CCommDbTableExtension::GetColType(TInt aType)
+    {
+    TDbColType ret;
+    switch(aType)
+        {
+        case EText:
+        case EMedText:
+            ret = EDbColText16;
+            break;
+        case ELongText:
+            ret = EDbColLongText;
+            break;
+        case EDesC8:
+            ret = EDbColText8;
+            break;
+        case EUint32:
+            ret = EDbColUint32;
+            break;
+        case EInt:
+            ret = EDbColUint32;
+            break;
+        case EBool:
+            ret = EDbColBit;
+            break;
+        default:
+            ret = EDbColInt32;
+        }
+
+    return ret;
+    }
+
+TInt CCommDbTableExtension::GetMaxTypeLength(TInt aType)
+    {
+    TInt ret;
+
+    switch(aType)
+        {
+        case EText:
+            ret = KMaxTextLength;
+            break;
+        case EDesC8:
+            ret = KMaxTextLength;
+            break;
+        case EUint32:
+            ret = KMaxNumLength;
+            break;
+        case EInt:
+            ret = KMaxNumLength;
+            break;
+        case EBool:
+            ret = KMaxNumLength;
+            break;
+        case ELongText:
+            ret = KMaxLongTextLength;
+            break;
+        case EMedText:
+            ret = KMaxMedTextLength;
+            break;
+        default:
+            ret = 0;
+        }
+
+    return ret;
+    }
+
+void CCommDbTableExtension::UpdateLastCommitSeq()
+	{
+	// Update the global commit sequence, for detecting possible changes when deciding whether to refresh records
+	TInt currCommitSeq;
+    if(iCommitSeqProperty.Get(currCommitSeq) == KErrNone)
+		{
+		iLastCommitSeq = currCommitSeq;
+		}
+	}
+
+TInt CCommDbTableExtension::MaybeRefreshCurrentRecord(CMDBSession& aDbs)
+	{
+	// If the global commit sequence number differs from the last one set or observed by us then we need to refresh to ensure we
+	// acquire any relevant changes
+	TInt err = KErrNone;
+	TInt currCommitSeq = iLastCommitSeq;
+    if(iCommitSeqProperty.Get(currCommitSeq) != KErrNone || currCommitSeq != iLastCommitSeq)
+		{
+	    TRAP(err,iCurrentRecord->RefreshL(aDbs));
+		if(err == KErrNone)
+			{
+			iLastCommitSeq = currCommitSeq;
+			}
+		}
+	return err;
+	}
+
+TInt CCommDbTableExtension::GotoFirstRecord(CMDBSession& aDbs)
+    {
+	TInt err(KErrNotFound);
+	
+	TInt countContRec = iRecordSetContainer->iRecords.Count();
+	
+    if (iRecordSetContainer && countContRec)
+        {
+		// set up stating point
+		iCurrentRecord = NULL;
+		// set up first valid record
+		TInt valid = FindFirstNextValidRecord(ETrue);
+
+		if(valid)
+			{
+			// save current record before change
+			CMDBRecordBase* currRecBackup(iCurrentRecord);
+
+            if ( iCurrentRecord->RecordId() == KCDDefaultRecord  &&
+                 (iCurrentRecord->Attributes() & ECDHidden ) &&
+                 ! aDbs.IsSetAttributeMask(ECDHidden) )
+                {
+                err = GotoNextRecord(aDbs); 
+                }
+            else 
+                {
+			    err = MaybeRefreshCurrentRecord(aDbs);
+				if (err != KErrNone) 
+					{
+					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoFirstRecord failed to Refresh the data Err=%d"),err);
+					iCurrentRecord = currRecBackup;
+					}
+                }
+			}
+
+		iEndOfTableRecordBackup = NULL;
+		iBeginingOfTableRecordBackup = NULL;
+        }
+
+    // record set is empty
+    return err;
+    }
+
+TInt CCommDbTableExtension::GotoNextRecord(CMDBSession& aDbs)
+    {
+    TInt err(KErrNone);
+	TInt currIndex(0);
+	
+	if (!iRecordSetContainer) 
+		{
+		return KErrNotFound;
+		}
+	
+    if (iCurrentRecord)
+        {
+        TInt count = iRecordSetContainer->iRecords.Count();
+		currIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
+        if (currIndex == count-1)
+            {
+            // record set is either empty or going out of scope
+            err = KErrNotFound;
+			// the marker is going beyond end of the table, so backup last record and use the value as end marker
+			iEndOfTableRecordBackup = iCurrentRecord;
+			iCurrentRecord = NULL;
+            }
+        else
+            {
+			// save current record before change
+			CMDBRecordBase* currRecBackup(iCurrentRecord);
+			// set up first next valid record
+			TInt valid = FindFirstNextValidRecord(EFalse);
+			if (valid) 
+				{
+			    err = MaybeRefreshCurrentRecord(aDbs);
+				if (err != KErrNone) 
+					{
+					// return to status prior to failure
+					iCurrentRecord = currRecBackup;
+					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoNextRecord failed to Refresh the data Err=%d"),err);
+					}
+				}
+			else
+				{
+				err = KErrNotFound;
+				}
+            }
+        }
+    else
+    	{
+		// if position was on the begining of the table then retrieve back first record and set up begining of table marker to null
+        if (iBeginingOfTableRecordBackup)
+			{
+			iCurrentRecord = iBeginingOfTableRecordBackup;
+			iBeginingOfTableRecordBackup = NULL;
+			}
+		else
+	        {
+	        err = KErrNotFound;
+	        }
+    	}
+
+    return err;
+    }
+
+TInt CCommDbTableExtension::GotoPreviousRecord(CMDBSession& aDbs)
+    {
+    TInt err = KErrNone;
+
+	if (!iRecordSetContainer) 
+		{
+		return KErrNotFound;
+		}
+	
+    if (iCurrentRecord)
+        {
+        const TInt count = iRecordSetContainer->iRecords.Count();
+		TInt currIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
+        if (currIndex == 0)
+            {
+            // record set is either empty or going out of scope
+            err = KErrNotFound;
+            }
+        else
+            {
+			// save current record before change
+			CMDBRecordBase* currRecBackup(iCurrentRecord);
+			// set up first prev valid record
+			TInt valid = FindFirstPrevValidRecord();
+			if (valid) 
+				{
+			    err = MaybeRefreshCurrentRecord(aDbs);
+				if (err != KErrNone) 
+					{
+					// return to status prior to failure
+					iCurrentRecord = currRecBackup;
+					__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::GotoPreviousRecord failed to Refresh the data Err=%d"),err);
+					}
+				}
+			else
+				{
+				err = KErrNotFound;
+				}
+            }
+        }
+    else
+        {
+		// if position was on the end of the table then retrieve back last record and set up end of table marker to null
+        if (iEndOfTableRecordBackup) 
+			{
+			iCurrentRecord = iEndOfTableRecordBackup;
+			iEndOfTableRecordBackup = NULL;
+			}
+		else
+			{
+	        err = KErrNotFound;
+			}
+        }
+
+    return err;
+    }
+
+void CCommDbTableExtension::InsertConnPrefRecordL(CCDConnectionPrefsRecord* aConnPref, CMDBSession& aDbs)
+	{
+	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::InsertConnPrefRecordL -> Entry Point"));
+
+	CMDBRecordSetBase* recSet = GetRecordSetL();
+
+	// store newly created record
+	aConnPref->SetRecordId(KCDNewRecordRequest);
+
+	aConnPref->StoreL(aDbs);
+	User::LeaveIfError(recSet->iRecords.Append(aConnPref));
+	
+	iCurrentRecord = recSet->iRecords[recSet->iRecords.Count()-1];
+	iInsertedRecords.Insert(iCurrentRecord->RecordId(), KFirstRecord);
+	
+	TInt index = iDeletedRecords.Find(iCurrentRecord->RecordId());
+	
+	// check if inserted record has the same record id as previously deleted record	
+	if(index>=0)
+		{
+		iDeletedRecords.Remove(index);
+		}
+
+	SortByRank();
+	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::InsertConnPrefRecordL -> Record Inserted"));
+	}
+
+
+TBool CCommDbTableExtension::IsGenericRecord(TMDBElementId aElementId) const
+    {
+    const TMDBElementId tableType = (aElementId & KCDMaskShowRecordType);
+    return (tableType >= KCDInitialUDefRecordType);
+    }
+
+void CCommDbTableExtension::InsertRecordL(TBool aCopy, TUint32& aId, CMDBSession& aDbs, TBool aIsTemplate)
+/**
+Deletes the current record from commsdat and from queue.
+Updates the value of record index.
+*/
+    {
+	CMDBRecordSetBase* recSet = GetRecordSetL();
+	// storing empty string in order to get RecordId for newly inserted record
+	CMDBRecordBase* newRecord;
+	
+	if(aCopy)
+		{
+		CMDBRecordBase* record = GetCurrentRecordL();
+		newRecord = CCDRecordBase::CreateCopyRecordL(*record);
+		CleanupStack::PushL(newRecord);
+		if(IsGenericRecord(newRecord->ElementId()))
+			{
+			newRecord->LoadL(aDbs);
+			}		
+		}
+	else
+		{
+		newRecord = CCDRecordBase::RecordFactoryL(recSet->TypeId());
+		CleanupStack::PushL(newRecord);
+		if(IsGenericRecord(newRecord->ElementId()))
+			{
+			newRecord->LoadL(aDbs);
+			}	
+		}
+	
+    TBool removeHiddenMask = EFalse;
+	if(aIsTemplate)
+		{
+		// this will mark record as template record
+		newRecord->SetRecordId(KCDDefaultRecord);
+        if (! aDbs.IsSetAttributeMask(ECDHidden))
+            {
+            aDbs.SetAttributeMask(ECDHidden);
+            removeHiddenMask = ETrue;
+            }
+		}
+	else
+		{
+		// this will give next valid record number
+		newRecord->SetRecordId(KCDNewRecordRequest);		
+		}
+	
+	// create and store record placeholder
+	newRecord->StoreL(aDbs);
+
+    if (removeHiddenMask)
+        {
+        aDbs.ClearAttributeMask(ECDHidden);
+        }
+
+	// check if inserted record has the same record id as previously deleted record
+	TInt index = iDeletedRecords.Find(newRecord->RecordId());
+	
+	if(index >= 0)
+		{
+		iDeletedRecords.Remove(index);
+		}
+
+	// append inserted record
+	User::LeaveIfError(recSet->iRecords.Append(newRecord));
+	CleanupStack::Pop(newRecord);
+	
+	iCurrentRecord = newRecord;
+	iInsertedRecords.Insert(iCurrentRecord->RecordId(), KFirstRecord);
+	SortById();
+	
+	aId = newRecord->RecordId();
+	}
+
+TInt CCommDbTableExtension::CancelRecordChanges(CMDBSession& aDbs)
+	{
+	TInt err = KErrNone;
+	if (!iRecordSetContainer)
+		{
+		return KErrNotFound;
+		}
+	
+	TRAP(err,iCurrentRecord->LoadL(aDbs));
+	if (err != KErrNone) 
+		{
+		// return to status prior to failure
+		__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::CancelRecordChanges failed to Refresh the data, Err=%d"),err);
+		return err;
+		}
+	
+	if (iInsertedRecords.Count()) 
+		{
+		TInt index = FindValueInRecSet(iInsertedRecords[KFirstRecord]);
+		
+		if(index >= 0)
+			{
+			delete iRecordSetContainer->iRecords[index];
+			iRecordSetContainer->iRecords.Remove(index);
+			iRecordSetContainer->iRecords.Compress();
+			// reuse index variable
+			index = iRecordSetContainer->iRecords.Count();
+			index ? iCurrentRecord = iRecordSetContainer->iRecords[index-1] : iCurrentRecord = NULL;
+			}
+		}
+
+	ResetArrays(aDbs);
+	
+	return err;
+	}
+
+void CCommDbTableExtension::ResetArrays(CMDBSession& aSession) 
+	{
+	if(!aSession.IsInTransaction())
+		{
+		iInsertedRecords.Reset();
+		iDeletedRecords.Reset();
+		}
+	// else they will be reseted on Commit or Rolback Transaction
+	}
+
+void CCommDbTableExtension::ResetAndDestroyL() 
+	{
+	GetRecordSetL()->iRecords.ResetAndDestroy();
+	iCurrentRecord = NULL;
+	}
+
+void CCommDbTableExtension::DeleteCurrentRecordL(CMDBSession& aDbs, TBool aContainerOnly)
+/**
+Deletes the current record from commsdat and from queue.
+Updates the value of record index.
+*/
+    {
+    // check for validity of current record through GetCurrentRecord call
+    CMDBRecordBase* currRec = GetCurrentRecordL();
+    /* TODO: Add iShowHidden in conditions. This might not be necessary checking */
+    /*if(iRecordIndex == 0) 
+        {
+        // it is not possible to delete template record
+        User::Leave(KErrNotSupported);
+        }*/
+	if(!aContainerOnly)
+		{
+		if (currRec->IsSetAttribute(ECDProtectedWrite))
+    		{
+    		User::Leave(KErrAccessDenied);
+    		}
+		
+		User::LeaveIfError(iDeletedRecords.Append(currRec->RecordId()));
+		
+		__FLOG_STMT(TInt count = iDeletedRecords.Count();)
+		__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::DeleteCurrentRecordL added to deleted record queue, as No:%d"), count);
+    	
+    	currRec->DeleteL(aDbs);
+		}
+
+	TInt currIndex = iRecordSetContainer->iRecords.Find(currRec);
+
+	iCurrentRecord = NULL;
+	
+	// If we just deleted the last or first non-deleted record then update the appropriate "backup" so that a next/prev
+	// will work
+	TInt probeIndex = currIndex;
+	iBeginingOfTableRecordBackup = NULL;
+	iEndOfTableRecordBackup = NULL;
+	if(!AdvanceIndexToPrevValidRecord(probeIndex))
+		{
+		// Deleted first record; Next from here should move to first record
+		probeIndex = currIndex;
+		if(AdvanceIndexToNextValidRecord(probeIndex))
+			{
+			iBeginingOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
+			}
+		}
+	else
+		{
+		iBeginingOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
+		}
+	probeIndex = currIndex;
+	if(!AdvanceIndexToNextValidRecord(probeIndex))
+		{
+		// Deleted last record; Prev from here should move to last record
+		probeIndex = currIndex;
+		if(AdvanceIndexToPrevValidRecord(probeIndex))
+			{
+			iEndOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
+			}
+		}
+	else
+		{
+		iEndOfTableRecordBackup = iRecordSetContainer->iRecords[probeIndex];
+		}
+
+	if(!aContainerOnly)
+		{
+		// remove an entry from container
+		delete iRecordSetContainer->iRecords[currIndex];
+		iRecordSetContainer->iRecords.Remove(currIndex);
+		iRecordSetContainer->iRecords.Compress();
+		}
+    }
+
+void CCommDbTableExtension::SetRecordSet(CMDBRecordSetBase* aRecordSetContainer)
+    {
+    iRecordSetContainer = aRecordSetContainer;
+	TInt currIndex = iRecordSetContainer->iRecords.Count();
+
+	currIndex == 0 ? iCurrentRecord = NULL : iCurrentRecord = iRecordSetContainer->iRecords[0];
+	
+	#ifdef _DEBUG
+       	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("Start of Table Contents"));
+		CCDRecordBase* ptrTemp;
+		CMDBRecordBase* currRec;
+		CMDBRecordSetBase* recSet = static_cast<CMDBRecordSetBase*>(iRecordSetContainer);
+		TInt count = recSet->iRecords.Count();
+		for(TInt i=0;i<count;++i)
+			{
+	        currRec = recSet->iRecords[i];
+			ptrTemp = static_cast<CCDRecordBase*>(currRec);
+			const TDesC& field = ptrTemp->iRecordName;
+			
+			__FLOG_STATIC3(KLogComponent, KCommDbShim, _L("Record[%d], RecordId:%d, RecordName:%S"),
+				i, currRec->RecordId(), &field);
+			}
+       	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("End of Table Contents"));
+	#endif
+    };
+
+CMDBRecordSetBase* CCommDbTableExtension::RecordSetFactoryL(const TDesC& aTableName, TBool preparePriming, CMDBSession& aDbs)
+	{
+	TMDBElementId recordSetId = 0;
+	CMDBRecordSetBase* recordSetContainer = NULL;
+	
+    if (aTableName.CompareF(TPtrC(KCDTypeNameConnectionPrefs)) == 0)
+        {
+        // connection preferance needs to be created via CommDbConnectionPref class
+        User::Leave(KErrNotSupported);
+        }
+	else if (aTableName.CompareF(TPtrC(KCDTypeNameGlobalSettings)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDGlobalSettingsRecord>(KCDTIdGlobalSettingsRecord);
+		recordSetId = KCDTIdGlobalSettingsRecord;
+		}
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameNetwork)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDNetworkRecord>(KCDTIdNetworkRecord);
+        recordSetId = KCDTIdNetworkRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameLocation)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLocationRecord>(KCDTIdLocationRecord);
+        recordSetId = KCDTIdLocationRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameIAP)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDIAPRecord>(KCDTIdIAPRecord);
+        recordSetId = KCDTIdIAPRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPAccessPoint)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPAccessPointRecord>(KCDTIdWAPAccessPointRecord);
+        recordSetId = KCDTIdWAPAccessPointRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameDialOutISP)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDDialOutISPRecord>(KCDTIdDialOutISPRecord);
+        recordSetId = KCDTIdDialOutISPRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameDialInISP)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDDialInISPRecord>(KCDTIdDialInISPRecord);
+        recordSetId = KCDTIdDialInISPRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameLANService)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLANServiceRecord>(KCDTIdLANServiceRecord);
+        recordSetId = KCDTIdLANServiceRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameWLANServiceExt)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWLANServiceExtRecord>(KCDTIdWLANServiceExtRecord);
+        recordSetId = KCDTIdWLANServiceExtRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNamePANServiceExt)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDPANServiceExtRecord>(KCDTIdPANServiceExtRecord);
+        recordSetId = KCDTIdPANServiceExtRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameVPNService)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDVPNServiceRecord>(KCDTIdVPNServiceRecord);
+        recordSetId = KCDTIdVPNServiceRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameDefaultWCDMA)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWCDMAPacketServiceRecord>(KCDTIdDefaultWCDMARecord);
+        recordSetId = KCDTIdDefaultWCDMARecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameIncomingWCDMA)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDIncomingGprsRecord>(KCDTIdIncomingGprsRecord);
+        recordSetId = KCDTIdIncomingGprsRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameOutgoingWCDMA)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDOutgoingGprsRecord>(KCDTIdOutgoingGprsRecord);
+        recordSetId = KCDTIdOutgoingGprsRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameModemBearer)) == 0 || aTableName.CompareF(TPtrC(OLD_MODEM_TABLE)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDModemBearerRecord>(KCDTIdModemBearerRecord);
+        recordSetId = KCDTIdModemBearerRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameLANBearer)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDLANBearerRecord>(KCDTIdLANBearerRecord);
+        recordSetId = KCDTIdLANBearerRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameVirtualBearer)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDVirtualBearerRecord>(KCDTIdVirtualBearerRecord);
+        recordSetId = KCDTIdVirtualBearerRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPSMSBearer)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPSMSBearerRecord>(KCDTIdWAPSMSBearerRecord);
+        recordSetId = KCDTIdWAPSMSBearerRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameWAPIPBearer)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDWAPIPBearerRecord>(KCDTIdWAPIPBearerRecord);
+        recordSetId = KCDTIdWAPIPBearerRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameChargecard)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDChargecardRecord>(KCDTIdChargecardRecord);
+        recordSetId = KCDTIdChargecardRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameProxies)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDProxiesRecord>(KCDTIdProxiesRecord);
+        recordSetId = KCDTIdProxiesRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameSSProto)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDSecureSocketRecord>(KCDTIdSSProtoRecord);
+        recordSetId = KCDTIdSSProtoRecord;
+        }
+    else if (aTableName.CompareF(TPtrC(KCDTypeNameAgentLookup)) == 0)
+        {
+		recordSetContainer = new (ELeave) CMDBRecordSet<CCDAgentLookupRecord>(KCDTIdAgentLookupRecord);
+        recordSetId = KCDTIdAgentLookupRecord;
+        }
+    else
+        {
+        // Create a temporary example of the user defined record, in order to do the lookup by name and get the Id back.
+        
+        CMDBGenericRecord* tempUserDefinedRecord = static_cast<CMDBGenericRecord*>(CCDRecordBase::RecordFactoryL(0));
+        CleanupStack::PushL(tempUserDefinedRecord);
+    	tempUserDefinedRecord->InitializeL(aTableName, NULL);
+        tempUserDefinedRecord->LoadL(aDbs);
+
+        // Get the Id that we're interested in...
+        recordSetId = tempUserDefinedRecord->TableId();
+
+        // ..and validate it.
+        if ((recordSetId & KCDMaskShowRecordType) < KCDInitialUDefRecordType)
+            {
+            User::Leave(KErrNotFound);
+            }
+        
+        
+		recordSetContainer = new (ELeave) CMDBRecordSet<CMDBGenericRecord>(recordSetId);
+		
+		if (preparePriming)
+			{
+			CleanupStack::PushL(recordSetContainer);
+			recordSetContainer->iRecords.AppendL(tempUserDefinedRecord);	
+			CleanupStack::Pop(2);
+			}
+		else
+			{
+			CleanupStack::PopAndDestroy(tempUserDefinedRecord);
+			}
+		return recordSetContainer;			
+        }
+
+    if (preparePriming)
+        {
+		CleanupStack::PushL(recordSetContainer);
+		CMDBRecordBase* record = CCDRecordBase::RecordFactoryL(recordSetId);
+		TInt err = recordSetContainer->iRecords.Append(record);
+		if(err != KErrNone)
+			{
+			delete record;
+			User::Leave(err);
+			}
+		CleanupStack::Pop(recordSetContainer);
+        }
+    return recordSetContainer;
+	}
+
+void CCommDbTableExtension::SetRecordSetL(const TDesC& aTableName, CMDBSession& aDbs, TBool aPreparePriming, TBool aLoadTable, TBool aTemplate)
+/**
+Sets the value of the member iRecordSetContainer
+*/
+    {
+    __FLOG_STATIC1(KLogComponent, KCommDbShim, _L("SetRecordSetL -> TableName=%S"), &aTableName);
+
+    // delete existing container
+    delete iRecordSetContainer;
+    iCurrentRecord = NULL;
+	
+    TBool removeHiddenMask = EFalse;
+	if (aTemplate) 
+		{
+		// keeping BC compatibility
+		TRAPD(err, iRecordSetContainer = RecordSetFactoryL(aTableName, aPreparePriming, aDbs));
+		if (err == KErrNotFound) 
+			{
+			err = KErrArgument;
+			}
+		User::LeaveIfError(err);
+        iRecordSetContainer->iRecords[0]->SetAttributes(ECDHidden);
+        if (! aDbs.IsSetAttributeMask(ECDHidden))
+            {
+            aDbs.SetAttributeMask(ECDHidden);
+            removeHiddenMask = ETrue;
+            }
+		}
+		else
+		{
+		iRecordSetContainer = RecordSetFactoryL(aTableName, aPreparePriming, aDbs);
+		}
+	
+    // load data
+    if (aLoadTable)
+        {
+        TRAPD(err, iRecordSetContainer->LoadL(aDbs));
+        // if table is empty don't leave
+        if (err != KErrNone && err != KErrNotFound)
+        	{
+        	User::LeaveIfError(err);
+        	}
+       	#ifdef _DEBUG
+        else
+        	{
+        	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("Start of Table Contents"));
+			CCDRecordBase* ptrTemp;
+			CMDBRecordBase* currRec;
+			CMDBRecordSetBase* recSet = static_cast<CMDBRecordSetBase*>(iRecordSetContainer);
+			TInt count = recSet->iRecords.Count();
+			for(TInt i=0;i<count;++i)
+				{
+		        currRec = recSet->iRecords[i];
+				ptrTemp = static_cast<CCDRecordBase*>(currRec);
+				const TDesC& field = ptrTemp->iRecordName;
+
+				__FLOG_STATIC3(KLogComponent, KCommDbShim, _L("Record[%d], RecordId:%d, RecordName:%S"),
+					i, currRec->RecordId(), &field);
+				}
+			__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("End of Table Contents"));
+        	}
+		#endif
+
+		UpdateLastCommitSeq();
+        }
+
+    if (removeHiddenMask)
+        {
+        aDbs.ClearAttributeMask(ECDHidden);
+        }
+
+
+    // reset the index
+	TInt currIndex = iRecordSetContainer->iRecords.Count();
+	currIndex ?  iCurrentRecord = iRecordSetContainer->iRecords[0] : iCurrentRecord = NULL;
+    }
+
+
+CMDBRecordSetBase* CCommDbTableExtension::GetRecordSetL()
+/**
+Gets the value of the member iRecordIndex
+
+@return A wrapper for an SQL string combined with a text comparison mode.
+*/	{
+    if (!iRecordSetContainer)
+        {
+        User::Leave(KErrNotFound);
+        }
+    return iRecordSetContainer;
+    }
+
+TInt CCommDbTableExtension::GetRecordSet(CMDBRecordSetBase*& aRecSet)
+    {
+    TInt ret = KErrNone;
+    if (!iRecordSetContainer)
+        {
+        ret = KErrNotFound;
+        }
+    else
+        {
+        aRecSet = iRecordSetContainer;
+        }
+    return ret;
+    }
+
+TInt CCommDbTableExtension::GetCurrentRecord(CMDBRecordBase*& aRecord)
+    {
+    TInt index(0);
+    TInt err = GetRecordSetIndex(index);
+
+    aRecord = 0;
+
+    if (err == KErrNone)
+        {
+        aRecord = iRecordSetContainer->iRecords[index];
+        err = KErrNone;
+        }
+
+    return err;
+    }
+
+CMDBRecordBase* CCommDbTableExtension::GetCurrentRecordL()
+    {
+    if(iCurrentRecord)
+        {
+        return iCurrentRecord;
+        }
+
+    User::Leave(KErrNotFound);
+
+    return NULL;
+    }
+
+TInt CCommDbTableExtension::GetRecordSetIndex(TInt &aIndex)
+/**
+Gets the value of the member iRecordIndex
+
+@return A wrapper for an SQL string combined with a text comparison mode.
+*/
+    {
+    TInt err = KErrNotFound;
+
+    if(iRecordSetContainer)
+        {
+        if (iCurrentRecord)
+            {
+            aIndex = iRecordSetContainer->iRecords.Find(iCurrentRecord);
+            err = KErrNone;
+            }
+        }
+
+    return err;
+    }
+
+TInt CCommDbTableExtension::GetRecordSetIndexL()
+/**
+Gets the value of the member iRecordIndex
+
+@return A wrapper for an SQL string combined with a text comparison mode.
+*/
+    {
+    if (iCurrentRecord)
+        {
+        User::Leave(KErrNotFound);
+        }
+
+    return iRecordSetContainer->iRecords.Find(iCurrentRecord);
+    }
+
+void CCommDbTableExtension::RefreshDatabaseL(CMDBSession& aDbs)
+/**
+Refresh the container
+*/
+	{
+	if(iRecordSetContainer)
+		{
+		iRecordSetContainer->RefreshL(aDbs);
+		}
+	}
+
+CCommDbTableExtension::~CCommDbTableExtension()
+/**
+Deletes the memory allocated to the members iColSet, iQueryText and iAccess
+*/
+    {
+    delete iRecordSetContainer;
+	iInsertedRecords.Reset();
+	iDeletedRecords.Reset();
+	iCommitSeqProperty.Close();
+    }
+
+TInt CCommDbTableExtension::CompareRecordsById(const CMDBRecordBase& aLeft, const CMDBRecordBase& aRight)
+/**
+
+@param
+@return
+*/
+    {
+    //We assume there can't be 2records with same record IDs
+    return (aLeft.RecordId()) < (aRight.RecordId()) ? -1 : 1;
+    }
+
+TInt CCommDbTableExtension::CompareRecordsByRank(
+            const CMDBRecordBase& aLeft, const CMDBRecordBase& aRight)
+/**
+
+@param
+@param
+@return
+*/
+    {
+    return ( ((CCDConnectionPrefsRecord&)aLeft).iRanking < ((CCDConnectionPrefsRecord&)aRight).iRanking) ? -1 : 1;
+    }
+
+void CCommDbTableExtension::SortById()
+/**
+    Sorting values in iRecordSetContainer by Id value
+*/
+    {
+    TLinearOrder<CMDBRecordBase> order(CompareRecordsById);
+	if(iRecordSetContainer)
+		{
+    	iRecordSetContainer->iRecords.Sort(order);
+		}
+    }
+
+void CCommDbTableExtension::SortByRank()
+/**
+
+@param
+@return
+*/
+    {
+    TLinearOrder<CMDBRecordBase> order(CompareRecordsByRank);
+	if(iRecordSetContainer)
+		{
+	    iRecordSetContainer->iRecords.Sort(order);
+		}
+    }
+
+TInt CCommDbTableExtension::GetTableAccess(RDbRowSet::TAccess &aAccess)
+    {
+    if( ! iRecordSetContainer)
+        return KErrNotFound;
+
+    if (iRecordSetContainer->IsSetAttribute(ECDProtectedWrite))
+       {
+       aAccess = RDbRowSet::EReadOnly;
+       }
+    else
+       {
+       aAccess = RDbRowSet::EUpdatable;
+       }
+    
+    return KErrNone;
+    }
+
+void CCommDbTableExtension::CommitTransaction()
+	{
+	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::CommitTransaction()"));
+	// remove flags since everything is valid
+	iInsertedRecords.Reset();
+	iDeletedRecords.Reset();
+	}
+
+void CCommDbTableExtension::RollBackTransaction()
+	{
+	__FLOG_STATIC0(KLogComponent, KCommDbShim, _L("CCommDbTableExtension::RollBackTransaction()"));
+
+ 	// we don't need to keep inserted records anymore
+	TInt index;
+	for (TInt i = 0; i < iInsertedRecords.Count(); ++i) 
+		{
+		index = FindValueInRecSet(iInsertedRecords[i]);
+
+		if(index >= 0)
+			{
+			delete iRecordSetContainer->iRecords[index];
+			iRecordSetContainer->iRecords.Remove(index);
+			}
+		}
+	iRecordSetContainer->iRecords.Compress();
+	index =	iRecordSetContainer->iRecords.Count();
+	index ? iCurrentRecord = iRecordSetContainer->iRecords[index-1] : iCurrentRecord = NULL;
+
+	// remove flags since everything is returned to begining
+	iInsertedRecords.Reset();
+	iDeletedRecords.Reset();
+	}
+
+TInt CCommDbTableExtension::GetCurrentRecordIndex() const
+	{
+	// If iCurrentRecord is valid then start with it, else start with most recently deleted record
+	const TInt numRecs = iRecordSetContainer->iRecords.Count();
+	TInt idx = -1;
+	const TInt numDeleted = iDeletedRecords.Count();
+	if(iCurrentRecord)
+		{
+		ASSERT(iDeletedRecords.Find(iCurrentRecord->RecordId()) == KErrNotFound);	// dbl-check it isn't somehow deleted too
+		idx = iRecordSetContainer->iRecords.Find(iCurrentRecord);
+		ASSERT(idx >= 0);
+		}
+	else 
+		{
+		if(numDeleted > 0)
+			{
+			idx = FindValueInRecSet(iDeletedRecords[numDeleted - 1]);
+			}
+		else
+			{
+			// No deleted records either, special case is going to -1, ie preparatory to advancing to first record
+			}
+		}
+	return idx;
+	}
+	
+TBool CCommDbTableExtension::AdvanceIndexToNextValidRecord(TInt& aIdx) const
+	{
+	// Advance to the next visible & not deleted in this view; hidden may not be visible
+	const TInt numRecs = iRecordSetContainer->iRecords.Count();
+	TInt idx;
+	for(idx = aIdx + 1; idx < numRecs; ++idx)
+		{
+		CMDBRecordBase* rec = iRecordSetContainer->iRecords[idx];
+		if(iDeletedRecords.Find(rec->RecordId()) >= 0)
+			{
+			continue;	// deleted are always invisible
+			}
+		if(iShowHidden || !rec->IsSetAttribute(ECDHidden))
+			{
+			break;
+			}
+		}
+	if(idx < numRecs)
+		{
+		aIdx = idx;
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+TBool CCommDbTableExtension::AdvanceIndexToPrevValidRecord(TInt& aIdx) const
+	{
+	// Advance to the previous visible & not deleted in this view; hidden may not be visible
+	TInt idx;
+	for(idx = aIdx - 1; idx >= 0; --idx)
+		{
+		CMDBRecordBase* rec = iRecordSetContainer->iRecords[idx];
+		if(iDeletedRecords.Find(rec->RecordId()) >= 0)
+			{
+			continue;	// deleted are always invisible
+			}
+		if(iShowHidden || !rec->IsSetAttribute(ECDHidden))
+			{
+			break;
+			}
+		}
+	if(idx >= 0)
+		{
+		aIdx = idx;
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+TBool CCommDbTableExtension::FindFirstNextValidRecord(TBool aResetToStart)
+	{
+	TInt idx;
+	if(aResetToStart)
+		{
+		iCurrentRecord = NULL;
+		idx = -1;
+		}
+	else 
+		{
+		idx = GetCurrentRecordIndex();
+		}
+	if(!AdvanceIndexToNextValidRecord(idx))
+		{
+		return EFalse;
+		}
+	iCurrentRecord = iRecordSetContainer->iRecords[idx];
+	__FLOG_STMT(TInt recNo = iRecordSetContainer->iRecords.Find(iCurrentRecord);)
+	__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("GotoNextRecord -> CurrentRecord is RecNo:%d"), recNo);
+	return ETrue;
+	}
+
+TBool CCommDbTableExtension::FindFirstPrevValidRecord()
+	{
+	TInt idx = GetCurrentRecordIndex();
+	if(!AdvanceIndexToPrevValidRecord(idx))
+		{
+		return EFalse;
+		}
+	iCurrentRecord = iRecordSetContainer->iRecords[idx];
+	__FLOG_STMT(TInt recNo = iRecordSetContainer->iRecords.Find(iCurrentRecord);)
+	__FLOG_STATIC1(KLogComponent, KCommDbShim, _L("GotoPreviousRecord -> CurrentRecord is RecNo:%d"), recNo);
+	return ETrue;
+	}
+
+TInt CCommDbTableExtension::FindValueInRecSet(TInt aValue) const
+	{
+	// in case of insertion remove inserted record
+	for(TInt index=0; index < iRecordSetContainer->iRecords.Count();index++)
+		{
+		if(iRecordSetContainer->iRecords[index]->RecordId() == aValue)
+			{
+			return index;
+			}
+		}
+	
+	return KErrNotFound;
+	}
+
+//--------------------------------------------------------------------
+//	CCommsDatabaseImpl
+//--------------------------------------------------------------------
+
+CCommsDatabaseImpl::CCommsDatabaseImpl()
+	:iHaveCheckedGSTableExists(EFalse), iDbs(NULL)
+	{
+	
+	}
+CCommsDatabaseImpl::~CCommsDatabaseImpl()
+	{
+	iTableViews.ResetAndDestroy();
+	iConnPrefViews.ResetAndDestroy();
+	
+	//Cancel any pending notifications
+	CancelRequestNotification();
+	
+	
+	// do not delete iDbs before destroying the view arrays above
+	delete iDbs;
+	}
+
+void CCommsDatabaseImpl::RegisterViewL(CCommsDbTableView* aTable)
+	{
+	iTableViews.AppendL(aTable);
+	}
+
+void CCommsDatabaseImpl::UnRegisterView(CCommsDbTableView* aTable)
+	{
+	TInt index = iTableViews.Find(aTable);
+	if (index>=0) 
+		{
+		iTableViews.Remove(index);
+		}
+	}
+
+void CCommsDatabaseImpl::RegisterConnPrefViewL(CCommsDbConnectionPrefTableView* aTable)
+	{
+	iConnPrefViews.AppendL(aTable);
+	}
+
+void CCommsDatabaseImpl::UnRegisterConnPrefView(CCommsDbConnectionPrefTableView* aTable)
+	{
+	TInt index = iConnPrefViews.Find(aTable);
+	if (index>=0) 
+		{
+		iConnPrefViews.Remove(index);
+		}
+	}
+
+void CCommsDatabaseImpl::CheckGlobalSettingsTableExistsL()
+/**
+    Important, this function requires 'ECapabilityWriteDeviceData' capability.
+*/
+    {
+    // We only need to check that the global settings table exists once, because if it doesn't we'll create a placeholder.
+    if (!iHaveCheckedGSTableExists)
+        {
+        // Ensure that a global record always exists.
+    
+        CCDGlobalSettingsRecord* pNewGlobalRecord = static_cast<CCDGlobalSettingsRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdGlobalSettingsRecord));
+        CleanupStack::PushL(pNewGlobalRecord);
+
+        const TInt KGlobalSettingsRecordID = 1;
+        
+        pNewGlobalRecord->SetRecordId(KGlobalSettingsRecordID);
+        
+        TRAPD(err, pNewGlobalRecord->StoreL(*iDbs));
+        if (!(err == KErrNone || err == KErrAlreadyExists))
+            {
+            User::Leave(err);
+            }
+            
+        iHaveCheckedGSTableExists = ETrue;
+                
+        CleanupStack::PopAndDestroy(pNewGlobalRecord);
+        }
+    }
+
+TInt CCommsDatabaseImpl::RequestNotification(TRequestStatus& aStatus)
+	{  
+        TInt ret(KErrNone);		
+	if(!iShimNotifier.Handle())
+                {
+                ret = iShimNotifier.Connect(); //Also starts the server if not running allready
+                }	
+	
+	if(ret == KErrNone)
+               {
+               iShimNotifier.RequestNotification(aStatus);
+               }
+               
+        return ret;
+	}
+
+void CCommsDatabaseImpl::CancelRequestNotification()
+	{
+	if(iShimNotifier.Handle())
+		{
+		iShimNotifier.CancelNotification(); 	
+		}
+	iShimNotifier.Close();	
+	}
+
+
+
+// ------------------------ CommDb Shim Utils -------------------------
+
+/**
+@internalTechnology
+*/
+typedef struct 
+	{
+	const TText* iTableName;
+	TUint iTableId;
+	} TCommDbTableMapping;
+		
+/**
+Number of mappings in the table
+@internalTechnology
+*/
+const TInt KTableMappingsCount = 30;
+
+/**
+Mappings between legacy commdb table names and the commsdat table element id's
+@internalTechnology
+*/
+const TCommDbTableMapping tableMappings[KTableMappingsCount] = 
+	{
+		{ KCDTypeNameModemBearer, CommsDat::KCDTIdModemBearerRecord },
+		{ KCDTypeNameLANBearer, CommsDat::KCDTIdLANBearerRecord },
+		{ KCDTypeNameVirtualBearer, CommsDat::KCDTIdVirtualBearerRecord },
+		{ KCDTypeNameWAPSMSBearer, CommsDat::KCDTIdWAPSMSBearerRecord },
+		{ KCDTypeNameWAPIPBearer, CommsDat::KCDTIdWAPIPBearerRecord },
+		{ KCDTypeNameGlobalSettings, CommsDat::KCDTIdGlobalSettingsRecord },
+		{ KCDTypeNameConnectionPrefs, CommsDat::KCDTIdConnectionPrefsRecord },
+		{ KCDTypeNameNetwork, CommsDat::KCDTIdNetworkRecord },
+		{ KCDTypeNameLocation, CommsDat::KCDTIdLocationRecord },
+		{ KCDTypeNameIAP, CommsDat::KCDTIdIAPRecord },
+		{ KCDTypeNameWAPAccessPoint, CommsDat::KCDTIdWAPAccessPointRecord },
+		{ KCDTypeNameDialOutISP, CommsDat::KCDTIdDialOutISPRecord },
+		{ KCDTypeNameDialInISP, CommsDat::KCDTIdDialInISPRecord },
+		{ KCDTypeNameLANService, CommsDat::KCDTIdLANServiceRecord },
+		{ KCDTypeNameWLANServiceExt, CommsDat::KCDTIdWLANServiceExtRecord },
+		{ KCDTypeNameVPNService, CommsDat::KCDTIdVPNServiceRecord },
+		{ KCDTypeNameOutgoingWCDMA, CommsDat::KCDTIdOutgoingGprsRecord },
+		{ KCDTypeNameIncomingWCDMA, CommsDat::KCDTIdIncomingGprsRecord },
+		{ KCDTypeNamePANServiceExt, CommsDat::KCDTIdPANServiceExtRecord },
+		{ KCDTypeNameDefaultWCDMA, CommsDat::KCDTIdDefaultWCDMARecord },
+		{ KCDTypeNameChargecard, CommsDat::KCDTIdChargecardRecord },
+		{ KCDTypeNameProxies, CommsDat::KCDTIdProxiesRecord },
+		{ KCDTypeNameSSProto, CommsDat::KCDTIdSSProtoRecord },
+		{ KCDTypeNameAgentLookup, CommsDat::KCDTIdAgentLookupRecord },
+		{ KCDTTypeNameEAPSec, CommsDat::KCDTIdEAPSecRecord },
+		{ KCDTTypeNameTunEAP, CommsDat::KCDTIdTunEAPRecord },
+		{ KCDTTypeNameEAPTLS, CommsDat::KCDTIdEAPTLSRecord },
+		{ KCDTTypeNameLEAP, CommsDat::KCDTIdLEAPRecord },
+
+		// These didn't exist in Commdb and don't have textual names
+		//		KCDTIdAccessPointRecord
+		//		KCDTIdIapPrioritySelectionPolicyRecord
+		//		KCDTIdWCDMAPacketServiceRecord
+		//		KCDTIdUmtsR99QoSAndOnTableRecord
+	};
+
+
+
+/**
+@internalTechnology
+*/
+EXPORT_C CommsDat::TMDBElementId CommDbShimUtil::GetElementIdFromFieldNameL(const TDesC& aFieldName)
+	{
+	_LIT(KSlashCharacter, "\\");
+   	TInt slashPos = aFieldName.Find(KSlashCharacter);
+   	if(slashPos < 0)
+   		{
+   		User::Leave(KErrArgument);
+   		}
+   	TPtrC tableName(aFieldName.Ptr(), slashPos);
+   	TPtrC fieldName(aFieldName.Ptr() + slashPos + 1, aFieldName.Length() - slashPos - 1);
+
+   	CMDBRecordBase* record = NULL;
+	TInt i = 0;
+	while (record == NULL && i < KTableMappingsCount)
+		{
+		if (!tableName.CompareF(TPtrC(tableMappings[i].iTableName))) 
+			{
+			record = CCDRecordBase::RecordFactoryL(tableMappings[i].iTableId);
+			CleanupStack::PushL(record);
+			break;
+			}
+		i++;
+		}
+
+	TMDBElementId elementId;
+	if (!record)
+		{
+        // Create a temporary example of the user defined record, in order to do the lookup by name and get the Id back.
+        CMDBGenericRecord* tempUserDefinedRecord = static_cast<CMDBGenericRecord*>(CCDRecordBase::RecordFactoryL(0));
+        CleanupStack::PushL(tempUserDefinedRecord);
+        
+    	tempUserDefinedRecord->InitializeL(tableName, NULL);
+
+    	CMDBSession* dbs = CMDBSession::NewLC(KCDVersion1_1);
+        tempUserDefinedRecord->LoadL(*dbs);
+
+        // Get the Id that we're interested in...
+        TUint tableId = tempUserDefinedRecord->TableId();
+
+        CleanupStack::PopAndDestroy(); // dbs
+        CleanupStack::PopAndDestroy(); // tempUserDefinedRecord
+        
+		record = CCDRecordBase::RecordFactoryL(tableId);
+		CleanupStack::PushL(record);	
+		}
+	
+	TInt tempType;
+	CMDBElement* field = record->GetFieldByNameL(fieldName, tempType);
+	elementId = field->ElementId();
+	CleanupStack::PopAndDestroy(); // record
+	return elementId;
+	}
+
+//EOF