phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp
changeset 24 0ba2181d7c28
parent 0 e686773b3f54
child 25 76a2435edfd4
--- a/phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Tue Feb 02 10:12:17 2010 +0200
+++ b/phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp	Fri Mar 19 09:27:18 2010 +0200
@@ -1,17 +1,20 @@
-// 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:
-//
+/*
+* 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
@@ -23,10 +26,16 @@
 #include "cntsqlprovider.h"
 #include "dbsqlconstants.h"
 #include "cntpersistenceutility.h"
+//#include "cntmetadataoperation.h"
 #include <cntdef.h>
 #include <sqldb.h>
 #include <cntdb.h>
 
+// TODO: The code related to predictive search table is placed inside this
+// macro. Uncomment the below line to get the table into use.
+#define USE_PRED_SEARCH_TABLE
+
+
 /**
 Creates a concrete CPplContactItemManager object 
 
@@ -52,9 +61,15 @@
 	{
 	delete iSelectStatement;	
 	delete iContactTable;
-	delete iCommAddrTable;	
+	delete iCommAddrTable;
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("delete pred search table"));
+	delete iPredSearchTable;
+#endif
+    delete 	iPresenceTable; 
 	delete iGroupTable;
 	delete iPreferencePersistor;
+	//iColSession.Close();
 	}
 	
 /**
@@ -113,6 +128,11 @@
 	iContactTable->CreateInDbL(aItem);	
 	iGroupTable->CreateInDbL(aItem);	
 	iCommAddrTable->CreateInDbL(aItem);
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("add new contact to pred search table"));
+	iPredSearchTable->CreateInDbL(aItem);
+	RDebug::Print(_L("add new contact to pred search table - done"));
+#endif
 
    	TContactItemId groupId = iIccContactStore.CreateInDbL(aItem, aSessionId);
    	if(groupId != KNullContactId)
@@ -136,6 +156,12 @@
 		CommitTransactionL();
 		}
 	
+	// Assuming success if no leaves at this point, so update
+	// the metadata search store for this entry
+	//CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
+	//TRAP_IGNORE(op->SaveContactLD(aItem));
+	//CleanupStack::Pop(op); // Do not destroy - called LD function
+	
 	return aItem.Id();	
 	}
 	
@@ -295,6 +321,11 @@
 	iContactTable->UpdateL(aItem);	
 	iGroupTable->UpdateL(aItem);	
 	iCommAddrTable->UpdateL(aItem);
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("update contact in pred search table"));
+	iPredSearchTable->UpdateL(aItem);
+	RDebug::Print(_L("update contact in pred search table - done"));
+#endif
 
 	if(controlTransaction)
 		{
@@ -307,6 +338,12 @@
 		{
 		iContactProperties.SystemTemplateManager().DeleteTemplate();
 		}
+	
+    // Assuming success if no leaves at this point, so update
+    // the metadata search store for this entry
+    //CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
+    //TRAP_IGNORE(op->SaveContactLD(aItem));
+    //CleanupStack::Pop(op); // Do not destroy - called LD function
 	}
 
 /**
@@ -372,7 +409,18 @@
 		{
 		DeleteInLowDiskConditionL(iCommAddrTable, savedContactItem);
 		}
-    
+
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("delete contact from pred search table"));
+	lowDisk = EFalse;
+    iPredSearchTable->DeleteL(*savedContactItem, lowDisk);
+    if(lowDisk) 
+		{
+		DeleteInLowDiskConditionL(iPredSearchTable, savedContactItem);
+		}
+	RDebug::Print(_L("delete contact from pred search table - done"));
+#endif
+  
     //Fake checking read access to ICCEntry store to keep BC.
     iIccContactStore.ReadL(*savedContactItem, EPlGroupMembershipInfo, aSessionId, EFalse);    
     
@@ -388,6 +436,12 @@
 	CleanupStack::PopAndDestroy(viewDef);	
 	CleanupStack::PushL(savedContactItem);
 
+	// Assume no leaves by this point indicates successful delete,
+	// therefore update the metadata store
+	//CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
+	//TRAP_IGNORE(op->DeleteContactLD(aItemId));
+	//CleanupStack::Pop(op); // Do not destroy - called LD function
+	
 	return savedContactItem;
 	
 	}
@@ -444,6 +498,7 @@
 */
 void CPplContactItemManager::ConstructL()
 	{
+	RDebug::Print(_L("CPplContactItemManager::ConstructL"));
 	TCntSqlStatementType statementType(ESelect, KSqlContactTableName);
 	
 	iSelectStatement = TSqlProvider::GetSqlStatementL(statementType);
@@ -478,6 +533,17 @@
 	iCommAddrTable = CPplCommAddrTable::NewL(iDatabase, iContactProperties);
 	iGroupTable = CPplGroupsTable::NewL(iDatabase);
 	iPreferencePersistor = CPplPreferencesPersistor::NewL(iDatabase);
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("create CPplPredictiveSearchTable object"));
+	iPredSearchTable = CPplPredictiveSearchTable::NewL(iDatabase);
+	RDebug::Print(_L("create CPplPredictiveSearchTable object - done"));
+#endif
+	iPresenceTable = CPplPresenceTable::NewL(iDatabase); 
+	
+	// Connect to metadata server
+	//User::LeaveIfError(iColSession.Connect());
+
+	RDebug::Print(_L("CPplContactItemManager::ConstructL ends"));
 	}
 
 /**
@@ -540,6 +606,8 @@
 */	
 void CPplContactItemManager::CreateTablesL()
 	{
+	RDebug::Print(_L("CPplContactItemManager::CreateTablesL"));	
+
 	TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
 	
 	if(controlTransaction)
@@ -551,11 +619,19 @@
 	iGroupTable->CreateTableL();	
 	iCommAddrTable->CreateTableL();
 	iPreferencePersistor->CreateTableL();
+#if defined(USE_PRED_SEARCH_TABLE)
+	RDebug::Print(_L("create pred search table to DB"));	
+	iPredSearchTable->CreateTableL();
+	RDebug::Print(_L("create pred search table to DB - done"));	
+#endif
+	iPresenceTable->CreateTableL(); 
 	
 	if(controlTransaction)
 		{
 		CommitTransactionL();
 		}			
+
+	RDebug::Print(_L("CPplContactItemManager::CreateTablesL ends"));	
 	}
 	
 /**
@@ -646,6 +722,35 @@
 	return idArray;
 	}
 
+CContactIdArray* CPplContactItemManager::SearchIdListL(const TDesC& aSearchQuery) const
+    {
+    CContactIdArray* idArray = CContactIdArray::NewLC();
+    
+    //Prepare ane execute the sql query
+    RSqlStatement selectStatement;
+    CleanupClosePushL(selectStatement);
+    User::LeaveIfError(selectStatement.Prepare(iDatabase, aSearchQuery));
+    const TInt KIdx = iSelectStatement->ParameterIndex(KContactId);
+        
+	// Iterate through the results and append the contactIds to idArray	
+    TInt err;
+    while((err = selectStatement.Next()) == KSqlAtRow)
+        {
+        idArray->AddL(selectStatement.ColumnInt(KIdx)); 
+        }
+
+    if(err != KSqlAtEnd)
+        {
+        User::Leave(err);
+        }
+
+    //Cleanup 
+    CleanupStack::PopAndDestroy(&selectStatement);
+    CleanupStack::Pop(idArray);
+    
+    return idArray;
+    }
+
 /**
 Utility method used to rthe prefered card template id
 */
