diff -r fd64c38c277d -r b46a585f6909 phonebookengines_old/contactsmodel/tsrc/T_UTILS.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/tsrc/T_UTILS.CPP Fri Jun 11 13:29:23 2010 +0300 @@ -0,0 +1,872 @@ +// Copyright (c) 1997-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: +// + +#include +#include +#include +#include "T_UTILS.H" + +// +// CCntTest +// +EXPORT_C CCntTest::~CCntTest() + { + delete iDb; + delete iCleanup; + iFs.Close(); + // RTest object is created in each test harness and does a __UHEAP_MARK + // the Close() method does a __UHEAP_MARKEND and so must now be the last action + iTest->Close(); + } + +EXPORT_C void CCntTest::ConstructL(RTest &aTest, const TDesC &aDatabaseName) + { + iDatabaseName.Copy(aDatabaseName); + CActiveScheduler::Install(new(ELeave) CActiveScheduler); + iTest=&aTest; + iTest->Title(); + iCleanup=CTrapCleanup::New(); + User::LeaveIfError(iFs.Connect()); + } + +EXPORT_C void CCntTest::SelectDriveL() + { + TDriveList driveList; + iFs.DriveList(driveList); + driveList[25]=0; // Get rid of Z: + TBuf<2> drive; + drive.Copy(_L("C:")); + TInt driveCount=0; + for(TInt loop0=0;loop01) + { + iTest->Printf(_L("Select drive for multi access test:\n")); + for(TInt loop=0;loopPrintf(_L("%c:\n"),loop+'A'); + FOREVER + { + TChar key=iTest->Getch(); + TInt index=key.GetLowerCase()-'a'; + if (index>=0 && indexEnd(); + (*iTest)(iFs.ResourceCount()==0); + delete CActiveScheduler::Current(); + delete this; + } + +EXPORT_C CContactDatabase *CCntTest::CreateDatabaseL() + { + CloseDatabase(); + iDb=CContactDatabase::ReplaceL(iDatabaseName); + return(iDb); + } + +EXPORT_C CContactDatabase* CCntTest::OpenDatabaseL() + { + CloseDatabase(); + iDb=CContactDatabase::OpenL(iDatabaseName); + return(iDb); + } + +EXPORT_C void CCntTest::CloseDatabase() + { + delete iDb; + iDb=NULL; + } + +EXPORT_C void CCntTest::DeleteDatabaseL() + { + CContactDatabase::DeleteDatabaseL(iDatabaseName); + } + +EXPORT_C void CCntTest::DeleteAllTemplateFieldsL() + { + CContactItemViewDef *viewDef=CContactItemViewDef::NewL(CContactItemViewDef::EMaskFields,CContactItemViewDef::EIncludeHiddenFields); + CContactItem *item=iDb->OpenContactLX(iDb->TemplateId(),*viewDef); + delete viewDef; + CleanupStack::PushL(item); + CContactItemFieldSet& fieldSet=item->CardFields(); + while(fieldSet.Count()) + fieldSet.Remove(0); + iDb->CommitContactL(*item); + CleanupStack::PopAndDestroy(2); // item,close + } + +EXPORT_C void CCntTest::TestField(CContactItemField &aField,TStorageType aType,TFieldType aFieldType,TUid aMapping) + { + (*iTest)(aField.StorageType()==aType); + (*iTest)(aField.ContentType().ContainsFieldType(aFieldType)); + (*iTest)(aField.ContentType().Mapping()==aMapping); + } + +EXPORT_C void CCntTest::AdjustContactAccessCountL(TContactItemId aItemId, TInt aCount) + { + CContactItem *incItem=iDb->OpenContactLX(aItemId); + CleanupStack::PushL(incItem); + while(aCount>0) + { + incItem->IncAccessCount(); + aCount--; + } + while(aCount<0) + { + incItem->DecAccessCount(); + aCount++; + } + iDb->CommitContactL(*incItem); + CleanupStack::PopAndDestroy(2); // incItem, Close(incItem) + } + +EXPORT_C void CCntTest::TestAccessCount(TContactItemId aItemId, TInt aCount) + { + CContactItem *item=iDb->ReadContactLC(aItemId); + (*iTest)(item->AccessCount()==aCount); + CleanupStack::PopAndDestroy(); // item + } + +EXPORT_C TBool CCntTest::CompareFields(CContactItemField &aField1, CContactItemField &aField2) + { + return(aField1.Label()==aField2.Label() && + aField1.StorageType()==aField2.StorageType() && + aField1.ContentType()==aField2.ContentType()); + } + +EXPORT_C void CCntTest::CheckDeletedContact(TContactItemId aDeleteId) + { + CContactItem *deletedContact=iDb->ReadContactLC(aDeleteId); + (*iTest)(deletedContact->IsDeleted()); + (*iTest)(deletedContact->CardFields().Count()==0); + TBuf<10> textDef; + iDb->ReadContactTextDefL(aDeleteId,textDef); + (*iTest)(textDef.Length()==0); + CleanupStack::PopAndDestroy(); // deletedContact + } + +EXPORT_C void CCntTest::CheckContactDoesNotExist(TContactItemId aNotExistId) + { + TRAPD(notExist,iDb->ReadContactLC(aNotExistId)); + (*iTest)(notExist==KErrNotFound); + } + +EXPORT_C void CCntTest::DeleteContact(TContactItemId aDeleteMe) + { + TRAP_IGNORE(iDb->DeleteContactL(aDeleteMe)); + } + +EXPORT_C HBufC *CCntTest::ContactUidLC(TContactItemId aId, TInt64 aMachineId) + { + CContactItem *contact=iDb->ReadContactLC(aId); + HBufC *uid=contact->UidStringL(aMachineId).AllocL(); + CleanupStack::PopAndDestroy(); // deletedContact + CleanupStack::PushL(uid); + return(uid); + } + +EXPORT_C CVCardTestStore* CCntTest::ExportContactsLC(const CContactIdArray *aIds, TUint aFormatFlags, TVCardStoreType aType, TInt aFileNum) + { + CVCardTestStore* store=ExportContactsL(iDb,aIds,aFormatFlags, aType, &iFs, aFileNum); + CleanupStack::PushL(store); // outstream + return(store); + } + +EXPORT_C CVCardTestStore* CCntTest::ExportContactLC(TContactItemId aId, TUint aFormatFlags, TVCardStoreType aType, TInt aFileNum) + { + CContactIdArray *ids=CContactIdArray::NewLC(); + ids->AddL(aId); + CVCardTestStore* store=ExportContactsLC(ids,aFormatFlags, aType, aFileNum); + CleanupStack::Pop(); // store + CleanupStack::PopAndDestroy(); // ids + CleanupStack::PushL(store); + return(store); + } + +EXPORT_C void CCntTest::ImportContacts1by1L(CVCardTestStore* aStore, TUint aFormatFlags) + { + RStoreReadStream instream; + instream.OpenLC(*aStore->Store(),aStore->StreamId()); + TBool success=EFalse; + do + { + CArrayPtr* items=iDb->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl),instream,success,aFormatFlags); + items->ResetAndDestroy(); + delete items; + } while(success); + CleanupStack::PopAndDestroy(); // instream + } + +EXPORT_C CArrayPtr* CCntTest::ImportContactsL(CVCardTestStore* aStore, TUint aFormatFlags) + { + return(::ImportContactsL(iDb,aStore,aFormatFlags)); + } + +EXPORT_C CArrayPtr* CCntTest::ImportContactsLC(CVCardTestStore* aStore, TUint aFormatFlags) + { + CArrayPtr* items=ImportContactsL(aStore, aFormatFlags); + CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy,items)); + return(items); + } + +class RTestSession : public RSessionBase + { +public: + TInt CreateSession(); + }; + +TInt RTestSession::CreateSession() + { + TVersion version; + return(RSessionBase::CreateSession(_L("CntLockServer"),version,1)); + } + +EXPORT_C TBool CCntTest::LockServerSessionExists(TBool aPause) const + { + if (aPause) + User::After(200000); + RTestSession session; + TInt sessionErr=session.CreateSession(); + session.Close(); + return(sessionErr==KErrNone); + } + +EXPORT_C void CCntTest::PrintfNewline() const + { + (*iTest).Printf(_L("\n")); + } + +EXPORT_C TInt CCntTest::LockServerProcessCount(TBool aPause, TBool aDisplayCount, TBool aDisplayList) const + { + if (aPause) + User::After(200000); + TInt count=0; + TFullName fullName; + TFindProcess find(_L("cntsrv*")); + if (aDisplayList) + iTest->Printf(_L("Lock server process list\n")); + while(find.Next(fullName)==KErrNone) + { + count++; + if (aDisplayList) + { + iTest->Printf(fullName); + PrintfNewline(); + } + } + if (aDisplayCount) + { + iTest->Printf(_L("Process count=%d"),count); + PrintfNewline(); + } + return(count); + } + +EXPORT_C void CCntTest::TestLockServerExists() const + { + (*iTest)(LockServerProcessCount(EFalse,EFalse,ETrue)==1); + } + +EXPORT_C void CCntTest::TestNoLockServer() const + { + TInt retries=0; + FOREVER + { + TInt count=LockServerProcessCount(EFalse,EFalse,ETrue); + if (count==0) + break; + if (retries==5) + { + iTest->Printf(_L("Error lock server count=%d\nPress 't' to try again\n"),count); + TChar key=iTest->Getch(); + if (key=='t') + retries--; + else + (*iTest)(EFalse); + } + User::After(100000); + retries++; + } + } + + +EXPORT_C void CCntTest::TestLockServerCloses() const + { + // Contacts Lock Server waits 5sec from last client until shutdown + TInt time = 0; + TInt count = LockServerProcessCount(); + + while (count) + { + if (time > 55) + { // 5.5 sec - too slow + (*iTest)(EFalse); + } + // wait a 1/10th second, then count again + User::After(100000); + time++; + count = LockServerProcessCount(); + } + } + + +/* +The RDebug::Profile APIs are removed from secure builds using +the __SECURE_API__ macro. + +Although the APIs are present in EKA2, the EKA2 macro has been +used because the implementation of the RDebug::Profile APIs +does not do anything in EKA2. + +In EKA2 +TCntProfileTls is stored in 'Thread Local Storage' and contains +a TTime, used to store the time when ProfileStart() is called +and a TCntProfile, used to store the time elapsed and to count +the pairs of calls to ProfileStart() and ProfileEnd(). +Only 1 'Profile Bin' can be used in EKA2 with this approach. + +The 'Thread Local Storage' is stored on the heap so therfore +if a call to ProfileStart() is made then it must be followed +by a call to either ProfileReset() or ProfileResult() to ensure +the memory is freed +*/ + +EXPORT_C TInt CCntTest::ProfileResult(TCntProfile* aProfile,TInt,TInt) + { + TCntProfileTls* tls = (TCntProfileTls*)Dll::Tls(); + if(!tls) + { + // The tls has not been created + // do nothing + } + else + { + *aProfile = tls->iProfile; + delete tls; + Dll::FreeTls(); + } + return KErrNone; + } + +EXPORT_C TInt CCntTest::ProfileReset(TInt,TInt) + { + // Always exit with no tls allocated + TCntProfileTls* tls = (TCntProfileTls*)Dll::Tls(); + if(!tls) + { + // The tls has not been created + // do nothing + } + else + { + delete tls; + Dll::FreeTls(); + } + return KErrNone; + } + +EXPORT_C TInt CCntTest::ProfileStart(TInt) + { + TCntProfileTls* tls = (TCntProfileTls*)Dll::Tls(); + if(!tls) + { + tls = new (ELeave) TCntProfileTls(); + Dll::SetTls(tls); + tls->iProfile.iTime = 0; + tls->iProfile.iCount = 0; + } + ++tls->iProfile.iCount; + tls->iTime.UniversalTime(); + return KErrNone; + } + +EXPORT_C TInt CCntTest::ProfileEnd(TInt) + { + TCntProfileTls* tls = (TCntProfileTls*)Dll::Tls(); + if(!tls) + { + // The tls has not been created + // do nothing + } + else + { + TTime myTime; + myTime.UniversalTime(); + tls->iProfile.iTime += ((myTime).MicroSecondsFrom(tls->iTime)).Int64(); + } + return KErrNone; + } + +/* +The RDebug::Profile APIs are present and working on EKA1 (keep these for when +this functionality is reinstated for EKA2. + + + +EXPORT_C TInt CCntTest::ProfileResult(TCntProfile* aProfile,TInt aStart,TInt aCount) + { + TProfile* p = reinterpret_cast(&aProfile[0]); + const TInt result = RDebug::ProfileResult(p,aStart,aCount); + return result; + } + +EXPORT_C TInt CCntTest::ProfileReset(TInt aStart,TInt aCount) + { + return RDebug::ProfileReset(aStart, aCount); + } + +EXPORT_C TInt CCntTest::ProfileStart(TInt aProfile) + { + return RDebug::ProfileStart(aProfile); + } + +EXPORT_C TInt CCntTest::ProfileEnd(TInt aProfile) + { + return RDebug::ProfileEnd(aProfile); + } +*/ + + +EXPORT_C TBool TestGroupStateL(CContactDatabase* aDb, TInt aGroupCount, TInt aGroupEntryCount) + { + CContactIdArray* groupIdList=aDb->GetGroupIdListL(); + CleanupStack::PushL(groupIdList); + TInt groupCount=groupIdList->Count(); + if (aGroupCount>=0 && groupCount!=aGroupCount) + return(EFalse); + TInt groupEntryCount=0; +// Cross check that all contacts think they are in all the groups that think they contain the contact + for(TInt groupIndex=0;groupIndexReadContactLC(groupId); + const CContactIdArray* itemsContained=group->ItemsContained(); + TInt itemCount=itemsContained->Count(); + groupEntryCount+=itemCount; + for (TInt itemLoop=0;itemLoopReadContactLC((*itemsContained)[itemLoop]); + CContactIdArray* groupsJoined=contact->GroupsJoinedLC(); + TInt groupsJoinedLoop=0; + for (;groupsJoinedLoopCount();groupsJoinedLoop++) + { + if ((*groupsJoined)[groupsJoinedLoop]==groupId) + break; + } + if (groupsJoinedLoop==groupsJoined->Count()) + return(EFalse); + CleanupStack::PopAndDestroy(2,contact); + } + CleanupStack::PopAndDestroy(group); + } + if (aGroupEntryCount>=0 && groupEntryCount!=aGroupEntryCount) + return(EFalse); + CleanupStack::PopAndDestroy(groupIdList); +// Now cross check the other way, + const CContactIdArray* contacts=aDb->SortedItemsL(); + for(TInt contactIndex=0;contactIndexCount();contactIndex++) + { + TContactItemId contactId=(*contacts)[contactIndex]; + CContactItemPlusGroup *item=(CContactItemPlusGroup*)aDb->ReadContactLC(contactId); + CContactIdArray* groupsJoined=item->GroupsJoinedLC(); + for (TInt groupsJoinedLoop=0;groupsJoinedLoopCount();groupsJoinedLoop++) + { + CContactGroup *group=(CContactGroup *)aDb->ReadContactLC((*groupsJoined)[groupsJoinedLoop]); + const CContactIdArray* itemsContained=group->ItemsContained(); + TInt itemsCount=itemsContained->Count(); + TInt itemLoop=0; + for (;itemLoop* array=(CArrayPtr*)aArray; + array->ResetAndDestroy(); + delete array; + } + } + +EXPORT_C TPtrC FieldText(CContactItem& aItem,TUid aType) + { + CContactItemFieldSet& fieldSet=aItem.CardFields(); + const TInt pos=fieldSet.Find(aType); + if (pos==KErrNotFound || fieldSet[pos].StorageType()!=KStorageTypeText) + return _L(""); + return fieldSet[pos].TextStorage()->Text(); + } + +EXPORT_C void SetNameL(CContactItem& aItem,TUid aFieldType,TUid aMapping, const TDesC& aName, TBool aAddEntry) +// +// Set the contents of a text field, creating the field if required +// + { + TInt pos=KErrNotFound; + if (!aAddEntry) + { + CContactItemFieldSet& fieldSet=aItem.CardFields(); + pos=fieldSet.Find(aFieldType); + if (pos!=KErrNotFound) + fieldSet[pos].TextStorage()->SetTextL(aName); + } + if (pos==KErrNotFound) + { + CContactItemField* field=CContactItemField::NewLC(KStorageTypeText,aFieldType); + field->SetMapping(aMapping); + field->TextStorage()->SetTextL(aName); + aItem.AddFieldL(*field); + CleanupStack::Pop(); // item + } + } + +EXPORT_C void SetUserFlags(CContactItemFieldSet& aFieldSet, TUint aFlags, TInt aIndex) + { + aFieldSet[aIndex].SetUserFlags(aFlags); + } + +EXPORT_C void SetUserFlags(CContactItemFieldSet& aFieldSet, TUint aFlags) + { + SetUserFlags(aFieldSet,aFlags,aFieldSet.Count()-1); + } + +EXPORT_C void SetUserFlags(CContactItem* aItem, TUint aFlags, TInt aIndex) + { + SetUserFlags(aItem->CardFields(),aFlags,aIndex); + } + +EXPORT_C void SetUserFlags(CContactItem* aItem, TUint aFlags) + { + SetUserFlags(aItem->CardFields(),aFlags); + } + +EXPORT_C void AddFieldL(CContactItemFieldSet* aFieldSet, TStorageType aType,TFieldType aFieldType,TUid aMapping) + { + CContactItemField* field=CContactItemField::NewLC(aType,aFieldType); + field->SetMapping(aMapping); + aFieldSet->AddL(*field); + CleanupStack::Pop(); // field + } + +EXPORT_C void AddFieldL(CContactItem* aItem, TStorageType aType,TFieldType aFieldType,TUid aMapping) + { + CContactItemField* field=CContactItemField::NewLC(aType,aFieldType); + field->SetMapping(aMapping); + aItem->AddFieldL(*field); + CleanupStack::Pop(); // field + } + +EXPORT_C void InsertFieldL(CContactItem& aItem, TInt aPos, TStorageType aType,TFieldType aFieldType,TUid aMapping) + { + CContactItemField* field=CContactItemField::NewLC(aType,aFieldType); + field->SetMapping(aMapping); + aItem.InsertFieldL(*field,aPos); + CleanupStack::Pop(); // field + } + +EXPORT_C void InsertFieldL(CContactItem& aItem, TInt aPos, TStorageType aType,TFieldType aFieldType,TUid aMapping, const TDesC& aText) + { + CContactItemField* field=CContactItemField::NewLC(aType,aFieldType); + field->SetMapping(aMapping); + aItem.InsertFieldL(*field,aPos); + field->TextStorage()->SetTextL(aText); + CleanupStack::Pop(); // field + } + +EXPORT_C TContactItemId AddContactL(CContactDatabase* aDb, TFieldType aFieldType,TUid aMapping, const TDesC &aText) + { + CContactCard *item=CContactCard::NewLC(); + SetNameL(*item,aFieldType,aMapping,aText,ETrue); + TContactItemId id=aDb->AddNewContactL(*item); + CleanupStack::PopAndDestroy(); // item + return(id); + } + +EXPORT_C CVCardTestStore* ExportContactsL(CContactDatabase* aDb, const CContactIdArray *aIds, TUint aFormatFlags, TVCardStoreType aType, RFs *aFs, TInt aFileNum) + { + CVCardTestStore* store=CVCardTestStore::NewLC(aType,aFs,aFileNum); + RStoreWriteStream outstream; + TStreamId streamId=outstream.CreateLC(*store->Store()); + TUid uid; + uid.iUid=KUidVCardConvDefaultImpl; + aDb->ExportSelectedContactsL(uid,*aIds,outstream,aFormatFlags); + outstream.CommitL(); + store->SetStreamId(streamId); + store->Store()->CommitL(); + CleanupStack::PopAndDestroy(); // outstream + CleanupStack::Pop(); // store + return(store); + } + +EXPORT_C CArrayPtr* ImportContactsL(CContactDatabase* aDb, CVCardTestStore* aStore, TUint aFormatFlags) + { + RStoreReadStream instream; + instream.OpenLC(*aStore->Store(),aStore->StreamId()); + TBool success=EFalse; + CArrayPtr* items=aDb->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl),instream,success,aFormatFlags); + CleanupStack::PopAndDestroy(); // instream + return(items); + } + +EXPORT_C TBool CompareItemField(const CContactItemField &aItemField1, const CContactItemField &aItemField2, TBool aCheckStorage) + { + if (aItemField1.StorageType()!=aItemField2.StorageType()) + return(EFalse); + TInt count=aItemField1.ContentType().FieldTypeCount(); + if (count!=aItemField2.ContentType().FieldTypeCount()) + return(EFalse); + for(TInt loop=0;loopText(); + TPtrC f2=aItemField2.TextStorage()->Text(); + TInt len=f1.Length(); + if (len==f2.Length()+1 && f1[0]==' ') + f1.Set(&f1[1],len-1); + //if (aItemField1.TextStorage()->Text()!=aItemField2.TextStorage()->Text()) + if (f1!=f2) + return(EFalse); + break; + } + case KStorageTypeStore: + break; + case KStorageTypeContactItemId: + break; + case KStorageTypeDateTime: + if (aItemField1.DateTimeStorage()->Time()!=aItemField2.DateTimeStorage()->Time()) + return(EFalse); + break; + } + } + return(ETrue); + } + +EXPORT_C TBool CompareItemFields(CContactItem *aItem1, CContactItem *aItem2, TBool aCheckStorage, TBool aTemplateLabelRemoved) + { + CContactItemFieldSet& fieldSet1 = aItem1->CardFields(); + CContactItemFieldSet& fieldSet2 = aItem2->CardFields(); + TInt count = fieldSet1.Count(); + TInt check = aTemplateLabelRemoved?count-1:count; + if (check != fieldSet2.Count()) + { + return(EFalse); + } + + for(TInt loop=0;loopConstructL(aType,aFs, aFileNum); + return(store); + } + +EXPORT_C CVCardTestStore::~CVCardTestStore() + { + delete iBufStore; + delete iFileStore; + } + +EXPORT_C void CVCardTestStore::ConstructL(TVCardStoreType aType, RFs *aFs, TInt aFileNum) + { + iType=aType; + switch(iType) + { + case KVCardStoreTypeBuf: + iBufStore=CBufStore::NewL(256); + break; + case KVCardStoreTypeFile: + { + aFs->MkDirAll(_L("c:\\vcards\\")); + TFileName fileName; + fileName.Format(_L("c:\\vcards\\VCard%04d"),aFileNum); + iFileStore=CDirectFileStore::ReplaceL(*aFs,fileName,EFileWrite); + iFileStore->SetTypeL(KDirectFileStoreLayoutUid); + } + break; + } + } + +EXPORT_C CStreamStore *CVCardTestStore::Store() const + { + CStreamStore *store=NULL; + switch(iType) + { + case KVCardStoreTypeBuf: + store=iBufStore; + break; + case KVCardStoreTypeFile: + store=iFileStore; + break; + } + return(store); + } + +// + +// +// TCntPerfTimer +// + +EXPORT_C TCntPerfTimer::TCntPerfTimer() + : iTickCount1(0), iTickCount2(0) + { + } + +EXPORT_C void TCntPerfTimer::StartTimer() + { + iTickCount1 = User::NTickCount(); + } + +EXPORT_C void TCntPerfTimer::StopTimer() + { + iTickCount2 = User::NTickCount(); + } + +EXPORT_C void TCntPerfTimer::ResetTimer() + { + iTickCount1 = 0; + iTickCount2 = 0; + } + +EXPORT_C TUint TCntPerfTimer::Result() + { + TInt tickPeriodMicroSeconds; + HAL::Get(HAL::ENanoTickPeriod, tickPeriodMicroSeconds); + TUint result(0); + if (iTickCount1 > 0 && iTickCount2 > iTickCount1) + { + result = (iTickCount2 - iTickCount1) * tickPeriodMicroSeconds; + } + return result; + } + + +EXPORT_C TBool DbShouldBeInDamagedState(CContactDatabase* aDb) + { + TBool isDamaged(aDb->IsDamaged()); +#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__ + return isDamaged; +#else + return ETrue; +#endif + } + +EXPORT_C CContactItem* ReadContactFromDamagedDbLC(CContactDatabase* aDb, TContactItemId aContactId) + { + CContactItem* item(aDb->ReadContactLC(aContactId) ); +#ifndef __SYMBIAN_CNTMODEL_USE_SQLITE__ + return item; +#else + User::Leave(KErrNotReady); + return NULL; +#endif + }