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