@@ -661,3 +766,139 @@
 	{
 	iPreferencePersistor->SetPreferredCardTemplateIdL(aCardTemplatePrefId);
 	}
+
+// If pred search table is missing, generate it from existing contacts table
+// Even if contact would not have any first name, last name or company name
+// defined, write an entry to predictive search. So that if contact is later
+// updated by adding e.g. company name, the predictive search table already
+// has an entry for the contact, and the company name can be updated there too.
+void CPplContactItemManager::SynchronizePredSearchTableL()
+	{
+#if !defined(USE_PRED_SEARCH_TABLE)
+	return;
+#endif
+	RDebug::Print(_L("CPplContactItemManager::SynchronizePredSearchTableL"));
+
+	if (DoesPredSearchTableExistL())
+		{
+		RDebug::Print(_L("pred search table exists, don't generate it"));
+		return;
+		}
+
+	iPredSearchTable->CreateTableL();
+	_LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S,%S FROM %S;");
+	TInt bufSize = KSelectAllContactsFormat().Length() +
+				   KContactId().Length() +
+				   KContactFirstName().Length() +
+				   KContactLastName().Length() +
+				   KContactCompanyName().Length() +
+				   KSqlContactTableName().Length();
+	HBufC* sqlStatement = HBufC::NewLC(bufSize);
+	sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
+		&KContactId,
+		&KContactFirstName,
+		&KContactLastName,
+		&KContactCompanyName,
+		&KSqlContactTableName);
+
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+	RDebug::Print(_L("SynchronizePredSearchTableL prepare SQL statement"));
+    stmnt.PrepareL(iDatabase, *sqlStatement);
+
+	const TInt KContactIdIndex = 0;
+	const TInt KFirstNameIndex = 1;
+	const TInt KLastNameIndex = 2;
+	const TInt KCompanyNameIndex = 3;
+	TInt err(KErrNone);
+    while ((err = stmnt.Next()) == KSqlAtRow)
+        {
+		RDebug::Print(_L("SynchronizePredSearchTableL create CContactItem"));
+
+		TInt id = KUidContactCardValue;
+		TUid uid;
+		uid.iUid = id;
+		CContactItem* contact = CContactItem::NewLC(uid);
+		contact->SetId(stmnt.ColumnInt(KContactIdIndex));
+
+		// If first name exists, write it to contact item
+		TPtrC firstName;
+		if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
+			{
+			RDebug::Print(_L("SynchronizePredSearchTableL read first name"));
+			CContactItemField* field =
+				CContactItemField::NewL(KStorageTypeText, KUidContactFieldGivenName);
+			CContactTextField* textfield = field->TextStorage();
+			RDebug::Print(_L("set first name to text field"));
+			textfield->SetTextL(firstName);
+			contact->AddFieldL(*field); // Takes ownership
+			}
+
+		TPtrC lastName;
+		if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
+			{
+			RDebug::Print(_L("SynchronizePredSearchTableL read last name"));
+			CContactItemField* field =
+				CContactItemField::NewL(KStorageTypeText, KUidContactFieldFamilyName);
+			CContactTextField* textfield = field->TextStorage();
+			RDebug::Print(_L("set last name to text field"));
+			textfield->SetTextL(lastName);
+			contact->AddFieldL(*field); // Takes ownership
+			}
+		
+		TPtrC companyName;
+		if (stmnt.ColumnText(KCompanyNameIndex, companyName) == KErrNone)
+			{
+			RDebug::Print(_L("SynchronizePredSearchTableL read company name"));
+			CContactItemField* field =
+				CContactItemField::NewL(KStorageTypeText, KUidContactFieldCompanyName);
+			CContactTextField* textfield = field->TextStorage();
+			RDebug::Print(_L("set company name to text field"));
+			textfield->SetTextL(companyName);
+			contact->AddFieldL(*field); // Takes ownership
+			}
+
+		RDebug::Print(_L("SynchronizePredSearchTableL create entry to pred search table"));
+		iPredSearchTable->CreateInDbL(*contact);
+		CleanupStack::PopAndDestroy(contact);
+        }
+	RDebug::Print(_L("SynchronizePredSearchTableL while loop done"));
+
+    // Leave if we didn't complete going through the results properly
+    if (err != KSqlAtEnd)
+        {
+		RDebug::Print(_L("SynchronizePredSearchTableL SQL err=%d"), err);
+        User::Leave(err);
+        }
+    CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(sqlStatement);
+	RDebug::Print(_L("CPplContactItemManager::SynchronizePredSearchTableL ends"));
+	}
+
+TBool CPplContactItemManager::DoesPredSearchTableExistL() const
+	{
+	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL"));
+
+	_LIT(KSelectContactIdsFormat, "SELECT %S FROM %S;");
+	TInt bufSize = KSelectContactIdsFormat().Length() +
+				   KPredSearchContactId().Length() +
+				   KSqlContactPredSearchTableName().Length();
+	HBufC* sqlStatement = HBufC::NewLC(bufSize);
+	sqlStatement->Des().AppendFormat(KSelectContactIdsFormat,
+		&KPredSearchContactId,
+		&KSqlContactPredSearchTableName);
+
+	RSqlStatement stmnt;
+	CleanupClosePushL(stmnt);
+	// If predictive search table does not exist, leaves with -311.
+    // If it exists, does not leave.
+    TRAPD(err, stmnt.PrepareL(iDatabase, *sqlStatement));
+	RDebug::Print(_L("err=%d"), err );
+
+	CleanupStack::PopAndDestroy(&stmnt);
+	CleanupStack::PopAndDestroy(sqlStatement);
+
+	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL return %d"),
+				  err == KErrNone );
+	return err == KErrNone;
+	}