tzservices/tzserver/Server/Source/tzuserdata.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "tzuserdata.h"
       
    17 #include <tz.h>
       
    18 #include <f32file.h>
       
    19 #include <e32property.h>
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <tzusernames.h>
       
    22 #include <tzuserdefineddata.h>
       
    23 #endif
       
    24 #include "tzidinternal.h"
       
    25 
       
    26 _LIT(KUserDatabaseName, "c:\\private\\1020383e\\SQLite__tzuserdata.db");
       
    27 _LIT(KTzPrivatePath, "c:\\private\\1020383e\\");
       
    28 
       
    29 // Transaction constants 
       
    30 _LIT(KBeginTransaction,"BEGIN TRANSACTION;");
       
    31 _LIT(KCommitTransaction,"COMMIT;");
       
    32 _LIT(KRollbackTransaction,"ROLLBACK;");
       
    33 
       
    34 // Tz Rules Table Parameters
       
    35 _LIT(KTzRulesTblTzIdParam, ":tzId");
       
    36 _LIT(KTzRulesTblRuleTypeParam, ":ruleType");
       
    37 _LIT(KTzRulesTblDSTStartTimeParam, ":dstStartTime");
       
    38 _LIT(KTzRulesTblDSTStartRefParam, ":dstStartRef"); 
       
    39 _LIT(KTzRulesTblDSTEndTimeParam, ":dstEndTime");
       
    40 _LIT(KTzRulesTblDSTEndRefParam, ":dstEndRef");
       
    41 _LIT(KTzRulesTblOldOffsetParam, ":oldOffset");
       
    42 _LIT(KTzRulesTblNewOffsetParam, ":newOffset");
       
    43 _LIT(KTzRulesTblMonthParam, ":month");
       
    44 _LIT(KTzRulesTblDayParam, ":day");
       
    45 _LIT(KTzRulesTblWeekParam, ":week");
       
    46 _LIT(KTzRulesTblTimeRefParam, ":timeRef");
       
    47 _LIT(KTzRulesTblMinsParam, ":mins");
       
    48 
       
    49 // Tz Rules Table Index
       
    50 _LIT(KTzRulesTblRuleTypeIndex, "ruleType");
       
    51 _LIT(KTzRulesTblDSTStartTimeIndex, "dstStartTime");
       
    52 _LIT(KTzRulesTblDSTStartRefIndex, "dstStartRef"); 
       
    53 _LIT(KTzRulesTblDSTEndTimeIndex, "dstEndTime");
       
    54 _LIT(KTzRulesTblDSTEndRefIndex, "dstEndRef");
       
    55 _LIT(KTzRulesTblOldOffsetIndex, "oldOffset");
       
    56 _LIT(KTzRulesTblNewOffsetIndex, "newOffset");
       
    57 _LIT(KTzRulesTblMonthIndex, "month");
       
    58 _LIT(KTzRulesTblDayIndex, "day");
       
    59 _LIT(KTzRulesTblWeekIndex, "week");
       
    60 _LIT(KTzRulesTblTimeRefIndex, "timeRef");
       
    61 _LIT(KTzRulesTblMinsIndex, "mins");
       
    62 
       
    63 // Tz Names Table Parameters
       
    64 _LIT(KTzNamesTblTzIdParam, ":tzId");
       
    65 _LIT(KTzNamesTblStdNameParam, ":stdName");
       
    66 _LIT(KTzNamesTblShortStdNameParam, ":shortStdName");
       
    67 _LIT(KTzNamesTblDSTNameParam, ":dstName");
       
    68 _LIT(KTzNamesTblShortDSTNameParam, ":shortDstName");
       
    69 _LIT(KTzNamesTblCityNameParam, ":cityName");
       
    70 _LIT(KTzNamesTblRegionNameParam, ":regionName");
       
    71 
       
    72 // Tz Names Table Index
       
    73 _LIT(KTzNamesTblTzIdIndex, "tzId");
       
    74 _LIT(KTzNamesTblStdNameIndex, "stdName");
       
    75 _LIT(KTzNamesTblShortStdNameIndex, "shortStdName");
       
    76 _LIT(KTzNamesTblDSTNameIndex, "dstName");
       
    77 _LIT(KTzNamesTblShortDSTNameIndex, "shortDstName");
       
    78 _LIT(KTzNamesTblCityNameIndex, "cityName");
       
    79 _LIT(KTzNamesTblRegionNameIndex, "regionName");
       
    80 
       
    81 // Identifier Table Index
       
    82 _LIT(KNextTzIdentifierIndex, "nextTzId");
       
    83 
       
    84 // InitialStdOffset Table Param
       
    85 _LIT(KTzInitialStdOffsetTblTzIdParam, ":tzId");
       
    86 _LIT(KTzInitialStdOffsetTblStdInitialOffsetParam, ":initialStdOffset");
       
    87 
       
    88 // InitialStdOffset Table Index
       
    89 _LIT(KTzInitialStdOffsetTblStdInitialOffsetIndex, "initialStdOffset");
       
    90 
       
    91 // Create statements
       
    92 _LIT8 (KTzRulesCreateStmnt, "CREATE TABLE rules (tzId INTEGER NOT NULL, ruleType \
       
    93 							 INTEGER, dstStartTime INT64 NOT NULL, dstStartRef INTEGER, \
       
    94 							 dstEndTime INT64 NOT NULL, dstEndRef INTEGER, oldOffset \
       
    95 							 INTEGER NOT NULL, newOffset INTEGER NOT NULL, month INTEGER, \
       
    96 							 day INTEGER, week INTEGER, timeRef INTEGER, mins INTEGER NOT NULL)");
       
    97 							 								
       
    98 _LIT8 (KTzNamesCreateStmnt, "CREATE TABLE names ( tzId INTEGER NOT NULL PRIMARY \
       
    99 							 KEY, stdName CHAR(255), shortStdName CHAR(10), dstName \
       
   100 							 CHAR(255), shortDstName CHAR(10), cityName CHAR(255), \
       
   101 							 regionName CHAR(255))");
       
   102 							
       
   103 _LIT8 (KTzIdentifierCreateStmnt, "CREATE TABLE  identifier ( nextTzId INTEGER NOT NULL )");
       
   104 
       
   105 _LIT8 (KTzInitialStdOffsetCreateStmnt, "CREATE TABLE initialStdOffset (tzId INTEGER NOT NULL, initialStdOffset INTEGER)");
       
   106 
       
   107 // Insert statements
       
   108 _LIT8(KInsertRulesStmnt, "INSERT INTO rules (tzId, ruleType, dstStartTime, dstStartRef, \
       
   109 						  dstEndTime, dstEndRef, oldOffset, newOffset, month, day, \
       
   110 						  week, timeRef, mins) VALUES (:tzId, :ruleType, :dstStartTime,\
       
   111 						  :dstStartRef, :dstEndTime, :dstEndRef, :oldOffset, :newOffset,\
       
   112 						  :month, :day, :week, :timeRef, :mins)");
       
   113 						  
       
   114 _LIT8(KInsertNamesStmnt, "INSERT INTO names(tzId, stdName, shortStdName, dstName, shortDstName,\
       
   115 						  cityName, regionName) VALUES(:tzId, :stdName, :shortStdName, :dstName,\
       
   116 						  :shortDstName, :cityName, :regionName)");
       
   117 						  
       
   118 _LIT(KInsertIdentifierStmnt, "INSERT INTO identifier (nextTzId) VALUES (%d)");
       
   119 
       
   120 _LIT8(KInsertInitialStdOffsetStmnt, "INSERT INTO initialStdOffset (tzId, initialStdOffset) \
       
   121 									 VALUES (:tzId, :initialStdOffset)");
       
   122 
       
   123 //Select statements
       
   124 _LIT8(KSelectNextTzIdStmnt, "SELECT nextTzId FROM identifier");
       
   125 
       
   126 _LIT(KSelectRulesStmnt, "SELECT * FROM rules WHERE tzId = %d");
       
   127 
       
   128 _LIT(KSelectRulesCountStmnt, "SELECT COUNT(tzId) FROM rules WHERE tzId = %d");
       
   129 
       
   130 _LIT(KSelectNamesCountStmnt, "SELECT COUNT(tzId) FROM names WHERE tzId = %d");
       
   131 
       
   132 _LIT(KSelectTzIdCountFromNamesStmnt, "SELECT COUNT(tzId) FROM names WHERE tzId = %d");
       
   133 
       
   134 _LIT(KSelectNamesStmnt, "SELECT * FROM names WHERE tzId = %d");
       
   135 
       
   136 _LIT(KSelectTzIdFromNamesStmnt, "SELECT tzId FROM names");
       
   137 
       
   138 _LIT(KSelectInitialStdOffsetStmnt, "SELECT initialStdOffset FROM initialStdOffset WHERE tzId = %d");
       
   139 
       
   140 //Update statements
       
   141 _LIT (KUpdateIdentifierStmnt, "UPDATE identifier SET nextTzId = :nextTzId");
       
   142 
       
   143 //Delete statements
       
   144 _LIT(KDeleteRulesStmnt, "DELETE FROM rules WHERE tzId = %d");
       
   145 
       
   146 _LIT(KDeleteNamesStmnt, "DELETE FROM names WHERE tzId = %d");
       
   147 
       
   148 _LIT(KDeleteInitialStdOffset, "DELETE FROM initialStdOffset WHERE tzId = %d");
       
   149 
       
   150 const TInt KSqlStringLength = 100;
       
   151 const TUint KOutOfBoundsUserId = 0x5000;
       
   152 
       
   153 CTzUserDataDb* CTzUserDataDb::NewL()
       
   154 	{
       
   155 	CTzUserDataDb* self = new(ELeave) CTzUserDataDb();
       
   156 	CleanupStack::PushL(self);
       
   157 	self->ConstructL();
       
   158 	CleanupStack::Pop(self);
       
   159 	return self;
       
   160 	}
       
   161 
       
   162 CTzUserDataDb::CTzUserDataDb()
       
   163 	{
       
   164 	}
       
   165 
       
   166 CTzUserDataDb::~CTzUserDataDb()
       
   167 	{
       
   168 	// We don't own the pointers in this array
       
   169 	iChangeObservers.Close();
       
   170 	iDatabase.Close();
       
   171 	}
       
   172 
       
   173 void CTzUserDataDb::ConstructL()
       
   174 	{
       
   175 	OpenL();	
       
   176 	}
       
   177 
       
   178 void CTzUserDataDb::Close()
       
   179 	{
       
   180 	iDatabase.Close();
       
   181 	}
       
   182 		
       
   183 void CTzUserDataDb::OpenL()
       
   184 	{
       
   185 	RFs fs;
       
   186 	CleanupClosePushL(fs);
       
   187 	
       
   188 	// Open the database
       
   189 	TInt ret = iDatabase.Open(KUserDatabaseName());
       
   190 	// If the database could not be opened because 
       
   191 	// the file was not found in the path provided, create the directory
       
   192 	if(ret == KErrNotFound || ret == KErrPathNotFound)
       
   193 		{
       
   194 		User::LeaveIfError(fs.Connect());
       
   195 		ret = fs.MkDir(KTzPrivatePath);
       
   196 		// If there are no errors while creating path
       
   197 		// or the path already exists, create the database
       
   198 		if(ret == KErrNone || ret == KErrAlreadyExists)
       
   199 			{
       
   200 			CreateL();	
       
   201 			}
       
   202 		}
       
   203 	else
       
   204 		{
       
   205 		User::LeaveIfError(ret);
       
   206 		}
       
   207 	CleanupStack::PopAndDestroy(&fs);
       
   208 	}
       
   209 	
       
   210 void CTzUserDataDb::CreateL()
       
   211 	{	
       
   212 	User::LeaveIfError(iDatabase.Create(KUserDatabaseName()));
       
   213     iDatabase.Close();    
       
   214     CreateSchemaL();
       
   215    	}
       
   216 	
       
   217 void CTzUserDataDb::CreateSchemaL()
       
   218 	{
       
   219 	RSqlStatement stmt;
       
   220 	CleanupClosePushL(stmt);
       
   221 	
       
   222 	User::LeaveIfError(iDatabase.Open(KUserDatabaseName()));
       
   223 	User::LeaveIfError(stmt.Prepare(iDatabase, KTzRulesCreateStmnt));
       
   224 	User::LeaveIfError(stmt.Exec());
       
   225 	stmt.Close();
       
   226 	
       
   227 	User::LeaveIfError(stmt.Prepare(iDatabase, KTzNamesCreateStmnt));
       
   228 	User::LeaveIfError(stmt.Exec());
       
   229 	stmt.Close();
       
   230 
       
   231 	User::LeaveIfError(stmt.Prepare(iDatabase, KTzIdentifierCreateStmnt));
       
   232 	User::LeaveIfError(stmt.Exec());
       
   233 	stmt.Close();
       
   234 		
       
   235 	TBuf<KSqlStringLength> sqlId;
       
   236 	sqlId.Format(KInsertIdentifierStmnt, KUserTzIdMin);
       
   237 	User::LeaveIfError(stmt.Prepare(iDatabase, sqlId));
       
   238 	User::LeaveIfError(stmt.Exec());
       
   239 	stmt.Close();
       
   240 	
       
   241 	User::LeaveIfError(stmt.Prepare(iDatabase, KTzInitialStdOffsetCreateStmnt));
       
   242 	User::LeaveIfError(stmt.Exec());
       
   243 	stmt.Close();
       
   244 	
       
   245 	CleanupStack::PopAndDestroy(&stmt);
       
   246 	}
       
   247 	
       
   248 TInt CTzUserDataDb::CreateTzL(const CTzRules& aRules, const CTzUserNames& aNames)
       
   249 	{
       
   250 	if(iBackupInProgress || iRestoreInProgress)
       
   251 		{
       
   252 		User::Leave(KErrLocked);
       
   253 		}
       
   254 
       
   255 	RSqlStatement stmt;
       
   256 	CleanupClosePushL(stmt);
       
   257 			
       
   258 	BeginTransactionL();
       
   259 	
       
   260 	TInt err = stmt.Prepare(iDatabase, KSelectNextTzIdStmnt);
       
   261 	User::LeaveIfError(err);
       
   262 	TInt colIndex = stmt.ColumnIndex(KNextTzIdentifierIndex);
       
   263 	User::LeaveIfError(colIndex);
       
   264 	while((err = stmt.Next()) == KSqlAtRow)
       
   265 		{
       
   266 		iNextCandidateTzId = stmt.ColumnInt64(colIndex);	
       
   267 		}
       
   268 	
       
   269 	stmt.Close();
       
   270 	
       
   271 	// Check if the next available user ID is valid
       
   272 	if(iNextCandidateTzId == KOutOfBoundsUserId || IsIdInDbL(iNextCandidateTzId))
       
   273 		{
       
   274 		iNextCandidateTzId = FindUnusedTzIdL();
       
   275 		}
       
   276 		
       
   277 	// If all the user IDs have been used, leave with KErrOverflow	
       
   278 	if(iNextCandidateTzId == KOutOfBoundsUserId)
       
   279 		{
       
   280 		User::Leave(KErrOverflow);		
       
   281 		}
       
   282 				
       
   283 	TUint retId = iNextCandidateTzId;
       
   284 	TInt index;	
       
   285 	TInt count = aRules.Count();
       
   286 	for(TInt i=0; i<count; i++)
       
   287 		{
       
   288 		TTzRule& rule = const_cast<CTzRules&>(aRules)[i];
       
   289 			
       
   290 		// Insert a row in the rules
       
   291 		User::LeaveIfError(stmt.Prepare(iDatabase, KInsertRulesStmnt()));
       
   292 		
       
   293 		index = stmt.ParameterIndex(KTzRulesTblTzIdParam);
       
   294 		User::LeaveIfError(index);
       
   295 		User::LeaveIfError(stmt.BindInt64(index, iNextCandidateTzId));
       
   296 		index = stmt.ParameterIndex(KTzRulesTblRuleTypeParam);
       
   297 		User::LeaveIfError(index);
       
   298 		User::LeaveIfError(stmt.BindInt(index, rule.iDayRule));
       
   299 		index = stmt.ParameterIndex(KTzRulesTblDSTStartTimeParam);
       
   300 		User::LeaveIfError(index);
       
   301 		User::LeaveIfError(stmt.BindInt64(index, rule.iFrom.iTime.Int64()));
       
   302 		index = stmt.ParameterIndex(KTzRulesTblDSTStartRefParam);
       
   303 		User::LeaveIfError(index);
       
   304 		User::LeaveIfError(stmt.BindInt(index, rule.iFrom.iTimeReference));
       
   305 		index = stmt.ParameterIndex(KTzRulesTblDSTEndTimeParam);
       
   306 		User::LeaveIfError(index);
       
   307 		User::LeaveIfError(stmt.BindInt64(index, rule.iTo.iTime.Int64()));		
       
   308 		index = stmt.ParameterIndex(KTzRulesTblDSTEndRefParam);
       
   309 		User::LeaveIfError(index);
       
   310 		User::LeaveIfError(stmt.BindInt(index, rule.iTo.iTimeReference));
       
   311 		index = stmt.ParameterIndex(KTzRulesTblOldOffsetParam);
       
   312 		User::LeaveIfError(index);
       
   313 		User::LeaveIfError(stmt.BindInt(index, rule.iOldLocalTimeOffset));
       
   314 		index = stmt.ParameterIndex(KTzRulesTblNewOffsetParam);
       
   315 		User::LeaveIfError(index);
       
   316 		User::LeaveIfError(stmt.BindInt(index, rule.iNewLocalTimeOffset));
       
   317 		index = stmt.ParameterIndex(KTzRulesTblMonthParam);
       
   318 		User::LeaveIfError(index);
       
   319 		User::LeaveIfError(stmt.BindInt(index, rule.iMonth));
       
   320 		index = stmt.ParameterIndex(KTzRulesTblDayParam);
       
   321 		User::LeaveIfError(index);
       
   322 		User::LeaveIfError(stmt.BindInt(index, rule.iDayOfMonth));
       
   323 		index = stmt.ParameterIndex(KTzRulesTblWeekParam);
       
   324 		User::LeaveIfError(index);
       
   325 		User::LeaveIfError(stmt.BindInt(index, rule.iDayOfWeek));
       
   326 		index = stmt.ParameterIndex(KTzRulesTblTimeRefParam);
       
   327 		User::LeaveIfError(index);
       
   328 		User::LeaveIfError(stmt.BindInt(index, rule.iTimeReference));
       
   329 		index = stmt.ParameterIndex(KTzRulesTblMinsParam);
       
   330 		User::LeaveIfError(index);
       
   331 		User::LeaveIfError(stmt.BindInt(index, rule.iTimeOfChange));
       
   332 	
       
   333 		TInt ret = stmt.Exec();
       
   334 		stmt.Close();
       
   335 		
       
   336 		if(ret < KErrNone)
       
   337 			{
       
   338 			User::Leave(ret);
       
   339 			}			
       
   340 		}
       
   341 		
       
   342 	// Insert a row in the names
       
   343 	User::LeaveIfError(stmt.Prepare(iDatabase, KInsertNamesStmnt()));
       
   344 	index = stmt.ParameterIndex(KTzNamesTblTzIdParam);
       
   345 	User::LeaveIfError(index);
       
   346 	User::LeaveIfError(stmt.BindInt64(index, iNextCandidateTzId));
       
   347 	index = stmt.ParameterIndex(KTzNamesTblStdNameParam);
       
   348 	User::LeaveIfError(index);
       
   349 	User::LeaveIfError(stmt.BindText(index, aNames.StandardName()));
       
   350 	index = stmt.ParameterIndex(KTzNamesTblShortStdNameParam);
       
   351 	User::LeaveIfError(index);
       
   352 	User::LeaveIfError(stmt.BindText(index, aNames.ShortStandardName()));
       
   353 	index = stmt.ParameterIndex(KTzNamesTblDSTNameParam);
       
   354 	User::LeaveIfError(index);
       
   355 	User::LeaveIfError(stmt.BindText(index, aNames.DaylightSaveName()));
       
   356 	index = stmt.ParameterIndex(KTzNamesTblShortDSTNameParam);
       
   357 	User::LeaveIfError(index);
       
   358 	User::LeaveIfError(stmt.BindText(index, aNames.ShortDaylightSaveName()));
       
   359 	index = stmt.ParameterIndex(KTzNamesTblCityNameParam);
       
   360 	User::LeaveIfError(index);
       
   361 	User::LeaveIfError(stmt.BindText(index, aNames.CityName()));
       
   362 	index = stmt.ParameterIndex(KTzNamesTblRegionNameParam);
       
   363 	User::LeaveIfError(index);
       
   364 	User::LeaveIfError(stmt.BindText(index, aNames.RegionName()));
       
   365 	TInt ret = stmt.Exec();
       
   366 	stmt.Close();
       
   367 	
       
   368 	if(ret < KErrNone)
       
   369 		{
       
   370 		User::Leave(ret);
       
   371 		}
       
   372 
       
   373 	User::LeaveIfError(stmt.Prepare(iDatabase, KInsertInitialStdOffsetStmnt));
       
   374 	index = stmt.ParameterIndex(KTzInitialStdOffsetTblTzIdParam);
       
   375 	User::LeaveIfError(index);
       
   376 	User::LeaveIfError(stmt.BindInt(index, iNextCandidateTzId));
       
   377 	index = stmt.ParameterIndex(KTzInitialStdOffsetTblStdInitialOffsetParam);
       
   378 	User::LeaveIfError(index);
       
   379 	TInt initialOffset = aRules.InitialStdTimeOffset();
       
   380 	User::LeaveIfError(stmt.BindInt(index, initialOffset));
       
   381 	ret = stmt.Exec();
       
   382 	stmt.Close();
       
   383 	
       
   384 	if(ret < KErrNone)
       
   385 		{
       
   386 		User::Leave(ret);
       
   387 		}
       
   388 	
       
   389 	// Update the next available user ID
       
   390 	if(iNextCandidateTzId >= KUserTzIdMax)
       
   391 		{
       
   392 		iNextCandidateTzId = FindUnusedTzIdL();
       
   393 		}
       
   394 	else
       
   395 		{
       
   396 		iNextCandidateTzId++;	
       
   397 		}
       
   398 	
       
   399 	//Insert a row with the new available value of tz id in TZ IdentifierTable
       
   400 	User::LeaveIfError(stmt.Prepare(iDatabase, KUpdateIdentifierStmnt));
       
   401 	User::LeaveIfError(stmt.BindInt64(0, iNextCandidateTzId));
       
   402 	ret = stmt.Exec();
       
   403 	stmt.Close();
       
   404 	
       
   405 	if(ret < KErrNone)
       
   406 		{
       
   407 		User::Leave(ret);
       
   408 		}
       
   409 	
       
   410 	CommitTransactionL();
       
   411 	NotifyTzRulesChange(retId, ETzUserDataCreated);
       
   412 	NotifyTzNamesChange(retId, ETzUserDataCreated);
       
   413 
       
   414 	CleanupStack::PopAndDestroy(&stmt);
       
   415 	return retId;	
       
   416 	}
       
   417 	
       
   418 void CTzUserDataDb::ReadTzRulesL(CTzRules& aRules, TUint aTzId)
       
   419 	{
       
   420 	if(iBackupInProgress || iRestoreInProgress)
       
   421 		{
       
   422 		User::Leave(KErrLocked);
       
   423 		}
       
   424 		
       
   425 	TSqlScalarFullSelectQuery fullSelectQuery(iDatabase);
       
   426 
       
   427 	RSqlStatement stmt;
       
   428 	CleanupClosePushL(stmt);
       
   429 	
       
   430 	TTzRule tzRule;	
       
   431 
       
   432 	TBuf<KSqlStringLength> sqlRules;
       
   433 	sqlRules.Format(KSelectRulesCountStmnt, aTzId);
       
   434 	TInt count = fullSelectQuery.SelectIntL(sqlRules);
       
   435 	if(count == 0)
       
   436 		{
       
   437 		User::Leave(KErrNotFound);
       
   438 		}
       
   439 
       
   440 	sqlRules.Format(KSelectRulesStmnt, aTzId);
       
   441 	TInt err = stmt.Prepare(iDatabase, sqlRules);
       
   442 	User::LeaveIfError(err);
       
   443 	
       
   444 	TInt ruleTypeColIdx = stmt.ColumnIndex(KTzRulesTblRuleTypeIndex);
       
   445 	User::LeaveIfError(ruleTypeColIdx);
       
   446 	TInt startTimeColIdx = stmt.ColumnIndex(KTzRulesTblDSTStartTimeIndex);
       
   447 	User::LeaveIfError(startTimeColIdx);
       
   448 	TInt startRefColIdx = stmt.ColumnIndex(KTzRulesTblDSTStartRefIndex);
       
   449 	User::LeaveIfError(startRefColIdx);
       
   450 	TInt endTimeColIdx = stmt.ColumnIndex(KTzRulesTblDSTEndTimeIndex);
       
   451 	User::LeaveIfError(endTimeColIdx);
       
   452 	TInt endRefColIdx = stmt.ColumnIndex(KTzRulesTblDSTEndRefIndex);
       
   453 	User::LeaveIfError(endRefColIdx);
       
   454 	TInt oldOffsetColIdx = stmt.ColumnIndex(KTzRulesTblOldOffsetIndex);
       
   455 	User::LeaveIfError(oldOffsetColIdx);
       
   456 	TInt newOffsetColIdx = stmt.ColumnIndex(KTzRulesTblNewOffsetIndex);		
       
   457 	User::LeaveIfError(newOffsetColIdx);
       
   458 	TInt monthColIdx = stmt.ColumnIndex(KTzRulesTblMonthIndex);
       
   459 	User::LeaveIfError(monthColIdx);
       
   460 	TInt dayColIdx = stmt.ColumnIndex(KTzRulesTblDayIndex);
       
   461 	User::LeaveIfError(dayColIdx);
       
   462 	TInt weekColIdx = stmt.ColumnIndex(KTzRulesTblWeekIndex);	
       
   463 	User::LeaveIfError(weekColIdx);
       
   464 	TInt timeRefColIdx = stmt.ColumnIndex(KTzRulesTblTimeRefIndex);
       
   465 	User::LeaveIfError(timeRefColIdx);
       
   466 	TInt minsColIdx = stmt.ColumnIndex(KTzRulesTblMinsIndex);
       
   467 	User::LeaveIfError(minsColIdx);
       
   468 	
       
   469 	while((err = stmt.Next()) == KSqlAtRow)
       
   470 		{			
       
   471 		tzRule.iDayRule = static_cast<TTzRuleDay>(stmt.ColumnInt(ruleTypeColIdx));
       
   472 		
       
   473 		tzRule.iFrom.iTime = stmt.ColumnInt64(startTimeColIdx);
       
   474 			
       
   475 		tzRule.iFrom.iTimeReference = static_cast<TTzTimeReference>(stmt.ColumnInt(startRefColIdx));
       
   476 		
       
   477 		tzRule.iTo.iTime = stmt.ColumnInt64(endTimeColIdx); 
       
   478 			
       
   479 		tzRule.iTo.iTimeReference = static_cast<TTzTimeReference>(stmt.ColumnInt(endRefColIdx));
       
   480 		
       
   481 		tzRule.iOldLocalTimeOffset = stmt.ColumnInt(oldOffsetColIdx);
       
   482 		
       
   483 		tzRule.iNewLocalTimeOffset = stmt.ColumnInt(newOffsetColIdx);
       
   484 		
       
   485 		tzRule.iMonth = static_cast<TMonth>(stmt.ColumnInt(monthColIdx));
       
   486 		
       
   487 		tzRule.iDayOfMonth = stmt.ColumnInt(dayColIdx);
       
   488 		
       
   489 		tzRule.iDayOfWeek = stmt.ColumnInt(weekColIdx);
       
   490 		
       
   491 		tzRule.iTimeReference = static_cast<TTzTimeReference>(stmt.ColumnInt(timeRefColIdx));
       
   492 			
       
   493 		tzRule.iTimeOfChange = stmt.ColumnInt(minsColIdx);
       
   494 		
       
   495 		aRules.AddRuleL(tzRule);	
       
   496 		}
       
   497 	stmt.Close();
       
   498 	
       
   499 	sqlRules.Format(KSelectInitialStdOffsetStmnt, aTzId);
       
   500 	err = stmt.Prepare(iDatabase, sqlRules);
       
   501 	User::LeaveIfError(err);
       
   502 	TInt stdInitialOffsetIdx = stmt.ColumnIndex(KTzInitialStdOffsetTblStdInitialOffsetIndex);
       
   503 	User::LeaveIfError(stdInitialOffsetIdx);	
       
   504 	
       
   505 	// Fetch the row.
       
   506 	User::LeaveIfError(stmt.Next());
       
   507 
       
   508 	TInt stdInitialOffset = stmt.ColumnInt(stdInitialOffsetIdx);
       
   509 	aRules.SetInitialStdTimeOffset(stdInitialOffset);
       
   510 
       
   511 	// This must be the only row.
       
   512 	__ASSERT_ALWAYS(stmt.Next() == KSqlAtEnd, RTz::Panic(RTz::EPanicBadSchema));
       
   513 
       
   514 	CleanupStack::PopAndDestroy(&stmt);	
       
   515 	}
       
   516 
       
   517 CTzUserNames* CTzUserDataDb::ReadTzNamesL(TUint aTzId)
       
   518 	{
       
   519 	if(iBackupInProgress || iRestoreInProgress)
       
   520 		{
       
   521 		User::Leave(KErrLocked);
       
   522 		}
       
   523 
       
   524 	RSqlStatement stmt;
       
   525 	CleanupClosePushL(stmt);	
       
   526 	
       
   527 	TBuf<KSqlStringLength> sqlNames;	
       
   528 	TSqlScalarFullSelectQuery fullSelectQuery(iDatabase);
       
   529 	sqlNames.Format(KSelectNamesCountStmnt, aTzId);
       
   530 	TInt count = fullSelectQuery.SelectIntL(sqlNames);
       
   531 	
       
   532 	if(count == 0)
       
   533 		{
       
   534 		User::Leave(KErrNotFound);
       
   535 		}
       
   536 	
       
   537 	sqlNames.Format(KSelectNamesStmnt, aTzId);
       
   538 	TInt err = stmt.Prepare(iDatabase, sqlNames);
       
   539 	User::LeaveIfError(err);
       
   540 		
       
   541 	TInt stdNameColIdx = stmt.ColumnIndex(KTzNamesTblStdNameIndex);
       
   542 	User::LeaveIfError(stdNameColIdx);
       
   543 
       
   544 	TInt shortStdNameColIdx = stmt.ColumnIndex(KTzNamesTblShortStdNameIndex);
       
   545 	User::LeaveIfError(shortStdNameColIdx);
       
   546 		
       
   547 	TInt dstNameColIdx = stmt.ColumnIndex(KTzNamesTblDSTNameIndex);
       
   548 	User::LeaveIfError(dstNameColIdx);
       
   549 		
       
   550 	TInt shortDstNameColIdx = stmt.ColumnIndex(KTzNamesTblShortDSTNameIndex);
       
   551 	User::LeaveIfError(shortDstNameColIdx);
       
   552 		
       
   553 	TInt cityNameColIdx = stmt.ColumnIndex(KTzNamesTblCityNameIndex);
       
   554 	User::LeaveIfError(cityNameColIdx);
       
   555 	
       
   556    	TInt regionNameColIdx = stmt.ColumnIndex(KTzNamesTblRegionNameIndex);
       
   557 	User::LeaveIfError(regionNameColIdx);
       
   558 	
       
   559    	CTzUserNames* userNames = NULL;
       
   560    	
       
   561 	// Fetch the row.
       
   562    	User::LeaveIfError(stmt.Next());
       
   563 
       
   564 	TPtrC standardName;
       
   565 	standardName.Set(stmt.ColumnTextL(stdNameColIdx));	
       
   566 
       
   567 	TPtrC shortStandardName;
       
   568 	shortStandardName.Set(stmt.ColumnTextL(shortStdNameColIdx));
       
   569 
       
   570 	TPtrC daylightName;
       
   571 	daylightName.Set(stmt.ColumnTextL(dstNameColIdx));
       
   572 
       
   573 	TPtrC shortDaylightName; 
       
   574 	shortDaylightName.Set(stmt.ColumnTextL(shortDstNameColIdx));
       
   575 
       
   576 	TPtrC cityName;
       
   577 	cityName.Set(stmt.ColumnTextL(cityNameColIdx));
       
   578 
       
   579 	TPtrC regionName;
       
   580 	regionName.Set(stmt.ColumnTextL(regionNameColIdx));
       
   581 
       
   582 	userNames = CTzUserNames::NewL(standardName, shortStandardName,
       
   583 		daylightName, shortDaylightName, cityName, regionName);
       
   584 
       
   585 	// This must be the only row.
       
   586 	__ASSERT_ALWAYS(stmt.Next() == KSqlAtEnd, RTz::Panic(RTz::EPanicBadSchema));
       
   587 
       
   588 	CleanupStack::PopAndDestroy(&stmt);
       
   589 
       
   590 	return userNames;
       
   591 	}
       
   592 	
       
   593 void CTzUserDataDb::ReadTzIdsL(RArray<TUint32>& aTzIds)
       
   594 	{
       
   595 	if(iBackupInProgress || iRestoreInProgress )
       
   596 		{
       
   597 		User::Leave(KErrLocked);
       
   598 		}
       
   599 	
       
   600 	RSqlStatement stmt;
       
   601 	CleanupClosePushL(stmt);
       
   602 
       
   603 	TBuf<KSqlStringLength> sqlRule;
       
   604 	sqlRule.Format(KSelectTzIdFromNamesStmnt);
       
   605 	TInt err = stmt.Prepare(iDatabase, sqlRule);
       
   606 	User::LeaveIfError(err);
       
   607 		
       
   608 	while((err = stmt.Next()) == KSqlAtRow)
       
   609 		{
       
   610 		TInt col = stmt.ColumnIndex(KTzNamesTblTzIdIndex);
       
   611 		User::LeaveIfError(col);
       
   612 		TUint id = stmt.ColumnInt64(col);
       
   613 		aTzIds.AppendL(id);
       
   614 		}
       
   615 
       
   616 	CleanupStack::PopAndDestroy(&stmt);
       
   617 	}
       
   618 	
       
   619 void CTzUserDataDb::UpdateTzL(TUint aTzId, const CTzRules& aTzRules, const CTzUserNames& aTzNames)
       
   620 	{	
       
   621 	if(iBackupInProgress || iRestoreInProgress)
       
   622 		{
       
   623 		User::Leave(KErrLocked);
       
   624 		} 
       
   625 		
       
   626 	RSqlStatement stmt;
       
   627 	CleanupClosePushL(stmt);
       
   628 	
       
   629 	BeginTransactionL();	
       
   630 					
       
   631 	TBuf<KSqlStringLength> sqlRules;
       
   632 	sqlRules.Format(KDeleteRulesStmnt, aTzId);
       
   633 	TInt ret = stmt.Prepare(iDatabase, sqlRules);
       
   634 	if(ret == KErrNone)
       
   635 		{
       
   636 		ret = stmt.Exec();
       
   637 		if(ret < KErrNone)
       
   638 			{
       
   639 			User::Leave(ret);
       
   640 			}
       
   641 		}
       
   642 	stmt.Close();
       
   643 	
       
   644 	const TInt count = aTzRules.Count();
       
   645 	for(TInt i=0; i<count; i++)
       
   646 		{
       
   647 		TTzRule& rule = const_cast<CTzRules&>(aTzRules)[i];
       
   648 
       
   649 		User::LeaveIfError(stmt.Prepare(iDatabase, KInsertRulesStmnt));
       
   650 
       
   651 		TInt paramIdx = stmt.ParameterIndex(KTzRulesTblTzIdParam);
       
   652 		User::LeaveIfError(paramIdx);
       
   653 		User::LeaveIfError(stmt.BindInt64(paramIdx, aTzId));
       
   654 
       
   655 		paramIdx = stmt.ParameterIndex(KTzRulesTblRuleTypeParam);
       
   656 		User::LeaveIfError(paramIdx);
       
   657 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iDayRule));
       
   658 
       
   659 		paramIdx = stmt.ParameterIndex(KTzRulesTblDSTStartTimeParam);
       
   660 		User::LeaveIfError(paramIdx);
       
   661 		User::LeaveIfError(stmt.BindInt64(paramIdx, rule.iFrom.iTime.Int64()));
       
   662 
       
   663 		paramIdx = stmt.ParameterIndex(KTzRulesTblDSTStartRefParam);
       
   664 		User::LeaveIfError(paramIdx);
       
   665 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iFrom.iTimeReference));
       
   666 
       
   667 		paramIdx = stmt.ParameterIndex(KTzRulesTblDSTEndTimeParam);
       
   668 		User::LeaveIfError(paramIdx);
       
   669 		User::LeaveIfError(stmt.BindInt64(paramIdx, rule.iTo.iTime.Int64()));
       
   670 
       
   671 		paramIdx = stmt.ParameterIndex(KTzRulesTblDSTEndRefParam);
       
   672 		User::LeaveIfError(paramIdx);
       
   673 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iTo.iTimeReference));
       
   674 
       
   675 		paramIdx = stmt.ParameterIndex(KTzRulesTblOldOffsetParam);
       
   676 		User::LeaveIfError(paramIdx);
       
   677 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iOldLocalTimeOffset));
       
   678 
       
   679 		paramIdx = stmt.ParameterIndex(KTzRulesTblNewOffsetParam);
       
   680 		User::LeaveIfError(paramIdx);
       
   681 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iNewLocalTimeOffset));
       
   682 
       
   683 		paramIdx = stmt.ParameterIndex(KTzRulesTblMonthParam);
       
   684 		User::LeaveIfError(paramIdx);
       
   685 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iMonth));
       
   686 
       
   687 		paramIdx = stmt.ParameterIndex(KTzRulesTblDayParam);
       
   688 		User::LeaveIfError(paramIdx);
       
   689 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iDayOfMonth));
       
   690 
       
   691 		paramIdx = stmt.ParameterIndex(KTzRulesTblWeekParam);
       
   692 		User::LeaveIfError(paramIdx);
       
   693 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iDayOfWeek));
       
   694 
       
   695 		paramIdx = stmt.ParameterIndex(KTzRulesTblTimeRefParam);
       
   696 		User::LeaveIfError(paramIdx);
       
   697 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iTimeReference));
       
   698 
       
   699 		paramIdx = stmt.ParameterIndex(KTzRulesTblMinsParam);
       
   700 		User::LeaveIfError(paramIdx);
       
   701 		User::LeaveIfError(stmt.BindInt(paramIdx, rule.iTimeOfChange));
       
   702 
       
   703 		ret = stmt.Exec();
       
   704 		stmt.Close();
       
   705 		if(ret < KErrNone)
       
   706 			{
       
   707 			User::Leave(ret);
       
   708 			}
       
   709 		}
       
   710 	
       
   711 	TBuf<KSqlStringLength> sqlInitialOffset;
       
   712 	sqlInitialOffset.Format(KDeleteInitialStdOffset, aTzId);
       
   713 	ret = stmt.Prepare(iDatabase, sqlInitialOffset);
       
   714 	if(ret == KErrNone)
       
   715 		{
       
   716 		ret = stmt.Exec();	
       
   717 		stmt.Close();
       
   718 		if(ret < KErrNone)
       
   719 			{
       
   720 			User::Leave(ret);
       
   721 			}
       
   722 		}
       
   723 
       
   724 	User::LeaveIfError(stmt.Prepare(iDatabase, KInsertInitialStdOffsetStmnt));
       
   725 
       
   726 	TInt paramIdx = stmt.ParameterIndex(KTzInitialStdOffsetTblTzIdParam);
       
   727 	User::LeaveIfError(paramIdx);
       
   728 	User::LeaveIfError(stmt.BindInt64(paramIdx, aTzId));
       
   729 
       
   730 	TInt initialOffset = aTzRules.InitialStdTimeOffset();
       
   731 
       
   732 	paramIdx = stmt.ParameterIndex(KTzInitialStdOffsetTblStdInitialOffsetParam);
       
   733 	User::LeaveIfError(paramIdx);
       
   734 	User::LeaveIfError(stmt.BindInt64(paramIdx, initialOffset));
       
   735 
       
   736 	ret = stmt.Exec();
       
   737 	stmt.Close();
       
   738 	if(ret < KErrNone)
       
   739 		{
       
   740 		User::Leave(ret);
       
   741 		}
       
   742 	
       
   743 	TBuf<KSqlStringLength> sqlNames; 
       
   744 	sqlNames.Format(KDeleteNamesStmnt, aTzId);
       
   745 	ret = stmt.Prepare(iDatabase, sqlNames);
       
   746 	if(ret == KErrNone)
       
   747 		{
       
   748 		ret = stmt.Exec();	
       
   749 		if(ret < KErrNone)
       
   750 			{
       
   751 			User::Leave(ret);
       
   752 			}
       
   753 		}
       
   754 	stmt.Close();
       
   755 	
       
   756 	// Insert a row in the names
       
   757 	User::LeaveIfError(stmt.Prepare(iDatabase, KInsertNamesStmnt));
       
   758 
       
   759 	paramIdx = stmt.ParameterIndex(KTzNamesTblTzIdParam);
       
   760 	User::LeaveIfError(paramIdx);
       
   761 	User::LeaveIfError(stmt.BindInt64(paramIdx, aTzId));
       
   762 
       
   763 	paramIdx = stmt.ParameterIndex(KTzNamesTblStdNameParam);
       
   764 	User::LeaveIfError(paramIdx);
       
   765 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.StandardName()));
       
   766 
       
   767 	paramIdx = stmt.ParameterIndex(KTzNamesTblShortStdNameParam);
       
   768 	User::LeaveIfError(paramIdx);
       
   769 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.ShortStandardName()));
       
   770 
       
   771 	paramIdx = stmt.ParameterIndex(KTzNamesTblDSTNameParam);
       
   772 	User::LeaveIfError(paramIdx);
       
   773 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.DaylightSaveName()));
       
   774 
       
   775 	paramIdx = stmt.ParameterIndex(KTzNamesTblShortDSTNameParam);
       
   776 	User::LeaveIfError(paramIdx);
       
   777 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.ShortDaylightSaveName()));
       
   778 
       
   779 	paramIdx = stmt.ParameterIndex(KTzNamesTblCityNameParam);
       
   780 	User::LeaveIfError(paramIdx);
       
   781 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.CityName()));
       
   782 
       
   783 	paramIdx = stmt.ParameterIndex(KTzNamesTblRegionNameParam);
       
   784 	User::LeaveIfError(paramIdx);
       
   785 	User::LeaveIfError(stmt.BindText(paramIdx, aTzNames.RegionName()));
       
   786 
       
   787 	ret = stmt.Exec();
       
   788 	stmt.Close();
       
   789 	if(ret < KErrNone)
       
   790 		{
       
   791 		User::Leave(ret);
       
   792 		}
       
   793 	
       
   794 	CommitTransactionL();
       
   795 
       
   796 	NotifyTzRulesChange(aTzId, ETzUserDataUpdated);
       
   797 	NotifyTzNamesChange(aTzId, ETzUserDataUpdated);
       
   798 	
       
   799 	CleanupStack::PopAndDestroy(&stmt);	
       
   800 	}
       
   801     
       
   802 /**
       
   803 Delete the time zone rule and name from the database that matches aTzId
       
   804 */
       
   805 void CTzUserDataDb::DeleteTzL(TUint aTzId)
       
   806 	{
       
   807 	if(iBackupInProgress || iRestoreInProgress)
       
   808 		{
       
   809 		User::Leave(KErrLocked);
       
   810 		}
       
   811 		
       
   812 	RSqlStatement stmt;
       
   813 	CleanupClosePushL(stmt);
       
   814 	
       
   815 	BeginTransactionL();
       
   816 	
       
   817 	TInt ret;		
       
   818 	TBuf<KSqlStringLength> sqlRules;
       
   819 	sqlRules.Format(KDeleteRulesStmnt, aTzId);
       
   820 	User::LeaveIfError(stmt.Prepare(iDatabase, sqlRules));
       
   821 	ret = stmt.Exec();
       
   822 	stmt.Close();
       
   823 	if(ret < KErrNone)
       
   824 		{
       
   825 		User::Leave(ret);
       
   826 		}
       
   827 	
       
   828 	TBuf<KSqlStringLength> sqlInitialOffset;
       
   829 	sqlInitialOffset.Format(KDeleteInitialStdOffset, aTzId);
       
   830 	ret = stmt.Prepare(iDatabase, sqlInitialOffset);
       
   831 	if(ret == KErrNone)
       
   832 		{
       
   833 		ret = stmt.Exec();	
       
   834 		stmt.Close();
       
   835 		if(ret < KErrNone)
       
   836 			{
       
   837 			User::Leave(ret);
       
   838 			}
       
   839 		}
       
   840 		
       
   841 	TBuf<KSqlStringLength> sqlNames;
       
   842 	sqlNames.Format(KDeleteNamesStmnt, aTzId);
       
   843 	User::LeaveIfError(stmt.Prepare(iDatabase, sqlNames));
       
   844 	ret = stmt.Exec();
       
   845 	stmt.Close();
       
   846 		
       
   847 	if(ret < KErrNone)
       
   848 		{
       
   849 		User::Leave(ret);
       
   850 		}
       
   851 	
       
   852 	CommitTransactionL();
       
   853 
       
   854 	NotifyTzRulesChange(aTzId, ETzUserDataDeleted);
       
   855 	NotifyTzNamesChange(aTzId, ETzUserDataDeleted);	
       
   856 	
       
   857 	CleanupStack::PopAndDestroy(&stmt);
       
   858 	}
       
   859 	
       
   860 void CTzUserDataDb::CleanupDatabaseRollback(TAny *aDatabase)
       
   861 	{
       
   862 	ASSERT(aDatabase);
       
   863 	CTzUserDataDb* db = static_cast<CTzUserDataDb*>(aDatabase);
       
   864 	db->RollbackTransaction();
       
   865 	}
       
   866 	
       
   867 /**
       
   868 Begin a new transation
       
   869 */
       
   870 void CTzUserDataDb::BeginTransactionL()
       
   871 	{
       
   872 	User::LeaveIfError(iDatabase.Exec(KBeginTransaction));
       
   873 	CleanupStack::PushL(TCleanupItem(CleanupDatabaseRollback, this));
       
   874 	}
       
   875 	
       
   876 /**
       
   877 Commit the changes made since the start of a transaction
       
   878 */
       
   879 void CTzUserDataDb::CommitTransactionL()
       
   880 	{
       
   881 	User::LeaveIfError(iDatabase.Exec(KCommitTransaction));
       
   882 	CleanupStack::Pop(); //CleanupDatabaseRollback
       
   883 	}
       
   884 	
       
   885 /**
       
   886 Rollback changes since the start of the transaction
       
   887 */
       
   888 void CTzUserDataDb::RollbackTransaction()
       
   889 	{
       
   890 	iDatabase.Exec(KRollbackTransaction);
       
   891 	}
       
   892 	
       
   893 // Notification operations.
       
   894 void CTzUserDataDb::NotifyTzRulesChange(TUint aTzId, TTzUserDataChangeOp aChangeOp)
       
   895 	{
       
   896 	TTzUserDataChange change;
       
   897 	change.iTzId = aTzId;
       
   898 	change.iOperation = aChangeOp;
       
   899 		
       
   900 	TInt j = 0;
       
   901 	TInt jEnd = iChangeObservers.Count();
       
   902 	while (j < jEnd)
       
   903 		{
       
   904 		iChangeObservers[j]->NotifyUserTzRulesChange(change);
       
   905 		++j;
       
   906 		}
       
   907 	
       
   908 	//Publish ETzRulesChange property to the subscribed clients
       
   909 	NTzUpdate::TTzRulesChange rulesChange;
       
   910 	rulesChange.iUTCTimeOfRulesChange.UniversalTime();
       
   911 	TPckgBuf<NTzUpdate::TTzRulesChange> bufRules(rulesChange);
       
   912 	RProperty::Set(NTzUpdate::KPropertyCategory, NTzUpdate::ETzRulesChange, bufRules);
       
   913 	}
       
   914     
       
   915 void CTzUserDataDb::NotifyTzNamesChange(TUint aTzId, TTzUserDataChangeOp aChangeOp)
       
   916 	{
       
   917 	TTzUserDataChange change;
       
   918 	change.iTzId = aTzId;
       
   919 	change.iOperation = aChangeOp;
       
   920 	
       
   921 	TInt j = 0;
       
   922 	TInt jEnd = iChangeObservers.Count();
       
   923 	while (j < jEnd)
       
   924 		{
       
   925 		iChangeObservers[j]->NotifyUserTzNamesChange(change);
       
   926 		++j;
       
   927 		}
       
   928 	
       
   929 	//Publish ETzNamesChange property to the subscribed clients
       
   930 	NTzUpdate::TTzNamesChange namesChange;
       
   931 	namesChange.iUTCTimeOfNamesChange.UniversalTime();
       
   932 	TPckgBuf<NTzUpdate::TTzNamesChange> bufNames(namesChange);
       
   933 	RProperty::Set(NTzUpdate::KPropertyCategory, NTzUpdate::ETzNamesChange, bufNames);	
       
   934 	}
       
   935 
       
   936  // Backup and restore operations
       
   937 void CTzUserDataDb::BackupBeginningL()
       
   938 	{
       
   939 	Close();
       
   940 	iBackupInProgress = ETrue;
       
   941 	}
       
   942 
       
   943 void CTzUserDataDb::BackupCompletedL()
       
   944 	{
       
   945 	OpenL();
       
   946 	iBackupInProgress = EFalse;
       
   947 	}
       
   948 
       
   949 void CTzUserDataDb::RestoreBeginningL()
       
   950 	{
       
   951 	Close();
       
   952 	iRestoreInProgress = ETrue;
       
   953 	}
       
   954 
       
   955 void CTzUserDataDb::RestoreCompletedL()
       
   956 	{
       
   957 	OpenL();		
       
   958 	iRestoreInProgress = EFalse;
       
   959 	}
       
   960 
       
   961 void CTzUserDataDb::AddObserverL(MTzUserDataChangeObserver* aChangeObs)
       
   962 	{
       
   963 	User::LeaveIfError(iChangeObservers.Append(aChangeObs));
       
   964 	}
       
   965 
       
   966 void CTzUserDataDb::RemoveObserver(MTzUserDataChangeObserver* aChangeObs)
       
   967 	{
       
   968 	TInt j = 0;
       
   969 	TInt jEnd = iChangeObservers.Count();
       
   970 	while (j < jEnd)
       
   971 		{
       
   972 		if (iChangeObservers[j] == aChangeObs)
       
   973 			{
       
   974 			iChangeObservers.Remove(j);
       
   975 			break;
       
   976 			}
       
   977 		++j;
       
   978 		}
       
   979 	}
       
   980 /**
       
   981 Checks if aTzId exists in the user timezone database
       
   982 */
       
   983 TBool CTzUserDataDb::IsIdInDbL(TUint aTzId)
       
   984 	{
       
   985 	TBuf<KSqlStringLength> sqlNames;
       
   986 	TSqlScalarFullSelectQuery fullSelectQuery(iDatabase);
       
   987 	sqlNames.Format(KSelectTzIdCountFromNamesStmnt, aTzId);
       
   988 	
       
   989 	TInt count = fullSelectQuery.SelectIntL(sqlNames);
       
   990 	if(count == 0)
       
   991 		{
       
   992 		return EFalse;
       
   993 		}		
       
   994 	return ETrue;
       
   995 	}
       
   996 /**
       
   997 Find the next unused id in the database. If all ids have been used
       
   998 KOutOfBoundsUserId will be returned
       
   999 */
       
  1000 TUint32 CTzUserDataDb::FindUnusedTzIdL()
       
  1001 	{
       
  1002 	RArray<TUint32> ids;
       
  1003 	CleanupClosePushL(ids);
       
  1004 	ReadTzIdsL(ids);
       
  1005 	const TInt count = ids.Count();
       
  1006 	TUint foundId = KOutOfBoundsUserId;
       
  1007 	if(count > 0)
       
  1008 		{
       
  1009 		ids.SortSigned();
       
  1010 	
       
  1011 		for(TInt i=0; i<count-1; i++)
       
  1012 			{
       
  1013 			if(ids[i]+1 != ids[i+1])
       
  1014 				{
       
  1015 				foundId = ids[i]+1;
       
  1016 				break;
       
  1017 				}
       
  1018 			}
       
  1019 		}
       
  1020 	CleanupStack::PopAndDestroy(&ids);
       
  1021 	return foundId;
       
  1022 	}