--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/src/c12keypredictivesearchtable.cpp Wed Jun 23 18:02:44 2010 +0300
@@ -0,0 +1,370 @@
+/*
+* Copyright (c) 2010 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:
+*
+*/
+
+#include "c12keypredictivesearchtable.h"
+#include "dbsqlconstants.h"
+#include "cntitem.h"
+#include "c12keykeymap.h"
+#include <QStringList>
+
+// This macro suppresses log writes
+//#define NO_PRED_SEARCH_LOGS
+#include "predictivesearchlog.h"
+
+
+// Max amount of tokens stored from contact
+const TInt KMaxTokens = 4;
+
+// How many digits are stored at most in the numeric field
+// Since BIGINT is a signed 64-bit integer, store only 15 hexadecimal characters
+// to prevent overflow when comparing upper and lower limits.
+const TInt KMaxTokenLength = 15;
+
+const quint64 KConversionError = 0xeeeeeeeeeeeeeee;
+
+#define MAPPED_CHAR_FOR_STAR 'a'
+#define MAPPED_CHAR_FOR_HASH 'b'
+
+const QChar KPadChar = 'f'; // Pad with hex-digit 0xF
+
+
+/**
+@param aDatabase A handle to the database.
+
+@return A pointer to a new C12keyPredictiveSearchTable object.
+*/
+C12keyPredictiveSearchTable*
+C12keyPredictiveSearchTable::NewL(RSqlDatabase& aDatabase)
+ {
+ PRINT(_L("C12keyPredictiveSearchTable::NewL"));
+ C12keyPredictiveSearchTable* self = C12keyPredictiveSearchTable::NewLC(aDatabase);
+ CleanupStack::Pop(self);
+ PRINT(_L("C12keyPredictiveSearchTable::NewL ends"));
+ return self;
+ }
+
+
+/**
+@param aDatabase A handle to the database.
+
+@return A pointer to a new C12keyPredictiveSearchTable object.
+*/
+C12keyPredictiveSearchTable*
+C12keyPredictiveSearchTable::NewLC(RSqlDatabase& aDatabase)
+ {
+ PRINT(_L("C12keyPredictiveSearchTable::NewLC"));
+ C12keyPredictiveSearchTable* self =
+ new (ELeave) C12keyPredictiveSearchTable(aDatabase);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ PRINT(_L("C12keyPredictiveSearchTable::NewLC ends"));
+ return self;
+ }
+
+
+/**
+Destructor
+*/
+C12keyPredictiveSearchTable::~C12keyPredictiveSearchTable()
+ {
+ PRINT(_L("C12keyPredictiveSearchTable dtor"));
+ PRINT(_L("C12keyPredictiveSearchTable dtor ends"));
+ }
+
+
+/**
+Creates the 12-key predictive search tables and its indexes in the database.
+*/
+void C12keyPredictiveSearchTable::CreateTableL()
+ {
+ PRINT(_L("C12keyPredictiveSearchTable::CreateTableL"));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable0Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable1Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable2Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable3Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable4Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable5Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable6Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable7Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable8Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable9Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable10Stmnt));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateTable11Stmnt));
+
+
+ PRINT(_L("Create indexes"));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable0));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable0));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable0));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable0));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable1));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable1));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable1));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable1));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable2));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable2));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable2));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable2));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable3));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable3));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable3));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable3));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable4));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable4));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable4));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable4));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable5));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable5));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable5));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable5));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable6));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable6));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable6));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable6));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable7));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable7));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable7));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable7));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable8));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable8));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable8));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable8));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable9));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable9));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable9));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable9));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable10));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable10));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable10));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable10));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbrIndexTable11));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr2IndexTable11));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr3IndexTable11));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateNbr4IndexTable11));
+
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable0));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable0));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable1));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable1));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable2));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable2));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable3));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable3));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable4));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable4));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable5));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable5));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable6));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable6));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable7));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable7));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable8));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable8));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable9));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable9));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable10));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable10));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateFNIndexInTable11));
+ User::LeaveIfError(iDatabase.Exec(KPredSearchCreateLNIndexInTable11));
+
+ PRINT(_L("C12keyPredictiveSearchTable::CreateTableL ends"));
+ }
+
+
+QList<QChar> C12keyPredictiveSearchTable::FillAllTables() const
+ {
+ QList<QChar> tables;
+
+ const TInt KLargestDigitKey = '9';
+ for (TInt i = '0'; i <= KLargestDigitKey; ++i)
+ {
+ QChar ch = i;
+ tables.append(ch);
+ }
+ tables.append(MAPPED_CHAR_FOR_STAR);
+ tables.append(MAPPED_CHAR_FOR_HASH);
+
+ return tables;
+ }
+
+
+HBufC* C12keyPredictiveSearchTable::TableNameL(const QChar aCh) const
+ {
+ // Enough space for the longest table name
+ HBufC* tableName = HBufC::NewLC(KSqlContactPredSearchTable11().Length());
+ TPtr ptr = tableName->Des();
+ ptr.Append(GetTableNameL(aCh));
+ CleanupStack::Pop(tableName);
+ return tableName;
+ }
+
+
+TBool C12keyPredictiveSearchTable::IsValidChar(const QChar aChar) const
+ {
+ return (aChar >= '0' && aChar <= '9') ||
+ aChar == MAPPED_CHAR_FOR_STAR ||
+ aChar == MAPPED_CHAR_FOR_HASH;
+ }
+
+
+void C12keyPredictiveSearchTable::FillKeyboardSpecificFieldsL(
+ RSqlStatement& aSqlStatement,
+ QStringList aTokens)
+ {
+ const TDesC* paramNames[] = {
+ &KPredSearchNameAsNumberParam,
+ &KPredSearchNameAsNumber2Param,
+ &KPredSearchNameAsNumber3Param,
+ &KPredSearchNameAsNumber4Param};
+ for (TInt i = 0; i < aTokens.count(); ++i)
+ {
+ quint64 hex(0);
+ QT_TRYCATCH_LEAVING(hex = ConvertToHex(aTokens[i]));
+ if (hex == KConversionError)
+ {
+ User::Leave(KErrArgument);
+ }
+ User::LeaveIfError(aSqlStatement.BindInt64(
+ User::LeaveIfError(aSqlStatement.ParameterIndex(*paramNames[i])), hex));
+ }
+ }
+
+
+/**
+Set up the CCntSqlStatement objects held by the class.
+*/
+void C12keyPredictiveSearchTable::ConstructL()
+ {
+ PRINT(_L("C12keyPredictiveSearchTable::ConstructL"));
+
+ CPplPredictiveSearchTableBase::ConstructL();
+ // Set details of INSERT
+ iInsertStmnt->SetParamL(KPredSearchContactId,
+ KPredSearchContactIdParam);
+ iInsertStmnt->SetParamL(KPredSearchNameAsNumber,
+ KPredSearchNameAsNumberParam);
+ iInsertStmnt->SetParamL(KPredSearchNameAsNumber2,
+ KPredSearchNameAsNumber2Param);
+ iInsertStmnt->SetParamL(KPredSearchNameAsNumber3,
+ KPredSearchNameAsNumber3Param);
+ iInsertStmnt->SetParamL(KPredSearchNameAsNumber4,
+ KPredSearchNameAsNumber4Param);
+ iInsertStmnt->SetParamL(KPredSearchFirstName,
+ KPredSearchFirstNameParam);
+ iInsertStmnt->SetParamL(KPredSearchLastName,
+ KPredSearchLastNameParam);
+
+ PRINT(_L("C12keyPredictiveSearchTable::ConstructL create key map"));
+ iKeyMap = C12keyKeyMap::NewL();
+
+ PRINT(_L("C12keyPredictiveSearchTable::ConstructL ends"));
+ }
+
+
+/**
+Constructor
+*/
+C12keyPredictiveSearchTable::C12keyPredictiveSearchTable(RSqlDatabase& aDatabase) :
+ CPplPredictiveSearchTableBase(aDatabase, KMaxTokens, KMaxTokenLength)
+ {
+ }
+
+
+// TODO: maybe move this fn to CPcsKeyMap, and it can use code of GetNumericLimits()
+
+// E.g. aToken = "01230" -> append KPadChar until has KMaxTokenLength characters
+// -> "01230ffffffffff" -> convert to hexadecimal number -> 0x01230ffffffffff.
+// If this function would leave, causes panic, perhaps because of QString parameter?
+quint64 C12keyPredictiveSearchTable::ConvertToHex(QString aToken) const
+ {
+ if (aToken.length() > KMaxTokenLength)
+ {
+ return KConversionError;
+ }
+ QString padded = aToken.leftJustified(KMaxTokenLength, KPadChar);
+
+ TBuf<KMaxTokenLength> log(padded.utf16());
+ PRINT1(_L("C12keyPredictiveSearchTable::ConvertToHex padded '%S'"), &log);
+
+ // Replace unmapped char and the following characters with KPadChar.
+ QString replaced = padded;
+ bool done(false);
+ for (TInt i = 0; i < KMaxTokenLength && !done; ++i)
+ {
+ if (!IsValidChar(padded[i]))
+ {
+ // replace() does not work, it puts just one KPadChar at end
+ // replaced = padded.replace(i, KMaxTokenLength - i, KPadChar);
+
+ padded.remove(i, KMaxTokenLength - i);
+ replaced = padded.leftJustified(KMaxTokenLength, KPadChar);
+ done = true;
+
+ TBuf<KMaxTokenLength> log2(replaced.utf16());
+ PRINT1(_L("After replacing '%S'"), &log2);
+ }
+ }
+
+ const TInt KHexadecimalBase = 16;
+ bool ok(true);
+ quint64 hex = replaced.toULongLong(&ok, KHexadecimalBase);
+ if (!ok)
+ {
+ PRINT(_L("conv to hex failed"));
+ return KConversionError;
+ }
+
+ PRINT1(_L("C12keyPredictiveSearchTable::ConvertToHex result 0x%lx"), hex);
+ return hex;
+ }
+
+
+const TDesC& C12keyPredictiveSearchTable::GetTableNameL(const QChar aCh) const
+ {
+ switch (aCh.toAscii())
+ {
+ case '0': return KSqlContactPredSearchTable0;
+ case '1': return KSqlContactPredSearchTable1;
+ case '2': return KSqlContactPredSearchTable2;
+ case '3': return KSqlContactPredSearchTable3;
+ case '4': return KSqlContactPredSearchTable4;
+ case '5': return KSqlContactPredSearchTable5;
+ case '6': return KSqlContactPredSearchTable6;
+ case '7': return KSqlContactPredSearchTable7;
+ case '8': return KSqlContactPredSearchTable8;
+ case '9': return KSqlContactPredSearchTable9;
+ case MAPPED_CHAR_FOR_STAR: return KSqlContactPredSearchTable10;
+ case MAPPED_CHAR_FOR_HASH: return KSqlContactPredSearchTable11;
+ default:
+ PRINT1(_L("C12keyPredictiveSearchTable::GetTableNameL unknown char '%c'"),
+ aCh.toAscii());
+ User::Leave(KErrArgument);
+ return KNullDesC;
+ }
+ }