TBool CPredictiveSearchSynchronizer::ReadMailAddressesL(CContactItem& aContact)
	{
	PRINT(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL"));

	// SELECT value FROM comm_addr
	//	 WHERE contact_id = [contact id value] AND type = [type value];
    _LIT(KSelectMailAddrFormat, "SELECT %S FROM %S WHERE %S = %d AND %S = %d;");
	const TInt KContactIdLength = 10;
	const TInt KCommAddrTypeLength = 2; // CPplCommAddrTable::EEmailAddress is enum
	TInt bufSize = KSelectMailAddrFormat().Length() +
				   KCommAddrValue().Length() +
				   KSqlContactCommAddrTableName().Length() +
				   KCommAddrContactId().Length() +
				   KContactIdLength +
				   KCommAddrType().Length() +
				   KCommAddrTypeLength;
	HBufC* sqlStatement = HBufC::NewLC(bufSize);
	sqlStatement->Des().AppendFormat(KSelectMailAddrFormat,
		&KCommAddrValue,
		&KSqlContactCommAddrTableName,
		&KCommAddrContactId,
		aContact.Id(),
		&KCommAddrType,
		CPplCommAddrTable::EEmailAddress);

	RSqlStatement stmnt;
	CleanupClosePushL(stmnt);
	PRINT1(_L("prepare SQL statement:%S"), sqlStatement);
    stmnt.PrepareL(iDatabase, *sqlStatement);

	const TInt KValueIndex = 0;
	TBool foundMailAddress(EFalse);
	TInt err(KErrNone);
    while ((err = stmnt.Next()) == KSqlAtRow)
        {
		TPtrC value;
		if (stmnt.ColumnText(KValueIndex, value) == KErrNone)
			{
			PRINT2(_L("  id=%d, found mail address=%S"), aContact.Id(), &value);
			CContactItemField* field =
				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldEMail);
			CContactTextField* textfield = field->TextStorage();
			textfield->SetTextL(value);
			aContact.AddFieldL(*field); // Takes ownership
			CleanupStack::Pop(field);
			foundMailAddress = ETrue;
			}
        }

    if (err != KSqlAtEnd)
        {
		PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL SQL err=%d"), err);
        User::Leave(err);
        }
    CleanupStack::PopAndDestroy(&stmnt);
	CleanupStack::PopAndDestroy(sqlStatement);
	PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL return %d"), foundMailAddress);
	return foundMailAddress;
	}
