os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServDatabaseMarshall.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServDatabaseMarshall.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,621 @@
1.4 +// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <logclientchangeobserver.h>
1.20 +#include "LogServDatabaseMarshall.h"
1.21 +#include "logservpanic.h"
1.22 +#include "LogServCacheConfig.h"
1.23 +#include "LogServCacheStrings.h"
1.24 +#include "LogServCacheTypes.h"
1.25 +#include "LogServBackupInterface.h"
1.26 +#include "LogServResourceInterpreter.h"
1.27 +#include "LogServDatabaseChangeInterface.h"
1.28 +#include "LogServSqlStrings.h"
1.29 +#include "LOGREPDEFS.H"
1.30 +
1.31 +
1.32 +// Constants
1.33 +const TInt KExpectedNumberOfTables = 4; // Should match the code in CreateTablesL
1.34 +
1.35 +// Literal constants
1.36 +_LIT(KLogDatabaseName,"Logdbu.dat");
1.37 +
1.38 +
1.39 +
1.40 +/////////////////////////////////////////////////////////////////////////////////////////
1.41 +// -----> CLogServDatabaseMarshall (source)
1.42 +/////////////////////////////////////////////////////////////////////////////////////////
1.43 +
1.44 +CLogServDatabaseMarshall::CLogServDatabaseMarshall(RFs& aFsSession,
1.45 + CLogServResourceInterpreter& aResourceInterface,
1.46 + MLogServBackupInterface& aBackupInterface)
1.47 +: iFsSession(aFsSession), iResourceInterface(aResourceInterface), iBackupInterface(aBackupInterface)
1.48 + {
1.49 + }
1.50 +
1.51 +CLogServDatabaseMarshall::~CLogServDatabaseMarshall()
1.52 + {
1.53 + iBackupInterface.BIObserverRemove(*this);
1.54 + //
1.55 + delete iDatabaseName;
1.56 + delete iCacheStrings;
1.57 + delete iCacheTypes;
1.58 + delete iCacheConfig;
1.59 + delete iSecurity;
1.60 + delete iEventType;
1.61 + //
1.62 + iDatabase.Close();
1.63 + iStandardTypeUids.Close();
1.64 + }
1.65 +
1.66 +void CLogServDatabaseMarshall::ConstructL()
1.67 + {
1.68 + iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectDatabaseMarshall);
1.69 + //
1.70 + iSecurity = CLogServSecurity::NewL(iResourceInterface);
1.71 + //
1.72 + iEventType = CLogEventType::NewL();
1.73 +
1.74 + DatabaseLocateL();
1.75 + DatabaseOpenL();
1.76 + RestoreStandardTypesL();
1.77 +
1.78 + iCacheTypes->CopyStandardTypeUidsL(iStandardTypeUids);
1.79 + }
1.80 +
1.81 +CLogServDatabaseMarshall* CLogServDatabaseMarshall::NewL(RFs& aFsSession,
1.82 + CLogServResourceInterpreter& aResourceInterface,
1.83 + MLogServBackupInterface& aBackupInterface)
1.84 + {
1.85 + CLogServDatabaseMarshall* self = new(ELeave) CLogServDatabaseMarshall(aFsSession, aResourceInterface, aBackupInterface);
1.86 + CleanupStack::PushL(self);
1.87 + self->ConstructL();
1.88 + CleanupStack::Pop(self);
1.89 + return self;
1.90 + }
1.91 +
1.92 +/////////////////////////////////////////////////////////////////////////////////////////
1.93 +/////////////////////////////////////////////////////////////////////////////////////////
1.94 +/////////////////////////////////////////////////////////////////////////////////////////
1.95 +
1.96 +TInt CLogServDatabaseMarshall::DTIBegin()
1.97 + {
1.98 + const TInt backupError = iBackupInterface.BIErrorValueForCurrentState();
1.99 + if (backupError != KErrNone)
1.100 + return backupError;
1.101 +
1.102 + __ASSERT_DEBUG(!iDatabase.InTransaction(), Panic(ELogBeginInTransaction));
1.103 + return iDatabase.Begin();
1.104 + }
1.105 +
1.106 +TInt CLogServDatabaseMarshall::DTICommitAndEnd()
1.107 + {
1.108 + __ASSERT_DEBUG(iDatabase.InTransaction(), Panic(ELogCommitNotInTransaction));
1.109 + TInt err = iDatabase.Commit();
1.110 + if (err == KErrNone && iCacheStrings != NULL)
1.111 + {
1.112 + iCacheStrings->Commit();
1.113 + }
1.114 + return err;
1.115 + }
1.116 +
1.117 +void CLogServDatabaseMarshall::DTIRollBack()
1.118 + {
1.119 + __ASSERT_DEBUG(iDatabase.InTransaction(), Panic(ELogRollbackNotInTransaction));
1.120 + iDatabase.Rollback();
1.121 + if (iCacheStrings != NULL)
1.122 + {
1.123 + iCacheStrings->Rollback();
1.124 + }
1.125 + }
1.126 +
1.127 +TInt CLogServDatabaseMarshall::DTIExecuteSql(const TDesC& aStatement, TDbTextComparison aComparison)
1.128 + {
1.129 + return iDatabase.Execute(aStatement, aComparison);
1.130 + }
1.131 +
1.132 +TBool CLogServDatabaseMarshall::DTIInTransaction() const
1.133 + {
1.134 + return iDatabase.InTransaction();
1.135 + }
1.136 +
1.137 +TBool CLogServDatabaseMarshall::DTIDatabaseIsDamaged() const
1.138 + {
1.139 + return iDatabase.IsDamaged();
1.140 + }
1.141 +
1.142 +CLogServResourceInterpreter& CLogServDatabaseMarshall::DTIResourceInterface() const
1.143 + {
1.144 + return iResourceInterface;
1.145 + }
1.146 +
1.147 +MLogServDatabaseChangeInterface& CLogServDatabaseMarshall::DTIChangeInterface() const
1.148 + {
1.149 + __ASSERT_ALWAYS(iChangeInterface, Panic(ELogNoChangeInterfacePointer));
1.150 + return *iChangeInterface;
1.151 + }
1.152 +
1.153 +CLogServCacheStrings& CLogServDatabaseMarshall::DTICacheStrings() const
1.154 + {
1.155 + __ASSERT_ALWAYS(iCacheStrings, Panic(ELogCacheAccessDuringBackupStrings));
1.156 + return *iCacheStrings;
1.157 + }
1.158 +
1.159 +CLogServCacheTypes& CLogServDatabaseMarshall::DTICacheTypes() const
1.160 + {
1.161 + __ASSERT_ALWAYS(iCacheTypes, Panic(ELogCacheAccessDuringBackupTypes));
1.162 + return *iCacheTypes;
1.163 + }
1.164 +
1.165 +CLogServCacheConfig& CLogServDatabaseMarshall::DTICacheConfig() const
1.166 + {
1.167 + __ASSERT_ALWAYS(iCacheConfig, Panic(ELogCacheAccessDuringBackupConfig));
1.168 + return *iCacheConfig;
1.169 + }
1.170 +
1.171 +RDbDatabase& CLogServDatabaseMarshall::DTIDatabase()
1.172 + {
1.173 + return iDatabase;
1.174 + }
1.175 +
1.176 +TBool CLogServDatabaseMarshall::DTIIsAllowed(TEventOp aEventOp, const RMessage2& aMessage, TUid aEventType, const char* aDiagnostic) const
1.177 + {
1.178 + return iSecurity->IsAllowed(aMessage, aEventType, aEventOp, aDiagnostic);
1.179 + }
1.180 +
1.181 +const RArray<TUid>& CLogServDatabaseMarshall::DTIUidsOfStandardTypes()
1.182 + {
1.183 + return iStandardTypeUids;
1.184 + }
1.185 +
1.186 +/////////////////////////////////////////////////////////////////////////////////////////
1.187 +/////////////////////////////////////////////////////////////////////////////////////////
1.188 +/////////////////////////////////////////////////////////////////////////////////////////
1.189 +
1.190 +void CLogServDatabaseMarshall::BOHandleEventL(TLogServBackupEvent aEvent)
1.191 + {
1.192 + switch(aEvent)
1.193 + {
1.194 + case EBackupStarting:
1.195 + {
1.196 + //Destroy config, types and strings caches
1.197 + delete iCacheConfig;
1.198 + iCacheConfig = NULL;
1.199 + delete iCacheStrings;
1.200 + iCacheStrings = NULL;
1.201 + delete iCacheTypes;
1.202 + iCacheTypes = NULL;
1.203 + //Close the database
1.204 + iDatabase.Close();
1.205 + }
1.206 + break;
1.207 +
1.208 + case EBackupEnded:
1.209 + {
1.210 + // Re-open the database and create config, types and strings caches
1.211 + DatabaseOpenL();
1.212 + // reset views as a different database is being restored
1.213 + DTIChangeInterface().DCISubmitGlobalChangeContextL(KLogClientChangeEventRefreshView);
1.214 + }
1.215 + break;
1.216 + default:
1.217 + break;
1.218 + }
1.219 + }
1.220 +
1.221 +/////////////////////////////////////////////////////////////////////////////////////////
1.222 +/////////////////////////////////////////////////////////////////////////////////////////
1.223 +/////////////////////////////////////////////////////////////////////////////////////////
1.224 +
1.225 +void CLogServDatabaseMarshall::DatabaseLocateL()
1.226 + {
1.227 + // Get drive for database
1.228 + TDriveUnit driveUnit(static_cast<TInt>(RFs::GetSystemDrive()));
1.229 + TDriveName name(driveUnit.Name());
1.230 +
1.231 + TFileName path;
1.232 + iFsSession.PrivatePath(path);
1.233 +
1.234 + // Ensure database path exists
1.235 + TParse parse;
1.236 + User::LeaveIfError(parse.Set(path, &name, NULL));
1.237 + path = parse.FullName();
1.238 +
1.239 + TInt error = iFsSession.MkDirAll(path);
1.240 + if (error != KErrAlreadyExists)
1.241 + User::LeaveIfError(error);
1.242 +
1.243 + path += KLogDatabaseName;
1.244 + iDatabaseName = path.AllocL();
1.245 + }
1.246 +
1.247 +/**
1.248 +Opens the LogEng database.
1.249 +@return KErrNone, If the "database open" operation completes successfully.
1.250 + If the "database open" operation fails the function returns the repported error code.
1.251 + KErrCorrupt, If the database is opened successfully but is damaged, then the function returns KErrCorrupt.
1.252 +*/
1.253 +TInt CLogServDatabaseMarshall::DoDbOpen()
1.254 + {
1.255 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - attempting to open db: %S", iDatabaseName);
1.256 +#ifdef LOGGING_ENABLED
1.257 + TEntry entry;
1.258 + if (iFsSession.Entry(*iDatabaseName, entry) == KErrNone)
1.259 + {
1.260 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Database file: %S DOES exist", iDatabaseName);
1.261 + }
1.262 + else
1.263 + {
1.264 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Database file: %S NOT FOUND", iDatabaseName);
1.265 + }
1.266 +#endif
1.267 + // Open database
1.268 + TInt err = iDatabase.Open(iFsSession, DatabaseName());
1.269 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - attempting to open DMBS database resulted in error: %d", error);
1.270 + // Check if the database is damaged. If it is set the error to KErrCorrupt so that it
1.271 + // will be deleted.
1.272 + if ((err == KErrNone) && iDatabase.IsDamaged())
1.273 + {
1.274 + err = KErrCorrupt;
1.275 + }
1.276 + return err;
1.277 + }
1.278 +
1.279 +/**
1.280 +Check if the database table count is the expected one - KExpectedNumberOfTables.
1.281 +@return True, The database tables count is KExpectedNumberOfTables,
1.282 + False, The database tables count is not KExpectedNumberOfTables;
1.283 +@leave KErrNoMemory, an out of memory condition has occurred;
1.284 + Note that the function may leave with database specific errors or
1.285 + other system-wide error codes.
1.286 +*/
1.287 +TBool CLogServDatabaseMarshall::DbTableCntCheckL()
1.288 + {
1.289 + CDbTableNames* tables = iDatabase.TableNamesL();
1.290 + TInt numberOfTables = tables->Count();
1.291 + delete tables;
1.292 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - Number of tables: %d", numberOfTables);
1.293 + return numberOfTables == KExpectedNumberOfTables;
1.294 + }
1.295 +
1.296 +/**
1.297 +Alters the "Event" table if the number column length is not KLogMaxNumberLength.
1.298 +@return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.
1.299 +*/
1.300 +TInt CLogServDatabaseMarshall::AlterEventTblIfOldFmt(CDbColSet& aEventTblColSet)
1.301 + {
1.302 + const TDbCol* numberCol = aEventTblColSet.Col(KLogFieldEventNumberString);
1.303 + __ASSERT_DEBUG(numberCol != NULL, User::Invariant());
1.304 + TInt err = KErrNone;
1.305 + // check the column width is correct
1.306 + if(numberCol->iMaxLength != KLogMaxNumberLength)
1.307 + {
1.308 + //The column width is not correct, so this is an old format database.
1.309 + //Modify the database so the number length is KLogMaxNumberLength.
1.310 + (const_cast <TDbCol*> (numberCol))->iMaxLength = KLogMaxNumberLength;
1.311 + err = iDatabase.AlterTable(KLogNameEventString, aEventTblColSet);
1.312 + }
1.313 + return err;
1.314 + }
1.315 +
1.316 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.317 +
1.318 +/**
1.319 +Alters the "Event" table if the the table does not have "SimId" column.
1.320 +@return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.
1.321 +@leave KErrNoMemory, an out of memory condition has occurred;
1.322 + Some other failure codes, not related to the "alter" opertaion.
1.323 +*/
1.324 +TInt CLogServDatabaseMarshall::AlterEventTblIfNoSimIdL(CDbColSet& aEventTblColSet)
1.325 + {//Compiled only when SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM macro is defined
1.326 + const TDbCol* simIdCol = aEventTblColSet.Col(KLogFieldEventSimId);
1.327 + TInt err = KErrNone;
1.328 + if(!simIdCol)
1.329 + {
1.330 + TDbCol col(KLogFieldEventSimId, EDbColUint32);
1.331 + aEventTblColSet.AddL(col);
1.332 + err = iDatabase.AlterTable(KLogNameEventString, aEventTblColSet);
1.333 + }
1.334 + return err;
1.335 + }
1.336 +
1.337 +#endif
1.338 +
1.339 +/**
1.340 +Checks the database structure and alters the tables if that's an old format database.
1.341 +@return KErrNone, The "alter" operation has completed successfully, system wide or database specific error code otherwise.
1.342 +@leave KErrNoMemory, an out of memory condition has occurred;
1.343 + Some other failure codes, not related to the "alter" opertaion.
1.344 +*/
1.345 +TInt CLogServDatabaseMarshall::AlterDbIfOldFmtL()
1.346 + {
1.347 + CDbColSet* tableEventCol = iDatabase.ColSetL(KLogNameEventString);
1.348 + CleanupStack::PushL(tableEventCol);
1.349 + //Check for old format database which had MaxNumberLength =32
1.350 + TInt err = AlterEventTblIfOldFmt(*tableEventCol);
1.351 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.352 + //Check if the "SimId" column is present
1.353 + if(err == KErrNone)
1.354 + {
1.355 + err = AlterEventTblIfNoSimIdL(*tableEventCol);
1.356 + }
1.357 +#endif
1.358 + CleanupStack::PopAndDestroy(tableEventCol);
1.359 + return err;
1.360 + }
1.361 +
1.362 +/**
1.363 +Closes and deletes the LogEng database. In _DEBUG builds the "delete file" error will be printed out.
1.364 +*/
1.365 +void CLogServDatabaseMarshall::DbDelete()
1.366 + {
1.367 + iDatabase.Close();
1.368 +#ifdef _DEBUG
1.369 + //Do not remove the statement bellow. In _DEBUG builds it forms a single "TInt err2 = iFsSession.Delete(DatabaseName());" statement.
1.370 + TInt err2 =
1.371 +#endif
1.372 + iFsSession.Delete(DatabaseName());
1.373 +#ifdef _DEBUG
1.374 + if((err2 != KErrNone) && (err2 != KErrNotFound))
1.375 + {
1.376 + RDebug::Print(_L("CLogServDatabaseMarshall::DatabaseOpenL() - Failed to delete file. Error = %d"), err2);
1.377 + }
1.378 +#endif
1.379 + }
1.380 +
1.381 +/**
1.382 +Attempts to create the LogEng database and tables.
1.383 +@return KErrNoNone, The database was created successfully, system wide or database specific error otherwise.
1.384 +*/
1.385 +TInt CLogServDatabaseMarshall::DbCreate()
1.386 + {
1.387 + // Try and create the database
1.388 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - trying to create database");
1.389 + TRAPD(err, DatabaseCreateL(DatabaseName()));
1.390 + LOGTEXT2("CLogServDatabaseMarshall::DatabaseOpenL() - creation error was: %d", error);
1.391 + return err;
1.392 + }
1.393 +
1.394 +/**
1.395 +Creates config and string LogEng caches. Finishes the initialization of the event types cache.
1.396 +@leave KErrNoMemory, an out of memory condition has occurred;
1.397 + Note that the function may leave with database specific errors or
1.398 + other system-wide error codes.
1.399 +*/
1.400 +void CLogServDatabaseMarshall::CreateCachesL()
1.401 + {
1.402 + // Create other cache objects (these require the database to be already opened)
1.403 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating config cache");
1.404 + iCacheConfig = CLogServCacheConfig::NewL(*this);
1.405 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating string cache");
1.406 + iCacheStrings = CLogServCacheStrings::NewL(*this);
1.407 + // Finish the type cache initialization
1.408 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - initializing type cache");
1.409 + iCacheTypes->InitializeL();
1.410 + }
1.411 +
1.412 +void CLogServDatabaseMarshall::DatabaseOpenL()
1.413 + {
1.414 + // Create the cache objects - objects need to be put into the cache as
1.415 + // soon as the database is open.
1.416 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - creating type cache");
1.417 + iCacheTypes = CLogServCacheTypes::NewL(*this);
1.418 + TInt err = DoDbOpen();
1.419 + // Check we have the expected number of tables
1.420 + if(err == KErrNone && !DbTableCntCheckL())
1.421 + {
1.422 + err = KErrCorrupt;
1.423 + }
1.424 + // Check a compaction can be performed. If it can't it indicates a serious problem?
1.425 + if(err == KErrNone && (err = iDatabase.Compact()) != KErrNone)
1.426 + {
1.427 + err = KErrCorrupt;
1.428 + }
1.429 + if(err == KErrNone)
1.430 + {
1.431 + err = CLogServDatabaseMarshall::AlterDbIfOldFmtL();
1.432 + }
1.433 + // If the database failed to open, delete and recreate.
1.434 + if(err == KErrNotFound || err == KErrCorrupt || err == KErrArgument || err == KErrEof)
1.435 + {
1.436 + DbDelete();
1.437 + // Try and create the database
1.438 + err = DbCreate();
1.439 + if(err != KErrNone)
1.440 + {
1.441 + DbDelete();
1.442 + }
1.443 + }
1.444 + User::LeaveIfError(err);
1.445 + CreateCachesL();
1.446 + // At this point, its safe to tell the backup interface what file it has to watch
1.447 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - registering database filename with backup interface");
1.448 + iBackupInterface.BISetDatabaseNameL(DatabaseName());
1.449 + LOGTEXT("CLogServDatabaseMarshall::DatabaseOpenL() - end");
1.450 + }
1.451 +
1.452 +void CLogServDatabaseMarshall::DatabaseCreateL(const TDesC& aName)
1.453 + {
1.454 + User::LeaveIfError(iDatabase.Replace(iFsSession, aName));
1.455 + CreateTablesL();
1.456 + }
1.457 +
1.458 +// Note: Number of tables HAS to match KExpectedNumberOfTables
1.459 +void CLogServDatabaseMarshall::CreateTablesL()
1.460 + {
1.461 + DTIBeginWithRollBackProtectionLC();
1.462 +
1.463 + // Create event table
1.464 + TheSql.Format(KLogTableEventString, KLogMaxRemotePartyLength, KLogMaxSubjectLength, KLogMaxNumberLength);
1.465 + User::LeaveIfError(iDatabase.Execute(TheSql));
1.466 + MakeColumnAutoIncremetingL(KLogNameEventString, KLogFieldIdString);
1.467 +
1.468 + // Create event type table
1.469 + TheSql.Format(KLogTableTypeString, KLogMaxDescriptionLength);
1.470 + User::LeaveIfError(iDatabase.Execute(TheSql));
1.471 + MakeColumnAutoIncremetingL(KLogNameTypeString, KLogFieldIdString);
1.472 +
1.473 + // Create string list table
1.474 + TheSql.Format(KLogTableStringString, KLogMaxSharedStringLength);
1.475 + User::LeaveIfError(iDatabase.Execute(TheSql));
1.476 + MakeColumnAutoIncremetingL(KLogNameStringString, KLogFieldIdString);
1.477 +
1.478 + // Create configuration table
1.479 + TheSql.Copy(KLogTableConfigString);
1.480 + User::LeaveIfError(iDatabase.Execute(TheSql));
1.481 +
1.482 + // Create the index
1.483 + CreateIndiciesL();
1.484 +
1.485 + // Set the initial configuration
1.486 + CreateConfigurationL();
1.487 +
1.488 + // Load standard event types
1.489 + CreateTypesL();
1.490 +
1.491 + DTICommitAndCancelRollbackProtectionL();
1.492 + }
1.493 +
1.494 +void CLogServDatabaseMarshall::CreateTypesL(TBool aReadOnly)
1.495 + {
1.496 + // Get the array size
1.497 + TResourceReader reader;
1.498 + iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INITIAL_EVENTS);
1.499 +
1.500 + // Create them
1.501 + DTICacheTypes().CreateStandardTypesL(reader, aReadOnly);
1.502 +
1.503 + CleanupStack::PopAndDestroy(); // reader
1.504 + }
1.505 +
1.506 +void CLogServDatabaseMarshall::CreateIndiciesL()
1.507 + {
1.508 + // Get the array size
1.509 + TResourceReader reader;
1.510 + iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INDEXES);
1.511 +
1.512 + const TInt indexes = reader.ReadInt16();
1.513 +
1.514 + // Read in the array
1.515 + for(TInt c1 = 0; c1 < indexes; c1++)
1.516 + {
1.517 + const TPtrC name(reader.ReadTPtrC());
1.518 + const TPtrC table(reader.ReadTPtrC());
1.519 +
1.520 + // Get the number of keys
1.521 + const TInt keys = reader.ReadInt16();
1.522 +
1.523 + CDbKey* key = CDbKey::NewLC();
1.524 +
1.525 + for(TInt c2 = 0; c2 < keys; c2++)
1.526 + {
1.527 + TPtrC col = reader.ReadTPtrC();
1.528 + TUint order = reader.ReadUint16();
1.529 + TInt len = reader.ReadInt16();
1.530 +
1.531 + // Add the key
1.532 + key->AddL(TDbKeyCol(col, len, (TDbKeyCol::TOrder)order));
1.533 + }
1.534 +
1.535 + // Make key unique if required
1.536 + if (reader.ReadInt8())
1.537 + key->MakeUnique();
1.538 +
1.539 + // Set comparison
1.540 + const TDbTextComparison comparison = static_cast<TDbTextComparison>(reader.ReadInt8());
1.541 + key->SetComparison(comparison);
1.542 +
1.543 + // Create the index
1.544 + User::LeaveIfError(iDatabase.CreateIndex(name, table, *key));
1.545 +
1.546 + CleanupStack::PopAndDestroy(key);
1.547 + }
1.548 +
1.549 + CleanupStack::PopAndDestroy(); // reader
1.550 + }
1.551 +
1.552 +void CLogServDatabaseMarshall::CreateConfigurationL()
1.553 + {
1.554 + // Load the resource/repository file default configuration
1.555 + // The precedence is given to the reading from the repository file.
1.556 + TLogConfig config;
1.557 +
1.558 + CRepository* repository = NULL;
1.559 + TRAPD(res, repository = CRepository::NewL(KUidLogengRepository));
1.560 + if (res == KErrNone)
1.561 + {
1.562 + CleanupStack::PushL(repository);
1.563 + ReadRepositoryFileConfigurationL(config, *repository);
1.564 + CleanupStack::PopAndDestroy(repository);
1.565 + }
1.566 + else if (res == KErrCorrupt)
1.567 + {
1.568 + User::Leave(res);
1.569 + }
1.570 + else
1.571 + {
1.572 + ReadResourceFileConfigurationL(config);
1.573 + }
1.574 + // Insert the column
1.575 + TheSql.Format(KLogSqlInsertConfigString, config.iMaxLogSize, config.iMaxRecentLogSize, config.iMaxEventAge);
1.576 + User::LeaveIfError(iDatabase.Execute(TheSql));
1.577 + }
1.578 +
1.579 +void CLogServDatabaseMarshall::ReadRepositoryFileConfigurationL(TLogConfig& aConfig, CRepository& repository) const
1.580 + {
1.581 + TInt maxLogSize;
1.582 + TInt maxRecentLogSize;
1.583 + TInt maxEventAge;
1.584 + //
1.585 + User::LeaveIfError(repository.Get(KMaxLogSizeRepKey, maxLogSize));
1.586 + aConfig.iMaxLogSize = static_cast<TLogSize> (maxLogSize);
1.587 + User::LeaveIfError(repository.Get(KMaxRecentLogSizeRepKey, maxRecentLogSize));
1.588 + aConfig.iMaxRecentLogSize = static_cast<TLogRecentSize> (maxRecentLogSize);
1.589 + User::LeaveIfError(repository.Get(KMaxEventAgeRepKey, maxEventAge));
1.590 + aConfig.iMaxEventAge = static_cast<TLogAge> (maxEventAge);
1.591 + }
1.592 +
1.593 +void CLogServDatabaseMarshall::ReadResourceFileConfigurationL(TLogConfig& aConfig) const
1.594 + {
1.595 + TResourceReader reader;
1.596 + iResourceInterface.CreateResourceReaderLC(reader, R_LOG_INITIAL_CONFIG);
1.597 + //
1.598 + aConfig.iMaxLogSize = static_cast<TLogSize>(reader.ReadUint16());
1.599 + aConfig.iMaxRecentLogSize = static_cast<TLogRecentSize>(reader.ReadUint8());
1.600 + aConfig.iMaxEventAge = static_cast<TLogAge>(reader.ReadUint32());
1.601 + //
1.602 + CleanupStack::PopAndDestroy(); // reader
1.603 + }
1.604 +
1.605 +void CLogServDatabaseMarshall::MakeColumnAutoIncremetingL(const TDesC& aTable, const TDesC& aColumn)
1.606 + {
1.607 + CDbColSet* newTable = iDatabase.ColSetL(aTable);
1.608 + CleanupStack::PushL(newTable);
1.609 +
1.610 + const TDbCol* oldCol = newTable->Col(aColumn);
1.611 + __ASSERT_DEBUG(oldCol != NULL, Panic(ELogNoSuchColumn));
1.612 +
1.613 + TDbCol newCol = *oldCol;
1.614 + newCol.iAttributes |= TDbCol::EAutoIncrement;
1.615 +
1.616 + newTable->Remove(aColumn);
1.617 + newTable->AddL(newCol);
1.618 +
1.619 + User::LeaveIfError(iDatabase.DropTable(aTable));
1.620 + User::LeaveIfError(iDatabase.CreateTable(aTable, *newTable));
1.621 +
1.622 + CleanupStack::PopAndDestroy(newTable);
1.623 + }
1.624 +