1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServView.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,861 @@
1.4 +// Copyright (c) 2002-2009 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 +#include "LogServView.h"
1.19 +#include "logpackage.h"
1.20 +#include "logservpanic.h"
1.21 +#include "LogServBackupInterface.h"
1.22 +#include "LogServViewChangeManager.h"
1.23 +#include "LogServDatabaseChangeInterface.h"
1.24 +#include "LogServCacheTypes.h"
1.25 +#include "LogServSqlStrings.h"
1.26 +#include "LOGFILTQ.H"
1.27 +
1.28 +// Constants
1.29 +const TInt KLogViewContentsGranuality = 20;
1.30 +const TInt KLogViewLockStatusEventGranularity = 3;
1.31 +
1.32 +TDbColNo CLogServViewBase::iIdColNo = 0;
1.33 +TDbColNo CLogServViewBase::iTypeColNo = 0;
1.34 +TDbColNo CLogServViewBase::iFlagColNo[] = {0, 0, 0, 0};
1.35 +
1.36 +TDbColNo CLogServViewRecent::iIdColNo = 0;
1.37 +TDbColNo CLogServViewRecent::iRecentColNo = 0;
1.38 +TDbColNo CLogServViewRecent::iDuplicateColNo = 0;
1.39 +
1.40 +//diagnostic message for the platform security
1.41 +const char* KIgnoreDiagnostic = "This diagnostic message does not indicate an error, please ignore it";
1.42 +
1.43 +/////////////////////////////////////////////////////////////////////////////////////////
1.44 +// -----> CLogServViewBase (source)
1.45 +/////////////////////////////////////////////////////////////////////////////////////////
1.46 +CLogServViewBase::CLogServViewBase(MLogServDatabaseTransactionInterface& aDatabase,
1.47 + MLogServBackupInterface& aBackupInterface,
1.48 + CLogPackage& aPackage, TLogViewType aType, TLogViewId aViewId,
1.49 + const RMessage2& aMessage) :
1.50 + iDatabase(aDatabase),
1.51 + iPackage(aPackage),
1.52 + iBackupInterface(aBackupInterface),
1.53 + iType(aType),
1.54 + iViewId(aViewId),
1.55 + iMessage (aMessage)
1.56 + {
1.57 + }
1.58 +
1.59 +CLogServViewBase::~CLogServViewBase()
1.60 + {
1.61 + iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsCancel(*this);
1.62 + iBackupInterface.BIObserverRemove(*this);
1.63 + //
1.64 + iViewContents.Close();
1.65 + //
1.66 + iStandardTypeSecurityCache.Close();
1.67 + //
1.68 + delete iLockChangeObserver;
1.69 + delete iSql;
1.70 + delete iChangeManager;
1.71 + }
1.72 +
1.73 +
1.74 +void CLogServViewBase::ConstructL()
1.75 + {
1.76 + // Handles changes for this view
1.77 + iChangeManager = CLogServViewChangeManager::NewL(iDatabase.DTIChangeInterface());
1.78 +
1.79 + // Register for change events
1.80 + iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsL(*this);
1.81 +
1.82 + // Register for backup events
1.83 + iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectView);
1.84 +
1.85 + // Observes when the view is locked/unlocked due to a backup
1.86 + iLockChangeObserver = CLogServViewLockObserver::NewL(iBackupInterface);
1.87 +
1.88 + const RArray<TUid>& arrTUids = iDatabase.DTIUidsOfStandardTypes();
1.89 + TInt count = arrTUids.Count();
1.90 + iStandardTypeSecurityCache.ReserveL(count);
1.91 + for(TInt i=0; i < count; i++)
1.92 + {
1.93 + SStandardTypeSecurity securitySetting;
1.94 + securitySetting.eventType = arrTUids[i];
1.95 + securitySetting.readAccess = iDatabase.DTIIsAllowed(EReadOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
1.96 + securitySetting.writeAccess = iDatabase.DTIIsAllowed(EWriteOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
1.97 + TInt err = iStandardTypeSecurityCache.Append(securitySetting);
1.98 + __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
1.99 + }
1.100 + }
1.101 +
1.102 +/////////////////////////////////////////////////////////////////////////////////////////
1.103 +/////////////////////////////////////////////////////////////////////////////////////////
1.104 +/////////////////////////////////////////////////////////////////////////////////////////
1.105 +
1.106 +void CLogServViewBase::DCOHandleChangeEventsL(const CLogChangeDefinition& aChanges)
1.107 + {
1.108 + // Just return if the view isn't setup
1.109 + if (!iSql)
1.110 + return;
1.111 +
1.112 + TRAPD(error, DoHandleChangeEventsL(aChanges));
1.113 + if (error != KErrNone)
1.114 + {
1.115 + iViewContents.Close();
1.116 + iViewContentsReady = EFalse;
1.117 + iRebuildViewContents = ETrue;
1.118 + }
1.119 + }
1.120 +
1.121 +/////////////////////////////////////////////////////////////////////////////////////////
1.122 +/////////////////////////////////////////////////////////////////////////////////////////
1.123 +/////////////////////////////////////////////////////////////////////////////////////////
1.124 +
1.125 +void CLogServViewBase::BOHandleEventL(TLogServBackupEvent aEvent)
1.126 + {
1.127 + switch(aEvent)
1.128 + {
1.129 + case EBackupStarting:
1.130 + iViewContents.Close();
1.131 + iViewContentsReady = EFalse;
1.132 + break;
1.133 + case EBackupEnded:
1.134 + RebuildViewL();
1.135 + break;
1.136 + }
1.137 + }
1.138 +
1.139 +/////////////////////////////////////////////////////////////////////////////////////////
1.140 +/////////////////////////////////////////////////////////////////////////////////////////
1.141 +/////////////////////////////////////////////////////////////////////////////////////////
1.142 +
1.143 +#pragma BullseyeCoverage off
1.144 +
1.145 +/**
1.146 +Remove an entry from the view.
1.147 +By default you can't remove an event from a view.
1.148 +*/
1.149 +void CLogServViewBase::RemoveL(const RMessage2& /*aMessage*/)
1.150 + {
1.151 + User::Leave(KErrNotSupported);
1.152 + }
1.153 +
1.154 +/**
1.155 +By default you can't clear duplicates from a view
1.156 +*/
1.157 +void CLogServViewBase::ClearDuplicatesL(const RMessage2& /*aMessage*/)
1.158 + {
1.159 + User::Leave(KErrNotSupported);
1.160 + }
1.161 +
1.162 +#pragma BullseyeCoverage on
1.163 +
1.164 +/**
1.165 +Set the flags of all the entries in the view.
1.166 +*/
1.167 +void CLogServViewBase::SetFlagsL(const RMessage2& aMessage)
1.168 + {
1.169 + if (ViewIsReady())
1.170 + {
1.171 + // Flags from client
1.172 + const TLogFlags flags = static_cast<TLogFlags>(aMessage.Int2());
1.173 + RLogDbView view;
1.174 + view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
1.175 + InitializeColumnsL(view);
1.176 + if(view.FirstL())
1.177 + {
1.178 + iDatabase.DTIBeginWithRollBackProtectionLC();
1.179 + // Iterate through the events
1.180 + do
1.181 + {
1.182 + // Get current event id
1.183 + view.GetL();
1.184 + const TLogId id = view.ColInt32(CLogServViewBase::iIdColNo);
1.185 + TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
1.186 + if(IsAllowed(EWriteOp, eventTypeIndex))
1.187 + {
1.188 + // Make the change
1.189 + view.UpdateL();
1.190 + TInt bit = KLogFlagsCount;
1.191 + while(bit--)
1.192 + {
1.193 + const TBool flagIsSet = flags & (0x1 << bit) ? 1 : 0;
1.194 + view.SetColL(CLogServViewBase::iFlagColNo[bit], flagIsSet);
1.195 + }
1.196 + view.PutL();
1.197 + iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChanged, id);
1.198 + }
1.199 + }
1.200 + while(view.NextL());
1.201 + iDatabase.DTICommitAndCancelRollbackProtectionL();
1.202 + }
1.203 + CleanupStack::PopAndDestroy(&view);
1.204 + }
1.205 + else
1.206 + ::PanicClientL(aMessage, ELogViewRecentViewNotYetReadyForFlagSetting);
1.207 + }
1.208 +
1.209 +/////////////////////////////////////////////////////////////////////////////////////////
1.210 +/////////////////////////////////////////////////////////////////////////////////////////
1.211 +/////////////////////////////////////////////////////////////////////////////////////////
1.212 +
1.213 +/**
1.214 +The client has requested change notifications
1.215 +*/
1.216 +void CLogServViewBase::RequestChangeNotifications(const RMessage2& aMessage)
1.217 + {
1.218 + iChangeManager->RequestChangeNotifications(aMessage);
1.219 + }
1.220 +
1.221 +/**
1.222 +The client has cancelled a previous change notification request
1.223 +*/
1.224 +void CLogServViewBase::RequestChangeNotificationsCancel()
1.225 + {
1.226 + iChangeManager->RequestChangeNotificationsCancel();
1.227 + }
1.228 +
1.229 +/**
1.230 +The client has requested lock status change notifications
1.231 +*/
1.232 +void CLogServViewBase::RequestLockStatusChanges(const RMessage2& aMessage)
1.233 + {
1.234 + iLockChangeObserver->RequestLockStatusChanges(aMessage);
1.235 + }
1.236 +
1.237 +/**
1.238 +The client has cancelled a previous change notification request
1.239 +*/
1.240 +void CLogServViewBase::RequestLockStatusChangesCancel()
1.241 + {
1.242 + iLockChangeObserver->RequestLockStatusChangesCancel();
1.243 + }
1.244 +
1.245 +/**
1.246 +The client has requested the current list of changes
1.247 +*/
1.248 +void CLogServViewBase::RequestChangesL(const RMessage2& aMessage)
1.249 + {
1.250 + if (!iSql)
1.251 + ::PanicClientL(aMessage, ELogViewNotSetupForChangesFetch);
1.252 + else
1.253 + iChangeManager->DeliverChangesL(aMessage);
1.254 + }
1.255 +
1.256 +/**
1.257 +Set up the server-side view based upon the client-side filter. This
1.258 +method essentially fetches a client-side filter and then dynamically
1.259 +executes the associated SELECT statement on the database to build up
1.260 +a view. This view is then cached in terms of the entry ids (iViewContents).
1.261 +*/
1.262 +void CLogServViewBase::SetupL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
1.263 + {
1.264 + // Get the query string
1.265 + const TPtrC pSQL(GetQueryStringL(aMessage, aFilterType));
1.266 + HBufC* buf = pSQL.AllocLC();
1.267 + // Setup the contents
1.268 + PrepareViewContentsL(pSQL);
1.269 + // Tidy up
1.270 + CleanupStack::Pop(buf);
1.271 + delete iSql;
1.272 + iSql = buf;
1.273 + }
1.274 +
1.275 +/**
1.276 +Returns the number of entries in this view
1.277 +*/
1.278 +TInt CLogServViewBase::Count() const
1.279 + {
1.280 + return const_cast<CLogServViewBase*>(this)->RebuildViewContentsIfNecessary() ? 0 : iViewContents.Count();
1.281 + }
1.282 +
1.283 +/**
1.284 +Get the log id at the specified index
1.285 +*/
1.286 +TLogId CLogServViewBase::At(TInt aIndex) const
1.287 + {
1.288 + return (TUint)aIndex < iViewContents.Count() ? iViewContents[aIndex] : KLogNullId;
1.289 + }
1.290 +
1.291 +/////////////////////////////////////////////////////////////////////////////////////////
1.292 +/////////////////////////////////////////////////////////////////////////////////////////
1.293 +/////////////////////////////////////////////////////////////////////////////////////////
1.294 +
1.295 +void CLogServViewBase::DestroyList(TAny *aPtr)
1.296 + {
1.297 + CLogFilterList* filter = reinterpret_cast<CLogFilterList*>(aPtr);
1.298 + filter->ResetAndDestroy();
1.299 + delete filter;
1.300 + }
1.301 +
1.302 +void CLogServViewBase::InitializeColumnsL(RDbRowSet& aRowSet)
1.303 + {
1.304 + if(CLogServViewBase::iIdColNo == 0)
1.305 + {
1.306 + CDbColSet* colset = aRowSet.ColSetL();
1.307 + CLogServViewBase::iIdColNo = colset->ColNo(KLogFieldIdString);
1.308 + CLogServViewBase::iTypeColNo = colset->ColNo(KLogFieldEventTypeString);
1.309 + for(TInt i=0;i<KLogFlagsCount;++i)
1.310 + {
1.311 + TDbColName colname;
1.312 + colname.Format(KLogFieldEventFlagString, i + 1);
1.313 + CLogServViewBase::iFlagColNo[i] = colset->ColNo(colname);
1.314 + __ASSERT_DEBUG(CLogServViewBase::iFlagColNo[i] > 0, User::Invariant());
1.315 + }
1.316 + delete colset;
1.317 + }
1.318 + __ASSERT_DEBUG(CLogServViewBase::iIdColNo > 0 && CLogServViewBase::iTypeColNo > 0, User::Invariant());
1.319 + }
1.320 +
1.321 +/////////////////////////////////////////////////////////////////////////////////////////
1.322 +/////////////////////////////////////////////////////////////////////////////////////////
1.323 +/////////////////////////////////////////////////////////////////////////////////////////
1.324 +
1.325 +void CLogServViewBase::ResetViewContentsL(RDbRowSet& aRowSet)
1.326 + {
1.327 + // Get the view contents
1.328 + RArray<TLogId> viewContents(KLogViewContentsGranuality);
1.329 + CleanupClosePushL(viewContents);
1.330 + viewContents.ReserveL(aRowSet.CountL());
1.331 + if(aRowSet.FirstL())
1.332 + {
1.333 + do
1.334 + {
1.335 + // Get the id at the current position
1.336 + aRowSet.GetL();
1.337 + const TLogId id = aRowSet.ColInt32(CLogServViewBase::iIdColNo);
1.338 + TUint8 eventTypeIndex = aRowSet.ColUint8(CLogServViewBase::iTypeColNo);
1.339 + if(IsAllowed(EReadOp, eventTypeIndex))
1.340 + {
1.341 + TInt err = viewContents.Append(id);
1.342 + __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
1.343 + }
1.344 + }
1.345 + while(aRowSet.NextL());
1.346 + }
1.347 + // Tidy up - don't leave from below here
1.348 + CleanupStack::Pop(&viewContents);
1.349 + iViewContents.Close();
1.350 + iViewContents = viewContents;
1.351 + iViewContentsReady = ETrue;
1.352 + }
1.353 +
1.354 +void CLogServViewBase::PrepareViewContentsL(const TDesC& aSQL)
1.355 + {
1.356 + // Generate the view
1.357 + RLogDbView view;
1.358 + view.PrepareLC(iDatabase.DTIDatabase(), aSQL);
1.359 + InitializeColumnsL(view);
1.360 + // Reset the view
1.361 + ResetViewContentsL(view);
1.362 + CleanupStack::PopAndDestroy(&view);
1.363 + }
1.364 +
1.365 +void CLogServViewBase::RebuildViewL()
1.366 + {
1.367 + if (iSql && iSql->Length())
1.368 + PrepareViewContentsL(*iSql);
1.369 + }
1.370 +
1.371 +//
1.372 +// The last change notification indication was not handled correctly.
1.373 +// Attempt to re-initialise the view
1.374 +//
1.375 +TInt CLogServViewBase::RebuildViewContentsIfNecessary()
1.376 + {
1.377 + TInt error = KErrNone;
1.378 + //
1.379 + if (iRebuildViewContents && iSql && iSql->Length())
1.380 + {
1.381 + TRAP(error,
1.382 +
1.383 + RebuildViewL();
1.384 +
1.385 + // The view is okay now
1.386 + iRebuildViewContents = EFalse;
1.387 + );
1.388 + }
1.389 + return error;
1.390 + }
1.391 +
1.392 +void CLogServViewBase::DoHandleChangeEventsL(const CLogChangeDefinition& aChanges)
1.393 + {
1.394 + if(!ViewIsReady())
1.395 + {
1.396 + return;
1.397 + }
1.398 +
1.399 + // Generate the view
1.400 + RLogDbView view;
1.401 + view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
1.402 + InitializeColumnsL(view);
1.403 + _LIT(KLogIdQuery, "Id = %d");
1.404 + TBuf<15> find;
1.405 + TInt changeIndex;
1.406 +
1.407 + // Prepare for a change transaction
1.408 + iChangeManager->ChangeTransactionPrepare();
1.409 +
1.410 + const TInt count = aChanges.Count();
1.411 + for(TInt i=0; i<count; i++)
1.412 + {
1.413 + // Fetch the change details
1.414 + TLogId logId = KLogNullId;
1.415 + TLogDatabaseChangeType type = aChanges.At(i, logId);
1.416 +
1.417 + // Mark the insertion position as 'not found'
1.418 + changeIndex = KErrNotFound;
1.419 +
1.420 + // Format the find query
1.421 + find.Format(KLogIdQuery, logId);
1.422 +
1.423 + // Handle the various change descriptions
1.424 + switch(type)
1.425 + {
1.426 + case ELogChangeTypeEventAdded:
1.427 + {
1.428 + __ASSERT_DEBUG(iViewContents.Find(logId) == KErrNotFound, Panic(ELogEventAlreadyInView));
1.429 +
1.430 + // See if the event is in the view
1.431 + if(view.FirstL())
1.432 + {
1.433 + const TDbQuery dbQuery(find);
1.434 + changeIndex = view.FindL(RDbRowSet::EForwards, dbQuery);
1.435 + if (changeIndex >= 0)
1.436 + {
1.437 + view.GetL();
1.438 + TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
1.439 + if (IsAllowed(EReadOp, eventTypeIndex))
1.440 + User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
1.441 +
1.442 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
1.443 + }
1.444 + }
1.445 + }
1.446 + break;
1.447 + case ELogChangeTypeEventChanged:
1.448 + case ELogChangeTypeEventChangedHidden:
1.449 + {
1.450 + // See if the event is in the view
1.451 + if (view.FirstL() && (changeIndex = view.FindL(RDbRowSet::EForwards, TDbQuery(find))) >= KErrNone)
1.452 + {
1.453 + // If the event was already in the view then it has changed otherwise it's been added
1.454 + const TInt findIndex = iViewContents.Find(logId);
1.455 + if (findIndex >= KErrNone)
1.456 + {
1.457 + // If the item that changed also caused its position within the view to be altered
1.458 + // then we need to simulate a delete, followed by an addition
1.459 + if (findIndex != changeIndex)
1.460 + {
1.461 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, findIndex);
1.462 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
1.463 + }
1.464 + // Only tell the view if the CLogEvent has changed
1.465 + else if (type != ELogChangeTypeEventChangedHidden)
1.466 + {
1.467 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventChanged, changeIndex);
1.468 + }
1.469 + }
1.470 + else
1.471 + {
1.472 + User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
1.473 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
1.474 +
1.475 + // Update the type to indicate that this change action
1.476 + // really resulted in an addition
1.477 + type = ELogChangeTypeEventAdded;
1.478 + }
1.479 + }
1.480 + else
1.481 + {
1.482 + changeIndex = iViewContents.Find(logId);
1.483 +
1.484 + // If it used to be in the view then it's been removed because it's
1.485 + // not in there anymore
1.486 + if (changeIndex >= KErrNone)
1.487 + {
1.488 + iViewContents.Remove(changeIndex);
1.489 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
1.490 +
1.491 + // Update the type to indicate that this change action
1.492 + // really resulted in a deletion
1.493 + type = ELogChangeTypeEventDeleted;
1.494 + }
1.495 + }
1.496 + }
1.497 + break;
1.498 + case ELogChangeTypeEventDeleted:
1.499 + {
1.500 + changeIndex = iViewContents.Find(logId);
1.501 +
1.502 + // If it used to be in the view then tell it about the deletion
1.503 + if (changeIndex >= KErrNone)
1.504 + {
1.505 + iViewContents.Remove(changeIndex);
1.506 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
1.507 + }
1.508 + }
1.509 + break;
1.510 + case ELogChangeTypeLogCleared:
1.511 + {
1.512 + RebuildViewL();
1.513 + iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeLogCleared, 0);
1.514 + }
1.515 + break;
1.516 + default:
1.517 + __ASSERT_DEBUG(EFalse, Panic(ELogUnrecognizedChangeType));
1.518 + break;
1.519 + }
1.520 + }
1.521 +
1.522 + CleanupStack::PopAndDestroy(&view);
1.523 +
1.524 + // Commit the transaction. Will notify client if necessary
1.525 + iChangeManager->ChangeTransactionCommitL();
1.526 + }
1.527 +
1.528 +TBool CLogServViewBase::IsAllowed(TEventOp aEventOp, TUint8 aEventTypeIndex)
1.529 + {
1.530 + TBool result = ETrue;
1.531 +
1.532 + const TLogServCacheTypeEntry& entry = iDatabase.DTICacheTypes().FindById(aEventTypeIndex);
1.533 + TUid eventTypeUid = entry.iEventType->Uid();
1.534 + TInt count = iStandardTypeSecurityCache.Count();
1.535 +
1.536 + for(TInt i=0;i<count;++i)
1.537 + {
1.538 + if (eventTypeUid == iStandardTypeSecurityCache[i].eventType)
1.539 + {
1.540 + result = (aEventOp == EWriteOp) ? iStandardTypeSecurityCache[i].writeAccess : iStandardTypeSecurityCache[i].readAccess;
1.541 + break;
1.542 + }
1.543 + }
1.544 +
1.545 + return result;
1.546 + }
1.547 +
1.548 +/////////////////////////////////////////////////////////////////////////////////////////
1.549 +// -----> CLogServViewLockObserver (source)
1.550 +/////////////////////////////////////////////////////////////////////////////////////////
1.551 +
1.552 +CLogServViewLockObserver::CLogServViewLockObserver(MLogServBackupInterface& aBackupInterface)
1.553 +: iBackupInterface(aBackupInterface), iLockEvents(KLogViewLockStatusEventGranularity)
1.554 + {
1.555 + }
1.556 +
1.557 +CLogServViewLockObserver::~CLogServViewLockObserver()
1.558 + {
1.559 + iBackupInterface.BIObserverRemove(*this);
1.560 + iLockEvents.Close();
1.561 + }
1.562 +
1.563 +void CLogServViewLockObserver::ConstructL()
1.564 + {
1.565 + // Register for backup events
1.566 + iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectViewLock);
1.567 + }
1.568 +
1.569 +CLogServViewLockObserver* CLogServViewLockObserver::NewL(MLogServBackupInterface& aBackupInterface)
1.570 + {
1.571 + CLogServViewLockObserver* self = new(ELeave) CLogServViewLockObserver(aBackupInterface);
1.572 + CleanupStack::PushL(self);
1.573 + self->ConstructL();
1.574 + CleanupStack::Pop(self);
1.575 + return self;
1.576 + }
1.577 +
1.578 +void CLogServViewLockObserver::BOHandleEventL(TLogServBackupEvent aEvent)
1.579 + {
1.580 + // Map event
1.581 + TLogViewLockStatus status = ELogViewWindowOpen;
1.582 + if (aEvent == MLogServBackupObserver::EBackupStarting)
1.583 + status = ELogViewWindowLocked;
1.584 +
1.585 + // Cache or complete immediately
1.586 + if (!HaveLockStatusChangePointer())
1.587 + User::LeaveIfError(iLockEvents.Append(status));
1.588 + else
1.589 + CompleteLockStatusChangeMessage(status);
1.590 + }
1.591 +
1.592 +/**
1.593 +The client has requested lock status change notifications
1.594 +*/
1.595 +void CLogServViewLockObserver::RequestLockStatusChanges(const RMessage2& aMessage)
1.596 + {
1.597 + if (!HaveLockStatusChangePointer())
1.598 + {
1.599 + iLockStatusChangeMessage = aMessage;
1.600 +
1.601 + // Already have one cached event
1.602 + if (iLockEvents.Count())
1.603 + {
1.604 + CompleteLockStatusChangeMessage(iLockEvents[0]);
1.605 + iLockEvents.Remove(0);
1.606 + }
1.607 + }
1.608 + else
1.609 + PanicClient(aMessage, ELogViewLockStatusChangeRequestAlreadyIssued);
1.610 + }
1.611 +
1.612 +/**
1.613 +The client has cancelled a previous change notification request
1.614 +*/
1.615 +void CLogServViewLockObserver::RequestLockStatusChangesCancel()
1.616 + {
1.617 + if (HaveLockStatusChangePointer())
1.618 + CompleteLockStatusChangeMessage(KErrCancel);
1.619 + }
1.620 +
1.621 +void CLogServViewLockObserver::CompleteLockStatusChangeMessage(TInt aCompletionCode)
1.622 + {
1.623 + __ASSERT_ALWAYS(HaveLockStatusChangePointer(), Panic(ELogViewNoLockStatusChangeMessage));
1.624 + iLockStatusChangeMessage.Complete(aCompletionCode);
1.625 + }
1.626 +
1.627 +/////////////////////////////////////////////////////////////////////////////////////////
1.628 +// -----> CLogServViewEvent (source)
1.629 +/////////////////////////////////////////////////////////////////////////////////////////
1.630 +CLogServViewEvent::CLogServViewEvent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.631 +: CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeEvent, aViewId, aMessage)
1.632 + {
1.633 + }
1.634 +
1.635 +CLogServViewEvent* CLogServViewEvent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.636 + {
1.637 + CLogServViewEvent* self = new(ELeave) CLogServViewEvent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
1.638 + CleanupStack::PushL(self);
1.639 + self->ConstructL();
1.640 + CleanupStack::Pop(self);
1.641 + return self;
1.642 + }
1.643 +
1.644 +/**
1.645 +Setup the view
1.646 +Fetch the client-side SQL query string which this view uses to obtain a data-set.
1.647 +*/
1.648 +TPtrC CLogServViewEvent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
1.649 + {
1.650 + // Read stuff from the client
1.651 + iPackage.ResizeL(aMessage.GetDesLengthL(2));
1.652 + aMessage.ReadL(2, iPackage.Ptr());
1.653 +
1.654 + // Decode the parameters we've read from the client
1.655 + CLogFilterList* filter = new(ELeave)CLogFilterList;
1.656 + CleanupStack::PushL(TCleanupItem(DestroyList, filter));
1.657 + iPackage.GetLogFilterListL(*filter);
1.658 + RLogDynBuf expr;
1.659 + TLogFilterExprBuilder exprBuilder(iDatabase);
1.660 + exprBuilder.BuildExprLC(expr, *filter, KLogWhere, aFilterType);
1.661 + // Generate the query string that will be used
1.662 + TheSql.Format(KLogSqlEventViewString, &KLogViewSelectColList, &expr.DesC());
1.663 + CleanupStack::PopAndDestroy(2, filter);
1.664 + return TheSql;
1.665 + }
1.666 +
1.667 +/////////////////////////////////////////////////////////////////////////////////////////
1.668 +// -----> CLogServViewRecent (source)
1.669 +/////////////////////////////////////////////////////////////////////////////////////////
1.670 +CLogServViewRecent::CLogServViewRecent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.671 +: CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeRecent, aViewId, aMessage)
1.672 + {
1.673 + }
1.674 +
1.675 +CLogServViewRecent* CLogServViewRecent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.676 + {
1.677 + CLogServViewRecent* self = new(ELeave) CLogServViewRecent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
1.678 + CleanupStack::PushL(self);
1.679 + self->ConstructL();
1.680 + CleanupStack::Pop(self);
1.681 + return self;
1.682 + }
1.683 +
1.684 +/**
1.685 +Setup the view
1.686 +Fetch the client-side SQL query string which this view uses to obtain a data-set.
1.687 +*/
1.688 +TPtrC CLogServViewRecent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
1.689 + {
1.690 + // Read stuff from the client
1.691 + iPackage.ResizeL(aMessage.GetDesLengthL(2));
1.692 + aMessage.ReadL(2, iPackage.Ptr());
1.693 +
1.694 + // Decode the parameters we've read from the client
1.695 + CLogFilterList* filter = new(ELeave)CLogFilterList;
1.696 + CleanupStack::PushL(TCleanupItem(DestroyList, filter));
1.697 + iPackage.GetLogFilterListL(*filter);
1.698 + RLogDynBuf expr;
1.699 + TLogFilterExprBuilder exprBuilder(iDatabase);
1.700 + exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
1.701 + iRecentList = static_cast<TLogRecentList>(aMessage.Int3());
1.702 + // Generate the view that will be used
1.703 + if (iRecentList == KLogNullRecentList)
1.704 + {
1.705 + TheSql.Format(KLogSqlAllRecentViewString, &KLogViewSelectColList, &expr.DesC());
1.706 + }
1.707 + else
1.708 + {
1.709 + TheSql.Format(KLogSqlRecentViewString, &KLogViewSelectColList, iRecentList, &expr.DesC());
1.710 + }
1.711 + CleanupStack::PopAndDestroy(2, filter);
1.712 + return TheSql;
1.713 + }
1.714 +
1.715 +/**
1.716 +Remove an entry from the view.
1.717 +Note the client can call this even if the view isn't valid.
1.718 +*/
1.719 +void CLogServViewRecent::RemoveL(const RMessage2& aMessage)
1.720 + {
1.721 + if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
1.722 + User::Leave(KErrPermissionDenied);
1.723 +
1.724 + const TLogId id = static_cast<TLogId>(aMessage.Int2());
1.725 + TBuf<20> num;
1.726 + num.AppendNum(id);
1.727 +
1.728 + iDatabase.DTIBeginWithRollBackProtectionLC();
1.729 +
1.730 + TheSql.Copy(KLogSqlRemoveDuplicateEvents);
1.731 + TheSql.Append(KIdEqStr);
1.732 + TheSql.Append(num);
1.733 + TheSql.Append(KLogOr);
1.734 + TheSql.Append(KDuplicateEqStr);
1.735 + TheSql.Append(num);
1.736 + User::LeaveIfError(iDatabase.DTIExecuteSql(TheSql));
1.737 +
1.738 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.739 + iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
1.740 + iDatabase.DTICommitAndCancelRollbackProtectionL();
1.741 + }
1.742 +
1.743 +/**
1.744 +Clear all duplicate events associated with this recent list.
1.745 +*/
1.746 +void CLogServViewRecent::ClearDuplicatesL(const RMessage2& aMessage)
1.747 + {
1.748 + if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
1.749 + User::Leave(KErrPermissionDenied);
1.750 +
1.751 + if (iRecentList > 0)
1.752 + {
1.753 + // Get list of duplicates
1.754 + TheSql.Format(KLogSqlSelectAllDuplicatesString, iRecentList);
1.755 + RLogDbView view;
1.756 + view.PrepareLC(iDatabase.DTIDatabase(), TheSql);
1.757 + InitializeColumns2L(view);
1.758 + if(view.FirstL())
1.759 + {
1.760 + iDatabase.DTIBeginWithRollBackProtectionLC();
1.761 + // Iterate through the events
1.762 + do
1.763 + {
1.764 + // Get current event id
1.765 + view.GetL();
1.766 + const TLogId id = view.ColInt32(CLogServViewRecent::iIdColNo);
1.767 + // Make the change
1.768 + view.UpdateL();
1.769 + view.SetColNullL(CLogServViewRecent::iRecentColNo);
1.770 + view.SetColNullL(CLogServViewRecent::iDuplicateColNo);
1.771 + view.PutL();
1.772 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.773 + iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
1.774 + }
1.775 + while(view.NextL());
1.776 + iDatabase.DTICommitAndCancelRollbackProtectionL();
1.777 + }
1.778 + CleanupStack::PopAndDestroy(&view);
1.779 + }
1.780 + else
1.781 + ::PanicClientL(aMessage, ELogInvalidRecentView);
1.782 + }
1.783 +
1.784 +void CLogServViewRecent::InitializeColumns2L(RDbRowSet& aRowSet)
1.785 + {
1.786 + if(CLogServViewRecent::iIdColNo == 0)
1.787 + {
1.788 + CDbColSet* colset = aRowSet.ColSetL();
1.789 + CLogServViewRecent::iIdColNo = colset->ColNo(KLogFieldIdString);
1.790 + CLogServViewRecent::iRecentColNo = colset->ColNo(KLogFieldEventRecentString);
1.791 + CLogServViewRecent::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
1.792 + delete colset;
1.793 + }
1.794 + __ASSERT_DEBUG(CLogServViewRecent::iIdColNo > 0 &&
1.795 + CLogServViewRecent::iRecentColNo > 0 &&
1.796 + CLogServViewRecent::iDuplicateColNo > 0, User::Invariant());
1.797 +
1.798 + }
1.799 +
1.800 +/////////////////////////////////////////////////////////////////////////////////////////
1.801 +// -----> CLogServViewDuplicate (source)
1.802 +/////////////////////////////////////////////////////////////////////////////////////////
1.803 +CLogServViewDuplicate::CLogServViewDuplicate(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.804 +: CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeDuplicate, aViewId, aMessage)
1.805 +//
1.806 +// Duplicate view
1.807 +//
1.808 + {
1.809 + }
1.810 +
1.811 +CLogServViewDuplicate* CLogServViewDuplicate::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
1.812 + {
1.813 + CLogServViewDuplicate* self = new(ELeave) CLogServViewDuplicate(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
1.814 + CleanupStack::PushL(self);
1.815 + self->ConstructL();
1.816 + CleanupStack::Pop(self);
1.817 + return self;
1.818 + }
1.819 +
1.820 +/**
1.821 +Setup the view
1.822 +Fetch the client-side SQL query string which this view uses to obtain a data-set.
1.823 +*/
1.824 +TPtrC CLogServViewDuplicate::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
1.825 + {
1.826 + // Read stuff from the client
1.827 + iPackage.ResizeL(aMessage.GetDesLengthL(2));
1.828 + aMessage.ReadL(2, iPackage.Ptr());
1.829 +
1.830 + // Decode the parameters we've read from the client
1.831 + CLogFilterList* filter = new(ELeave)CLogFilterList;
1.832 + CleanupStack::PushL(TCleanupItem(DestroyList, filter));
1.833 + iPackage.GetLogFilterListL(*filter);
1.834 + RLogDynBuf expr;
1.835 + TLogFilterExprBuilder exprBuilder(iDatabase);
1.836 + exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
1.837 + iSourceId = (TInt)aMessage.Ptr3();
1.838 + // Generate the view that will be used
1.839 + TheSql.Format(KLogSqlDuplicateViewString2, &KLogViewSelectColList, iSourceId, &expr.DesC());
1.840 + CleanupStack::PopAndDestroy(2, filter);
1.841 + return TheSql;
1.842 + }
1.843 +
1.844 +/**
1.845 +Remove an entry from the view.
1.846 +*/
1.847 +void CLogServViewDuplicate::RemoveL(const RMessage2& aMessage)
1.848 + {
1.849 + if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
1.850 + User::Leave(KErrPermissionDenied);
1.851 +
1.852 + const TLogId id = static_cast<TLogId>(aMessage.Int2());
1.853 +
1.854 + iDatabase.DTIBeginWithRollBackProtectionLC();
1.855 +
1.856 + // Do the actual work
1.857 + TheSql.Format(KLogSqlRemoveDuplicateString, id, iSourceId);
1.858 + const TInt error = iDatabase.DTIExecuteSql(TheSql);
1.859 + User::LeaveIfError(error);
1.860 + //
1.861 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.862 + iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
1.863 + iDatabase.DTICommitAndCancelRollbackProtectionL();
1.864 + }