phonebookengines/contactsmodel/cntplsql/src/pplcontactitemmanager.cpp
changeset 24 0ba2181d7c28
parent 0 e686773b3f54
child 25 76a2435edfd4
equal deleted inserted replaced
0:e686773b3f54 24:0ba2181d7c28
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 /*
     2 // All rights reserved.
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 // This component and the accompanying materials are made available
     3 * All rights reserved.
     4 // under the terms of "Eclipse Public License v1.0"
     4 * This component and the accompanying materials are made available
     5 // which accompanies this distribution, and is available
     5 * under the terms of "Eclipse Public License v1.0"
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 * which accompanies this distribution, and is available
     7 //
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 // Initial Contributors:
     8 *
     9 // Nokia Corporation - initial contribution.
     9 * Initial Contributors:
    10 //
    10 * Nokia Corporation - initial contribution.
    11 // Contributors:
    11 *
    12 //
    12 * Contributors:
    13 // Description:
    13 *
    14 //
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
    15 
    18 
    16 /**
    19 /**
    17  @file
    20  @file
    18  @internalComponent
    21  @internalComponent
    19  @released
    22  @released
    21 
    24 
    22 #include "pplcontactitemmanager.h"
    25 #include "pplcontactitemmanager.h"
    23 #include "cntsqlprovider.h"
    26 #include "cntsqlprovider.h"
    24 #include "dbsqlconstants.h"
    27 #include "dbsqlconstants.h"
    25 #include "cntpersistenceutility.h"
    28 #include "cntpersistenceutility.h"
       
    29 //#include "cntmetadataoperation.h"
    26 #include <cntdef.h>
    30 #include <cntdef.h>
    27 #include <sqldb.h>
    31 #include <sqldb.h>
    28 #include <cntdb.h>
    32 #include <cntdb.h>
       
    33 
       
    34 // TODO: The code related to predictive search table is placed inside this
       
    35 // macro. Uncomment the below line to get the table into use.
       
    36 #define USE_PRED_SEARCH_TABLE
       
    37 
    29 
    38 
    30 /**
    39 /**
    31 Creates a concrete CPplContactItemManager object 
    40 Creates a concrete CPplContactItemManager object 
    32 
    41 
    33 @param 	aDatabase reference to RSqlDatabase
    42 @param 	aDatabase reference to RSqlDatabase
    50 */		
    59 */		
    51 CPplContactItemManager::~CPplContactItemManager()
    60 CPplContactItemManager::~CPplContactItemManager()
    52 	{
    61 	{
    53 	delete iSelectStatement;	
    62 	delete iSelectStatement;	
    54 	delete iContactTable;
    63 	delete iContactTable;
    55 	delete iCommAddrTable;	
    64 	delete iCommAddrTable;
       
    65 #if defined(USE_PRED_SEARCH_TABLE)
       
    66 	RDebug::Print(_L("delete pred search table"));
       
    67 	delete iPredSearchTable;
       
    68 #endif
       
    69     delete 	iPresenceTable; 
    56 	delete iGroupTable;
    70 	delete iGroupTable;
    57 	delete iPreferencePersistor;
    71 	delete iPreferencePersistor;
       
    72 	//iColSession.Close();
    58 	}
    73 	}
    59 	
    74 	
    60 /**
    75 /**
    61 Class constructor
    76 Class constructor
    62 
    77 
   111 		}
   126 		}
   112 		
   127 		
   113 	iContactTable->CreateInDbL(aItem);	
   128 	iContactTable->CreateInDbL(aItem);	
   114 	iGroupTable->CreateInDbL(aItem);	
   129 	iGroupTable->CreateInDbL(aItem);	
   115 	iCommAddrTable->CreateInDbL(aItem);
   130 	iCommAddrTable->CreateInDbL(aItem);
       
   131 #if defined(USE_PRED_SEARCH_TABLE)
       
   132 	RDebug::Print(_L("add new contact to pred search table"));
       
   133 	iPredSearchTable->CreateInDbL(aItem);
       
   134 	RDebug::Print(_L("add new contact to pred search table - done"));
       
   135 #endif
   116 
   136 
   117    	TContactItemId groupId = iIccContactStore.CreateInDbL(aItem, aSessionId);
   137    	TContactItemId groupId = iIccContactStore.CreateInDbL(aItem, aSessionId);
   118    	if(groupId != KNullContactId)
   138    	if(groupId != KNullContactId)
   119    	    {
   139    	    {
   120    	    //Every ICC entry is added to a special group, created by the Phonebook
   140    	    //Every ICC entry is added to a special group, created by the Phonebook
   133 
   153 
   134 	if(controlTransaction)
   154 	if(controlTransaction)
   135 		{
   155 		{
   136 		CommitTransactionL();
   156 		CommitTransactionL();
   137 		}
   157 		}
       
   158 	
       
   159 	// Assuming success if no leaves at this point, so update
       
   160 	// the metadata search store for this entry
       
   161 	//CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
       
   162 	//TRAP_IGNORE(op->SaveContactLD(aItem));
       
   163 	//CleanupStack::Pop(op); // Do not destroy - called LD function
   138 	
   164 	
   139 	return aItem.Id();	
   165 	return aItem.Id();	
   140 	}
   166 	}
   141 	
   167 	
   142 /**
   168 /**
   293 
   319 
   294 	iIccContactStore.UpdateL(aItem, aSessionId);
   320 	iIccContactStore.UpdateL(aItem, aSessionId);
   295 	iContactTable->UpdateL(aItem);	
   321 	iContactTable->UpdateL(aItem);	
   296 	iGroupTable->UpdateL(aItem);	
   322 	iGroupTable->UpdateL(aItem);	
   297 	iCommAddrTable->UpdateL(aItem);
   323 	iCommAddrTable->UpdateL(aItem);
       
   324 #if defined(USE_PRED_SEARCH_TABLE)
       
   325 	RDebug::Print(_L("update contact in pred search table"));
       
   326 	iPredSearchTable->UpdateL(aItem);
       
   327 	RDebug::Print(_L("update contact in pred search table - done"));
       
   328 #endif
   298 
   329 
   299 	if(controlTransaction)
   330 	if(controlTransaction)
   300 		{
   331 		{
   301 		CommitTransactionL();
   332 		CommitTransactionL();
   302 		}
   333 		}
   305 	// manager.  The template can later be recreated from the table.
   336 	// manager.  The template can later be recreated from the table.
   306 	if (aItem.Id() == KGoldenTemplateId)
   337 	if (aItem.Id() == KGoldenTemplateId)
   307 		{
   338 		{
   308 		iContactProperties.SystemTemplateManager().DeleteTemplate();
   339 		iContactProperties.SystemTemplateManager().DeleteTemplate();
   309 		}
   340 		}
       
   341 	
       
   342     // Assuming success if no leaves at this point, so update
       
   343     // the metadata search store for this entry
       
   344     //CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
       
   345     //TRAP_IGNORE(op->SaveContactLD(aItem));
       
   346     //CleanupStack::Pop(op); // Do not destroy - called LD function
   310 	}
   347 	}
   311 
   348 
   312 /**
   349 /**
   313 Deletes the given contact from the database.Forward the call to CPplTableBase
   350 Deletes the given contact from the database.Forward the call to CPplTableBase
   314 based classes representing the tables in the contact database. In low disk condition
   351 based classes representing the tables in the contact database. In low disk condition
   370 	iCommAddrTable->DeleteL(*savedContactItem, lowDisk);	
   407 	iCommAddrTable->DeleteL(*savedContactItem, lowDisk);	
   371 	if(lowDisk) 
   408 	if(lowDisk) 
   372 		{
   409 		{
   373 		DeleteInLowDiskConditionL(iCommAddrTable, savedContactItem);
   410 		DeleteInLowDiskConditionL(iCommAddrTable, savedContactItem);
   374 		}
   411 		}
   375     
   412 
       
   413 #if defined(USE_PRED_SEARCH_TABLE)
       
   414 	RDebug::Print(_L("delete contact from pred search table"));
       
   415 	lowDisk = EFalse;
       
   416     iPredSearchTable->DeleteL(*savedContactItem, lowDisk);
       
   417     if(lowDisk) 
       
   418 		{
       
   419 		DeleteInLowDiskConditionL(iPredSearchTable, savedContactItem);
       
   420 		}
       
   421 	RDebug::Print(_L("delete contact from pred search table - done"));
       
   422 #endif
       
   423   
   376     //Fake checking read access to ICCEntry store to keep BC.
   424     //Fake checking read access to ICCEntry store to keep BC.
   377     iIccContactStore.ReadL(*savedContactItem, EPlGroupMembershipInfo, aSessionId, EFalse);    
   425     iIccContactStore.ReadL(*savedContactItem, EPlGroupMembershipInfo, aSessionId, EFalse);    
   378     
   426     
   379 	//Don't need to check low disk state for ICC synchronizer.
   427 	//Don't need to check low disk state for ICC synchronizer.
   380 	iIccContactStore.DeleteL(*savedContactItem, aSessionId);
   428 	iIccContactStore.DeleteL(*savedContactItem, aSessionId);
   386 		
   434 		
   387 	CleanupStack::Pop();		// Pops item or transaction
   435 	CleanupStack::Pop();		// Pops item or transaction
   388 	CleanupStack::PopAndDestroy(viewDef);	
   436 	CleanupStack::PopAndDestroy(viewDef);	
   389 	CleanupStack::PushL(savedContactItem);
   437 	CleanupStack::PushL(savedContactItem);
   390 
   438 
       
   439 	// Assume no leaves by this point indicates successful delete,
       
   440 	// therefore update the metadata store
       
   441 	//CCntMetadataOperation* op = CCntMetadataOperation::NewLC(iColSession);
       
   442 	//TRAP_IGNORE(op->DeleteContactLD(aItemId));
       
   443 	//CleanupStack::Pop(op); // Do not destroy - called LD function
       
   444 	
   391 	return savedContactItem;
   445 	return savedContactItem;
   392 	
   446 	
   393 	}
   447 	}
   394 	
   448 	
   395 /**
   449 /**
   442 Sets the CCntSqlStatement to be used for reading contact item.
   496 Sets the CCntSqlStatement to be used for reading contact item.
   443 
   497 
   444 */
   498 */
   445 void CPplContactItemManager::ConstructL()
   499 void CPplContactItemManager::ConstructL()
   446 	{
   500 	{
       
   501 	RDebug::Print(_L("CPplContactItemManager::ConstructL"));
   447 	TCntSqlStatementType statementType(ESelect, KSqlContactTableName);
   502 	TCntSqlStatementType statementType(ESelect, KSqlContactTableName);
   448 	
   503 	
   449 	iSelectStatement = TSqlProvider::GetSqlStatementL(statementType);
   504 	iSelectStatement = TSqlProvider::GetSqlStatementL(statementType);
   450 	
   505 	
   451 	// also prepare everything in CCntSqlStatement
   506 	// also prepare everything in CCntSqlStatement
   476 	// construct tables
   531 	// construct tables
   477 	iContactTable = CPplContactTable::NewL(iDatabase, iContactProperties);
   532 	iContactTable = CPplContactTable::NewL(iDatabase, iContactProperties);
   478 	iCommAddrTable = CPplCommAddrTable::NewL(iDatabase, iContactProperties);
   533 	iCommAddrTable = CPplCommAddrTable::NewL(iDatabase, iContactProperties);
   479 	iGroupTable = CPplGroupsTable::NewL(iDatabase);
   534 	iGroupTable = CPplGroupsTable::NewL(iDatabase);
   480 	iPreferencePersistor = CPplPreferencesPersistor::NewL(iDatabase);
   535 	iPreferencePersistor = CPplPreferencesPersistor::NewL(iDatabase);
       
   536 #if defined(USE_PRED_SEARCH_TABLE)
       
   537 	RDebug::Print(_L("create CPplPredictiveSearchTable object"));
       
   538 	iPredSearchTable = CPplPredictiveSearchTable::NewL(iDatabase);
       
   539 	RDebug::Print(_L("create CPplPredictiveSearchTable object - done"));
       
   540 #endif
       
   541 	iPresenceTable = CPplPresenceTable::NewL(iDatabase); 
       
   542 	
       
   543 	// Connect to metadata server
       
   544 	//User::LeaveIfError(iColSession.Connect());
       
   545 
       
   546 	RDebug::Print(_L("CPplContactItemManager::ConstructL ends"));
   481 	}
   547 	}
   482 
   548 
   483 /**
   549 /**
   484 Cleanup operation. If one of the crud operation fails, this method will be called
   550 Cleanup operation. If one of the crud operation fails, this method will be called
   485 to rollback the sql transaction
   551 to rollback the sql transaction
   538 /**
   604 /**
   539 Utility method used to create tables in a newly create database
   605 Utility method used to create tables in a newly create database
   540 */	
   606 */	
   541 void CPplContactItemManager::CreateTablesL()
   607 void CPplContactItemManager::CreateTablesL()
   542 	{
   608 	{
       
   609 	RDebug::Print(_L("CPplContactItemManager::CreateTablesL"));	
       
   610 
   543 	TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
   611 	TBool controlTransaction = !(iTransactionManager.IsTransactionActive());
   544 	
   612 	
   545 	if(controlTransaction)
   613 	if(controlTransaction)
   546 		{
   614 		{
   547 		StartTransactionL(0);
   615 		StartTransactionL(0);
   549 		
   617 		
   550 	iContactTable->CreateTableL();	
   618 	iContactTable->CreateTableL();	
   551 	iGroupTable->CreateTableL();	
   619 	iGroupTable->CreateTableL();	
   552 	iCommAddrTable->CreateTableL();
   620 	iCommAddrTable->CreateTableL();
   553 	iPreferencePersistor->CreateTableL();
   621 	iPreferencePersistor->CreateTableL();
       
   622 #if defined(USE_PRED_SEARCH_TABLE)
       
   623 	RDebug::Print(_L("create pred search table to DB"));	
       
   624 	iPredSearchTable->CreateTableL();
       
   625 	RDebug::Print(_L("create pred search table to DB - done"));	
       
   626 #endif
       
   627 	iPresenceTable->CreateTableL(); 
   554 	
   628 	
   555 	if(controlTransaction)
   629 	if(controlTransaction)
   556 		{
   630 		{
   557 		CommitTransactionL();
   631 		CommitTransactionL();
   558 		}			
   632 		}			
       
   633 
       
   634 	RDebug::Print(_L("CPplContactItemManager::CreateTablesL ends"));	
   559 	}
   635 	}
   560 	
   636 	
   561 /**
   637 /**
   562 Utility method used to check if there is any record in the contact database
   638 Utility method used to check if there is any record in the contact database
   563 
   639 
   644 	CleanupStack::Pop(idArray);
   720 	CleanupStack::Pop(idArray);
   645 	
   721 	
   646 	return idArray;
   722 	return idArray;
   647 	}
   723 	}
   648 
   724 
       
   725 CContactIdArray* CPplContactItemManager::SearchIdListL(const TDesC& aSearchQuery) const
       
   726     {
       
   727     CContactIdArray* idArray = CContactIdArray::NewLC();
       
   728     
       
   729     //Prepare ane execute the sql query
       
   730     RSqlStatement selectStatement;
       
   731     CleanupClosePushL(selectStatement);
       
   732     User::LeaveIfError(selectStatement.Prepare(iDatabase, aSearchQuery));
       
   733     const TInt KIdx = iSelectStatement->ParameterIndex(KContactId);
       
   734         
       
   735 	// Iterate through the results and append the contactIds to idArray	
       
   736     TInt err;
       
   737     while((err = selectStatement.Next()) == KSqlAtRow)
       
   738         {
       
   739         idArray->AddL(selectStatement.ColumnInt(KIdx)); 
       
   740         }
       
   741 
       
   742     if(err != KSqlAtEnd)
       
   743         {
       
   744         User::Leave(err);
       
   745         }
       
   746 
       
   747     //Cleanup 
       
   748     CleanupStack::PopAndDestroy(&selectStatement);
       
   749     CleanupStack::Pop(idArray);
       
   750     
       
   751     return idArray;
       
   752     }
       
   753 
   649 /**
   754 /**
   650 Utility method used to rthe prefered card template id
   755 Utility method used to rthe prefered card template id
   651 */
   756 */
   652 TInt CPplContactItemManager::CardTemplatePrefIdL() const
   757 TInt CPplContactItemManager::CardTemplatePrefIdL() const
   653 	{
   758 	{
   659 */
   764 */
   660 void CPplContactItemManager::SetCardTemplatePrefIdL(TInt aCardTemplatePrefId)
   765 void CPplContactItemManager::SetCardTemplatePrefIdL(TInt aCardTemplatePrefId)
   661 	{
   766 	{
   662 	iPreferencePersistor->SetPreferredCardTemplateIdL(aCardTemplatePrefId);
   767 	iPreferencePersistor->SetPreferredCardTemplateIdL(aCardTemplatePrefId);
   663 	}
   768 	}
       
   769 
       
   770 // If pred search table is missing, generate it from existing contacts table
       
   771 // Even if contact would not have any first name, last name or company name
       
   772 // defined, write an entry to predictive search. So that if contact is later
       
   773 // updated by adding e.g. company name, the predictive search table already
       
   774 // has an entry for the contact, and the company name can be updated there too.
       
   775 void CPplContactItemManager::SynchronizePredSearchTableL()
       
   776 	{
       
   777 #if !defined(USE_PRED_SEARCH_TABLE)
       
   778 	return;
       
   779 #endif
       
   780 	RDebug::Print(_L("CPplContactItemManager::SynchronizePredSearchTableL"));
       
   781 
       
   782 	if (DoesPredSearchTableExistL())
       
   783 		{
       
   784 		RDebug::Print(_L("pred search table exists, don't generate it"));
       
   785 		return;
       
   786 		}
       
   787 
       
   788 	iPredSearchTable->CreateTableL();
       
   789 	_LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S,%S FROM %S;");
       
   790 	TInt bufSize = KSelectAllContactsFormat().Length() +
       
   791 				   KContactId().Length() +
       
   792 				   KContactFirstName().Length() +
       
   793 				   KContactLastName().Length() +
       
   794 				   KContactCompanyName().Length() +
       
   795 				   KSqlContactTableName().Length();
       
   796 	HBufC* sqlStatement = HBufC::NewLC(bufSize);
       
   797 	sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
       
   798 		&KContactId,
       
   799 		&KContactFirstName,
       
   800 		&KContactLastName,
       
   801 		&KContactCompanyName,
       
   802 		&KSqlContactTableName);
       
   803 
       
   804 	RSqlStatement stmnt;
       
   805 	CleanupClosePushL(stmnt);
       
   806 	RDebug::Print(_L("SynchronizePredSearchTableL prepare SQL statement"));
       
   807     stmnt.PrepareL(iDatabase, *sqlStatement);
       
   808 
       
   809 	const TInt KContactIdIndex = 0;
       
   810 	const TInt KFirstNameIndex = 1;
       
   811 	const TInt KLastNameIndex = 2;
       
   812 	const TInt KCompanyNameIndex = 3;
       
   813 	TInt err(KErrNone);
       
   814     while ((err = stmnt.Next()) == KSqlAtRow)
       
   815         {
       
   816 		RDebug::Print(_L("SynchronizePredSearchTableL create CContactItem"));
       
   817 
       
   818 		TInt id = KUidContactCardValue;
       
   819 		TUid uid;
       
   820 		uid.iUid = id;
       
   821 		CContactItem* contact = CContactItem::NewLC(uid);
       
   822 		contact->SetId(stmnt.ColumnInt(KContactIdIndex));
       
   823 
       
   824 		// If first name exists, write it to contact item
       
   825 		TPtrC firstName;
       
   826 		if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
       
   827 			{
       
   828 			RDebug::Print(_L("SynchronizePredSearchTableL read first name"));
       
   829 			CContactItemField* field =
       
   830 				CContactItemField::NewL(KStorageTypeText, KUidContactFieldGivenName);
       
   831 			CContactTextField* textfield = field->TextStorage();
       
   832 			RDebug::Print(_L("set first name to text field"));
       
   833 			textfield->SetTextL(firstName);
       
   834 			contact->AddFieldL(*field); // Takes ownership
       
   835 			}
       
   836 
       
   837 		TPtrC lastName;
       
   838 		if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
       
   839 			{
       
   840 			RDebug::Print(_L("SynchronizePredSearchTableL read last name"));
       
   841 			CContactItemField* field =
       
   842 				CContactItemField::NewL(KStorageTypeText, KUidContactFieldFamilyName);
       
   843 			CContactTextField* textfield = field->TextStorage();
       
   844 			RDebug::Print(_L("set last name to text field"));
       
   845 			textfield->SetTextL(lastName);
       
   846 			contact->AddFieldL(*field); // Takes ownership
       
   847 			}
       
   848 		
       
   849 		TPtrC companyName;
       
   850 		if (stmnt.ColumnText(KCompanyNameIndex, companyName) == KErrNone)
       
   851 			{
       
   852 			RDebug::Print(_L("SynchronizePredSearchTableL read company name"));
       
   853 			CContactItemField* field =
       
   854 				CContactItemField::NewL(KStorageTypeText, KUidContactFieldCompanyName);
       
   855 			CContactTextField* textfield = field->TextStorage();
       
   856 			RDebug::Print(_L("set company name to text field"));
       
   857 			textfield->SetTextL(companyName);
       
   858 			contact->AddFieldL(*field); // Takes ownership
       
   859 			}
       
   860 
       
   861 		RDebug::Print(_L("SynchronizePredSearchTableL create entry to pred search table"));
       
   862 		iPredSearchTable->CreateInDbL(*contact);
       
   863 		CleanupStack::PopAndDestroy(contact);
       
   864         }
       
   865 	RDebug::Print(_L("SynchronizePredSearchTableL while loop done"));
       
   866 
       
   867     // Leave if we didn't complete going through the results properly
       
   868     if (err != KSqlAtEnd)
       
   869         {
       
   870 		RDebug::Print(_L("SynchronizePredSearchTableL SQL err=%d"), err);
       
   871         User::Leave(err);
       
   872         }
       
   873     CleanupStack::PopAndDestroy(&stmnt);
       
   874 	CleanupStack::PopAndDestroy(sqlStatement);
       
   875 	RDebug::Print(_L("CPplContactItemManager::SynchronizePredSearchTableL ends"));
       
   876 	}
       
   877 
       
   878 TBool CPplContactItemManager::DoesPredSearchTableExistL() const
       
   879 	{
       
   880 	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL"));
       
   881 
       
   882 	_LIT(KSelectContactIdsFormat, "SELECT %S FROM %S;");
       
   883 	TInt bufSize = KSelectContactIdsFormat().Length() +
       
   884 				   KPredSearchContactId().Length() +
       
   885 				   KSqlContactPredSearchTableName().Length();
       
   886 	HBufC* sqlStatement = HBufC::NewLC(bufSize);
       
   887 	sqlStatement->Des().AppendFormat(KSelectContactIdsFormat,
       
   888 		&KPredSearchContactId,
       
   889 		&KSqlContactPredSearchTableName);
       
   890 
       
   891 	RSqlStatement stmnt;
       
   892 	CleanupClosePushL(stmnt);
       
   893 	// If predictive search table does not exist, leaves with -311.
       
   894     // If it exists, does not leave.
       
   895     TRAPD(err, stmnt.PrepareL(iDatabase, *sqlStatement));
       
   896 	RDebug::Print(_L("err=%d"), err );
       
   897 
       
   898 	CleanupStack::PopAndDestroy(&stmnt);
       
   899 	CleanupStack::PopAndDestroy(sqlStatement);
       
   900 
       
   901 	RDebug::Print(_L("CPplContactItemManager::DoesPredSearchTableExistL return %d"),
       
   902 				  err == KErrNone );
       
   903 	return err == KErrNone;
       
   904 	}