plugins/contacts/symbian/contactsmodel/cntplsql/src/cpredictivesearchsynchronizer.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cpredictivesearchsynchronizer.h"
       
    19 #include "c12keypredictivesearchtable.h"
       
    20 #include "cqwertypredictivesearchtable.h"
       
    21 #include "cpredictivesearchsettingstable.h"
       
    22 #include "dbsqlconstants.h"
       
    23 
       
    24 // This macro suppresses log writes
       
    25 //#define NO_PRED_SEARCH_LOGS
       
    26 #include "predictivesearchlog.h"
       
    27 
       
    28 _LIT(KFirstQwertyTableName, "qm0");
       
    29 
       
    30 
       
    31 CPredictiveSearchSynchronizer*
       
    32 CPredictiveSearchSynchronizer::NewL(RSqlDatabase& aDatabase,
       
    33 									C12keyPredictiveSearchTable& a12keyTable,
       
    34 									CQwertyPredictiveSearchTable& aQwertyTable,
       
    35 									CPredictiveSearchSettingsTable& aSettingsTable)
       
    36 	{
       
    37 	PRINT(_L("CPredictiveSearchSynchronizer::NewL"));
       
    38 	CPredictiveSearchSynchronizer* self =
       
    39 		CPredictiveSearchSynchronizer::NewLC(aDatabase, a12keyTable,
       
    40 											 aQwertyTable, aSettingsTable);
       
    41 	CleanupStack::Pop(self);
       
    42 	PRINT(_L("CPredictiveSearchSynchronizer::NewL ends"));
       
    43 	return self;
       
    44 	}
       
    45 
       
    46 CPredictiveSearchSynchronizer*
       
    47 CPredictiveSearchSynchronizer::NewLC(RSqlDatabase& aDatabase,
       
    48 									 C12keyPredictiveSearchTable& a12keyTable,
       
    49 									 CQwertyPredictiveSearchTable& aQwertyTable,
       
    50 									 CPredictiveSearchSettingsTable& aSettingsTable)
       
    51 	{
       
    52 	PRINT(_L("CPredictiveSearchSynchronizer::NewLC"));
       
    53 	CPredictiveSearchSynchronizer* self =
       
    54 		new (ELeave) CPredictiveSearchSynchronizer(aDatabase, a12keyTable,
       
    55 												   aQwertyTable, aSettingsTable);
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL();
       
    58 	PRINT(_L("CPredictiveSearchSynchronizer::NewLC ends"));
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 CPredictiveSearchSynchronizer::~CPredictiveSearchSynchronizer()
       
    63 	{
       
    64 	PRINT(_L("CPredictiveSearchSynchronizer dtor"));
       
    65 	PRINT(_L("CPredictiveSearchSynchronizer dtor ends"));
       
    66 	}
       
    67 
       
    68 void CPredictiveSearchSynchronizer::ConstructL()
       
    69 	{
       
    70 	}
       
    71 
       
    72 /**
       
    73 Constructor
       
    74 */
       
    75 CPredictiveSearchSynchronizer::CPredictiveSearchSynchronizer(
       
    76 	RSqlDatabase& aDatabase,
       
    77 	C12keyPredictiveSearchTable& a12keyTable,
       
    78 	CQwertyPredictiveSearchTable& aQwertyTable,
       
    79 	CPredictiveSearchSettingsTable& aSettingsTable) :
       
    80 	iDatabase(aDatabase),
       
    81 	i12keyTable(a12keyTable),
       
    82 	iQwertyTable(aQwertyTable),
       
    83 	iSettingsTable(aSettingsTable)
       
    84 	{
       
    85 	}
       
    86 
       
    87 // There are 3 cases:
       
    88 // - none of the pred.search tables exist
       
    89 // - just 12-key pred.search tables exist
       
    90 // - all pred.search tables exist (12-key, QWERTY, settings)
       
    91 // There is no case where QWERTY tables exist but settings table does not,
       
    92 // since such a version was not released.
       
    93 void CPredictiveSearchSynchronizer::SynchronizeTablesL()
       
    94 	{
       
    95 	PRINT(_L("CPredictiveSearchSynchronizer::SynchronizeTablesL"));
       
    96 
       
    97 	if (CheckIfPredSearchTableExistsL(KSqlContactPredSearchTable0))
       
    98 		{
       
    99 		if (CheckIfPredSearchTableExistsL(KFirstQwertyTableName))
       
   100 			{
       
   101 			// All tables exist, check if language has been changed
       
   102 			if (!iSettingsTable.IsLanguageValidL())
       
   103 				{
       
   104 				PRINT(_L("language has changed, re-create QWERTY tables"));
       
   105 				DeletePredSearchTableL(iQwertyTable);
       
   106 				CreatePredSearchTablesL(EFalse);
       
   107 				iSettingsTable.StoreCurrentLanguageL();
       
   108 				}
       
   109 			}
       
   110 		else
       
   111 			{
       
   112 			PRINT(_L("QWERTY and settings tables missing, re-create all tables"));
       
   113 			DeletePredSearchTablesL();
       
   114 			CreatePredSearchTablesL();
       
   115 			}
       
   116 		}
       
   117 	else
       
   118 		{
       
   119 		// All predictive search tables missing, create all
       
   120 		CreatePredSearchTablesL();
       
   121 		}
       
   122 
       
   123 	PRINT(_L("CPredictiveSearchSynchronizer::SynchronizeTablesL ends"));
       
   124 	}
       
   125 
       
   126 void CPredictiveSearchSynchronizer::CreatePredSearchTablesL(TBool aAllTables)
       
   127 	{
       
   128 	PRINT1(_L("CPredictiveSearchSynchronizer::CreatePredSearchTablesL all=%d"), aAllTables);
       
   129 
       
   130 	if (aAllTables)
       
   131 		{
       
   132 		i12keyTable.CreateTableL();
       
   133 		iSettingsTable.CreateTableL();
       
   134 		iSettingsTable.StoreCurrentLanguageL();
       
   135 		}
       
   136 	iQwertyTable.CreateTableL();
       
   137 
       
   138 	_LIT(KSelectAllContactsFormat, "SELECT %S,%S,%S FROM %S;");
       
   139 	TInt bufSize = KSelectAllContactsFormat().Length() +
       
   140 				   KContactId().Length() +
       
   141 				   KContactFirstName().Length() +
       
   142 				   KContactLastName().Length() +
       
   143 				   KSqlContactTableName().Length();
       
   144 	HBufC* sqlStatement = HBufC::NewLC(bufSize);
       
   145 	sqlStatement->Des().AppendFormat(KSelectAllContactsFormat,
       
   146 		&KContactId,
       
   147 		&KContactFirstName,
       
   148 		&KContactLastName,
       
   149 		&KSqlContactTableName);
       
   150 
       
   151 	RSqlStatement stmnt;
       
   152 	CleanupClosePushL(stmnt);
       
   153 	PRINT1(_L("CreatePredSearchTablesL prepare SQL statement:%S"), sqlStatement);
       
   154     stmnt.PrepareL(iDatabase, *sqlStatement);
       
   155 
       
   156 	const TInt KContactIdIndex = 0;
       
   157 	const TInt KFirstNameIndex = 1;
       
   158 	const TInt KLastNameIndex = 2;
       
   159 	TInt err(KErrNone);
       
   160     while ((err = stmnt.Next()) == KSqlAtRow)
       
   161         {
       
   162 		PRINT(_L("CreatePredSearchTablesL create CContactItem"));
       
   163 
       
   164 		TInt id = KUidContactCardValue;
       
   165 		TUid uid;
       
   166 		uid.iUid = id;
       
   167 		CContactItem* contact = CContactItem::NewLC(uid);
       
   168 		contact->SetId(stmnt.ColumnInt(KContactIdIndex));
       
   169 
       
   170 		// If first name exists, write it to contact item
       
   171 		TPtrC firstName;
       
   172 		if (stmnt.ColumnText(KFirstNameIndex, firstName) == KErrNone)
       
   173 			{
       
   174 			CContactItemField* field =
       
   175 				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
       
   176 			CContactTextField* textfield = field->TextStorage();
       
   177 			textfield->SetTextL(firstName);
       
   178 			contact->AddFieldL(*field); // Takes ownership
       
   179 			CleanupStack::Pop(field);
       
   180 			}
       
   181 
       
   182 		TPtrC lastName;
       
   183 		if (stmnt.ColumnText(KLastNameIndex, lastName) == KErrNone)
       
   184 			{
       
   185 			CContactItemField* field =
       
   186 				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
       
   187 			CContactTextField* textfield = field->TextStorage();
       
   188 			textfield->SetTextL(lastName);
       
   189 			contact->AddFieldL(*field); // Takes ownership
       
   190 			CleanupStack::Pop(field);
       
   191 			}
       
   192 		PRINT(_L("CreatePredSearchTablesL create entry to tables"));
       
   193 		if (aAllTables)
       
   194 			{
       
   195 			i12keyTable.CreateInDbL(*contact);
       
   196 			}
       
   197 		if (ReadMailAddressesL(*contact))
       
   198 			{
       
   199 			iQwertyTable.CreateInDbL(*contact);
       
   200 			}
       
   201 
       
   202 		CleanupStack::PopAndDestroy(contact);
       
   203         }
       
   204 
       
   205     // Leave if we didn't complete going through the results properly
       
   206     if (err != KSqlAtEnd)
       
   207         {
       
   208 		PRINT1(_L("CreatePredSearchTablesL SQL err=%d"), err);
       
   209         User::Leave(err);
       
   210         }
       
   211     CleanupStack::PopAndDestroy(&stmnt);
       
   212 	CleanupStack::PopAndDestroy(sqlStatement);
       
   213 
       
   214 	PRINT(_L("CPredictiveSearchSynchronizer::CreatePredSearchTablesL ends"));
       
   215 	}
       
   216 
       
   217 void CPredictiveSearchSynchronizer::DeletePredSearchTablesL()
       
   218 	{
       
   219 	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTablesL"));
       
   220 
       
   221 	DeletePredSearchTableL(i12keyTable);
       
   222 	DeletePredSearchTableL(iQwertyTable);
       
   223 	DeletePredSearchTableL(iSettingsTable);
       
   224 	
       
   225 	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTablesL ends"));
       
   226 	}
       
   227 
       
   228 TBool CPredictiveSearchSynchronizer::CheckIfPredSearchTableExistsL(
       
   229 	const TDesC& aTableName) const
       
   230 	{
       
   231 	PRINT1(_L("CPredictiveSearchSynchronizer::CheckIfPredSearchTableExistsL table='%S'"),
       
   232 		   &aTableName);
       
   233 
       
   234 	_LIT(KSelectFirstTableFormat,
       
   235 		 "SELECT name FROM sqlite_master WHERE type='table' AND name='%S';");
       
   236 
       
   237 	TInt bufSize = KSelectFirstTableFormat().Length() +
       
   238 				   aTableName.Length();
       
   239 	HBufC* select = HBufC::NewLC(bufSize);
       
   240 	select->Des().AppendFormat(KSelectFirstTableFormat, &aTableName);
       
   241 	RSqlStatement stmnt;
       
   242 	CleanupClosePushL(stmnt);
       
   243     stmnt.PrepareL(iDatabase, *select);
       
   244 
       
   245 	TBool tableExists = (stmnt.Next() == KSqlAtRow);
       
   246 
       
   247 	CleanupStack::PopAndDestroy(&stmnt);
       
   248 	CleanupStack::PopAndDestroy(select);
       
   249 
       
   250 	PRINT1(_L("CPredictiveSearchSynchronizer::CheckIfPredSearchTablesExistL return %d"),
       
   251 		   tableExists);
       
   252 	return tableExists;
       
   253 	}
       
   254 
       
   255 void CPredictiveSearchSynchronizer::DeletePredSearchTableL(CPplPredictiveSearchTableBase& aTable)
       
   256 	{
       
   257 	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTableL"));
       
   258 
       
   259 	// IF EXISTS suppresses error that would occur if table does not exist
       
   260 	_LIT(KDropTable, "DROP TABLE IF EXISTS %S;");
       
   261 
       
   262 	QList<QChar> tables;
       
   263 	QT_TRYCATCH_LEAVING(tables = aTable.FillAllTables());
       
   264 	HBufC* tableName(NULL);
       
   265 	while ((tableName = aTable.GetNextTableNameL(tables)) != NULL)
       
   266 		{
       
   267 		CleanupStack::PushL(tableName);
       
   268 		HBufC* dropTable = HBufC::NewLC(KDropTable().Length() + tableName->Length());
       
   269         dropTable->Des().Format(KDropTable, tableName);
       
   270 
       
   271 		User::LeaveIfError(iDatabase.Exec(*dropTable));
       
   272 
       
   273         CleanupStack::PopAndDestroy(dropTable);
       
   274 		CleanupStack::PopAndDestroy(tableName);
       
   275 		}
       
   276 	PRINT(_L("CPredictiveSearchSynchronizer::DeletePredSearchTableL ends"));
       
   277 	}
       
   278 
       
   279 TBool CPredictiveSearchSynchronizer::ReadMailAddressesL(CContactItem& aContact)
       
   280 	{
       
   281 	PRINT(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL"));
       
   282 
       
   283 	// SELECT value FROM comm_addr
       
   284 	//	 WHERE contact_id = [contact id value] AND type = [type value];
       
   285     _LIT(KSelectMailAddrFormat, "SELECT %S FROM %S WHERE %S = %d AND %S = %d;");
       
   286 	const TInt KContactIdLength = 10;
       
   287 	const TInt KCommAddrTypeLength = 2; // CPplCommAddrTable::EEmailAddress is enum
       
   288 	TInt bufSize = KSelectMailAddrFormat().Length() +
       
   289 				   KCommAddrValue().Length() +
       
   290 				   KSqlContactCommAddrTableName().Length() +
       
   291 				   KCommAddrContactId().Length() +
       
   292 				   KContactIdLength +
       
   293 				   KCommAddrType().Length() +
       
   294 				   KCommAddrTypeLength;
       
   295 	HBufC* sqlStatement = HBufC::NewLC(bufSize);
       
   296 	sqlStatement->Des().AppendFormat(KSelectMailAddrFormat,
       
   297 		&KCommAddrValue,
       
   298 		&KSqlContactCommAddrTableName,
       
   299 		&KCommAddrContactId,
       
   300 		aContact.Id(),
       
   301 		&KCommAddrType,
       
   302 		CPplCommAddrTable::EEmailAddress);
       
   303 
       
   304 	RSqlStatement stmnt;
       
   305 	CleanupClosePushL(stmnt);
       
   306 	PRINT1(_L("prepare SQL statement:%S"), sqlStatement);
       
   307     stmnt.PrepareL(iDatabase, *sqlStatement);
       
   308 
       
   309 	const TInt KValueIndex = 0;
       
   310 	TBool foundMailAddress(EFalse);
       
   311 	TInt err(KErrNone);
       
   312     while ((err = stmnt.Next()) == KSqlAtRow)
       
   313         {
       
   314 		TPtrC value;
       
   315 		if (stmnt.ColumnText(KValueIndex, value) == KErrNone)
       
   316 			{
       
   317 			PRINT2(_L("  id=%d, found mail address=%S"), aContact.Id(), &value);
       
   318 			CContactItemField* field =
       
   319 				CContactItemField::NewLC(KStorageTypeText, KUidContactFieldEMail);
       
   320 			CContactTextField* textfield = field->TextStorage();
       
   321 			textfield->SetTextL(value);
       
   322 			aContact.AddFieldL(*field); // Takes ownership
       
   323 			CleanupStack::Pop(field);
       
   324 			foundMailAddress = ETrue;
       
   325 			}
       
   326         }
       
   327 
       
   328     if (err != KSqlAtEnd)
       
   329         {
       
   330 		PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL SQL err=%d"), err);
       
   331         User::Leave(err);
       
   332         }
       
   333     CleanupStack::PopAndDestroy(&stmnt);
       
   334 	CleanupStack::PopAndDestroy(sqlStatement);
       
   335 	PRINT1(_L("CPredictiveSearchSynchronizer::ReadMailAddressesL return %d"), foundMailAddress);
       
   336 	return foundMailAddress;
       
   337 	}