phonebookengines/contactsmodel/tsrc/performance/T_PerfCrudOperations.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/performance/T_PerfCrudOperations.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,333 @@
+// 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:
+//
+
+/**
+@SYMPREQ                  PREQ1187
+@SYMComponent             app-engines_cntmodel
+@SYMAuthor                Simon Mellor, JamesCl
+@SYMTestStatus            Implemented
+@SYMTestType              CT
+
+@SYMTestCaseDesc          Tests the performance of Reading and Updating a single contact and of
+						  Matching Contacts by Phone Number on a corporate profile database of 
+						  1000 contacts. 
+
+@SYMTestActions           Measures the time taken to: 
+						  -- Attempt to match a phone number using CContactDatabase::MatchPhoneNumberL()
+						  -- Create a contact using CContactDatabase::AddNewContactL()
+						  -- Read   a contact using CContactDatabase::OpenContactLX()
+						  -- Update a contact using CContactDatabase::CommitContactL()
+						  -- Delete a contact using CContactDatabase::DeleteContactL()
+
+@SYMTestExpectedResults   Test cases will run without leaving and will output timing information.
+
+*/
+
+#include "T_PerfCrudOperations.h"
+#include "../T_UTILS.H"
+#include <cntitem.h>
+
+// Constants   
+_LIT(KDbPathName,"C:Contacts.cdb");
+const TPtrC KDbPath( (KDbPathName) );
+
+
+CCrudOperations::CCrudOperations()
+	{
+	} 
+
+CCrudOperations::~CCrudOperations()
+	{
+	iDb->CloseTables();
+	delete iDb;
+	} 
+	
+CCrudOperations* CCrudOperations::NewLC(RTest& aTest)
+	{
+	CCrudOperations* self = new(ELeave) CCrudOperations();
+	CleanupStack::PushL(self);
+	self->ConstructL(aTest);
+	return(self);
+	}  
+
+void CCrudOperations::ConstructL(RTest& aTest)
+	{
+	iTest = &aTest;
+	iDb = CContactDatabase::OpenL(KDbPath);
+	CCntTest::ProfileReset(0, 59);
+	} 
+
+/**
+	Main test routine.
+*/
+void CCrudOperations::DoTestsL(TInt aNumMsToGet20ItemsFromView)
+	{
+	iNumMsToGet20ItemsFromView= aNumMsToGet20ItemsFromView;
+
+	// As, at this point, we haven't used the database before, this is the 
+	// equivalent of startup. We fetch a contact as a bare minimum operation 
+	// on the database to ensure that we fetch and cache the system template.
+	// Then, we just get rid of the contact item as we don't actually want it.
+	const TInt KContactIdOne(1);
+	CContactItem* tmpItem = iDb->ReadContactLC(KContactIdOne);
+	CleanupStack::PopAndDestroy(tmpItem);
+	tmpItem = NULL;
+
+	MatchContactsByPhoneNumL();
+	MatchContactsByEmailAndSipL();
+	DoCrudTestsL();
+	}
+
+/**
+	Try to match the phone number given with existing numbers in the database.
+*/
+void CCrudOperations::MatchContactsByPhoneNumL()
+	{
+	_LIT(KPass, "Pass");
+	_LIT(KFail, "Fail");
+	_LIT(KMatchOutputFormat1, "Number of phone numbers matched: %d -- %s\n");
+	_LIT(KMatchOutputFormat2, "Phone number lookup took: %d s %03d\n");
+	_LIT(KMatchOutputFormat3, "The contact's first name: %S\n");
+
+	_LIT(KPhoneNumberToFind, "241867306233253164487125"); // this number belongs to the 1000th
+														  // contact item in the database, which 
+														  // has a photo. 
+	
+	const TInt KMatchLengthFromRight(7); // match on the number without the dialling code prefix
+										 // to avoid differences like +447876... and 07876...
+	_LIT(KPhoneNumberTestTitle, "\nBeginning Phone Number Match testing...\n");
+
+
+	iTest->Printf(KPhoneNumberTestTitle);
+	TCntPerfTimer timer;
+	timer.StartTimer();
+	
+	// Search the database...
+	CContactIdArray* idArray = iDb->MatchPhoneNumberL(KPhoneNumberToFind, KMatchLengthFromRight);
+	CleanupStack::PushL(idArray);
+	TInt numMatches = idArray->Count();
+	iTest->Printf(KMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr());
+
+	if (numMatches)
+		{
+		//fetch first contact item in array
+		CContactItem* item = iDb->ReadContactLC((*idArray)[0]);
+		timer.StopTimer();
+		CContactItemFieldSet& fieldSet = item->CardFields();
+		TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName);
+		if (firstNameFieldId == KErrNotFound)
+			{
+			User::Leave(KErrNotFound);
+			}
+		CContactItemField& firstNameField = fieldSet[firstNameFieldId];
+		CContactTextField* firstNameText = firstNameField.TextStorage();
+		TPtrC firstName(firstNameText->Text());
+		iTest->Printf(KMatchOutputFormat3, &firstName);
+
+		CleanupStack::PopAndDestroy(item);
+		}
+	else
+		{
+		timer.StopTimer();
+		}
+
+	CleanupStack::PopAndDestroy(idArray);
+
+	TInt result = timer.Result();
+	TBuf<64> formattable;
+	formattable.Format(KMatchOutputFormat2, result / 1000000, (result / 1000) % 1000);
+	iTest->Printf(formattable);
+	}
+
+/**
+	Try to match the phone number given with existing numbers in the database.
+*/
+void CCrudOperations::MatchContactsByEmailAndSipL()
+	{
+	_LIT(KPass, "Pass");
+	_LIT(KFail, "Fail");
+	_LIT(KEmailMatchOutputFormat1,"Number of email addresses matched: %d -- %s\n");
+	_LIT(KEmailMatchOutputFormat2,"Email address lookup took: %d s %03d\n");
+	_LIT(KMatchOutputFormat3, "The contact's first name: %S\n");
+
+	// Test Email address matching
+
+	// this address belongs to the 1000th contact item in the database, which has a photo. 
+	_LIT(KEmailAddressToFind, "fred.bloggs@symbian.com"); 
+	_LIT(KEmailTestTitle, "\nBeginning Email Address Match testing...\n");
+
+	iTest->Printf(KEmailTestTitle);
+	TCntPerfTimer timer;
+	timer.StartTimer();
+	
+	// Search the database...
+	CContactItemFieldDef* fieldsToSearch = new (ELeave) CContactItemFieldDef();
+	CleanupStack::PushL(fieldsToSearch);
+	fieldsToSearch->AppendL(KUidContactFieldEMail);
+	CContactIdArray* idArray = iDb->FindLC(KEmailAddressToFind, fieldsToSearch);
+	TInt numMatches = idArray->Count();
+	iTest->Printf(KEmailMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr());
+
+	if (numMatches)
+		{
+		//fetch first contact item in array
+		CContactItem* item = iDb->ReadContactLC((*idArray)[0]);
+		CContactItemFieldSet& fieldSet = item->CardFields();
+		TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName);
+		if (firstNameFieldId == KErrNotFound)
+			{
+			User::Leave(KErrNotFound);
+			}
+		CContactItemField& firstNameField = fieldSet[firstNameFieldId];
+		CContactTextField* firstNameText = firstNameField.TextStorage();
+		TPtrC firstName(firstNameText->Text());
+		iTest->Printf(KMatchOutputFormat3, &firstName);
+		CleanupStack::PopAndDestroy(item);
+		}
+	
+	timer.StopTimer();
+	CleanupStack::PopAndDestroy(2, fieldsToSearch); // and idArray
+
+	
+	TInt result = timer.Result();
+	TBuf<64> formattable;
+	formattable.Format(KEmailMatchOutputFormat2, result / 1000000, (result / 1000) % 1000);
+	iTest->Printf(formattable);
+
+	// reset variables
+	fieldsToSearch = NULL;
+	idArray = NULL;
+	numMatches = 0;
+	timer.ResetTimer();
+	result = 0;
+	formattable.Zero();
+
+	
+	// Test SIP address matching
+
+	// this address belongs to the 1000th contact item in the database, which has a photo. 
+	_LIT(KSipAddressToFind, "sip:fred.bloggs@symbian.com"); 
+	_LIT(KSipTestTitle, "\nBeginning SIP Address Match testing...\n");
+	_LIT(KSipMatchOutputFormat1,"Number of SIP addresses matched: %d -- %s\n");
+	_LIT(KSipMatchOutputFormat2,"SIP address lookup took: %d s %03d\n");
+
+	iTest->Printf(KSipTestTitle);
+	timer.StartTimer();
+	
+	// Search the database...
+	fieldsToSearch = new (ELeave) CContactItemFieldDef();
+	CleanupStack::PushL(fieldsToSearch);
+	fieldsToSearch->AppendL(KUidContactFieldSIPID);
+	idArray = iDb->FindLC(KSipAddressToFind, fieldsToSearch);
+	numMatches = idArray->Count();
+	iTest->Printf(KSipMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr());
+
+	if (numMatches)
+		{
+		//fetch first contact item in array
+		CContactItem* item = iDb->ReadContactLC((*idArray)[0]);
+		CContactItemFieldSet& fieldSet = item->CardFields();
+		TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName);
+		if (firstNameFieldId == KErrNotFound)
+			{
+			User::Leave(KErrNotFound);
+			}
+		CContactItemField& firstNameField = fieldSet[firstNameFieldId];
+		CContactTextField* firstNameText = firstNameField.TextStorage();
+		TPtrC firstName(firstNameText->Text());
+		iTest->Printf(KMatchOutputFormat3, &firstName);
+		CleanupStack::PopAndDestroy(item);
+		}
+	
+	timer.StopTimer();
+	CleanupStack::PopAndDestroy(2, fieldsToSearch); // and idArray
+
+	result = timer.Result();
+	formattable.Format(KSipMatchOutputFormat2, result / 1000000, (result / 1000) % 1000);
+	iTest->Printf(formattable);
+	}
+
+
+/**
+	Perform CRUD operations with 1 item in the database.
+*/
+void CCrudOperations::DoCrudTestsL()
+	{
+	// chosen because they have a photo field
+	const TContactItemId K901stContactItemId(901);
+	const TContactItemId K973rdContactItemId(973); 
+	const TContactItemId K926thContactItemId(926);
+
+	_LIT(KCRUDTestTitle, "\nBeginning CRUD Operations on 1 Contact (with photo) testing ...\n");
+	_LIT(KCRUDTestNote, "[Figures for each write operation include time to fetch first 20 items in view.]\n");
+	iTest->Printf(KCRUDTestTitle);
+	iTest->Printf(KCRUDTestNote);
+	
+	TCntPerfTimer timer;
+
+	// fetch a contact item to seed a new one
+	CContactItem* temp = iDb->OpenContactL(K901stContactItemId);
+	CleanupStack::PushL(temp);
+	CContactItem* item = CContactCard::NewL(temp);
+	CleanupStack::PopAndDestroy(temp);
+	CleanupStack::PushL(item);
+
+	// Create (add) a contact with a photo
+	timer.StartTimer();
+	iDb->AddNewContactL(*item);
+	timer.StopTimer();
+	TInt createResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view.
+	timer.ResetTimer();
+	CleanupStack::PopAndDestroy(item);
+	item = NULL;
+
+	// Read a contact with a photo
+	timer.StartTimer();
+	item = iDb->OpenContactLX(K973rdContactItemId); // lock object put on the CleanupStack
+	CleanupStack::PushL(item);
+	timer.StopTimer();
+	TInt readResult = timer.Result();
+	timer.ResetTimer();
+	
+	// Update the contact in the database
+	timer.StartTimer();
+	iDb->CommitContactL(*item);
+	timer.StopTimer();
+	TInt updateResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view.
+	timer.ResetTimer();
+	CleanupStack::PopAndDestroy(item);
+	item = NULL;
+	CleanupStack::PopAndDestroy(); // lock object
+
+	// Delete a contact with a photo
+	timer.StartTimer();
+	iDb->DeleteContactL(K926thContactItemId);
+	timer.StopTimer();
+	TInt deleteResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view.
+	timer.ResetTimer();
+	
+	// output timing result
+	_LIT(KCreateOutputFormat,"Creating (adding) 1 contact took: %d s %03d\n");
+	iTest->Printf(KCreateOutputFormat, createResult / 1000000, (createResult / 1000) % 1000);
+
+	_LIT(KReadOutputFormat,"Reading 1 contact took: %d s %03d\n");
+	iTest->Printf(KReadOutputFormat, readResult / 1000000, (readResult / 1000) % 1000);
+
+	_LIT(KUpdateOutputFormat,"Updating 1 contact took: %d s %03d\n");
+	iTest->Printf(KUpdateOutputFormat, updateResult / 1000000, (updateResult / 1000) % 1000);
+
+	_LIT(KDeleteOutputFormat,"Deleting 1 contact took: %d s %03d\n");
+	iTest->Printf(KDeleteOutputFormat, deleteResult / 1000000, (deleteResult / 1000) % 1000);
+	}