--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,670 @@
+// 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:
+//
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+#include "pplcontactitemmanager.h"
+#include "cntsqlprovider.h"
+#include "dbsqlconstants.h"
+#include "cntpersistenceutility.h"
+#include <cntdef.h>
+#include <sqldb.h>
+#include <cntdb.h>
+
+/**
+Creates a concrete CPplContactItemManager object
+
+@param aDatabase reference to RSqlDatabase
+ aTransactionManager reference to MLplTransactionManager (provided by CPlContactsFile)
+@return concrete CPplContactItemManager object
+@leave KErrNoMemory, an out of memory occured
+*/
+CPplContactItemManager* CPplContactItemManager::NewL(RSqlDatabase& aDatabase, MLplTransactionManager& aTransactionManager, CLplContactProperties& aContactProperties, RPplIccContactStore& aIccContactStore)
+ {
+ CPplContactItemManager* self = new (ELeave) CPplContactItemManager(aDatabase, aTransactionManager, aContactProperties, aIccContactStore);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Class destructor. Deletes holded CCntSqlStatement
+
+*/
+CPplContactItemManager::~CPplContactItemManager()
+ {
+ delete iSelectStatement;
+ delete iContactTable;
+ delete iCommAddrTable;
+ delete iGroupTable;
+ delete iPreferencePersistor;
+ }
+
+/**
+Class constructor
+
+@param aDatabase reference to RSqlDatabase
+@param aTransactionManager reference to transaction manager
+@param aContactProperties reference to contact properties
+*/
+CPplContactItemManager::CPplContactItemManager(RSqlDatabase& aDatabase, MLplTransactionManager& aTransactionManager, CLplContactProperties& aContactProperties, RPplIccContactStore& aIccContactStore) :
+ iDatabase(aDatabase),
+ iTransactionManager(aTransactionManager),
+ iContactProperties(aContactProperties),
+ iIccContactStore(aIccContactStore)
+ {
+ }
+
+/**
+Add the given contact item to the database. Forward the call to CPplTableBase
+based classes representing the tables in the contact database.
+
+@param aItem The contact item to be added to the database.
+@param aSessionId The ID of the session that issued the request. Used to
+ prevent Phonebook Synchroniser deadlock.
+
+@return Contact item ID of the contact added to the database.
+*/
+TContactItemId CPplContactItemManager::CreateL(CContactItem& aItem, TUint aSessionId)
+ {
+ TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
+
+ TBool compressedGuid=EFalse;
+
+ // If needed generate a gui for the current contact item
+ if (aItem.Guid() == TPtrC(KNullDesC))
+ {
+ iPreferencePersistor->SetGuidL(aItem, compressedGuid);
+ }
+
+ if (compressedGuid)
+ {
+ aItem.SetHasCompressedGuid(compressedGuid);
+ }
+
+ if (aItem.Type() == KUidContactICCEntry)
+ {
+ const TInt ret = iContactProperties.ContactSynchroniserL(aSessionId).ValidateWriteContact(static_cast<CContactICCEntry&>(aItem));
+ User::LeaveIfError(ret);
+ }
+
+ if(controlTransaction)
+ {
+ StartTransactionL(aSessionId);
+ }
+
+ iContactTable->CreateInDbL(aItem);
+ iGroupTable->CreateInDbL(aItem);
+ iCommAddrTable->CreateInDbL(aItem);
+
+ TContactItemId groupId = iIccContactStore.CreateInDbL(aItem, aSessionId);
+ if(groupId != KNullContactId)
+ {
+ //Every ICC entry is added to a special group, created by the Phonebook
+ //Synchroniser server during the initial synchronisation with the Contacts Model.
+ CContactItemViewDef* itemDef = CContactItemViewDef::NewLC(CContactItemViewDef::EIncludeFields,CContactItemViewDef::EMaskHiddenFields);
+ itemDef->AddL(KUidContactFieldMatchAll);
+
+ // Add ICC entry to the group.
+ CContactGroup* grp = static_cast<CContactGroup*>(ReadLC(groupId, *itemDef, EPlAllInfo, aSessionId));
+
+ grp->AddContactL(aItem.Id());
+ UpdateL(*grp, aSessionId);
+
+ CleanupStack::PopAndDestroy(2, itemDef); // grp
+ }
+
+ if(controlTransaction)
+ {
+ CommitTransactionL();
+ }
+
+ return aItem.Id();
+ }
+
+/**
+Reads the contact item from the database using the given contact item ID.
+
+@param aItemId The Id number of the contact to be read.
+@param aView Specifies the fields to be read.
+@param aInfoToRead not used
+@param aSessionId The ID of the session that issued the request. This is used
+to prevent Phonebook Synchroniser deadlock.
+@param aIccOpenCheck Specifies if validation with the Phonebook Synchroniser is
+needed for this contact.
+
+@leave KErrArgument if the itemID can't be set within select statement
+@leave KErrNotFound if a contact item with aItemId does not exist within contact database
+@leave KSqlErrBusy the database file is locked; thrown if RSqlStatement::Next()
+ returns this error
+@leave KErrNoMemory an out of memory condition has occurred - the statement
+ will be reset;thrown if RSqlStatement::Next() returns this error
+@leave KSqlErrGeneral a run-time error has occured - this function must not
+ be called again;thrown if RSqlStatement::Next() returns this error
+@leave KSqlErrMisuse this function has been called after a previous call
+ returned KSqlAtEnd or KSqlErrGeneral.thrown if RSqlStatement::Next()
+ returns this error
+@leave KSqlErrStmtExpired the SQL statement has expired (if new functions or
+ collating sequences have been registered or if an
+ authorizer function has been added or changed);
+ thrown if RSqlStatement::Next() returns this error
+
+@return CContactItem created from reading the database tables.
+*/
+CContactItem* CPplContactItemManager::ReadLC(TContactItemId aItemId, const CContactItemViewDef& aView, TInt aInfoToRead, TUint aSessionId, TBool aIccOpenCheck) const
+ {
+ CContactTemplate* sysTemplate = NULL;
+ if (aItemId != KGoldenTemplateId)
+ {
+ sysTemplate = const_cast<CContactTemplate*>(&iContactProperties.SystemTemplateL());
+ }
+
+ RSqlStatement selectStmt;
+ CleanupClosePushL(selectStmt);
+ User::LeaveIfError(selectStmt.Prepare(iDatabase, iSelectStatement->SqlStringL()));
+
+ TInt err = selectStmt.BindInt(KFirstParam, aItemId);
+
+ if(err != KErrNone)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ CContactItem* item = NULL;
+ TUid type(KNullUid);
+
+ if((err = selectStmt.Next()) == KSqlAtRow)
+ {
+ TInt contactId = selectStmt.ColumnInt(iSelectStatement->ParameterIndex(KContactId));
+ TInt templateId = selectStmt.ColumnInt(iSelectStatement->ParameterIndex(KContactTemplateId));
+ TInt typeFlags = selectStmt.ColumnInt(iSelectStatement->ParameterIndex(KContactTypeFlags));
+ type = TCntPersistenceUtility::TypeFlagsToContactTypeUid(typeFlags);
+ item = CContactItem::NewLC(type);
+ item->SetId(contactId);
+ TPtrC guid = selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactGuidString));
+ item->SetUidStringL(guid);
+ TInt attr = (typeFlags & EContactAttributes_Mask) >> EContactAttributes_Shift;
+ item->SetAttributes(attr);
+ item->SetTemplateRefId(templateId);
+ item->SetLastModified(TTime(selectStmt.ColumnInt64(iSelectStatement->ParameterIndex(KContactLastModified))));
+ item->SetCreationDate(TTime(selectStmt.ColumnInt64(iSelectStatement->ParameterIndex(KContactCreationDate))));
+ item->SetAccessCount(selectStmt.ColumnInt(iSelectStatement->ParameterIndex(KContactAccessCount)));
+
+ RArray<TPtrC> fastAccessFields;
+ CleanupClosePushL(fastAccessFields);
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactFirstName)));
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactLastName)));
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactCompanyName)));
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactFirstNamePrn)));
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactLastNamePrn)));
+ fastAccessFields.AppendL(selectStmt.ColumnTextL(iSelectStatement->ParameterIndex(KContactCompanyNamePrn)));
+
+ //set first name, last name, company name, first name pronunciation, last name pronunciation, company name pronunciation
+ for (TInt fieldNum = item->CardFields().Count() - 1; fieldNum>=0; --fieldNum)
+ {
+ CContactItemField& textField = (item->CardFields())[fieldNum];
+ const TInt nameFieldIndex = NameFieldIndex(textField);
+
+ // Check if field is first name, last name, company name,
+ // first name pronunciation, last name pronunciation, company name pronunciation.
+ if (nameFieldIndex != KErrNotFound)
+ {
+ HBufC* text = HBufC::NewLC(fastAccessFields[nameFieldIndex].Size());
+ text->Des() = fastAccessFields[nameFieldIndex];
+ textField.TextStorage()->SetText(text);
+ CleanupStack::PopAndDestroy(text);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&fastAccessFields);
+ }
+ else
+ {
+ if(err == KSqlAtEnd)
+ {
+ User::Leave(KErrNotFound); // Select statement did not return any row
+ }
+ else
+ {
+ User::Leave(err); // Otherwise selectStmt.Next() generated a sql error
+ }
+
+ }
+
+ if (!(item->IsDeleted()) || type == KUidContactCardTemplate)
+ {
+ TCntPersistenceUtility::ReadBlobL(*item, aView, sysTemplate, iDatabase);
+ }
+
+ //Fill in group content.
+ static_cast<CPplGroupsTable*>(iGroupTable)->ReadL(*item);
+
+ //Validate checking ICC entry.
+ iIccContactStore.ReadL(*item, aInfoToRead, aSessionId, aIccOpenCheck);
+
+ CleanupStack::Pop(item);
+ CleanupStack::PopAndDestroy(&selectStmt);
+ CleanupStack::PushL(item);
+
+ return item;
+ }
+
+/**
+Updates the given contact item in the database.Forward the call to CPplTableBase
+based classes representing the tables in the contact database.
+
+@param aItem The contact to be updated with all the changes (received from the
+user).
+@param aSessionId The ID of the session that issued the request. Used to
+prevent Phonebook Synchroniser deadlock.
+*/
+void CPplContactItemManager::UpdateL(CContactItem& aItem, TUint aSessionId, TBool /*aSpeeDailUpdate*/)
+ {
+ TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
+
+ if (aItem.Type() == KUidContactICCEntry)
+ {
+ //Fakely validating read right to ICC entry to keep BC.
+ const TInt ret = iContactProperties.ContactSynchroniserL(aSessionId).ValidateContact(MContactSynchroniser::ERead, aItem.Id());
+ User::LeaveIfError(ret);
+ }
+
+ if(controlTransaction)
+ {
+ StartTransactionL(aSessionId);
+ }
+
+ iIccContactStore.UpdateL(aItem, aSessionId);
+ iContactTable->UpdateL(aItem);
+ iGroupTable->UpdateL(aItem);
+ iCommAddrTable->UpdateL(aItem);
+
+ if(controlTransaction)
+ {
+ CommitTransactionL();
+ }
+
+ // If the item is the System template then delete it from the template
+ // manager. The template can later be recreated from the table.
+ if (aItem.Id() == KGoldenTemplateId)
+ {
+ iContactProperties.SystemTemplateManager().DeleteTemplate();
+ }
+ }
+
+/**
+Deletes the given contact from the database.Forward the call to CPplTableBase
+based classes representing the tables in the contact database. In low disk condition
+checks if it can gain access to reserver database space and perform the deletion. If
+this is not possible a KErrDiskFull will be thrown.
+
+@param aItemId The contact ID of the contact item to be deleted.
+@param aSessionId The ID of the session that issued the request. Used to
+prevent Phonebook Synchroniser deadlock.
+
+@leave KErrDiskFull if a full disk error appears
+
+@return The item which was read from the database before it was deleted. This
+object can be used by, for example, the CLplAnalyserProxy::DeleteLC() method to
+create a notification message.
+*/
+CContactItem* CPplContactItemManager::DeleteLC(TContactItemId aItemId, TUint aSessionId, TCntSendEventAction /*aEventType*/)
+ {
+ TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
+
+ CContactItemViewDef* viewDef = CContactItemViewDef::NewL(CContactItemViewDef::EIncludeFields, CContactItemViewDef::EIncludeHiddenFields);
+ CleanupStack::PushL(viewDef);
+
+ if(controlTransaction)
+ {
+ StartTransactionL(aSessionId);
+ }
+
+ TBool lowDisk = EFalse;
+ CContactItem* savedContactItem = static_cast<CPplContactTable*>(iContactTable)->DeleteLC(aItemId, lowDisk);
+ if(lowDisk)
+ {
+ CleanupStack::PopAndDestroy(savedContactItem); // this was returned from the first call, but not deleted in the db
+ TInt err = iDatabase.GetReserveAccess();
+ if(err != KErrNotFound)
+ {
+ User::Leave(KErrDiskFull);
+ }
+
+ lowDisk = EFalse;
+
+ savedContactItem = static_cast<CPplContactTable*>(iContactTable)->DeleteLC(aItemId, lowDisk);
+ if(lowDisk)
+ {
+ iDatabase.FreeReservedSpace();
+ User::Leave(KErrDiskFull);
+ }
+ iDatabase.FreeReservedSpace();
+ }
+
+ lowDisk = EFalse;
+ iGroupTable->DeleteL(*savedContactItem, lowDisk);
+ if(lowDisk)
+ {
+ DeleteInLowDiskConditionL(iGroupTable, savedContactItem);
+ }
+
+ lowDisk = EFalse;
+ iCommAddrTable->DeleteL(*savedContactItem, lowDisk);
+ if(lowDisk)
+ {
+ DeleteInLowDiskConditionL(iCommAddrTable, savedContactItem);
+ }
+
+ //Fake checking read access to ICCEntry store to keep BC.
+ iIccContactStore.ReadL(*savedContactItem, EPlGroupMembershipInfo, aSessionId, EFalse);
+
+ //Don't need to check low disk state for ICC synchronizer.
+ iIccContactStore.DeleteL(*savedContactItem, aSessionId);
+
+ if(controlTransaction)
+ {
+ CommitTransactionL(); // Pops item
+ }
+
+ CleanupStack::Pop(); // Pops item or transaction
+ CleanupStack::PopAndDestroy(viewDef);
+ CleanupStack::PushL(savedContactItem);
+
+ return savedContactItem;
+
+ }
+
+/**
+Perform a deletion in low disk condition
+
+@param aTable CPplTableBase on which the deletion will be done
+@param aContactItem the contact item to be deleted
+
+@leave KErrDiskFull if the deletion can't be done a KerrDiskFull will be throw
+*/
+void CPplContactItemManager::DeleteInLowDiskConditionL(CPplTableBase* aTable, CContactItem* aContactItem)
+ {
+ TInt err = iDatabase.GetReserveAccess();
+ if(err != KErrNotFound)
+ {
+ User::Leave(KErrDiskFull);
+ }
+
+ TBool lowDisk = EFalse;
+ aTable->DeleteL(*aContactItem, lowDisk);
+ if(lowDisk)
+ {
+ iDatabase.FreeReservedSpace();
+ User::Leave(KErrDiskFull);
+ }
+ iDatabase.FreeReservedSpace();
+ }
+
+/**
+Change the type of the given contact item to the given type.Forward the call to CPplTableBase
+based classes representing the tables in the contact database.
+
+@param aItemId Contact item ID whose type is to be changed.
+@param aNewType New type for contact item.
+*/
+void CPplContactItemManager::ChangeTypeL(TContactItemId aItemId, TUid aNewType)
+ {
+ static_cast<CPplContactTable*>(iContactTable)->ChangeTypeL(aItemId, aNewType);
+ }
+
+/**
+Does nothing: the CLplAnalyserProxy class sets the connetion ID.
+*/
+void CPplContactItemManager::SetConnectionId(TInt /*aConnectionId*/)
+ {
+ }
+
+/**
+Second phase constructor for CPplContactItemManager object.
+Sets the CCntSqlStatement to be used for reading contact item.
+
+*/
+void CPplContactItemManager::ConstructL()
+ {
+ TCntSqlStatementType statementType(ESelect, KSqlContactTableName);
+
+ iSelectStatement = TSqlProvider::GetSqlStatementL(statementType);
+
+ // also prepare everything in CCntSqlStatement
+ // First add columns from contact table
+ iSelectStatement->SetParamL(KContactId, KSpace);
+ iSelectStatement->SetParamL(KContactTemplateId, KSpace);
+ iSelectStatement->SetParamL(KContactTypeFlags, KSpace);
+ iSelectStatement->SetParamL(KContactAccessCount, KSpace);
+ iSelectStatement->SetParamL(KContactCreationDate, KSpace);
+ iSelectStatement->SetParamL(KContactLastModified, KSpace);
+ iSelectStatement->SetParamL(KContactGuidString, KSpace);
+ iSelectStatement->SetParamL(KContactFirstName, KSpace);
+ iSelectStatement->SetParamL(KContactLastName, KSpace);
+ iSelectStatement->SetParamL(KContactCompanyName, KSpace);
+ iSelectStatement->SetParamL(KContactFirstNamePrn, KSpace);
+ iSelectStatement->SetParamL(KContactLastNamePrn, KSpace);
+ iSelectStatement->SetParamL(KContactCompanyNamePrn, KSpace);
+
+ HBufC* condition = HBufC::NewLC(KWhereStringEqualsStringFormatText().Size() + KContactId().Size());
+ TPtr ptrCondition = condition->Des();
+ ptrCondition.Format(KWhereStringEqualsStringFormatText, &KContactId, &KVar);
+
+ // Set condition
+ iSelectStatement->SetConditionL(ptrCondition);
+
+ CleanupStack::PopAndDestroy( condition );
+
+ // construct tables
+ iContactTable = CPplContactTable::NewL(iDatabase, iContactProperties);
+ iCommAddrTable = CPplCommAddrTable::NewL(iDatabase, iContactProperties);
+ iGroupTable = CPplGroupsTable::NewL(iDatabase);
+ iPreferencePersistor = CPplPreferencesPersistor::NewL(iDatabase);
+ }
+
+/**
+Cleanup operation. If one of the crud operation fails, this method will be called
+to rollback the sql transaction
+
+*/
+void CPplContactItemManager::CleanupOperationRollbackL(TAny* aPplContactItemanager)
+ {
+ CPplContactItemManager* contactItemManager = static_cast<CPplContactItemManager*>(aPplContactItemanager);
+ contactItemManager->iTransactionManager.RollbackCurrentTransactionL(contactItemManager->iSessionId);
+ }
+
+/**
+Utility method used to identify if the provided CContactItemField is first name, last name,
+company name, first name pronunciation, last name pronunciation or company name pronunciation
+Method used to fill information when a CContactItem is read from contact database
+
+@param aNameField reference to a constant CContactItemField for which the index will be returned
+
+*/
+TInt CPplContactItemManager::NameFieldIndex(const CContactItemField& aNameField) const
+ {
+ // For all the name fields...
+ for (TInt nameFieldNum=0; nameFieldNum < sizeof(KFastAccessFieldUids)/sizeof(TInt); ++nameFieldNum)
+ {
+ if (aNameField.ContentType().ContainsFieldType(TUid::Uid(KFastAccessFieldUids[nameFieldNum])))
+ {
+ return nameFieldNum;
+ }
+ }
+ return KErrNotFound;
+ }
+
+/**
+Utility method used to start a transaction in database
+
+@param aSessionId id of the session
+*/
+void CPplContactItemManager::StartTransactionL(TUint aSessionId)
+ {
+ iTransactionManager.StartTransactionL();
+
+ iSessionId = aSessionId;
+ CleanupStack::PushL(TCleanupItem(CleanupOperationRollbackL, this));
+ }
+
+/**
+Utility method used to commit a transaction
+*/
+void CPplContactItemManager::CommitTransactionL()
+ {
+ iTransactionManager.CommitCurrentTransactionL(iSessionId);
+
+ CleanupStack::Pop(); //CleanupOperationRollbackL
+ }
+
+/**
+Utility method used to create tables in a newly create database
+*/
+void CPplContactItemManager::CreateTablesL()
+ {
+ TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
+
+ if(controlTransaction)
+ {
+ StartTransactionL(0);
+ }
+
+ iContactTable->CreateTableL();
+ iGroupTable->CreateTableL();
+ iCommAddrTable->CreateTableL();
+ iPreferencePersistor->CreateTableL();
+
+ if(controlTransaction)
+ {
+ CommitTransactionL();
+ }
+ }
+
+/**
+Utility method used to check if there is any record in the contact database
+
+@return ETrue if the contact database is empty and EFalse otherwise
+*/
+TBool CPplContactItemManager::IsDatabaseEmptyL()
+ {
+ return static_cast<CPplContactTable*>(iContactTable)->IsTableEmptyL();
+ }
+
+CContactIdArray* CPplContactItemManager::MatchPhoneNumberL(const TDesC& aNumber, TInt aMatchLengthFromRight)
+ {
+ // Call comm address table
+ if (aMatchLengthFromRight == KBestMatchingPhoneNumbers)
+ {
+ return static_cast<CPplCommAddrTable*>(iCommAddrTable)->BestMatchingPhoneNumberL(aNumber);
+ }
+ else
+ {
+ return static_cast<CPplCommAddrTable*>(iCommAddrTable)->MatchPhoneNumberL(aNumber, aMatchLengthFromRight);
+ }
+ }
+
+/**
+Utility method used to retrieve an array of card template ids
+
+@return reference to a CContactIdArray containing the card template ids
+*/
+CContactIdArray& CPplContactItemManager::CardTemplateIdsL()
+ {
+ // Call contact table
+ return static_cast<CPplContactTable*>(iContactTable)->CardTemplateIdsL();
+ }
+
+/**
+Utility method used to retrieve a reference to persistence layer preference persistor
+*/
+CPplPreferencesPersistor& CPplContactItemManager::PreferencesPersitor()
+ {
+ return *iPreferencePersistor;
+ }
+
+/**
+Utility method used to retrieve own card contact id
+*/
+TContactItemId CPplContactItemManager::OwnCardIdL()
+ {
+ // Call contact table
+ return static_cast<CPplContactTable*>(iContactTable)->OwnCardIdL();
+ }
+
+/**
+Utility method used to set own card id
+*/
+void CPplContactItemManager::SetOwnCardIdL(TContactItemId aId)
+ {
+ // Call contact table
+ static_cast<CPplContactTable*>(iContactTable)->SetOwnCardIdL(aId);
+ }
+
+/**
+Utility class. Returns an array with ids of all groups in contact database
+*/
+CContactIdArray* CPplContactItemManager::GroupIdListL()
+ {
+ CContactIdArray* idArray = CContactIdArray::NewLC();
+
+ HBufC* selectString = HBufC::NewLC(KOneTypeField().Length() + KSqlContactTableName().Length() + KContactTypeFlags().Length() + 3);
+ TPtr ptrSelectString = selectString->Des();
+ ptrSelectString.Format(KOneTypeField, &KContactId, &KSqlContactTableName, &KContactTypeFlags, EContactType_Shift, EContactTypeFlags_Group);
+
+ RSqlStatement selectStatement;
+ CleanupClosePushL(selectStatement);
+
+ User::LeaveIfError(selectStatement.Prepare(iDatabase, ptrSelectString));
+ const TInt KIdx = iSelectStatement->ParameterIndex(KContactId);
+
+ TInt err;
+ while((err = selectStatement.Next()) == KSqlAtRow)
+ {
+ idArray->AddL(selectStatement.ColumnInt(KIdx));
+ }
+
+ if(err != KSqlAtEnd)
+ {
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(&selectStatement);
+ CleanupStack::PopAndDestroy(selectString);
+ CleanupStack::Pop(idArray);
+
+ return idArray;
+ }
+
+/**
+Utility method used to rthe prefered card template id
+*/
+TInt CPplContactItemManager::CardTemplatePrefIdL() const
+ {
+ return iPreferencePersistor->PreferredCardTemplateIdL();
+ }
+
+/**
+Utility method used to set the prefered card template id
+*/
+void CPplContactItemManager::SetCardTemplatePrefIdL(TInt aCardTemplatePrefId)
+ {
+ iPreferencePersistor->SetPreferredCardTemplateIdL(aCardTemplatePrefId);
+ }