// 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