loggingservices/eventlogger/LogServ/src/LogServDatabaseMarshall.cpp
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2002-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 <logclientchangeobserver.h>
       
    17 #include "LogServDatabaseMarshall.h"
       
    18 #include "logservpanic.h"
       
    19 #include "LogServCacheConfig.h"
       
    20 #include "LogServCacheStrings.h"
       
    21 #include "LogServCacheTypes.h"
       
    22 #include "LogServBackupInterface.h"
       
    23 #include "LogServResourceInterpreter.h"
       
    24 #include "LogServDatabaseChangeInterface.h"
       
    25 #include <logserv.rsg>
       
    26 #include "LogServSqlStrings.h"
       
    27 #include "LOGREPDEFS.H"
       
    28 
       
    29 
       
    30 // Constants
       
    31 const TInt KExpectedNumberOfTables = 4; // Should match the code in CreateTablesL
       
    32 
       
    33 // Literal constants
       
    34 _LIT(KLogDatabaseName,"Logdbu.dat");
       
    35 
       
    36 
       
    37 
       
    38 /////////////////////////////////////////////////////////////////////////////////////////
       
    39 // -----> CLogServDatabaseMarshall (source)
       
    40 /////////////////////////////////////////////////////////////////////////////////////////
       
    41 
       
    42 CLogServDatabaseMarshall::CLogServDatabaseMarshall(RFs& aFsSession, 
       
    43 												   CLogServResourceInterpreter& aResourceInterface, 
       
    44 												   MLogServBackupInterface& aBackupInterface)
       
    45 :	iFsSession(aFsSession), iResourceInterface(aResourceInterface), iBackupInterface(aBackupInterface)
       
    46 	{
       
    47 	}
       
    48 
       
    49 CLogServDatabaseMarshall::~CLogServDatabaseMarshall()
       
    50 	{
       
    51 	iBackupInterface.BIObserverRemove(*this);
       
    52 	//
       
    53 	delete iDatabaseName;
       
    54 	delete iCacheStrings;
       
    55 	delete iCacheTypes;
       
    56 	delete iCacheConfig;
       
    57 	delete iSecurity;
       
    58 	delete iEventType;
       
    59 	//
       
    60 	iDatabase.Close();
       
    61 	iStandardTypeUids.Close();
       
    62 	}
       
    63 
       
    64 void CLogServDatabaseMarshall::ConstructL()
       
    65 	{
       
    66 	iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectDatabaseMarshall);
       
    67 	//
       
    68 	iSecurity = CLogServSecurity::NewL(iResourceInterface);
       
    69 	//
       
    70 	iEventType = CLogEventType::NewL();
       
    71 	
       
    72 	DatabaseLocateL();
       
    73 	DatabaseOpenL();
       
    74 	RestoreStandardTypesL();
       
    75 	
       
    76 	iCacheTypes->CopyStandardTypeUidsL(iStandardTypeUids);
       
    77 	}
       
    78 
       
    79 CLogServDatabaseMarshall* CLogServDatabaseMarshall::NewL(RFs& aFsSession, 
       
    80 														 CLogServResourceInterpreter& aResourceInterface, 
       
    81 														 MLogServBackupInterface& aBackupInterface)
       
    82 	{
       
    83 	CLogServDatabaseMarshall* self = new(ELeave) CLogServDatabaseMarshall(aFsSession, aResourceInterface, aBackupInterface);
       
    84 	CleanupStack::PushL(self);
       
    85 	self->ConstructL();
       
    86 	CleanupStack::Pop(self);
       
    87 	return self;
       
    88 	}
       
    89 
       
    90 /////////////////////////////////////////////////////////////////////////////////////////
       
    91 /////////////////////////////////////////////////////////////////////////////////////////
       
    92 /////////////////////////////////////////////////////////////////////////////////////////
       
    93 
       
    94 TInt CLogServDatabaseMarshall::DTIBegin()
       
    95 	{
       
    96 	const TInt backupError = iBackupInterface.BIErrorValueForCurrentState();
       
    97 	if	(backupError != KErrNone)
       
    98 		return backupError;
       
    99 
       
   100 	__ASSERT_DEBUG(!iDatabase.InTransaction(), Panic(ELogBeginInTransaction));
       
   101 	return iDatabase.Begin();
       
   102 	}
       
   103 
       
   104 TInt CLogServDatabaseMarshall::DTICommitAndEnd()
       
   105 	{
       
   106 	__ASSERT_DEBUG(iDatabase.InTransaction(), Panic(ELogCommitNotInTransaction));
       
   107 	TInt err = iDatabase.Commit();
       
   108 	if (err == KErrNone && iCacheStrings != NULL)
       
   109 		{
       
   110 		iCacheStrings->Commit();
       
   111 		}
       
   112 	return err;
       
   113 	}
       
   114 
       
   115 void CLogServDatabaseMarshall::DTIRollBack()
       
   116 	{
       
   117 	__ASSERT_DEBUG(iDatabase.InTransaction(), Panic(ELogRollbackNotInTransaction));
       
   118 	iDatabase.Rollback();
       
   119 	if (iCacheStrings != NULL)
       
   120 		{
       
   121 		iCacheStrings->Rollback();
       
   122 		}
       
   123 	}
       
   124 
       
   125 TInt CLogServDatabaseMarshall::DTIExecuteSql(const TDesC& aStatement, TDbTextComparison aComparison)
       
   126 	{
       
   127 	return iDatabase.Execute(aStatement, aComparison);
       
   128 	}
       
   129 
       
   130 TBool CLogServDatabaseMarshall::DTIInTransaction() const
       
   131 	{
       
   132 	return iDatabase.InTransaction();
       
   133 	}
       
   134 
       
   135 TBool CLogServDatabaseMarshall::DTIDatabaseIsDamaged() const
       
   136 	{
       
   137 	return iDatabase.IsDamaged();
       
   138 	}
       
   139 
       
   140 CLogServResourceInterpreter& CLogServDatabaseMarshall::DTIResourceInterface() const
       
   141 	{
       
   142 	return iResourceInterface;
       
   143 	}
       
   144 
       
   145 MLogServDatabaseChangeInterface& CLogServDatabaseMarshall::DTIChangeInterface() const
       
   146 	{
       
   147 	__ASSERT_ALWAYS(iChangeInterface, Panic(ELogNoChangeInterfacePointer));
       
   148 	return *iChangeInterface;
       
   149 	}
       
   150 
       
   151 CLogServCacheStrings& CLogServDatabaseMarshall::DTICacheStrings() const
       
   152 	{
       
   153 	__ASSERT_ALWAYS(iCacheStrings, Panic(ELogCacheAccessDuringBackupStrings));
       
   154 	return *iCacheStrings;
       
   155 	}
       
   156 
       
   157 CLogServCacheTypes& CLogServDatabaseMarshall::DTICacheTypes() const
       
   158 	{
       
   159 	__ASSERT_ALWAYS(iCacheTypes, Panic(ELogCacheAccessDuringBackupTypes));
       
   160 	return *iCacheTypes;
       
   161 	}
       
   162 
       
   163 CLogServCacheConfig& CLogServDatabaseMarshall::DTICacheConfig() const
       
   164 	{
       
   165 	__ASSERT_ALWAYS(iCacheConfig, Panic(ELogCacheAccessDuringBackupConfig));
       
   166 	return *iCacheConfig;
       
   167 	}
       
   168 
       
   169 RDbDatabase& CLogServDatabaseMarshall::DTIDatabase()
       
   170 	{
       
   171 	return iDatabase;
       
   172 	}
       
   173 
       
   174 TBool CLogServDatabaseMarshall::DTIIsAllowed(TEventOp aEventOp, const RMessage2& aMessage, TUid aEventType, const char* aDiagnostic) const
       
   175 	{
       
   176 	return iSecurity->IsAllowed(aMessage, aEventType, aEventOp, aDiagnostic);
       
   177 	}
       
   178 	
       
   179 const RArray<TUid>& CLogServDatabaseMarshall::DTIUidsOfStandardTypes()
       
   180 	{
       
   181 	return iStandardTypeUids;
       
   182 	}
       
   183 
       
   184 /////////////////////////////////////////////////////////////////////////////////////////
       
   185 /////////////////////////////////////////////////////////////////////////////////////////
       
   186 /////////////////////////////////////////////////////////////////////////////////////////
       
   187 
       
   188 void CLogServDatabaseMarshall::BOHandleEventL(TLogServBackupEvent aEvent)
       
   189 	{
       
   190 	switch(aEvent)
       
   191 		{
       
   192 		case EBackupStarting:
       
   193 			{
       
   194 			//Destroy config, types and strings caches
       
   195 			delete iCacheConfig;
       
   196 			iCacheConfig = NULL;
       
   197 			delete iCacheStrings;
       
   198 			iCacheStrings = NULL;
       
   199 			delete iCacheTypes;
       
   200 			iCacheTypes = NULL;
       
   201 			//Close the database
       
   202 			iDatabase.Close();
       
   203 			}
       
   204 			break;
       
   205 			
       
   206 		case EBackupEnded:
       
   207 			{
       
   208 			// Re-open the database and create config, types and strings caches 
       
   209 			DatabaseOpenL();
       
   210 			// reset views as a different database is being restored
       
   211 			DTIChangeInterface().DCISubmitGlobalChangeContextL(KLogClientChangeEventRefreshView);
       
   212 			}
       
   213 			break;
       
   214 		default:
       
   215 			break;
       
   216 		}
       
   217 	}
       
   218 
       
   219 /////////////////////////////////////////////////////////////////////////////////////////
       
   220 /////////////////////////////////////////////////////////////////////////////////////////
       
   221 /////////////////////////////////////////////////////////////////////////////////////////
       
   222 
       
   223 void CLogServDatabaseMarshall::DatabaseLocateL()
       
   224 	{
       
   225 	// Get drive for database
       
   226 	TDriveUnit driveUnit(static_cast<TInt>(RFs::GetSystemDrive()));
       
   227 	TDriveName name(driveUnit.Name());
       
   228 	
       
   229 	TFileName path;
       
   230 	iFsSession.PrivatePath(path);
       
   231 	
       
   232 	// Ensure database path exists
       
   233 	TParse parse;
       
   234 	User::LeaveIfError(parse.Set(path, &name, NULL));
       
   235 	path = parse.FullName();
       
   236 	
       
   237 	TInt error = iFsSession.MkDirAll(path);
       
   238 	if	(error != KErrAlreadyExists)
       
   239 		User::LeaveIfError(error);
       
   240 	
       
   241 	path += KLogDatabaseName;
       
   242 	iDatabaseName = path.AllocL();
       
   243 	}
       
   244 
       
   245 /**
       
   246 Opens the LogEng database.
       
   247 @return KErrNone,    If the "database open" operation completes successfully.
       
   248                      If the "database open" operation fails the function returns the repported error code. 
       
   249         KErrCorrupt, If the database is opened successfully but is damaged, then the function returns KErrCorrupt.
       
   250 */
       
   251 TInt CLogServDatabaseMarshall::DoDbOpen()
       
   252     {
       
   253     LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - attempting to open db: %S", iDatabaseName);
       
   254 #ifdef LOGGING_ENABLED
       
   255     TEntry entry;
       
   256     if  (iFsSession.Entry(*iDatabaseName, entry) == KErrNone)
       
   257         {
       
   258         LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Database file: %S DOES exist", iDatabaseName);        
       
   259         }
       
   260     else
       
   261         {
       
   262         LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Database file: %S NOT FOUND", iDatabaseName);     
       
   263         }
       
   264 #endif
       
   265     // Open database
       
   266     TInt err = iDatabase.Open(iFsSession, DatabaseName());
       
   267     LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - attempting to open DMBS database resulted in error: %d", error);
       
   268     // Check if the database is damaged. If it is set the error to KErrCorrupt so that it 
       
   269     // will be deleted.
       
   270     if ((err == KErrNone) && iDatabase.IsDamaged()) 
       
   271         {
       
   272         err =  KErrCorrupt;
       
   273         }
       
   274     return err;
       
   275     }
       
   276 
       
   277 /**
       
   278 Check if the database table count is the expected one -  KExpectedNumberOfTables.
       
   279 @return True,   The database tables count is KExpectedNumberOfTables,
       
   280         False,  The database tables count is not KExpectedNumberOfTables;
       
   281 @leave  KErrNoMemory, an out of memory condition has occurred;
       
   282                       Note that the function may leave with database specific errors or 
       
   283                       other system-wide error codes.
       
   284 */
       
   285 TBool CLogServDatabaseMarshall::DbTableCntCheckL()
       
   286     {
       
   287     CDbTableNames* tables = iDatabase.TableNamesL();
       
   288     TInt numberOfTables = tables->Count();
       
   289     delete tables;
       
   290     LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Number of tables: %d", numberOfTables);
       
   291     return numberOfTables == KExpectedNumberOfTables;
       
   292     }
       
   293 
       
   294 /**
       
   295 Alters the "Event" table if the number column length is not KLogMaxNumberLength.
       
   296 @return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.  
       
   297 */
       
   298 TInt CLogServDatabaseMarshall::AlterEventTblIfOldFmt(CDbColSet& aEventTblColSet)
       
   299     {
       
   300     const TDbCol* numberCol = aEventTblColSet.Col(KLogFieldEventNumberString);
       
   301     __ASSERT_DEBUG(numberCol != NULL, User::Invariant());
       
   302     TInt err = KErrNone;
       
   303     // check the column width is correct
       
   304     if(numberCol->iMaxLength != KLogMaxNumberLength)
       
   305         {
       
   306         //The column width is not correct, so this is an old format database.
       
   307         //Modify the database so the number length is KLogMaxNumberLength.
       
   308         (const_cast <TDbCol*> (numberCol))->iMaxLength = KLogMaxNumberLength;
       
   309         err = iDatabase.AlterTable(KLogNameEventString, aEventTblColSet);
       
   310         }
       
   311     return err;
       
   312     }
       
   313 
       
   314 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM	
       
   315 
       
   316 /**
       
   317 Alters the "Event" table if the the table does not have "SimId" column.
       
   318 @return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.  
       
   319 @leave  KErrNoMemory, an out of memory condition has occurred;
       
   320                       Some other failure codes, not related to the "alter" opertaion.
       
   321 */
       
   322 TInt CLogServDatabaseMarshall::AlterEventTblIfNoSimIdL(CDbColSet& aEventTblColSet)
       
   323     {//Compiled only when SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM macro is defined
       
   324     const TDbCol* simIdCol = aEventTblColSet.Col(KLogFieldEventSimId);
       
   325     TInt err = KErrNone;
       
   326     if(!simIdCol)
       
   327         {
       
   328         TDbCol col(KLogFieldEventSimId, EDbColUint32);
       
   329         aEventTblColSet.AddL(col);
       
   330         err = iDatabase.AlterTable(KLogNameEventString, aEventTblColSet);
       
   331         }
       
   332     return err;
       
   333     }
       
   334 
       
   335 #endif
       
   336 
       
   337 /**
       
   338 Checks the database structure and alters the tables if that's an old format database.
       
   339 @return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.
       
   340 @leave  KErrNoMemory, an out of memory condition has occurred;
       
   341                       Some other failure codes, not related to the "alter" opertaion.
       
   342 */
       
   343 TInt CLogServDatabaseMarshall::AlterDbIfOldFmtL()
       
   344     {
       
   345     CDbColSet* tableEventCol = iDatabase.ColSetL(KLogNameEventString);
       
   346     CleanupStack::PushL(tableEventCol);
       
   347     //Check for old format database which had MaxNumberLength =32
       
   348     TInt err = AlterEventTblIfOldFmt(*tableEventCol);
       
   349 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM	
       
   350     //Check if the "SimId" column is present
       
   351     if(err == KErrNone)
       
   352         {
       
   353         err = AlterEventTblIfNoSimIdL(*tableEventCol);
       
   354         }
       
   355 #endif    
       
   356     CleanupStack::PopAndDestroy(tableEventCol);
       
   357     return err;
       
   358     }
       
   359 
       
   360 /**
       
   361 Closes and deletes the LogEng database. In _DEBUG builds the "delete file" error will be printed out. 
       
   362 */
       
   363 void CLogServDatabaseMarshall::DbDelete()
       
   364     {
       
   365     iDatabase.Close();
       
   366 #ifdef _DEBUG       
       
   367 	//Do not remove the statement bellow. In _DEBUG builds it forms a single "TInt err2 = iFsSession.Delete(DatabaseName());" statement.
       
   368     TInt err2 =
       
   369 #endif      
       
   370     iFsSession.Delete(DatabaseName());
       
   371 #ifdef _DEBUG
       
   372     if((err2 != KErrNone) && (err2 != KErrNotFound))
       
   373         {
       
   374         RDebug::Print(_L("CLogServDatabaseMarshall::DatabaseOpenL() - Failed to delete file. Error = %d"), err2);
       
   375         }
       
   376 #endif
       
   377     }
       
   378 
       
   379 /**
       
   380 Attempts to create the LogEng database and tables.
       
   381 @return   KErrNoNone, The database was created successfully, system wide or database specific error otherwise.
       
   382 */
       
   383 TInt CLogServDatabaseMarshall::DbCreate()
       
   384     {
       
   385     // Try and create the database
       
   386     LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - trying to create database");
       
   387     TRAPD(err, DatabaseCreateL(DatabaseName()));
       
   388     LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - creation error was: %d", error);
       
   389     return err;
       
   390     }
       
   391 
       
   392 /**
       
   393 Creates config and string LogEng caches. Finishes the initialization of the event types cache. 
       
   394 @leave  KErrNoMemory, an out of memory condition has occurred;
       
   395                       Note that the function may leave with database specific errors or 
       
   396                       other system-wide error codes.
       
   397 */
       
   398 void CLogServDatabaseMarshall::CreateCachesL()
       
   399     {
       
   400     // Create other cache objects (these require the database to be already opened)
       
   401     LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating config cache");
       
   402     iCacheConfig = CLogServCacheConfig::NewL(*this);
       
   403     LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating string cache");
       
   404     iCacheStrings = CLogServCacheStrings::NewL(*this);
       
   405     // Finish the type cache initialization
       
   406     LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - initializing type cache");
       
   407     iCacheTypes->InitializeL();
       
   408     }
       
   409 
       
   410 void CLogServDatabaseMarshall::DatabaseOpenL()
       
   411 	{
       
   412 	// Create the cache objects - objects need to be put into the cache as
       
   413 	// soon as the database is open.
       
   414 	LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating type cache");
       
   415 	iCacheTypes = CLogServCacheTypes::NewL(*this);
       
   416 	TInt err = DoDbOpen();
       
   417 	// Check we have the expected number of tables
       
   418 	if(err == KErrNone && !DbTableCntCheckL())
       
   419 		{
       
   420 	    err = KErrCorrupt;
       
   421 		}
       
   422     // Check a compaction can be performed. If it can't it indicates a serious problem?
       
   423     if(err == KErrNone && (err = iDatabase.Compact()) != KErrNone)
       
   424        {
       
   425        err = KErrCorrupt;
       
   426        }
       
   427 	if(err == KErrNone)
       
   428 		{
       
   429 		err = CLogServDatabaseMarshall::AlterDbIfOldFmtL();
       
   430 		}
       
   431 	// If the database failed to open, delete and recreate.
       
   432 	if(err == KErrNotFound || err == KErrCorrupt || err == KErrArgument || err == KErrEof)
       
   433 		{
       
   434 		DbDelete();
       
   435 		// Try and create the database
       
   436 		err = DbCreate();
       
   437 	    if(err != KErrNone)
       
   438 	        {
       
   439 	        DbDelete();
       
   440 	        }
       
   441 		}
       
   442 	User::LeaveIfError(err);
       
   443 	CreateCachesL();
       
   444     // At this point, its safe to tell the backup interface what file it has to watch
       
   445     LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - registering database filename with backup interface");
       
   446     iBackupInterface.BISetDatabaseNameL(DatabaseName());
       
   447 	LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - end");
       
   448 	}
       
   449 
       
   450 void CLogServDatabaseMarshall::DatabaseCreateL(const TDesC& aName)
       
   451 	{
       
   452 	User::LeaveIfError(iDatabase.Replace(iFsSession, aName));
       
   453 	CreateTablesL();
       
   454 	}
       
   455 
       
   456 // Note: Number of tables HAS to match KExpectedNumberOfTables
       
   457 void CLogServDatabaseMarshall::CreateTablesL()
       
   458 	{
       
   459 	DTIBeginWithRollBackProtectionLC();
       
   460 
       
   461 	// Create event table
       
   462 	TheSql.Format(KLogTableEventString, KLogMaxRemotePartyLength, KLogMaxSubjectLength, KLogMaxNumberLength);
       
   463 	User::LeaveIfError(iDatabase.Execute(TheSql));
       
   464 	MakeColumnAutoIncremetingL(KLogNameEventString, KLogFieldIdString);
       
   465 
       
   466 	// Create event type table
       
   467 	TheSql.Format(KLogTableTypeString, KLogMaxDescriptionLength);
       
   468 	User::LeaveIfError(iDatabase.Execute(TheSql));
       
   469 	MakeColumnAutoIncremetingL(KLogNameTypeString, KLogFieldIdString);
       
   470 
       
   471 	// Create string list table
       
   472 	TheSql.Format(KLogTableStringString, KLogMaxSharedStringLength);
       
   473 	User::LeaveIfError(iDatabase.Execute(TheSql));
       
   474 	MakeColumnAutoIncremetingL(KLogNameStringString, KLogFieldIdString);
       
   475 
       
   476 	// Create configuration table
       
   477 	TheSql.Copy(KLogTableConfigString);
       
   478 	User::LeaveIfError(iDatabase.Execute(TheSql));
       
   479 
       
   480 	// Create the index
       
   481 	CreateIndiciesL();
       
   482 
       
   483 	// Set the initial configuration
       
   484 	CreateConfigurationL();
       
   485 
       
   486 	// Load standard event types
       
   487 	CreateTypesL();
       
   488 
       
   489 	DTICommitAndCancelRollbackProtectionL();
       
   490 	}
       
   491 
       
   492 void CLogServDatabaseMarshall::CreateTypesL(TBool aReadOnly)
       
   493 	{
       
   494 	// Get the array size
       
   495 	TResourceReader reader;
       
   496 	iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INITIAL_EVENTS, CLogServResourceInterpreter::ELogWrap);
       
   497 
       
   498 	// Create them
       
   499 	DTICacheTypes().CreateStandardTypesL(reader, aReadOnly);
       
   500 
       
   501 	CleanupStack::PopAndDestroy(); // reader
       
   502 	}
       
   503 
       
   504 void CLogServDatabaseMarshall::CreateIndiciesL()
       
   505 	{
       
   506 	// Get the array size
       
   507 	TResourceReader reader;
       
   508 	iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INDEXES, CLogServResourceInterpreter::ELogWrap);
       
   509 
       
   510 	const TInt indexes = reader.ReadInt16();
       
   511 
       
   512 	// Read in the array
       
   513 	for(TInt c1 = 0; c1 < indexes; c1++)
       
   514 		{
       
   515 		const TPtrC name(reader.ReadTPtrC());
       
   516 		const TPtrC table(reader.ReadTPtrC());
       
   517 
       
   518 		// Get the number of keys
       
   519 		const TInt keys = reader.ReadInt16();
       
   520 
       
   521 		CDbKey* key = CDbKey::NewLC();
       
   522 
       
   523 		for(TInt c2 = 0; c2 < keys; c2++)
       
   524 			{
       
   525 			TPtrC col = reader.ReadTPtrC();
       
   526 			TUint order = reader.ReadUint16();
       
   527 			TInt len = reader.ReadInt16();
       
   528 
       
   529 			// Add the key
       
   530 			key->AddL(TDbKeyCol(col, len, (TDbKeyCol::TOrder)order));
       
   531 			}
       
   532 
       
   533 		// Make key unique if required
       
   534 		if (reader.ReadInt8())
       
   535 			key->MakeUnique();
       
   536 
       
   537 		// Set comparison
       
   538 		const TDbTextComparison comparison = static_cast<TDbTextComparison>(reader.ReadInt8());
       
   539 		key->SetComparison(comparison);
       
   540 
       
   541 		// Create the index
       
   542 		User::LeaveIfError(iDatabase.CreateIndex(name, table, *key));
       
   543 
       
   544 		CleanupStack::PopAndDestroy(key);
       
   545 		}
       
   546 
       
   547 	CleanupStack::PopAndDestroy(); // reader
       
   548 	}
       
   549 
       
   550 void CLogServDatabaseMarshall::CreateConfigurationL()
       
   551 	{
       
   552 	// Load the resource/repository file default configuration
       
   553 	// The precedence is given to the reading from the repository file.
       
   554    	TLogConfig config;
       
   555 	
       
   556 	CRepository* repository = NULL;
       
   557 	TRAPD(res, repository = CRepository::NewL(KUidLogengRepository));		
       
   558 	if (res == KErrNone)
       
   559 		{
       
   560 		CleanupStack::PushL(repository);
       
   561 		ReadRepositoryFileConfigurationL(config, *repository);
       
   562 		CleanupStack::PopAndDestroy(repository);
       
   563 		}
       
   564 	else if (res == KErrCorrupt)
       
   565 		{
       
   566 		User::Leave(res);
       
   567 		}
       
   568 	else
       
   569 		{
       
   570 		ReadResourceFileConfigurationL(config);
       
   571 		}	
       
   572    	// Insert the column
       
   573    	TheSql.Format(KLogSqlInsertConfigString, config.iMaxLogSize, config.iMaxRecentLogSize, config.iMaxEventAge);
       
   574 	User::LeaveIfError(iDatabase.Execute(TheSql));
       
   575 	}
       
   576 
       
   577 void CLogServDatabaseMarshall::ReadRepositoryFileConfigurationL(TLogConfig& aConfig, CRepository& repository) const
       
   578 	{
       
   579 	TInt maxLogSize;
       
   580 	TInt maxRecentLogSize;
       
   581 	TInt maxEventAge;
       
   582 	//	
       
   583 	User::LeaveIfError(repository.Get(KMaxLogSizeRepKey, maxLogSize));
       
   584 	aConfig.iMaxLogSize = static_cast<TLogSize> (maxLogSize);
       
   585 	User::LeaveIfError(repository.Get(KMaxRecentLogSizeRepKey, maxRecentLogSize));
       
   586 	aConfig.iMaxRecentLogSize = static_cast<TLogRecentSize> (maxRecentLogSize);
       
   587 	User::LeaveIfError(repository.Get(KMaxEventAgeRepKey, maxEventAge));
       
   588 	aConfig.iMaxEventAge = static_cast<TLogAge> (maxEventAge);	
       
   589 	}
       
   590 
       
   591 void CLogServDatabaseMarshall::ReadResourceFileConfigurationL(TLogConfig& aConfig) const
       
   592 	{	
       
   593 	TResourceReader reader;
       
   594 	iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INITIAL_CONFIG, CLogServResourceInterpreter::ELogWrap);
       
   595 	//
       
   596 	aConfig.iMaxLogSize = static_cast<TLogSize>(reader.ReadUint16());
       
   597 	aConfig.iMaxRecentLogSize = static_cast<TLogRecentSize>(reader.ReadUint8());
       
   598 	aConfig.iMaxEventAge = static_cast<TLogAge>(reader.ReadUint32());
       
   599 	//
       
   600 	CleanupStack::PopAndDestroy(); // reader	
       
   601 	}
       
   602 
       
   603 void CLogServDatabaseMarshall::MakeColumnAutoIncremetingL(const TDesC& aTable, const TDesC& aColumn)
       
   604 	{
       
   605 	CDbColSet* newTable = iDatabase.ColSetL(aTable);
       
   606 	CleanupStack::PushL(newTable);
       
   607 
       
   608 	const TDbCol* oldCol = newTable->Col(aColumn);
       
   609 	__ASSERT_DEBUG(oldCol != NULL, Panic(ELogNoSuchColumn));
       
   610 
       
   611 	TDbCol newCol = *oldCol;
       
   612 	newCol.iAttributes |= TDbCol::EAutoIncrement;
       
   613 
       
   614 	newTable->Remove(aColumn);
       
   615 	newTable->AddL(newCol);
       
   616 
       
   617 	User::LeaveIfError(iDatabase.DropTable(aTable));
       
   618 	User::LeaveIfError(iDatabase.CreateTable(aTable, *newTable));
       
   619 		
       
   620 	CleanupStack::PopAndDestroy(newTable);
       
   621 	}
       
   622