phonebookengines/contactsmodel/cntplsql/src/cpplpredictivesearchtable.cpp
changeset 31 2a11b5b00470
parent 27 de1630741fbe
child 46 efe85016a067
equal deleted inserted replaced
27:de1630741fbe 31:2a11b5b00470
    32 // How many digits are stored at most in the numeric field
    32 // How many digits are stored at most in the numeric field
    33 // Since BIGINT is a signed 64-bit integer, store only 15 hexadecimal characters
    33 // Since BIGINT is a signed 64-bit integer, store only 15 hexadecimal characters
    34 // to prevent overflow when comparing upper and lower limits.
    34 // to prevent overflow when comparing upper and lower limits.
    35 const TInt KMaxDigits = 15;
    35 const TInt KMaxDigits = 15;
    36 
    36 
    37 const QChar KPadChar = 'a'; // Pad with hex-digit 0xA
       
    38 
       
    39 const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
    37 const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
    40 
    38 
       
    39 #define MAPPED_CHAR_FOR_STAR	'a'
       
    40 #define MAPPED_CHAR_FOR_HASH	'b'
       
    41 
       
    42 const QChar KMappedQCharForStar = MAPPED_CHAR_FOR_STAR;
       
    43 const QChar KMappedQCharForHash = MAPPED_CHAR_FOR_HASH;
       
    44 
       
    45 // These must be same as in cpcskeymap.cpp
       
    46 const TChar KMappedCharForStar = MAPPED_CHAR_FOR_STAR;
       
    47 const TChar KMappedCharForHash = MAPPED_CHAR_FOR_HASH;
       
    48 const QChar KPadChar = 'f'; // Pad with hex-digit 0xF
    41 
    49 
    42 
    50 
    43 /**
    51 /**
    44 @param aDatabase A handle to the database.
    52 @param aDatabase A handle to the database.
    45 @param aProperties A contact properties object.
    53 @param aProperties A contact properties object.
    90 
    98 
    91 
    99 
    92 /**
   100 /**
    93 @param aItem A contact item whose data are added to the table.
   101 @param aItem A contact item whose data are added to the table.
    94 */
   102 */
    95 void CPplPredictiveSearchTable::CreateInDbL( CContactItem& aItem )
   103 void CPplPredictiveSearchTable::CreateInDbL(CContactItem& aItem)
    96 	{
   104 	{
    97 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL"));
   105 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL"));
    98 	WriteToDbL(aItem);
   106 	WriteToDbL(aItem);
    99 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL ends"));
   107 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateInDbL ends"));
   100 	}
   108 	}
   104 Update is done in two steps: delete contact from all predictive search tables,
   112 Update is done in two steps: delete contact from all predictive search tables,
   105 then insert it into relevant tables.
   113 then insert it into relevant tables.
   106 
   114 
   107 @param aItem A contact item whose data is updated in the database.
   115 @param aItem A contact item whose data is updated in the database.
   108 */
   116 */
   109 void CPplPredictiveSearchTable::UpdateL( const CContactItem& aItem )
   117 void CPplPredictiveSearchTable::UpdateL(const CContactItem& aItem)
   110 	{
   118 	{
   111 	RDebug::Print(_L("CPplPredictiveSearchTable::UpdateL"));
   119 	RDebug::Print(_L("CPplPredictiveSearchTable::UpdateL"));
   112 
   120 
   113 	TBool lowDiskErrorOccurred(EFalse);
   121 	TBool lowDiskErrorOccurred(EFalse);
   114 	DeleteFromAllTablesL(aItem.Id(), lowDiskErrorOccurred);
   122 	DeleteFromAllTablesL(aItem.Id(), lowDiskErrorOccurred);
   144 */
   152 */
   145 void CPplPredictiveSearchTable::CreateTableL()
   153 void CPplPredictiveSearchTable::CreateTableL()
   146 	{
   154 	{
   147 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL"));
   155 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL"));
   148 
   156 
   149 	RDebug::Print(_L("Create 10 tables"));
   157 	RDebug::Print(_L("Create 12 tables"));
   150 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable0Stmnt));
   158 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable0Stmnt));
   151 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable1Stmnt));
   159 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable1Stmnt));
   152 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable2Stmnt));
   160 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable2Stmnt));
   153 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable3Stmnt));
   161 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable3Stmnt));
   154 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable4Stmnt));
   162 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable4Stmnt));
   155 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable5Stmnt));
   163 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable5Stmnt));
   156 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable6Stmnt));
   164 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable6Stmnt));
   157 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable7Stmnt));
   165 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable7Stmnt));
   158 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable8Stmnt));
   166 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable8Stmnt));
   159 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable9Stmnt));
   167 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable9Stmnt));
       
   168 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable10Stmnt));
       
   169 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable11Stmnt));
   160 
   170 
   161 
   171 
   162 	RDebug::Print(_L("Create indexes"));
   172 	RDebug::Print(_L("Create indexes"));
   163 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable0));
   173 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable0));
   164 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable0));
   174 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable0));
   207 
   217 
   208 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable9));
   218 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable9));
   209 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable9));
   219 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable9));
   210 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable9));
   220 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable9));
   211 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable9));
   221 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable9));
       
   222 
       
   223 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable10));
       
   224 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable10));
       
   225 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable10));
       
   226 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable10));
       
   227 
       
   228 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable11));
       
   229 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable11));
       
   230 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable11));
       
   231 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable11));
   212 
   232 
   213 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable0));
   233 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable0));
   214 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable0));
   234 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable0));
   215 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable1));
   235 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable1));
   216 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable1));
   236 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable1));
   228 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable7));
   248 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable7));
   229 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable8));
   249 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable8));
   230 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable8));
   250 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable8));
   231 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable9));
   251 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable9));
   232 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable9));
   252 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable9));
       
   253 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable10));
       
   254 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable10));
       
   255 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable11));
       
   256 	User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable11));
   233 
   257 
   234 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL ends"));
   258 	RDebug::Print(_L("CPplPredictiveSearchTable::CreateTableL ends"));
   235 	}
   259 	}
   236 
   260 
   237 
   261 
   245 	// Using dummy table names here
   269 	// Using dummy table names here
   246 	TCntSqlStatementType insertType(EInsert, KSqlContactPredSearchTable0);
   270 	TCntSqlStatementType insertType(EInsert, KSqlContactPredSearchTable0);
   247 	TCntSqlStatementType deleteType(EDelete, KSqlContactPredSearchTable0);
   271 	TCntSqlStatementType deleteType(EDelete, KSqlContactPredSearchTable0);
   248 
   272 
   249 	// Insert new record
   273 	// Insert new record
   250 	// INSERT INTO predictivesearchX (X=0..9)
   274 	// INSERT INTO predictivesearchX (X=0..11)
   251 	//   (contact_id, nbr, nbr2, nbr3, nbr4, first_name, last_name)
   275 	//   (contact_id, nbr, nbr2, nbr3, nbr4, first_name, last_name)
   252 	//   VALUES (contact_id value, nbr value, nbr2 value, nbr3 value, nbr4 value,
   276 	//   VALUES (contact_id value, nbr value, nbr2 value, nbr3 value, nbr4 value,
   253 	//			 first_name value, last_name value);
   277 	//			 first_name value, last_name value);
   254 	iInsertStmnt = TSqlProvider::GetSqlStatementL(insertType);
   278 	iInsertStmnt = TSqlProvider::GetSqlStatementL(insertType);
   255 	iInsertStmnt->SetParamL(KPredSearchContactId,
   279 	iInsertStmnt->SetParamL(KPredSearchContactId,
   275 	// for WHERE contact_id = [contact id value]
   299 	// for WHERE contact_id = [contact id value]
   276 	whereContactIdClause->Des().AppendFormat(KWhereStringEqualsStringFormatText,
   300 	whereContactIdClause->Des().AppendFormat(KWhereStringEqualsStringFormatText,
   277 		&KPredSearchContactId, &KPredSearchContactIdParam);
   301 		&KPredSearchContactId, &KPredSearchContactIdParam);
   278 
   302 
   279 	// Delete information of a particular contact item
   303 	// Delete information of a particular contact item
   280 	// 	DELETE FROM predictivesearchX (X=0..9)
   304 	// 	DELETE FROM predictivesearchX (X=0..11)
   281 	//	WHERE contact_id = [contact id value];
   305 	//	WHERE contact_id = [contact id value];
   282 	iDeleteStmnt = TSqlProvider::GetSqlStatementL(deleteType);
   306 	iDeleteStmnt = TSqlProvider::GetSqlStatementL(deleteType);
   283 	iDeleteStmnt->SetConditionL(*whereContactIdClause);
   307 	iDeleteStmnt->SetConditionL(*whereContactIdClause);
   284 
   308 
   285 	CleanupStack::PopAndDestroy(whereContactIdClause);
   309 	CleanupStack::PopAndDestroy(whereContactIdClause);
   319 		numericTokens = GetNumericTokens(firstNameAsNbr, lastNameAsNbr);
   343 		numericTokens = GetNumericTokens(firstNameAsNbr, lastNameAsNbr);
   320 		tables = DetermineTables(numericTokens);
   344 		tables = DetermineTables(numericTokens);
   321 	});
   345 	});
   322 
   346 
   323 	HBufC* tableName(NULL);
   347 	HBufC* tableName(NULL);
   324 	while ((tableName = GetTableNameL(tables)) != NULL)
   348 	while ((tableName = GetNextTableNameL(tables)) != NULL)
   325 		{
   349 		{
   326 		// Takes ownership. Clears also earlier SQL statement.
   350 		// Takes ownership. Clears also earlier SQL statement.
   327 		iInsertStmnt->SetTableName(tableName);
   351 		iInsertStmnt->SetTableName(tableName);
   328 		RSqlStatement stmnt;
   352 		RSqlStatement stmnt;
   329 		CleanupClosePushL( stmnt ); 
   353 		CleanupClosePushL( stmnt ); 
   445 QList<TChar> CPplPredictiveSearchTable::DetermineTables(QStringList aTokens) const
   469 QList<TChar> CPplPredictiveSearchTable::DetermineTables(QStringList aTokens) const
   446 	{
   470 	{
   447 	QList<TChar> tables;
   471 	QList<TChar> tables;
   448 	for (TInt i = aTokens.count() - 1; i >= 0; --i)
   472 	for (TInt i = aTokens.count() - 1; i >= 0; --i)
   449 		{
   473 		{
       
   474 		__ASSERT_ALWAYS(IsValidChar(aTokens[i][0]),
       
   475 						User::Panic(_L("DetermineTables"), KErrArgument));
   450 		TChar ch(aTokens[i][0].unicode());
   476 		TChar ch(aTokens[i][0].unicode());
   451 		__ASSERT_ALWAYS(IsValidChar(ch),
       
   452 						User::Panic(_L("DetermineTables"), KErrArgument));
       
   453 		if (!tables.contains(ch))
   477 		if (!tables.contains(ch))
   454 			{
   478 			{
   455 			tables.append(ch);
   479 			tables.append(ch);
   456 			}
   480 			}
   457 		}
   481 		}
   458 	return tables;
   482 	return tables;
   459 	}
       
   460 
       
   461 
       
   462 // Ignore tokens beginning with something else than '0'..'9'.
       
   463 // Keep duplicate tokens to support e.g. search "202" when both FN and LN are "23".
       
   464 void
       
   465 CPplPredictiveSearchTable::AddTokens(HBufC* aString, QStringList& aTokens) const
       
   466 	{
       
   467 	if (aString)
       
   468 		{
       
   469 		QString s((QChar*)aString->Ptr(), aString->Length());
       
   470 #if defined(USE_ORBIT_KEYMAP)
       
   471 		QStringList tokens = s.split(iKeyMap->Separator(), QString::SkipEmptyParts);
       
   472 #else
       
   473 		QStringList tokens = s.split(' ', QString::SkipEmptyParts);
       
   474 #endif
       
   475 
       
   476 		// Select tokens in the same order they are in original aString
       
   477 		for (TInt i = 0; i < tokens.count(); ++i)
       
   478 			{
       
   479 			if (IsValidChar(tokens[i][0]))
       
   480 				{
       
   481 				aTokens.append(tokens[i]);
       
   482 				}
       
   483 			}
       
   484 		}
       
   485 	}
       
   486 
       
   487 
       
   488 TBool CPplPredictiveSearchTable::IsValidChar(TInt aChar) const
       
   489 	{
       
   490 	return (aChar >= '0' && aChar <= '9');
       
   491 	}
       
   492 
       
   493 
       
   494 TBool CPplPredictiveSearchTable::IsValidChar(QChar aChar) const
       
   495 	{
       
   496 	return (aChar >= '0' && aChar <= '9');
       
   497 	}
   483 	}
   498 
   484 
   499 
   485 
   500 // 1. get first token of LN
   486 // 1. get first token of LN
   501 // 2. get first token of FN
   487 // 2. get first token of FN
   528                   tokens.count());
   514                   tokens.count());
   529 	return tokens;
   515 	return tokens;
   530 	}
   516 	}
   531 
   517 
   532 
   518 
       
   519 // Ignore tokens beginning with invalid (unknown) character.
       
   520 // Keep duplicate tokens to support e.g. search "202" when both FN and LN are "23".
       
   521 void
       
   522 CPplPredictiveSearchTable::AddTokens(HBufC* aString, QStringList& aTokens) const
       
   523 	{
       
   524 	if (aString)
       
   525 		{
       
   526 		QString s((QChar*)aString->Ptr(), aString->Length());
       
   527 #if defined(USE_ORBIT_KEYMAP)
       
   528 		QStringList tokens = s.split(iKeyMap->Separator(), QString::SkipEmptyParts);
       
   529 #else
       
   530 		QStringList tokens = s.split(' ', QString::SkipEmptyParts);
       
   531 #endif
       
   532 
       
   533 		// Select tokens in the same order they are in original aString
       
   534 		for (TInt i = 0; i < tokens.count(); ++i)
       
   535 			{
       
   536 			if (IsValidChar(tokens[i][0]))
       
   537 				{
       
   538 				aTokens.append(tokens[i]);
       
   539 				}
       
   540 			}
       
   541 		}
       
   542 	}
       
   543 
       
   544 
       
   545 TBool CPplPredictiveSearchTable::IsValidChar(QChar aChar) const
       
   546 	{
       
   547 	return (aChar >= '0' && aChar <= '9') ||
       
   548 			aChar == MAPPED_CHAR_FOR_STAR ||
       
   549 			aChar == MAPPED_CHAR_FOR_HASH;
       
   550 	}
       
   551 
       
   552 
   533 void CPplPredictiveSearchTable::GetNextToken(QStringList& aSource,
   553 void CPplPredictiveSearchTable::GetNextToken(QStringList& aSource,
   534 											 QStringList& aDestination) const
   554 											 QStringList& aDestination) const
   535 	{
   555 	{
   536 	if (!aSource.isEmpty() && aDestination.count() < KMaxTokens)
   556 	if (!aSource.isEmpty() && aDestination.count() < KMaxTokens)
   537 		{
   557 		{
   545 void
   565 void
   546 CPplPredictiveSearchTable::DeleteFromAllTablesL(TContactItemId aContactId,
   566 CPplPredictiveSearchTable::DeleteFromAllTablesL(TContactItemId aContactId,
   547 											    TBool& aLowDiskErrorOccurred) const
   567 											    TBool& aLowDiskErrorOccurred) const
   548 	{
   568 	{
   549 	QList<TChar> tables;
   569 	QList<TChar> tables;
   550 	QT_TRYCATCH_LEAVING(tables = FillTableList());
   570 	QT_TRYCATCH_LEAVING(tables = FillAllTables());
   551 
   571 
   552 	HBufC* tableName(NULL);
   572 	HBufC* tableName(NULL);
   553 	while ((tableName = GetTableNameL(tables)) != NULL)
   573 	while ((tableName = GetNextTableNameL(tables)) != NULL)
   554 		{
   574 		{
   555 		iDeleteStmnt->SetTableName(tableName); // Clears also earlier SQL statement
   575 		iDeleteStmnt->SetTableName(tableName); // Clears also earlier SQL statement
   556 
   576 
   557 		RSqlStatement stmnt;
   577 		RSqlStatement stmnt;
   558 		CleanupClosePushL(stmnt);
   578 		CleanupClosePushL(stmnt);
   565 		// accessed with iDeleteStmnt->ParameterIndex().
   585 		// accessed with iDeleteStmnt->ParameterIndex().
   566 		// It is the first and only parameter in query
   586 		// It is the first and only parameter in query
   567 		const TInt KContactIdParamIndex(KFirstIndex);
   587 		const TInt KContactIdParamIndex(KFirstIndex);
   568 		User::LeaveIfError(stmnt.BindInt(KContactIdParamIndex, aContactId));
   588 		User::LeaveIfError(stmnt.BindInt(KContactIdParamIndex, aContactId));
   569 		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL execute statement"));
   589 		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL execute statement"));
   570 		// Returns the amount of rows that were changed/inserted/deleted.
   590 		// Returns the amount of affected rows. As contact is not present each
   571 		// Since contact is not present in all tables, some operations return 0,
   591 		// table, some operations return 0, it is not an error.
   572 		// it is not an error.
       
   573 		TInt status = stmnt.Exec();
   592 		TInt status = stmnt.Exec();
   574 		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL rows deleted=%d"), status);
   593 		RDebug::Print(_L("CPplPredictiveSearchTable::DeleteFromAllTablesL rows deleted=%d"), status);
   575 		CleanupStack::PopAndDestroy(&stmnt);
   594 		CleanupStack::PopAndDestroy(&stmnt);
   576 
   595 
   577 		if (status == KErrDiskFull)
   596 		if (status == KErrDiskFull)
   586 			}
   605 			}
   587 		}
   606 		}
   588 	}
   607 	}
   589 
   608 
   590 
   609 
   591 QList<TChar> CPplPredictiveSearchTable::FillTableList() const
   610 QList<TChar> CPplPredictiveSearchTable::FillAllTables() const
   592 	{
   611 	{
   593 	QList<TChar> tables;
   612 	QList<TChar> tables;
   594 	const TInt KLargestKey = '9';
   613 
   595 	for (TInt i = '0'; i <= KLargestKey; ++i)
   614 	const TInt KLargestDigitKey = '9';
       
   615 	for (TInt i = '0'; i <= KLargestDigitKey; ++i)
   596 		{
   616 		{
   597 		TChar ch = i;
   617 		TChar ch = i;
   598 		tables << ch;
   618 		tables << ch;
   599 		}
   619 		}
       
   620 	tables << KMappedCharForStar;
       
   621 	tables << KMappedCharForHash;
       
   622 
   600 	return tables;
   623 	return tables;
   601 	}
   624 	}
   602 
   625 
   603 
   626 
   604 HBufC* CPplPredictiveSearchTable::GetTableNameL(QList<TChar>& aTables) const
   627 HBufC* CPplPredictiveSearchTable::GetNextTableNameL(QList<TChar>& aTables) const
   605 	{
   628 	{
   606 	HBufC* tableName(NULL);
   629 	HBufC* tableName(NULL);
   607 	if (aTables.count() > 0)
   630 	if (aTables.count() > 0)
   608 		{
   631 		{
   609 		TChar ch = aTables[0];
   632         // Enough space for the longest table name
   610 		__ASSERT_ALWAYS(IsValidChar(ch), User::Leave(KErrArgument));
   633         tableName = HBufC::NewL(KSqlContactPredSearchTable11().Length());
   611 
       
   612         // Each table's name has same length, replace last char with the correct one
       
   613         tableName = HBufC::NewL(KSqlContactPredSearchTable0().Length());
       
   614         TPtr ptr = tableName->Des();
   634         TPtr ptr = tableName->Des();
   615         ptr.Append(KSqlContactPredSearchTable0);
   635 		ptr.Append(TableNameL(aTables[0]));
   616         ptr[ptr.Length() - 1] = ch;
   636 
   617 		aTables.removeFirst();
   637 		aTables.removeFirst();
   618 		RDebug::Print(_L("CPplPredictiveSearchTable::GetTableNameL '%S'"), tableName);
   638 		RDebug::Print(_L("CPplPredictiveSearchTable::GetNextTableNameL '%S'"), tableName);
   619         }
   639         }
   620 	return tableName;
   640 	return tableName;
   621 	}
   641 	}
   622 
   642 
   623 
   643 // when qwerty will be supported, keymap prob maps original chars to
   624 // E.g. aToken = "01230" -> append 'a' until has KMaxDigits characters
   644 // 0..9, a..z + few capital letters
   625 // -> "01230aaaaaaaaaa" -> convert to hexadecimal number -> 0x01230aaaaaaaaaa.
   645 const TDesC& CPplPredictiveSearchTable::TableNameL(TChar aCh) const
   626 // Leaving from this function causes panic, perhaps because of QString
   646 	{
   627 // parameter? So rather return an error code if conversion fails.
   647 	switch (aCh)
       
   648 		{
       
   649 		case '0': return KSqlContactPredSearchTable0;
       
   650 		case '1': return KSqlContactPredSearchTable1;
       
   651 		case '2': return KSqlContactPredSearchTable2;
       
   652 		case '3': return KSqlContactPredSearchTable3;
       
   653 		case '4': return KSqlContactPredSearchTable4;
       
   654 		case '5': return KSqlContactPredSearchTable5;
       
   655 		case '6': return KSqlContactPredSearchTable6;
       
   656 		case '7': return KSqlContactPredSearchTable7;
       
   657 		case '8': return KSqlContactPredSearchTable8;
       
   658 		case '9': return KSqlContactPredSearchTable9;
       
   659 		case MAPPED_CHAR_FOR_STAR: return KSqlContactPredSearchTable10;
       
   660 		case MAPPED_CHAR_FOR_HASH: return KSqlContactPredSearchTable11;
       
   661 		default:
       
   662 			TUint ch = aCh;
       
   663 			RDebug::Print(_L("CPplPredictiveSearchTable::TableName unknown char '%c'"), ch);
       
   664 			User::Leave(KErrArgument);
       
   665 			return KNullDesC;
       
   666 		}
       
   667 	}
       
   668 
       
   669 
       
   670 // E.g. aToken = "01230" -> append KPadChar until has KMaxDigits characters
       
   671 // -> "01230ffffffffff" -> convert to hexadecimal number -> 0x01230ffffffffff.
       
   672 // If this function would leave, causes panic, perhaps because of QString parameter?
   628 quint64 CPplPredictiveSearchTable::ConvertToHex(QString aToken) const
   673 quint64 CPplPredictiveSearchTable::ConvertToHex(QString aToken) const
   629 	{
   674 	{
   630 	if (aToken.length() > KMaxDigits)
   675 	if (aToken.length() > KMaxDigits)
   631 		{
   676 		{
   632 		return KConversionError;
   677 		return KConversionError;