Пример #2
0
LOCAL_C void CheckBasicPopulatedGroup()
	{
	test.Next(_L("Populate Basic Group"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CntTest->CreateDatabaseL();
	TRAP_IGNORE(PopulateDatabaseL(KFamilySizeRecords,ETrue));
	
	CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(_L("Family Group"));
	TContactItemId groupId = newGroup->Id();
	for(TInt ii=2;ii<12;ii++)
		{
		CntTest->Db()->AddContactToGroupL(ii,groupId);
		}
	CntTest->CloseDatabase();
	CntTest->OpenDatabaseL();
//
	CContactItem* familyGroup = CntTest->Db()->ReadContactLC(groupId);
	CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
	test(memberArray->Count()==10);
//
	CContactItem* familyMember = CntTest->Db()->ReadContactLC(2);
	CContactIdArray* groups = STATIC_CAST(CContactCard*, familyMember)->GroupsJoinedLC();
	test(groups->Count()==1);
	TContactItemId memberShip = (*groups)[0];
	test(memberShip==groupId);
	CleanupStack::PopAndDestroy(5); 
	// newGroup familyGroup memberArray familyMember groups
	}
Пример #3
0
void TestOneL()
	{
	g_test.Start(_L("@SYMTestCaseID:PIM-T-SPEEDDIALTEST-0001 Create Database with Speed Dials then Delete and Create database"));

	TestDatabaseWithSpeedDialsL();

	g_test.Next(_L("Delete database"));
	CContactDatabase::DeleteDatabaseL(KDbFileName);
	
	g_test.Next( _L("open database should fail"));
	CContactDatabase* database = NULL;

	TRAPD(openError, database =  CContactDatabase::OpenL(KDbFileName));
	g_test(openError == KErrNotFound && database == NULL);
	

	g_test.Next( _L("create replacement database"));
	database =  CContactDatabase::CreateL(KDbFileName);
	CleanupStack::PushL(database);

	CreateContactsL(*database);

	CContactItem* item = database->ReadContactL(KSpeedDialContact);
	CleanupStack::PushL(item);
	
	g_test.Next( _L("Check that Speed dial is forgotten"));
	g_test(item->Id() == KSpeedDialContact);
	// retored item should not be a SpeedDial
	g_test(!ContactIsASpeedDial( *item ));

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(database);

	g_test.End();
	}
Пример #4
0
// This tests tries to reproduce defect 
// EDNRTRN-4J5C5E "Groups in Cntmodel cannot be renamed.." 
//
// This defect was caused because groups weren't included in the view and
// MoveInSortArrayL doesn't check that the contact item will be in the 
// iSortedItems list (this list depends on the view chosen).
//
LOCAL_C void RenameDefectL()
	{
	test.Next(_L("Rename a group"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();

	CContactDatabase* db=CntTest->CreateDatabaseL();
	_LIT(KCntmodelOriginalName,"Original");
	_LIT(KCntmodelRevisedName,"Revised");
	CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(KCntmodelOriginalName);
	TContactItemId groupId = newGroup->Id();
	CleanupStack::PopAndDestroy(); //newGroup

	TContactItemId contactA=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("a"));
	TContactItemId contactB=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("b"));
	CntTest->Db()->AddContactToGroupL(contactA,groupId);
	CntTest->Db()->AddContactToGroupL(contactB,groupId);

	CntTest->Db()->SetDbViewContactType(KUidContactCard);
	CntTest->Db()->SortedItemsL(); // ensures theres a iSortedItems
	SetSortOrderL(*db,TUid::Uid(KUidContactFieldDefinedTextValue));		// required so that the comparision 

	CContactGroup* group = static_cast<CContactGroup*>(CntTest->Db()->OpenContactL(groupId));	
	CleanupStack::PushL(group);
	group->SetGroupLabelL(KCntmodelRevisedName);
	CntTest->Db()->CommitContactL(*group);
	CntTest->Db()->CloseContactL(groupId);
	CleanupStack::PopAndDestroy(); //group

	CContactItem* revisedGroup = CntTest->Db()->ReadContactLC(groupId,*CntTest->Db()->AllFieldsView());
	TPtrC testLabel = static_cast<CContactGroup*>(revisedGroup)->GetGroupLabelL();
	test(testLabel==KCntmodelRevisedName);
	CleanupStack::PopAndDestroy(); //revisedGroup
	}
Пример #5
0
// Regression testcode for MAT-5B7JD4 "AddContactToGroupL()/RemoveContactFromGroupL() does not update 
// object passed as argument"
//
LOCAL_C void GroupAddRemoveTestL()
	{
	test.Next(_L("Group addition/removal defect"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CContactDatabase* db=CntTest->CreateDatabaseL();

	_LIT(KCntmodelGroup,"MyGroup");
	CContactItem* group = db->CreateContactGroupLC(KCntmodelGroup);
	TContactItemId groupId = group->Id();
	
	TContactItemId itemId=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("C"));
	CContactItem* item = CntTest->Db()->ReadContactLC(itemId);

	CntTest->Db()->AddContactToGroupL(*item,*group);
	// write change to database
	const CContactIdArray* groupsJoined = STATIC_CAST(CContactItemPlusGroup*,item)->GroupsJoined();
	test(groupsJoined->Find(groupId)==0);
	const CContactIdArray* itemsContained = STATIC_CAST(CContactGroup*,group)->ItemsContained();
	test(itemsContained->Find(itemId)==0);
	
	CntTest->Db()->RemoveContactFromGroupL(*item,*group);
	test(STATIC_CAST(CContactItemPlusGroup*,item)->GroupsJoined()->Find(groupId)!=0);
	test(STATIC_CAST(CContactGroup*,group)->ItemsContained()->Find(itemId)!=0);

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(group); 
	}
/**
Deletes all the communication addresses for a particular contact item. Should be used when
deleting a contact item from the database altogether.

@param aItem The contact item whose communcation addresses are to be deleted.
*/
void CPplCommAddrTable::DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred)
	{
	const TUid KType = aItem.Type();
    if (KType != KUidContactCard && KType != KUidContactOwnCard && KType != KUidContactICCEntry && KType != KUidContactGroup)
		{
		return;
		}

	RSqlStatement stmnt;
	CleanupClosePushL(stmnt);
	stmnt.PrepareL(iDatabase, iAllForItemDeleteStmnt->SqlStringL() );
	const TInt KContactIdParamIndex(KFirstIndex); // first and only parameter in query
	User::LeaveIfError(stmnt.BindInt(KContactIdParamIndex, aItem.Id() ) );
	TInt err = stmnt.Exec();
	CleanupStack::PopAndDestroy(&stmnt);

	if (err == KErrDiskFull)
		{
		aLowDiskErrorOccurred = ETrue;
		}
	else
		{
		User::LeaveIfError(err);
		}
	}
/**
 * Create a new template and add it to the database
 * @param aDb Contact database
 * @param aTemplateName Name for the template
 * @param aFieldSet Array of fields which should are added to the template
 * @return TContactItemId Id of the newly created template
 */
TContactItemId CreatePhonebookTemplateL(CContactDatabase& aDb, const TDesC& aTemplateName, RArray<TFieldEntry>& aFieldSet)
	{
	CContactItem* temp = aDb.CreateContactCardTemplateLC(aTemplateName);
	TContactItemId templateId = temp->Id();
	CleanupStack::PopAndDestroy(temp);
	temp=NULL;

	//Remove all the unnecessary fields
	temp = aDb.OpenContactLX(templateId);
	CleanupStack::PushL(temp);	
	const TInt fieldCount = temp->CardFields().Count();
	for(TInt i=fieldCount-1;i>=0;i--)
		temp->RemoveField(i);

	// Add each of the required fields to the template
	for (TInt j=0; j<aFieldSet.Count(); ++j)
		{
		TFieldEntry fieldEntry=aFieldSet[j];

		CContactItemField* field = CContactItemField::NewLC(KStorageTypeText,fieldEntry.iField);
		if (fieldEntry.iFieldType!=KNullUid)
			field->AddFieldTypeL(fieldEntry.iFieldType);
		temp->AddFieldL(*field);
		CleanupStack::Pop(field);
		}

	aDb.CommitContactL(*temp);
	CleanupStack::PopAndDestroy(2); // temp, close template
	
	return templateId;
	}
Пример #8
0
void CConcurrentNotifierStep::OwnCardTestL()
	{
	INFO_PRINTF1(KTest7);
	SetSharedTextL(KSharedNextTest, KSingleCharacter, ETrue);
	iWaiting = ETrue;
	iMyActive->Activate();
	CContactItem *item = iContactsDatabase->CreateOwnCardLC();
	iIterate->AddL( item->Id() );
	AddEventL( EContactDbObserverEventContactAdded );
	AddContactL( item->Id() );
	AddEventL( EContactDbObserverEventOwnCardChanged );
	AddContactL( item->Id() );
	CleanupStack::PopAndDestroy( item );
	SetMessageCountL();
	iStart.UniversalTime();
	}
Пример #9
0
/** 
 * Create phonebook group 
 * @param aDb Contact database
 */
TContactItemId CreatePhonebookGroupL(CContactDatabase& aDb)
	{
	_LIT(KPhbkGroup,"ADN Phonebook"); 
	CContactItem* group = aDb.CreateContactGroupLC(KPhbkGroup);
	TContactItemId groupId = group->Id();
	CleanupStack::PopAndDestroy(group);	
	return groupId;
	}
TBool CPackagerCntComparator::Compare(const CContactItem& anItem1, const CContactItem& anItem2) const
/** Compares two CContactItem items. 

@param anItem1 The first CContactItem to be compared.
@param anItem2 The second CContactItem to be compared.
@return ETrue if the two items are equal, EFalse otherwise. */
	{
	return (DoCompareCContactItemType(anItem1, anItem2) 							&
		DoCompareCContactItemFieldSet(anItem1.CardFields(), anItem2.CardFields())	&
		DoCompareCContactItemAttribute(anItem1, anItem2)							&
		DoCompareTContactItemId(anItem1.Id(), anItem2.Id())							&
		DoCompareTContactItemId(anItem1.TemplateRefId(), anItem2.TemplateRefId())	&
		DoCompareTTime(anItem1.LastModified(), anItem2.LastModified())				&
		DoCompareTTime(anItem1.iCreationDate, anItem2.iCreationDate)				&
		DoCompareTInt(anItem1.AccessCount(), anItem2.AccessCount())					&
		DoCompareTPtrC(const_cast<CContactItem&>(anItem1).Guid(), const_cast<CContactItem&>(anItem2).Guid()));

	}
Пример #11
0
void TestFourL()
	{
	g_test.Start(_L("Check that Settings are saved - killing ContactLockSrv"));
	
    g_test.Next(_L("Setting up..."));
	CLockServerTester* lockSrvTester = CLockServerTester::NewL();
	CleanupStack::PushL(lockSrvTester);
	CContactDatabase* database = SetupLC();
	
	g_test.Next( _L("Assign Speed Dial"));
	TInt error = KErrNone;
	TRAP(error, AssignSpeedDialL( KSpeedDialContact, KSpeedDialPositionOne, *database ) );
	g_test(error == KErrNone);
	
	g_test.Next( _L("Update Speed Dial"));
	error = KErrNone;
	TRAP(error, UpdateSpeedDialL( KSpeedDialContact, KSpeedDialPositionTwo, *database ) );
	g_test(error == KErrNone);
	
	g_test.Next( _L("Change Database Drive"));
	CContactDatabase::SetDatabaseDriveL(TDriveUnit(EDriveD),EFalse);
	
	CleanupStack::PopAndDestroy(database);
	
	// Kill ContactLockServer process
	g_test.Next( _L("Kill CntServer"));
	lockSrvTester->FindServerAndKillItL();
	CleanupStack::PopAndDestroy( lockSrvTester );

	g_test.Next( _L("Open Database"));
	database =  CContactDatabase::OpenL(KDbFileName);
	CleanupStack::PushL(database);
		
	TDriveUnit driveUnit;
	CContactDatabase::DatabaseDrive(driveUnit);
	g_test.Next( _L("Check that Database Drive is changed"));
	g_test(driveUnit==TDriveUnit(EDriveD));
	
	CContactItem* item = database->ReadContactL(KSpeedDialContact);
	CleanupStack::PushL(item);
	
	g_test.Next( _L("Check that Speed Dial is remembered"));
	g_test(item->Id() == KSpeedDialContact);
	// retored item should be a SpeedDial
	g_test(ContactIsASpeedDial( *item ));
	
	// reset Database Drive
	g_test.Next( _L("Reset Database Drive setting"));
	CContactDatabase::SetDatabaseDriveL(TDriveUnit(EDriveC),EFalse);

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(database);
	
	g_test.End();		
	}
Пример #12
0
// Extended to provide coverage for defect 
// EDNBWHE-4HXCXM "group retains link to a nested group after it has been deleted"
//
LOCAL_C void CheckNestedGroup()
	{	
	test.Next(_L("Check Nested Group"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CntTest->CreateDatabaseL();
	CContactItem* newGroup = CntTest->Db()->CreateContactGroupLC(_L("Family Group"));
	TContactItemId groupId = newGroup->Id();
	
	CContactItem* nestedGroup = CntTest->Db()->CreateContactGroupLC(_L("nested Group"));
	TContactItemId nestedGroupId = nestedGroup->Id();

	CntTest->Db()->AddContactToGroupL(nestedGroupId,groupId);

	CntTest->CloseDatabase();
	CntTest->OpenDatabaseL();

	CContactItem* familyGroup = CntTest->Db()->ReadContactLC(groupId);
	CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
	test(memberArray->Count()==1);

	CContactItem* newNestedGroup = CntTest->Db()->ReadContactLC(nestedGroupId);
	CContactIdArray* nestedMemberArray = STATIC_CAST(CContactGroup*,newNestedGroup)->ItemsContainedLC();
	test(nestedMemberArray->Count()==0); //fails as count = 0

	CContactIdArray* groups = STATIC_CAST(CContactGroup*, newNestedGroup)->GroupsJoinedLC();
	test(groups->Count()==1); 
	
	TContactItemId memberShip = (*groups)[0];
	test(memberShip==groupId);
	
	// If delete a group member, then retrieve the group from the database, 
	// group.contactCount() is the same and group.getContacts() includes a 
	// null entry where the deleted group member was.
	CntTest->Db()->DeleteContactL(nestedGroupId);
	CContactItem* newFamilyGroup  = CntTest->Db()->ReadContactLC(groupId);
	CContactIdArray* newMemberArray = STATIC_CAST(CContactGroup*,newFamilyGroup )->ItemsContainedLC();
	test(newMemberArray->Count()==0);		//fails
	
	CleanupStack::PopAndDestroy(9); 
	// newGroup, nestedGroup, familyGroup memberArray newMemberArray newNestedGroup, newFamilyGroup  nestedMemberArray, groups
	}
Пример #13
0
LOCAL_C void AddGroupToCard()
	{
//
	test.Next(_L("Group to Card"));
	CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(_L("New Group"));
	TContactItemId tempId = newGroup->Id();
	delete newGroup;
	// assumes Prior Knowldege of contact 3 (is a card)
	CntTest->Db()->AddContactToGroupL(tempId,3);	
//
	}
Пример #14
0
void TestThreeL()
	{
	g_test.Start(_L("Check that Settings are saved - normal shutdown"));
	
    g_test.Next(_L("Setting up..."));
	CContactDatabase* database = SetupLC();

	g_test.Next( _L("Assign Speed Dial"));
	TInt error = KErrNone;
	TRAP(error, AssignSpeedDialL( KSpeedDialContact, KSpeedDialPositionOne, *database ) );
	g_test(error == KErrNone);
	
	g_test.Next( _L("Update Speed Dial"));
	error = KErrNone;
	TRAP(error, UpdateSpeedDialL( KSpeedDialContact, KSpeedDialPositionTwo, *database ) );
	g_test(error == KErrNone);
	
	g_test.Next( _L("Change Database Drive"));
	CContactDatabase::SetDatabaseDriveL(TDriveUnit(EDriveD),EFalse);
	
	CleanupStack::PopAndDestroy( database );

	g_test.Next(_L("Wait for Contact Server to shutdown"));
	// wait until Contacts Lock Server shuts down
	// applicabale only in the case of transient server.
	User::After(6000000);
	
	g_test.Next( _L("Try to open Database again"));

	database =  CContactDatabase::OpenL(KDbFileName);
	CleanupStack::PushL(database);
		
	TDriveUnit driveUnit;
	CContactDatabase::DatabaseDrive(driveUnit);
	g_test.Next( _L("Check that Database Drive is changed"));
	g_test(driveUnit==TDriveUnit(EDriveD));
	
	CContactItem* item = database->ReadContactL(KSpeedDialContact);
	CleanupStack::PushL(item);
	
	g_test.Next( _L("Check that Speed Dial is remembered"));
	g_test(item->Id() == KSpeedDialContact);
	// retored item should be a SpeedDial
	g_test(ContactIsASpeedDial( *item ));
	
	// reset Database Drive
	g_test.Next( _L("Reset Database Drive setting"));
	CContactDatabase::SetDatabaseDriveL(TDriveUnit(EDriveC),EFalse);

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(database);
	
	g_test.End();
	}
Пример #15
0
// Check that the speed dial at position aSpeedDialPosition matches the aExpectedId
// and the contents of the field with aFieldId is the same in the speed dial.
//
LOCAL_C void CheckSpeedDialL(TInt aSpeedDialPosition, CContactItem& aContact, TInt aFieldId)
{
    HBufC* buf=HBufC::NewLC(100);
    TPtr fieldContents=buf->Des();

    TContactItemId id = CntTest->Db()->GetSpeedDialFieldL(aSpeedDialPosition, fieldContents);
    TPtrC actualContents =(aContact.CardFields()[aFieldId].TextStorage()->Text());
    test(id==aContact.Id());
    test(actualContents==fieldContents);

    CleanupStack::PopAndDestroy(); //buf
}
Пример #16
0
void UpdateSpeedDialL(TInt aContact, TInt aSpeedDialID, CContactDatabase& database )
	{
	CContactItem* item = NULL;
	item = database.OpenContactL( aContact );
	CleanupStack::PushL( item );

	if ( ContactIsASpeedDial( *item ) )
		{
		g_test.Printf( _L("Contact is a speed dial !!! \n") );
		database.SetFieldAsSpeedDialL(*item, item->Id(), aSpeedDialID );
		}
	else
		{
		g_test.Printf( _L("Contact is NOT A SPEED DIAL \n") );
		}

	CleanupStack::PopAndDestroy( item );
	}
Пример #17
0
LOCAL_C void CheckLargePopulatedGroup()
	{
	test.Next(_L("Create MANY Contacts"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CntTest->CreateDatabaseL();
	TRAP_IGNORE(PopulateDatabaseL(KLargeSizeRecords,ETrue));
	CContactItem* newGroup = CntTest->Db()->CreateContactGroupL(_L("Large Group"));
	CleanupStack::PushL(newGroup);
	TContactItemId groupId = newGroup->Id();
	test.Next(_L("Add MANY Contacts to a Group"));
	TTime before;
	before.UniversalTime();
	for(TInt ii=1;ii<KLargeSizeRecords+1;ii++)
		{
		CntTest->Db()->AddContactToGroupL(ii, groupId); //*tempContact,*newGroup);
		if (ii%100==0)
			test.Printf(_L("."));	// Just to show some life
		}
	test(TestGroupStateL(CntTest->Db(),1,KLargeSizeRecords));
	TTime after;
	after.UniversalTime();
	TTimeIntervalSeconds secondsTaken;
	after.SecondsFrom(before,secondsTaken);
	test.Printf(_L(" TIME: %d  Secs"),secondsTaken.Int());
	test.Printf(_L("\n"));	
	//test.Getch();
	CntTest->CloseDatabase();
	CntTest->OpenDatabaseL();
//
	CContactItem* familyGroup = CntTest->Db()->ReadContactL(groupId);
	CContactIdArray* memberArray = STATIC_CAST(CContactGroup*,familyGroup)->ItemsContainedLC();
	test(memberArray->Count()==KLargeSizeRecords);
	delete familyGroup;
//
	CContactItem* familyMember = CntTest->Db()->ReadContactL(2);
	CContactIdArray* groups = STATIC_CAST(CContactCard*, familyMember)->GroupsJoinedLC();
	test(groups->Count()==1);
	TContactItemId memberShip = (*groups)[0];
	test(memberShip==groupId);
	delete familyMember;
	CleanupStack::PopAndDestroy(3); // newGroup groups memberArray
	}
Пример #18
0
LOCAL_C void TestReadContactTextDefL() // Added to test changes made for DEF065476 and DEF065477
	{
	test.Next(_L("Testing ReadContactTextDef ( Defect DEF065476 and DEF065477 )"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();
	CContactDatabase* db=CntTest->CreateDatabaseL();

	_LIT(KContactGroup,"ContactGroup");
	CContactItem* group = db->CreateContactGroupLC(KContactGroup);
	TContactItemId groupId = group->Id();

	TBuf<128> scratchBuf;
	CntTest->Db()->ReadContactTextDefL(groupId, scratchBuf);
	test(scratchBuf==KContactGroup);

	test.Printf(_L("The Group name is %S\n"), &scratchBuf);

	CleanupStack::PopAndDestroy(group); 
	}
Пример #19
0
void TestDatabaseWithSpeedDialsL()
	{
	g_test.Next(_L("Setting up..."));

	CContactDatabase* database = SetupLC();

	g_test.Next(_L("First Speed dial assignment"));
	// Assign First time ok !
	TRAPD(error, AssignSpeedDialL( KSpeedDialContact, KSpeedDialPositionOne, *database ) );
	g_test(error == KErrNone);

	g_test.Next(_L("Second Speed dial assignment"));
	// Assign Second time falls over !
	TRAP(error, AssignSpeedDialL( KSpeedDialContact, KSpeedDialPositionOne, *database ) );
	g_test(error == KErrNone);

	g_test.Next(_L("Open contact, remove from speed dial, open again"));
	// The remove from speed dial on the open contact should return KErrInUse.
	// The second open should also return KErrInUse.
	TRAP(error, RemoveSpeedDialWhenOpenL(KSpeedDialContact, KSpeedDialPositionOne, *database));
	g_test(error == KErrNone);

	CleanupStack::PopAndDestroy( database );

	// wait until Contacts Lock Server shuts down
	User::After(6000000);

	g_test.Next( _L("Try to open db again"));

	database =  CContactDatabase::OpenL(KDbFileName);
	CleanupStack::PushL(database);
	
	CContactItem* item = database->ReadContactL(KSpeedDialContact);
	CleanupStack::PushL(item);
	
	g_test.Next( _L("Check that Speed dial is remembered"));
	g_test(item->Id() == KSpeedDialContact);
	// retored item should be a SpeedDial
	g_test(ContactIsASpeedDial( *item ));

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(database);
	}
Пример #20
0
/**
ReadL has a dual functionality. If passed parameter is a group, will be filled to contacts
bellonging to that group. Otherwirse, the contact item will be filed with all groups to which
it belongs

@param aItem Reference to contact item.
*/
void CPplGroupsTable::ReadL(CContactItem& aItem)
	{
	const TContactItemId KItemId(aItem.Id() );
	const TUid KType(aItem.Type() );
	if (KType == KUidContactGroup)
		{
		CContactGroup& group = static_cast<CContactGroup&>(aItem);
		group.ResetItems();
		group.SetItems(GetListForItemL(KItemId, ETrue));
		}	


	if (KType == KUidContactCard || KType == KUidContactOwnCard || KType == KUidContactICCEntry || KType == KUidContactGroup)
		{
		CContactItemPlusGroup& item = static_cast<CContactItemPlusGroup&>(aItem);
		item.ResetGroups();
		item.SetGroups(GetListForItemL(KItemId, EFalse));
		}	
	}
Пример #21
0
void TestTwoL()
	{
	g_test.Start(_L("Create Database with Speed Dials then Replace database"));

	TestDatabaseWithSpeedDialsL();

	g_test.Next(_L("Replace database"));
	CContactDatabase* database = ReplaceDatabaseAndCreateContactsLC();

	CContactItem* item = database->ReadContactL(KSpeedDialContact );	
	CleanupStack::PushL(item);
	
	g_test.Next(_L("Check that Speed dial is forgotten"));
	g_test(item->Id() == KSpeedDialContact);
	// retored item should not be a SpeedDial
	g_test(!ContactIsASpeedDial( *item ));

	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(database);

	g_test.End();
	}
Пример #22
0
void CTestResources::CreateTestContactsL()
    {
    const TInt KContacts = 4;
    TInt i;
    iContacts = CContactIdArray::NewL();

    // Create contacts
    for (i=1; i <= KContacts; ++i)
        {
        CContactCard* card = CContactCard::NewLC();
        CContactItemField* field = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
        TBuf<30> name;
        name.Format(_L("Contact%02d"), i);
        field->TextStorage()->SetTextL(name);
        card->AddFieldL(*field);
        CleanupStack::Pop(field);
        const TContactItemId contactId = iDb->AddNewContactL(*card);
        iContacts->AddL(contactId);
        CleanupStack::PopAndDestroy(card);
        // Eat away contact db events
        TContactDbObserverEvent event;
        test(iDbEventQueue->ListenForEvent(10,event));
        }

    // Create a group
    CContactItem* group = iDb->CreateContactGroupLC(_L("TestGroup"));
    iGroupId = group->Id();
    CleanupStack::PopAndDestroy(group);

    // Connect half of the contacts to the group
    for (i=0; i < iContacts->Count(); ++i)
        {
        if (i%2 == 0)
            {
            iDb->AddContactToGroupL((*iContacts)[i], iGroupId);            
            }
        }
    }
Пример #23
0
/** 
 * Create template card for ICC contact items 
 * @param aDb Contact database
 */
TContactItemId CreateICCTemplateL(CContactDatabase& aDb)
	{
	CContactItem* temp = aDb.CreateContactCardTemplateLC(KTemplateName);
	TContactItemId templateId = temp->Id();
	CleanupStack::PopAndDestroy(temp);
	temp=NULL;

	//Remove all the unnecessary fields
	temp = aDb.OpenContactLX(templateId);
	CleanupStack::PushL(temp);	
	const TInt fieldCount = temp->CardFields().Count();
	for(TInt i=fieldCount-1;i>=0;i--)
		temp->RemoveField(i);
		
	CContactItemField* name = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldFamilyName);
	name->SetMapping(KUidContactFieldVCardMapUnusedN);
	temp->AddFieldL(*name);
	CleanupStack::Pop(name);

	CContactItemField* number = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldPhoneNumber);
	number->SetMapping(KUidContactFieldVCardMapTEL);
	temp->AddFieldL(*number);
	CleanupStack::Pop(number);
				
	CContactItemField* slotnum = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCSlot);
	temp->AddFieldL(*slotnum);
	CleanupStack::Pop(slotnum);

	CContactItemField* phonebook = CContactItemField::NewLC(KStorageTypeText,KUidContactFieldICCPhonebook);
	temp->AddFieldL(*phonebook);
	CleanupStack::Pop(phonebook);

	aDb.CommitContactL(*temp);
	CleanupStack::PopAndDestroy(2);	// temp, close template	
	
	return templateId;
	}
Пример #24
0
// This tests reproduces defect 
// BET-4YDGB3 "Contacts crashes when creating two entries"
//
// This was caused because the CContactTables::ContactType() method uses the 
// iCurrentIdInIdentityTable to determine which contact should be used to read 
// the type information from. This member stores the last contact ID to be read 
// from the identity table. However, since AddContactToGroupL() doesn't read any 
// information from the identity table, the value set in iCurrentIdInIdentityTable 
// should be set to KErrNotFound so that the correct contact from main CONTACTS table 
// is used.
//
LOCAL_C void QuartzGroupDefectL()
	{
	test.Next(_L("Quartz defect"));
	CntTest->CloseDatabase();
	CntTest->DeleteDatabaseL();

	CContactDatabase* db=CntTest->CreateDatabaseL();

	_LIT(KCntmodelGroupAll,"All");
	CContactItem* group = db->CreateContactGroupLC(KCntmodelGroupAll);
	TContactItemId groupId = group->Id();
	CleanupStack::PopAndDestroy(group); 
	

	CntTest->Db()->SetDbViewContactType(KUidContactCard);
	CntTest->Db()->SortedItemsL(); // ensures theres a iSortedItems
	SetSortOrderL(*db,TUid::Uid(KUidContactFieldDefinedTextValue));		// required so that the comparision 
	
	TContactItemId contactB=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("B"));
	CntTest->Db()->AddContactToGroupL(contactB,groupId);
	
	TContactItemId contactA=AddContactL(db,KUidContactFieldFamilyName,KUidContactFieldVCardMapUnusedN,_L("A"));
	CntTest->Db()->AddContactToGroupL(contactA,groupId);
	}
/**
Updates communication addresses in the database.

If there are the same number of items to be updated as are already in the database, the
existing records are overwritten using the update statement. However, if there is a
different number of addresses to be updated, records in the database (if there are any)
are deleted (using DeleteL() ) and the new data is inserted (using CreateInDbL() ).

@param aItem A contact item whose communication addresses are to be updated in the contacts database.
*/
void CPplCommAddrTable::UpdateL(const CContactItem& aItem)
	{
	// Check that the contact item is a card, own card or ICC entry.
	const TUid type(aItem.Type() );
	if (type != KUidContactCard && type != KUidContactOwnCard && type != KUidContactICCEntry && type != KUidContactGroup)
		{
		return;
		}

	const TContactItemId KItemId(aItem.Id() );

	// create lists for comm_addrs and go through contact item to populate them with any new ones we find
	RArray<TMatch> newPhones;
	RArray<TPtrC>  newEmails;
	RArray<TPtrC>  newSips;
	CleanupClosePushL(newPhones);
	CleanupClosePushL(newEmails);
	CleanupClosePushL(newSips);
	
	CPplCommAddrTable::TCommAddrExtraInfoType extraInfoType = ENonMobileNumber;

	for (TInt fieldNum = aItem.CardFields().Count() - 1; fieldNum >= 0; --fieldNum)
		{
		CContactItemField& currField = aItem.CardFields()[fieldNum];
		const CContentType& contType = currField.ContentType();
		TBool isPhone(contType.ContainsFieldType(KUidContactFieldPhoneNumber) ||
					  contType.ContainsFieldType(KUidContactFieldFax)		  ||
					  contType.ContainsFieldType(KUidContactFieldSms)		  );
		TBool isEmail(contType.ContainsFieldType(KUidContactFieldEMail) );
		TBool isSip(contType.ContainsFieldType(KUidContactFieldSIPID) );

		// check it's a field we want and that it's not empty
		// store a new address if we haven't already seen it -- no point storing the same one twice.
		if ((isPhone || isEmail || isSip) && currField.StorageType() == KStorageTypeText
				&& currField.TextStorage()->IsFull() )
			{
			// get phone numbers
			if (isPhone)
				{
				TMatch phoneNumber;
				phoneNumber = CreatePaddedPhoneDigitsL(currField.TextStorage()->Text(), KLowerSevenDigits,
													   KMaxPhoneMatchLength - KLowerSevenDigits);
				if (newPhones.Find(phoneNumber, TIdentityRelation<TMatch>(&TMatch::Equals) ) == KErrNotFound)
					{
					newPhones.AppendL(phoneNumber);
					}
				if(contType.ContainsFieldType(KUidContactFieldVCardMapCELL))
                    {
                    extraInfoType = EMobileNumber;
                    }
				}
			// get email addresses
			else if (isEmail && newEmails.Find(currField.TextStorage()->Text() ) == KErrNotFound)
				{
				newEmails.AppendL(currField.TextStorage()->Text() );
				}
			// get SIP addresses
			else if (newSips.Find(currField.TextStorage()->Text() ) == KErrNotFound)
				{
				newSips.AppendL(currField.TextStorage()->Text() );
				}
			}
		}

	// if there are no comm addresses in the contact item, delete any from the database
	if (!(newPhones.Count() + newEmails.Count() + newSips.Count() ) )
		{
		TBool lowDiskErr(EFalse);
		DeleteL(aItem, lowDiskErr);
		CleanupStack::PopAndDestroy(3, &newPhones); // and newSips, newEmails
		if (lowDiskErr)
			{
			User::Leave(KErrDiskFull);
			}
		return;
		}

	// create from the database a list of comm_addr_ids that can be recycled as their
	// comm_addrs are in the database but not in the new version of the contact item
	RArray<TInt> freeCommAddrIds;
	CleanupClosePushL(freeCommAddrIds);

	// weed out addresses from the list that are already in the db but haven't changed
	// and populate the freeCommAddrIds list
	RemoveNonUpdatedAddrsL(newPhones, newEmails, newSips, freeCommAddrIds, KItemId, extraInfoType);

	// do the actual updating on an address-by-address basis

	DoUpdateCommAddrsL(newPhones, newEmails, newSips, freeCommAddrIds, KItemId,extraInfoType);

	CleanupStack::PopAndDestroy(4, &newPhones); // and freeCommAddrIds, newSips, newEmails
	}
Пример #26
0
/**
 * Check that speed dials are working correctly;
 * Add first contact to speed dial 1, add second contact to speed dial 9.
 * Check speed dial 1 still matches contact 1 after adding speed dial
 * Check persistance of speed dial list
 * Check overwriting old speed dial with new contact id
 * Check deletion of contact removes all existing speed dials
 */
LOCAL_C void SpeedDialSimpleTest()
{
    ResetDatabaseL();
    TRAP_IGNORE(PopulateDatabaseL(KTestContactsNum));

    const CContactIdArray* sortedItems = CntTest->Db()->SortedItemsL();

    // first item in position 1
    CContactItem* firstItem = CntTest->Db()->OpenContactL((*sortedItems)[0]);
    CleanupStack::PushL(firstItem);
    TInt fieldId=5;
    const TInt speedDialPositionOne=1;
    CntTest->Db()->SetFieldAsSpeedDialL(*firstItem, fieldId, speedDialPositionOne);
    CheckSpeedDialL(speedDialPositionOne,*firstItem,fieldId);

    // second item in position 2
    CContactItem* secondItem = CntTest->Db()->OpenContactL((*sortedItems)[1]);
    CleanupStack::PushL(secondItem);
    fieldId=5;
    const TInt speedDialPositionNine=9;
    CntTest->Db()->SetFieldAsSpeedDialL(*secondItem, fieldId, speedDialPositionNine);
    CheckSpeedDialL(speedDialPositionNine,*secondItem,fieldId);

    // wrong answers.....
    CheckSpeedDialL(speedDialPositionOne,*firstItem,5);

    // check persistance
    CntTest->CloseDatabase();
    CntTest->OpenDatabaseL();
    CheckSpeedDialL(speedDialPositionOne,*firstItem,5);
    CheckSpeedDialL(speedDialPositionNine,*secondItem,5);

    // check overwriting old speed dial (third contact, speed dial 1)
    const CContactIdArray* newSortedItems = CntTest->Db()->SortedItemsL();
    CContactItem* thirdItem = CntTest->Db()->OpenContactL((*newSortedItems)[2]);
    CleanupStack::PushL(thirdItem);
    fieldId=5;
    CntTest->Db()->SetFieldAsSpeedDialL(*thirdItem, fieldId, speedDialPositionOne);
    CheckSpeedDialL(speedDialPositionOne,*thirdItem,5);

    // delete contact and check that speed dials have been removed
    CntTest->Db()->DeleteContactL((*newSortedItems)[2]);
    HBufC* temp8=HBufC::NewLC(100);
    TPtr testText8=temp8->Des();
    TContactItemId eightId = CntTest->Db()->GetSpeedDialFieldL(speedDialPositionOne, testText8);
    test(eightId==KNullContactId);
    test(testText8==KNullDesC);

    // modify a contact with a speed dial - but do not change the relavent field.
    CContactItem* fourthItem = CntTest->Db()->OpenContactL((*newSortedItems)[2]);
    CleanupStack::PushL(fourthItem);
    fieldId=5;

    CntTest->Db()->SetFieldAsSpeedDialL(*fourthItem, fieldId, speedDialPositionOne);
    TInt fieldPosOfSpeedDial = fourthItem->CardFields().Find(KUidSpeedDialOne);
    test(fieldPosOfSpeedDial != KErrNotFound);

    CContactItem* fifthItem = CntTest->Db()->OpenContactL(fourthItem->Id());
    CleanupStack::PushL(fifthItem);

    // remove the first field in the list.
    fieldPosOfSpeedDial = fifthItem->CardFields().Find(KUidSpeedDialOne);

    fifthItem->CardFields().Remove(1);
    CntTest->Db()->CommitContactL(*fifthItem);

    CleanupStack::PopAndDestroy(6); // firstItem, secondItem, thirdItem, fourthItem, fifthItem, temp8
}
/**
Insert new communication addresses into the comm_addr table.
@param aItem A contact item whose communication addresses are to be added to the contacts database.
*/
void CPplCommAddrTable::CreateInDbL(CContactItem& aItem)
	{
	// Check that the contact item is a card, own card or ICC entry.
	const TUid KType = aItem.Type();
	if (KType != KUidContactCard && KType != KUidContactOwnCard && KType != KUidContactICCEntry && KType != KUidContactGroup)
		{
		return;
		}

	// create lists for comm_addrs to keep track of what we have already seen so as to avoid duplicates
	RArray<TMatch> newPhones;
	RArray<TPtrC>  newEmails;
	RArray<TPtrC>  newSips;
	CleanupClosePushL(newPhones);
	CleanupClosePushL(newEmails);
	CleanupClosePushL(newSips);

	for (TInt fieldNum = aItem.CardFields().Count() - 1; fieldNum >= 0; --fieldNum)
		{
		CContactItemField& currField = aItem.CardFields()[fieldNum];
		const CContentType& contType = currField.ContentType();
		TBool isPhone(contType.ContainsFieldType(KUidContactFieldPhoneNumber) ||
					  contType.ContainsFieldType(KUidContactFieldFax)		  ||
					  contType.ContainsFieldType(KUidContactFieldSms)		  );
		TBool isEmail(contType.ContainsFieldType(KUidContactFieldEMail) );
		TBool isSip(contType.ContainsFieldType(KUidContactFieldSIPID) );

		// check it's a field we want and that it's not empty
		// insert a new address only if we haven't already seen it -- no point storing the same one twice.
		if ((isPhone || isEmail || isSip) && currField.StorageType() == KStorageTypeText
				&& currField.TextStorage()->IsFull() )
			{
			const TContactItemId KItemId(aItem.Id());

			// get phone numbers
			if (isPhone)
				{
				TMatch phoneNumber;
				phoneNumber = CreatePaddedPhoneDigitsL(currField.TextStorage()->Text(), KLowerSevenDigits,
													   KMaxPhoneMatchLength - KLowerSevenDigits);
				if (newPhones.Find(phoneNumber, TIdentityRelation<TMatch>(&TMatch::Equals) ) == KErrNotFound)
					{
					if(contType.ContainsFieldType(KUidContactFieldVCardMapCELL))
                        {
                        DoPhoneNumWriteOpL(phoneNumber, EInsert, KItemId,EPhoneNumber,EMobileNumber);
                        }
					else
					    {
					    DoPhoneNumWriteOpL(phoneNumber, EInsert, KItemId);
					    }
					
					newPhones.AppendL(phoneNumber);
					}
				}
			// get email addresses
			else if (isEmail && newEmails.Find(currField.TextStorage()->Text() ) == KErrNotFound)
				{
				DoNonPhoneWriteOpL(currField.TextStorage()->Text(), EInsert, KItemId, EEmailAddress);
				newEmails.AppendL(currField.TextStorage()->Text() );
				}
			// get SIP addresses
			else if (newSips.Find(currField.TextStorage()->Text() ) == KErrNotFound)
				{
				DoNonPhoneWriteOpL(currField.TextStorage()->Text(), EInsert, KItemId, ESipAddress);
				newSips.AppendL(currField.TextStorage()->Text() );
				}
			}
		}

	CleanupStack::PopAndDestroy(3, &newPhones); // and newSips, newEmails
	}
Пример #28
0
/** Create Contact user defuned Template add add field to contact item  
 *	through template and verify the field is being added
 *	aValue - field value
 *  @param aStorageType - Storage type of each field
 *	@param aContFieldUid - Uid of Contact field
 *	@param avCardMapUid - Uid of vCard 
 *	@return - void
*/	
void CTestAddFieldsStep::AddFieldsNewTemplateL(TPtrC aValue, TInt aStorageType,TUid aContFieldUid, TUid avCardMap)	
	{
	TPtrC value;
	TInt year, month, day;
	CContactDatabase *base = NULL;
	_LIT(KTestDbName, "c:mytemplate.cdb");
	_LIT(KUserDefinedTemplate,"MyTemplate");
	
	// replace existing database name
	base = CContactDatabase::ReplaceL(KTestDbName);
	CleanupStack::PushL(base);
		
	TContactItemId TempId ;
	CContactItemField* field = NULL;
	
	//Create User defined Template
	CContactItem* contactTemplate = base->CreateContactCardTemplateLC(KUserDefinedTemplate);
	
	// Get the ID of Template
	TempId = contactTemplate->Id();
	
	//Add fields to it
    field = CContactItemField::NewL(aStorageType, aContFieldUid);
    CleanupStack::PushL(field); 
    field->SetMapping(avCardMap);
    contactTemplate->AddFieldL(*field);  
   	CleanupStack::Pop(field);
   	
	//Allocates and constructs a new contact card.
	CContactItem* item = CContactCard::NewLC();
	
	//Sets the ID of the template on which this contact item is based
	item->SetTemplateRefId(TempId);
	
	//create contact item and add field value to it
    field = CContactItemField::NewL(aStorageType, aContFieldUid);
    CleanupStack::PushL(field); 
    field->SetMapping(avCardMap);
    if(aStorageType==KStorageTypeDateTime)
    	{
    	//Get the int value
		TBool res;
		res = GetIntFromConfig(ConfigSection(), KIniYear, year);
		if(!res)
			{
			ERR_PRINTF1(_L("Unable to read year val from ini file"));
			SetTestStepResult(EFail);
			}
		res = GetIntFromConfig(ConfigSection(), KIniMonth, month);
		if(!res)
			{
			ERR_PRINTF1(_L("Unable to read month val from ini file"));
			SetTestStepResult(EFail);
			}
		res = GetIntFromConfig(ConfigSection(), KIniDay, day);
		if(!res)
			{
			ERR_PRINTF1(_L("Unable to read day val from ini file"));
			SetTestStepResult(EFail);
			}
		TDateTime date(year,(TMonth)month,day,0,0,0,0);
   		field->DateTimeStorage()->SetTime(date);
    	}
    else
    	{
    	field->TextStorage()->SetTextL(aValue);	
    	}	
   	item->AddFieldL(*field); 

   	// verify the field is being added to the user defined template    	
	CContactItemFieldSet& ContactFieldSet = item->CardFields();
	TInt pos = ContactFieldSet.Find(aContFieldUid, avCardMap);	
	if(pos != KErrNotFound)	
		{
		if(aStorageType==KStorageTypeDateTime)
			{
			TDateTime result=ContactFieldSet[pos].DateTimeStorage()->Time().DateTime();
			//compair the results
			if((result.Year() == year) && (result.Month() == (TMonth)month) && (result.Day() == day)) 
				{
				SetTestStepResult(EPass);	
				}
			else
				{
				SetTestStepResult(EFail);	
				}
			}
		else
			{	
			value.Set(ContactFieldSet[pos].TextStorage()->Text());
			//compair the results
			if(aValue.Compare(value)==0 )
				{
				SetTestStepResult(EPass);
				}
			else
				{
				SetTestStepResult(EFail);
				}
			}
		}
	CleanupStack::Pop(field);
	CleanupStack::PopAndDestroy(item);
	CleanupStack::PopAndDestroy(contactTemplate);
	CleanupStack::PopAndDestroy(base);
	}
Пример #29
0
/**
Persist the items belonging to curent group into group table

@param aGroup referece to a contact group
*/
void CPplGroupsTable::WriteGroupMembersL(const CContactItem& aGroup)
	{
	if (aGroup.Type() != KUidContactGroup)
		{
		return;
		}

	const TContactItemId KGroupId(aGroup.Id() );

	// make sure we clear out any previous, out-of-date data
	TBool lowDiskErr(EFalse);
	DeleteItemL(KGroupId, lowDiskErr);
	if (lowDiskErr)
		{
		User::Leave(KErrDiskFull);
		}

	// build the RSqlStatement
	RSqlStatement stmnt;
	CleanupClosePushL(stmnt);
	stmnt.PrepareL(iDatabase, iInsertStmnt->SqlStringL() );
	const TInt KGroupIdIndex(KFirstIndex); 			// first parameter in query...	
	const TInt KMemberIdIndex(KGroupIdIndex + 1); 	// ...and the second parameter
	
	// copy and sort the member id array so we can see if there are duplicates
	const CContactIdArray* contactIdArray = static_cast<const CContactGroup&>(aGroup).ItemsContained();  //does not take the ownership
	
	const TInt arrayCount = contactIdArray->Count();
	CArrayFixFlat<TContactItemId>* sortedList = new(ELeave) CArrayFixFlat<TContactItemId>(KArrayGranularity);	
	CleanupStack::PushL(sortedList);
    for(TInt loop = 0;loop < arrayCount; ++loop)
    	{
    	sortedList->AppendL((*contactIdArray)[loop]);		
    	}
	TKeyArrayFix key(0,ECmpTInt);
	sortedList->Sort(key);

	// insert the group-member relationships
	const TInt KCountStmntParamIndex(KFirstIndex); // first and only parameter in query
	const TInt listLen(sortedList->Count() );
	TInt lastId(0);
	for (TInt i = 0; i < listLen; ++i)
		{
		TInt itemId((*sortedList)[i]);
		
		//check if a contact item with itemId id really exists in contact database
		RSqlStatement countStmnt;
		CleanupClosePushL(countStmnt);
		countStmnt.PrepareL(iDatabase, iCountContactsStmnt->SqlStringL() );
		User::LeaveIfError(countStmnt.BindInt(KCountStmntParamIndex, itemId) );
		TInt count = 0;
		TInt err = KErrNone;
		if((err = countStmnt.Next() ) == KSqlAtRow)
			{
			count = countStmnt.ColumnInt(iCountContactsStmnt->ParameterIndex(KSqlCount) );
			}
		else
			{
			User::LeaveIfError(err);	
			}	

		if(count == 0) 
			{
			User::Leave(KErrNotFound);	
			}
		CleanupStack::PopAndDestroy(&countStmnt);
			
		// only insert this if we haven't already seen it
		if (itemId != lastId || i == 0)
			{
			User::LeaveIfError(stmnt.BindInt(KGroupIdIndex, KGroupId) );
			User::LeaveIfError(stmnt.BindInt(KMemberIdIndex, itemId) );
			User::LeaveIfError(stmnt.Exec() );
			User::LeaveIfError(stmnt.Reset() );
			}
		lastId = itemId;
		}

	CleanupStack::PopAndDestroy(2, &stmnt); // and sortedList
	}
/**
Utility method used to read binary blob fields from contacts database. Provides a mechanism to
fill a contact item with informations stored in binary blobs within contact database.
A reference to the contact item to be fill has to be provided. A template has to be provided
if the contact item is based on a template. Template can be NULL. Also a view definition can
be provided to filter which fields are read from blob fields.

@param		aItem Contact item to be filled with information from binary blob field.
@param		aView View definition specifying what item fields should be read from binary blob field
@param		aTemplate Contact item representing a template based on which aItem should be read. Can be NULL
@param		aDatabase RSqlDatabase reference.
@leave		KErrNotFound if the specified contact item does not exist any more in contact database
*/	
void TCntPersistenceUtility::ReadBinaryBlobL(CContactItem& aItem, const CContactItemViewDef& aView, const CContactItem* aTemplate, RSqlDatabase& aDatabase)
	{
	HBufC* selectString = HBufC::NewLC(KSelectTwoFields().Length() + KContactBinaryFieldHeader().Length() + KContactBinaryFields().Length() + KSqlContactTableName().Length() + KContactId().Length());
	TPtr ptrSelectString = selectString->Des();
	ptrSelectString.Format(KSelectTwoFields, &KContactBinaryFieldHeader, &KContactBinaryFields, &KSqlContactTableName, &KContactId, aItem.Id());
	
	RSqlStatement selectStmt;
	CleanupClosePushL(selectStmt);
	User::LeaveIfError(selectStmt.Prepare(aDatabase, ptrSelectString));

	TInt err = selectStmt.Next();
	if(err != KSqlAtRow)
		{
		if(err == KSqlAtEnd)
			{
			User::Leave(KErrNotFound);	
			}
		else
			{
			User::Leave(err);	
			}	
		}
	
	TPtrC8 binaryHeader;
	selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KContactBinaryFieldHeader)), binaryHeader);
	RDesReadStream binaryHeaderStream(binaryHeader);
	CleanupClosePushL(binaryHeaderStream);
	CEmbeddedStore* binaryHeaderStore = CEmbeddedStore::FromLC(binaryHeaderStream);
	
	TPtrC8 binaryFields;
	selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KContactBinaryFields)), binaryFields);
	RDesReadStream binaryFieldsStream(binaryFields);
	CleanupClosePushL(binaryFieldsStream);
	CEmbeddedStore* binaryBlobStore = CEmbeddedStore::FromLC(binaryFieldsStream);

	ReadBinaryBlobL(*binaryHeaderStore, *binaryBlobStore, aItem, aView, aTemplate);	

	CleanupStack::PopAndDestroy(6, selectString); //binaryHeaderStore, binaryHeaderStrean, binaryBlobStore, binaryBlobStream, selectStmt, selectString
	}