phonebookengines/contactsmodel/tsrc/Integration/CntPerfTest/src/PrepareDataTestStep.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/tsrc/Integration/CntPerfTest/src/PrepareDataTestStep.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,553 @@
+// Copyright (c) 2007-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 "PrepareDataTestStep.h"
+
+/**
+ * Constructor
+ */
+CPrepareDataTestStep::CPrepareDataTestStep()
+	{
+	// Mandatory call to base class method to set up the human readable name for logging.
+	SetTestStepName(KPrepareDataTestStep);
+	}
+
+/**
+ * Destructor
+ */
+CPrepareDataTestStep::~CPrepareDataTestStep()
+	{
+	iListOfContactItemsInDatabase.Close();
+	}
+
+/**
+ * Setup the environment required for test, install schedular in the current thread
+ * Opens the relevant contacts database file
+ */
+TVerdict CPrepareDataTestStep::doTestStepPreambleL()
+	{
+ 	CTestContactViewDatabaseUtilitiesStep::doTestStepPreambleL();
+	return TestStepResult();
+	}
+
+/**
+ * Cleanup function for the test step
+ */
+TVerdict CPrepareDataTestStep::doTestStepPostambleL()
+	{
+ 	CTestContactViewDatabaseUtilitiesStep::doTestStepPostambleL();
+	return TestStepResult();
+	}
+
+
+/**
+Base class pure virtual.
+* @return EPass or EFail indicating the result of the test step.
+*/
+TVerdict CPrepareDataTestStep::doTestStepL()
+	{
+	ImportContactsL();
+	AddContactsInDatabaseL();
+	IterateThroAllSortOrderSectionsAndUpdateContactsInDatabaseL();
+	IterateThroAllFilterViewsSectionsAndUpdateL();
+	IterateThroAllMatchingStringSectionsAndUpdateL();
+	AddGroupsInDatabaseL();
+	IterateThroAllGroupSectionsAndUpdateL();
+	UpdateContactToSpecificStringL();
+	CloseDatabaseL();
+	CopyDatabaseL();
+	return TestStepResult();
+	}
+
+/**
+* Import Contact entries
+*/
+void CPrepareDataTestStep::ImportContactsL()
+	{
+	ViewUtilityReference().ImportContactsL();
+	}
+
+/**
+ * Here we are trying add blank contact items in the database
+ * Say some 2000 thousand contacts are added to the database
+ */
+void CPrepareDataTestStep::AddContactsInDatabaseL()
+	{
+	_LIT(KNumOfContacts, "numofcontacts");
+	TInt numOfContacts = 0;
+	GetIntFromConfig(ConfigSection(), KNumOfContacts, numOfContacts);
+
+	for(TInt i = 0; i < numOfContacts; ++i)
+		{
+		CContactCard* contactCard = CContactCard::NewL();
+		CleanupStack::PushL(contactCard);
+		TContactItemId contactId = DatabaseReference().AddNewContactL(*contactCard);
+		CleanupStack::PopAndDestroy(contactCard);
+		iListOfContactItemsInDatabase.AppendL(contactId);
+		DatabaseReference().CloseContactL(contactId);
+		}
+
+	TInt count = DatabaseReference().CountL();
+	_LIT(KDatabaseCount, "Total number of contact entries is %d :");
+	INFO_PRINTF2(KDatabaseCount, count);
+	}
+
+
+/* As mentioned earlier there will be some 1000 blank contacts in the database
+ * Now any view will have it's own criteria like
+ * -- view sort order i.e. the order in which the contact items in the view must be sorted
+ * -- view preferences i.e. whether only contact cards or contact groups or both must be included in the view
+ *    whether the unsorted contacts must be included in the view or not, if included, whether they must be included in the
+ *    start of view or end  of view
+ * It becomes necessary to supply the necessary envirnoment that meets the view criteia
+ * Each view can supply its desired criteria. Based on this, the contacts in the database will be updated to meet the view specificattions
+ */
+void CPrepareDataTestStep::IterateThroAllSortOrderSectionsAndUpdateContactsInDatabaseL()
+	{
+	_LIT(KListOfSortOrderSections, "listofsortorder");
+	TPtrC listOfSortOrderSectionsString;
+	GetStringFromConfig(ConfigSection(), KListOfSortOrderSections, listOfSortOrderSectionsString);
+
+	RArray<TPtrC>	listOfSortOrderSections;
+	CleanupClosePushL(listOfSortOrderSections);
+
+	ViewUtilityReference().TokenizeStringL(listOfSortOrderSectionsString, listOfSortOrderSections);
+
+	for ( TInt i = 0; i < listOfSortOrderSections.Count(); ++i )
+		{
+		UpdateContactFieldsSpecificToSortOrderL(listOfSortOrderSections[i]);
+		}
+
+	CleanupStack::PopAndDestroy(&listOfSortOrderSections);
+	}
+
+/**
+ * Here we are trying add contacts fields in the existing contacts such that they meet the contact views
+ * Sort Order. Intentionally some of the contacts are updated with the contact fields of Null data to meet
+ * the unsorted contacts criteria
+ */
+void CPrepareDataTestStep::UpdateContactFieldsSpecificToSortOrderL(const TPtrC& aSortOrderSection)
+	{
+	// Based on the sort order, the desired number of contacts will be updated i.e contact fields will be
+	// added to the contacts in the database. The new fields added will be as per the sort order
+	// at the end of this operation, if we constuct a contact view with this sort order
+	// then the desired number of contacts will be included in the view
+
+	_LIT(KViewSortOrder, "sortorder");
+	TPtrC viewSortOrderString;
+	GetStringFromConfig(aSortOrderSection, KViewSortOrder, viewSortOrderString);
+
+	RContactViewSortOrder sortOrder = ViewUtilityReference().ConvertStringToSortOrderL(viewSortOrderString) ;
+	CleanupClosePushL(sortOrder);
+
+	_LIT(KNumOfSortableContacts, "numofsortablecontacts");
+	TInt numOfSortableContacts;
+	GetIntFromConfig(aSortOrderSection, KNumOfSortableContacts, numOfSortableContacts);
+
+	// Here we are trying to update the desired number of contacts in the database
+	// with Null contact fields in order to meet the unsortable contacts requirement
+
+	_LIT(KNumUnSortableContacts, "numunsortedcontacts");
+	TInt numUnSortableContacts;
+	GetIntFromConfig(aSortOrderSection, KNumUnSortableContacts, numUnSortableContacts);
+
+	const TInt KTotalNumOfContactsSpecificToThisSortOrder =  numOfSortableContacts + numUnSortableContacts;
+
+	TInt numberOfReadySortableContacts = 0;
+	TInt numberOfReadyUnSortableContacts = 0;
+
+	// There may be contact items in the database that meet the sort order
+	// We need be sure about the contact items that we should update
+
+	RArray <TContactItemId> ListOfContactItemsThatCanUpdatedToMeetSortOrder;
+	CleanupClosePushL(ListOfContactItemsThatCanUpdatedToMeetSortOrder);
+
+
+	for(TInt i = 0; i < iListOfContactItemsInDatabase.Count(); ++i)
+		{
+		TContactItemId desiredContactItemId = iListOfContactItemsInDatabase[i];
+		CContactItem* contact = DatabaseReference().OpenContactL(desiredContactItemId);
+		CleanupStack::PushL(contact);
+		CContactItemFieldSet& fieldSet = contact->CardFields();
+
+		TInt firstContactFieldPosition = fieldSet.Find(sortOrder[0]);
+		TInt secondContactFieldPosition = fieldSet.Find(sortOrder[1]);
+		TInt thirdContactFieldPosition = fieldSet.Find(sortOrder[2]);
+
+		if ((firstContactFieldPosition != KErrNotFound) &&  (secondContactFieldPosition != KErrNotFound) && (thirdContactFieldPosition!= KErrNotFound))
+			{
+			CContactItemField& firstContactItemField = fieldSet[firstContactFieldPosition];
+			CContactItemField& secondContactItemField = fieldSet[secondContactFieldPosition];
+			CContactItemField& thirdContactItemField  = fieldSet[thirdContactFieldPosition];
+
+			if((firstContactItemField.Storage() == NULL) && (secondContactItemField.Storage() == NULL) && (thirdContactItemField.Storage() == NULL))
+				{
+		  		++numberOfReadyUnSortableContacts;
+				}
+			else
+				{
+				++numberOfReadySortableContacts;
+				}
+			}
+		else
+			{
+			ListOfContactItemsThatCanUpdatedToMeetSortOrder.AppendL(desiredContactItemId);
+			}
+
+		CleanupStack::PopAndDestroy(contact);
+		DatabaseReference().CloseContactL(desiredContactItemId);
+		}
+
+	if((numberOfReadyUnSortableContacts + numberOfReadySortableContacts) < KTotalNumOfContactsSpecificToThisSortOrder)
+		{
+		TInt j = 0;
+		for(; j < (numOfSortableContacts-numberOfReadySortableContacts); ++j)
+			{
+			TContactItemId contactItemIdToBeUpdated = ListOfContactItemsThatCanUpdatedToMeetSortOrder[j];
+			CContactItem* contact = DatabaseReference().OpenContactL(contactItemIdToBeUpdated);
+			CleanupStack::PushL(contact);
+			AddContactFieldL(*contact, sortOrder, ETrue);
+			DatabaseReference().CommitContactL(*contact);
+			DatabaseReference().CloseContactL(contactItemIdToBeUpdated);
+			CleanupStack::PopAndDestroy(contact);
+			}
+
+		for(TInt k = j; k < (j + (numUnSortableContacts-numberOfReadyUnSortableContacts)); ++k)
+			{
+			TContactItemId contactItemIdToBeUpdated = ListOfContactItemsThatCanUpdatedToMeetSortOrder[k];
+			CContactItem* contact = DatabaseReference().OpenContactL(contactItemIdToBeUpdated);
+			CleanupStack::PushL(contact);
+			AddContactFieldL(*contact, sortOrder);
+			DatabaseReference().CommitContactL(*contact);
+			DatabaseReference().CloseContactL(contactItemIdToBeUpdated);
+			CleanupStack::PopAndDestroy(contact);
+			}
+		}
+
+	CleanupStack::PopAndDestroy(2,&sortOrder);
+	}
+
+/** Adds contact fields specific to sort order,
+ * Sort Order. Intentionally some of the contacts are updated with the contact fields of Null data to meet
+ * the unsorted contacts criteria
+ */
+void CPrepareDataTestStep::AddContactFieldL(CContactItem& aContact, const RContactViewSortOrder& aSortOrder,
+																								TBool aDataRequired)
+	{
+	const TInt KMaxSortOrderCount = 3;
+	for(TInt i = 0; i < KMaxSortOrderCount; ++i)
+		{
+		TFieldType fieldType = aSortOrder[i];
+		TStorageType storageType = GetStorageType(fieldType);
+		CContentType* contentType = CContentType::NewL();
+		CleanupStack::PushL(contentType);
+		contentType->AddFieldTypeL(fieldType);
+		CContactItemField* field = 	CContactItemField::NewL(storageType, *contentType);
+		CleanupStack::PushL(field);
+
+		if(aDataRequired)
+			{
+			SetDataL(fieldType, *field);
+			}
+
+		aContact.AddFieldL(*field);
+		CleanupStack::Pop(field);
+		CleanupStack::PopAndDestroy(contentType);
+		}
+	}
+
+/**
+ * Reads all the sections in the ini file relevant for updating the contacts database
+ * in order to meet filter view requirements
+ */
+void CPrepareDataTestStep::IterateThroAllFilterViewsSectionsAndUpdateL()
+	{
+	_LIT(KListOfFilterViewSectionsString, "listoffilterviewsections");
+	TPtrC listOfFilterViewSectionsString;
+	GetStringFromConfig(ConfigSection(), KListOfFilterViewSectionsString, listOfFilterViewSectionsString);
+
+	RArray<TPtrC>	listOfFilterViewSections;
+	CleanupClosePushL(listOfFilterViewSections);
+	ViewUtilityReference().TokenizeStringL(listOfFilterViewSectionsString, listOfFilterViewSections);
+
+	for(TInt i = 0; i < listOfFilterViewSections.Count(); ++i)
+		{
+		UpdateContactsInDatabaseAsPerFilteredViewRequirementsL(listOfFilterViewSections[i]);
+		}
+
+	CleanupStack::PopAndDestroy(&listOfFilterViewSections);
+	}
+
+/**
+ * Updates contacts in database as per filter view requirements specified in the ini section
+ */
+void CPrepareDataTestStep::UpdateContactsInDatabaseAsPerFilteredViewRequirementsL(const TPtrC& aFilteredViewSection)
+	{
+	_LIT(KViewSortOrder, "sortorder");
+	TPtrC viewSortOrderString;
+	GetStringFromConfig(aFilteredViewSection, KViewSortOrder, viewSortOrderString);
+
+	RContactViewSortOrder sortOrder = 	ViewUtilityReference().ConvertStringToSortOrderL(viewSortOrderString);
+	CleanupClosePushL(sortOrder);
+
+	_LIT(KNumOfContactsWithFilter, "numofcontactswiththisfilter");
+	TInt numOfContactsWithFilter;
+	GetIntFromConfig(aFilteredViewSection, KNumOfContactsWithFilter, numOfContactsWithFilter);
+
+	_LIT(KDesiredFilterString, "desiredFilter");
+	TPtrC desiredFilterString;
+	GetStringFromConfig(aFilteredViewSection, KDesiredFilterString, desiredFilterString);
+
+	CContactDatabase::TContactViewFilter	viewFilter = ViewUtilityReference().GetContactViewFilterL(desiredFilterString);
+
+	RArray<TContactItemId> contactSpecificToSortOrder;
+	CleanupClosePushL(contactSpecificToSortOrder);
+
+	RetrieveContactsSpecificToSortOrderL(sortOrder, contactSpecificToSortOrder);
+
+	for(TInt i = 0; i < numOfContactsWithFilter; ++i)
+		{
+		TContactItemId id = contactSpecificToSortOrder[i];
+		CContactItem* contactItem = DatabaseReference().OpenContactL(id);
+		CleanupStack::PushL(contactItem);
+		AddFilterBasedFieldsL(*contactItem, viewFilter);
+		DatabaseReference().CommitContactL(*contactItem);
+		DatabaseReference().CloseContactL(id);
+		CleanupStack::PopAndDestroy(contactItem);
+		}
+
+	CleanupStack::PopAndDestroy(2, &sortOrder);
+	}
+
+
+/**
+ * Retrieves contacts specific to desired sort order from the database
+ */
+void CPrepareDataTestStep::RetrieveContactsSpecificToSortOrderL(const RContactViewSortOrder& aSortOrder, RArray<TContactItemId>& aContactSpecificToSorder)
+	{
+	for(TInt i = 0; i < iListOfContactItemsInDatabase.Count(); ++i)
+		{
+		TContactItemId contactId = iListOfContactItemsInDatabase[i];
+		CContactItem* contactItem = DatabaseReference().OpenContactL(contactId);
+		CleanupStack::PushL(contactItem);
+		TBool exists = CheckAllTheFieldsExists(*contactItem, aSortOrder);
+		if(exists)
+			{
+			aContactSpecificToSorder.AppendL(contactId);
+			}
+		DatabaseReference().CloseContactL(contactId);
+		CleanupStack::PopAndDestroy(contactItem);
+		}
+
+	}
+
+/**
+ * Checks whether all the three desired contact fields are present in the contact or not
+ */
+TBool CPrepareDataTestStep::CheckAllTheFieldsExists(const CContactItem& aContact, const RContactViewSortOrder& aSortOrder)
+	{
+	CContactItemFieldSet& fieldSet = aContact.CardFields();
+
+	TInt firstContactFieldPosition = fieldSet.Find(aSortOrder[0]);
+	TInt secondContactFieldPosition = fieldSet.Find(aSortOrder[1]);
+	TInt thirdContactFieldPosition = fieldSet.Find(aSortOrder[2]);
+
+	TInt error = KErrNotFound;
+
+	if ((firstContactFieldPosition != error) &&  (secondContactFieldPosition != error) && (thirdContactFieldPosition!= error))
+		{
+		return ETrue;
+		}
+	else
+		{
+		return EFalse;
+		}
+	}
+
+
+/**
+ * Data is read from the ini file about the matching strings expected to be present in some of the
+ * contact fields and desired number of contacts in the database are updated with this matching string info
+ */
+void CPrepareDataTestStep::IterateThroAllMatchingStringSectionsAndUpdateL()
+	{
+	_LIT(KListOfMatchingStringSectionsString, "listofMatchingString");
+	TPtrC listOfMatchingStringSectionsString;
+	GetStringFromConfig(ConfigSection(), KListOfMatchingStringSectionsString, listOfMatchingStringSectionsString);
+
+	RArray<TPtrC>	listOfMatchingStringSections;
+	CleanupClosePushL(listOfMatchingStringSections);
+	ViewUtilityReference().TokenizeStringL(listOfMatchingStringSectionsString, listOfMatchingStringSections);
+
+	for(TInt i = 0; i < listOfMatchingStringSections.Count(); ++i)
+		{
+		UpdateContactsInDatabaseAsPerMatchingStringsL(listOfMatchingStringSections[i]);
+		}
+
+	CleanupStack::PopAndDestroy(&listOfMatchingStringSections);
+	}
+
+/**
+ * Updates the contacts in the database based on the data available in the ini section
+ * @param aMatchingStringSection - Relevant section in the ini file
+ */
+void CPrepareDataTestStep::UpdateContactsInDatabaseAsPerMatchingStringsL(const TPtrC& aMatchingStringSection)
+	{
+	_LIT(KViewSortOrder, "sortorder");
+	TPtrC viewSortOrderString;
+	GetStringFromConfig(aMatchingStringSection, KViewSortOrder, viewSortOrderString);
+
+	RContactViewSortOrder sortOrder = ViewUtilityReference().ConvertStringToSortOrderL(viewSortOrderString);
+	CleanupClosePushL(sortOrder);
+
+
+	_LIT(KNumOfContactsWithFilter, "numofcontactswiththisstring");
+	TInt numOfContactsWithThisString;
+	GetIntFromConfig(aMatchingStringSection, KNumOfContactsWithFilter, numOfContactsWithThisString);
+
+	_LIT(KDesiredMatchingString, "matchingstring");
+	TPtrC desiredMatchingString;
+	GetStringFromConfig(aMatchingStringSection, KDesiredMatchingString, desiredMatchingString);
+
+	_LIT(KDesiredContactField, "contactfield");
+	TPtrC desiredContactField;
+	GetStringFromConfig(aMatchingStringSection, KDesiredContactField, desiredContactField);
+
+	TUid uidInfo = GetContactFieldType(desiredContactField);
+
+	RArray<TContactItemId> contactSpecificToSortOrder;
+	CleanupClosePushL(contactSpecificToSortOrder);
+
+	RetrieveContactsSpecificToSortOrderL(sortOrder, contactSpecificToSortOrder);
+
+	for(TInt i = 0; (i < (contactSpecificToSortOrder.Count()) && (i < numOfContactsWithThisString)); ++i)
+		{
+		TContactItemId id = contactSpecificToSortOrder[i];
+		CContactItem* contactItem = DatabaseReference().OpenContactL(id);
+		CleanupStack::PushL(contactItem);	// contactItem
+		AddMatchingStringToContactL(*contactItem, uidInfo, desiredMatchingString);
+		DatabaseReference().CommitContactL(*contactItem);
+		DatabaseReference().CloseContactL(id);
+		CleanupStack::PopAndDestroy(contactItem);
+		}
+
+	CleanupStack::PopAndDestroy(2, &sortOrder);
+
+	}
+
+/**
+ * Update contacts in database with desired string
+ * This feature is useful while constructing Find Views, Sub Views etc..
+ * @param aContact - Contact to be updated
+ * @param aUid - uid of field in the contact item to be updated
+ * @param aDesiredMatchingString - Matching string
+ */
+void CPrepareDataTestStep::AddMatchingStringToContactL(CContactItem& aContact, TUid aUid, const TPtrC& aDesiredMatchingString)
+	{
+	CContactItemFieldSet& fieldSet = aContact.CardFields();
+	TInt pos = fieldSet.Find(aUid);
+	if(pos == KErrNotFound)
+		{
+		TFieldType fieldType = aUid;
+		TStorageType storageType = GetStorageType(fieldType);
+		CContentType* contentType = CContentType::NewL();
+		contentType->AddFieldTypeL(fieldType);
+		CContactItemField* field = 	CContactItemField::NewL(storageType, *contentType);
+		CleanupStack::PushL(field);
+		field->TextStorage()->SetTextL(aDesiredMatchingString);
+		aContact.AddFieldL(*field);
+		CleanupStack::Pop();	// field
+		}
+	else
+		{
+		CContactItemField& field = fieldSet[pos];
+		field.TextStorage()->SetTextL(aDesiredMatchingString);
+		}
+	}
+
+void CPrepareDataTestStep::UpdateContactToSpecificStringL()
+	{
+		_LIT(KListOfSetDesiredStringSections, "listofcontacttoupdate");
+		TPtrC listOfSections;
+		GetStringFromConfig(ConfigSection(), KListOfSetDesiredStringSections, listOfSections);
+
+		RArray<TPtrC>	listOfUpdateContact;
+		CleanupClosePushL(listOfUpdateContact);
+
+		ViewUtilityReference().TokenizeStringL(listOfSections, listOfUpdateContact);
+
+		for ( TInt i = 0; i < listOfUpdateContact.Count(); ++i )
+			{
+			UpdateContactFieldsToDesireStingL(listOfUpdateContact[i]);
+			}
+
+		CleanupStack::PopAndDestroy(&listOfUpdateContact);
+
+	}
+
+void CPrepareDataTestStep::UpdateContactFieldsToDesireStingL(const TPtrC& aMatchingStringSection)
+	{
+	_LIT(KViewSortOrder, "sortorder");
+	_LIT(KContactId, "contactid");
+	_LIT(KDesiredString, "desiredstring");
+
+	TPtrC viewSortOrderString;
+	GetStringFromConfig(aMatchingStringSection, KViewSortOrder, viewSortOrderString);
+
+	RContactViewSortOrder sortOrder = ViewUtilityReference().ConvertStringToSortOrderL(viewSortOrderString) ;
+	CleanupClosePushL(sortOrder);
+
+	TInt contactId;
+	GetIntFromConfig(aMatchingStringSection, KContactId, contactId);
+
+	TPtrC desiredSting;
+	GetStringFromConfig(aMatchingStringSection, KDesiredString, desiredSting);
+
+	RArray<TContactItemId> contactSpecificToSortOrder;
+	CleanupClosePushL(contactSpecificToSortOrder);
+
+	RetrieveContactsSpecificToSortOrderL(sortOrder, contactSpecificToSortOrder);
+	CContactItem* contactItem = DatabaseReference().OpenContactL(contactId);
+	CleanupStack::PushL(contactItem);
+
+	CContactItemFieldSet& fieldSet = contactItem->CardFields();
+
+	TInt firstContactFieldPosition = fieldSet.Find(sortOrder[0]);
+	TInt secondContactFieldPosition = fieldSet.Find(sortOrder[1]);
+	TInt thirdContactFieldPosition = fieldSet.Find(sortOrder[2]);
+
+	// Check whether they have content.
+	CContactItemField& field1 = fieldSet[firstContactFieldPosition];
+	CContactFieldStorage* firstStorage = field1.Storage();
+
+	CContactItemField& field2 = fieldSet[secondContactFieldPosition];
+	CContactFieldStorage* secondStorage = field2.Storage();
+
+	CContactItemField& field3 = fieldSet[thirdContactFieldPosition];
+	CContactFieldStorage* thirdStorage = field3.Storage();
+
+	field1.TextStorage()->SetTextL(desiredSting);
+	field2.TextStorage()->SetTextL(desiredSting);
+	field3.TextStorage()->SetTextL(desiredSting);
+
+	DatabaseReference().CommitContactL(*contactItem);
+	DatabaseReference().CloseContactL(contactId);
+
+	CleanupStack::PopAndDestroy(contactItem);
+	CleanupStack::PopAndDestroy(&contactSpecificToSortOrder);
+	CleanupStack::PopAndDestroy(&sortOrder);
+	}
+
+