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