os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServView.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-2009 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
#include "LogServView.h"
sl@0
    16
#include "logpackage.h"
sl@0
    17
#include "logservpanic.h"
sl@0
    18
#include "LogServBackupInterface.h"
sl@0
    19
#include "LogServViewChangeManager.h"
sl@0
    20
#include "LogServDatabaseChangeInterface.h"
sl@0
    21
#include "LogServCacheTypes.h"
sl@0
    22
#include "LogServSqlStrings.h"
sl@0
    23
#include "LOGFILTQ.H"
sl@0
    24
sl@0
    25
// Constants
sl@0
    26
const TInt KLogViewContentsGranuality = 20;
sl@0
    27
const TInt KLogViewLockStatusEventGranularity = 3;
sl@0
    28
sl@0
    29
TDbColNo CLogServViewBase::iIdColNo = 0;
sl@0
    30
TDbColNo CLogServViewBase::iTypeColNo = 0;
sl@0
    31
TDbColNo CLogServViewBase::iFlagColNo[] = {0, 0, 0, 0};
sl@0
    32
sl@0
    33
TDbColNo CLogServViewRecent::iIdColNo = 0;
sl@0
    34
TDbColNo CLogServViewRecent::iRecentColNo = 0;
sl@0
    35
TDbColNo CLogServViewRecent::iDuplicateColNo = 0;
sl@0
    36
sl@0
    37
//diagnostic message for the platform security
sl@0
    38
const char* KIgnoreDiagnostic = "This diagnostic message does not indicate an error, please ignore it";
sl@0
    39
sl@0
    40
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    41
// -----> CLogServViewBase (source)
sl@0
    42
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
    43
CLogServViewBase::CLogServViewBase(MLogServDatabaseTransactionInterface& aDatabase, 
sl@0
    44
                                   MLogServBackupInterface& aBackupInterface, 
sl@0
    45
                                   CLogPackage& aPackage, TLogViewType aType, TLogViewId aViewId, 
sl@0
    46
                                   const RMessage2& aMessage) :
sl@0
    47
    iDatabase(aDatabase), 
sl@0
    48
    iPackage(aPackage),
sl@0
    49
    iBackupInterface(aBackupInterface), 
sl@0
    50
    iType(aType), 
sl@0
    51
    iViewId(aViewId), 
sl@0
    52
    iMessage (aMessage)
sl@0
    53
	{
sl@0
    54
	}
sl@0
    55
sl@0
    56
CLogServViewBase::~CLogServViewBase()
sl@0
    57
	{
sl@0
    58
	iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsCancel(*this);
sl@0
    59
	iBackupInterface.BIObserverRemove(*this);
sl@0
    60
	//
sl@0
    61
	iViewContents.Close();
sl@0
    62
	//	
sl@0
    63
	iStandardTypeSecurityCache.Close();
sl@0
    64
	//
sl@0
    65
	delete iLockChangeObserver;
sl@0
    66
	delete iSql;
sl@0
    67
	delete iChangeManager;
sl@0
    68
	}
sl@0
    69
sl@0
    70
sl@0
    71
void CLogServViewBase::ConstructL()
sl@0
    72
	{
sl@0
    73
	// Handles changes for this view
sl@0
    74
	iChangeManager = CLogServViewChangeManager::NewL(iDatabase.DTIChangeInterface());
sl@0
    75
sl@0
    76
	// Register for change events
sl@0
    77
	iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsL(*this);
sl@0
    78
sl@0
    79
	// Register for backup events
sl@0
    80
	iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectView);
sl@0
    81
sl@0
    82
	// Observes when the view is locked/unlocked due to a backup
sl@0
    83
	iLockChangeObserver = CLogServViewLockObserver::NewL(iBackupInterface);
sl@0
    84
sl@0
    85
	const RArray<TUid>& arrTUids = iDatabase.DTIUidsOfStandardTypes();
sl@0
    86
	TInt count = arrTUids.Count();
sl@0
    87
	iStandardTypeSecurityCache.ReserveL(count);
sl@0
    88
	for(TInt i=0; i < count; i++)
sl@0
    89
		{
sl@0
    90
		SStandardTypeSecurity securitySetting;
sl@0
    91
		securitySetting.eventType = arrTUids[i];
sl@0
    92
		securitySetting.readAccess = iDatabase.DTIIsAllowed(EReadOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
sl@0
    93
		securitySetting.writeAccess = iDatabase.DTIIsAllowed(EWriteOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
sl@0
    94
		TInt err = iStandardTypeSecurityCache.Append(securitySetting);	
sl@0
    95
        __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
sl@0
    96
		}
sl@0
    97
	}
sl@0
    98
sl@0
    99
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   100
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   101
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   102
sl@0
   103
void CLogServViewBase::DCOHandleChangeEventsL(const CLogChangeDefinition& aChanges)
sl@0
   104
	{
sl@0
   105
	// Just return if the view isn't setup
sl@0
   106
	if	(!iSql)
sl@0
   107
		return;
sl@0
   108
sl@0
   109
	TRAPD(error, DoHandleChangeEventsL(aChanges));
sl@0
   110
	if	(error != KErrNone)
sl@0
   111
		{
sl@0
   112
		iViewContents.Close();
sl@0
   113
	    iViewContentsReady = EFalse;
sl@0
   114
		iRebuildViewContents = ETrue;
sl@0
   115
		}
sl@0
   116
	}
sl@0
   117
sl@0
   118
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   119
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   120
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   121
sl@0
   122
void CLogServViewBase::BOHandleEventL(TLogServBackupEvent aEvent)
sl@0
   123
	{
sl@0
   124
	switch(aEvent)
sl@0
   125
		{
sl@0
   126
	case EBackupStarting:
sl@0
   127
		iViewContents.Close();
sl@0
   128
	    iViewContentsReady = EFalse;
sl@0
   129
		break;
sl@0
   130
	case EBackupEnded:
sl@0
   131
		RebuildViewL();
sl@0
   132
		break;
sl@0
   133
		}
sl@0
   134
	}
sl@0
   135
sl@0
   136
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   137
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   138
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   139
sl@0
   140
#pragma BullseyeCoverage off
sl@0
   141
sl@0
   142
/**
sl@0
   143
Remove an entry from the view.
sl@0
   144
By default you can't remove an event from a view.
sl@0
   145
*/
sl@0
   146
void CLogServViewBase::RemoveL(const RMessage2& /*aMessage*/)
sl@0
   147
	{
sl@0
   148
	User::Leave(KErrNotSupported);
sl@0
   149
	}
sl@0
   150
sl@0
   151
/**
sl@0
   152
By default you can't clear duplicates from a view
sl@0
   153
*/
sl@0
   154
void CLogServViewBase::ClearDuplicatesL(const RMessage2& /*aMessage*/)
sl@0
   155
	{
sl@0
   156
	User::Leave(KErrNotSupported);
sl@0
   157
	}
sl@0
   158
sl@0
   159
#pragma BullseyeCoverage on
sl@0
   160
sl@0
   161
/**
sl@0
   162
Set the flags of all the entries in the view.
sl@0
   163
*/
sl@0
   164
void CLogServViewBase::SetFlagsL(const RMessage2& aMessage)
sl@0
   165
	{
sl@0
   166
	if	(ViewIsReady())
sl@0
   167
		{
sl@0
   168
		// Flags from client
sl@0
   169
		const TLogFlags flags = static_cast<TLogFlags>(aMessage.Int2());
sl@0
   170
		RLogDbView view;
sl@0
   171
		view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
sl@0
   172
		InitializeColumnsL(view);
sl@0
   173
		if(view.FirstL())
sl@0
   174
			{
sl@0
   175
            iDatabase.DTIBeginWithRollBackProtectionLC();
sl@0
   176
			// Iterate through the events
sl@0
   177
			do
sl@0
   178
				{
sl@0
   179
				// Get current event id
sl@0
   180
				view.GetL();
sl@0
   181
				const TLogId id = view.ColInt32(CLogServViewBase::iIdColNo);
sl@0
   182
				TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
sl@0
   183
				if(IsAllowed(EWriteOp, eventTypeIndex))
sl@0
   184
					{
sl@0
   185
					// Make the change
sl@0
   186
					view.UpdateL();
sl@0
   187
		            TInt bit = KLogFlagsCount;
sl@0
   188
		            while(bit--)
sl@0
   189
		                {
sl@0
   190
                        const TBool flagIsSet = flags & (0x1 << bit) ? 1 : 0;
sl@0
   191
		                view.SetColL(CLogServViewBase::iFlagColNo[bit], flagIsSet);
sl@0
   192
		                }
sl@0
   193
					view.PutL();
sl@0
   194
					iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChanged, id);
sl@0
   195
					}
sl@0
   196
				}
sl@0
   197
			while(view.NextL());
sl@0
   198
			iDatabase.DTICommitAndCancelRollbackProtectionL();
sl@0
   199
			}
sl@0
   200
		CleanupStack::PopAndDestroy(&view);
sl@0
   201
		}
sl@0
   202
	else
sl@0
   203
		::PanicClientL(aMessage, ELogViewRecentViewNotYetReadyForFlagSetting);
sl@0
   204
	}
sl@0
   205
sl@0
   206
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   207
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   208
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   209
sl@0
   210
/**
sl@0
   211
The client has requested change notifications
sl@0
   212
*/
sl@0
   213
void CLogServViewBase::RequestChangeNotifications(const RMessage2& aMessage)
sl@0
   214
	{
sl@0
   215
	iChangeManager->RequestChangeNotifications(aMessage);
sl@0
   216
	}
sl@0
   217
sl@0
   218
/**
sl@0
   219
The client has cancelled a previous change notification request
sl@0
   220
*/
sl@0
   221
void CLogServViewBase::RequestChangeNotificationsCancel()
sl@0
   222
	{
sl@0
   223
	iChangeManager->RequestChangeNotificationsCancel();
sl@0
   224
	}
sl@0
   225
sl@0
   226
/**
sl@0
   227
The client has requested lock status change notifications
sl@0
   228
*/
sl@0
   229
void CLogServViewBase::RequestLockStatusChanges(const RMessage2& aMessage)
sl@0
   230
	{
sl@0
   231
	iLockChangeObserver->RequestLockStatusChanges(aMessage);
sl@0
   232
	}
sl@0
   233
sl@0
   234
/**
sl@0
   235
The client has cancelled a previous change notification request
sl@0
   236
*/
sl@0
   237
void CLogServViewBase::RequestLockStatusChangesCancel()
sl@0
   238
	{
sl@0
   239
	iLockChangeObserver->RequestLockStatusChangesCancel();
sl@0
   240
	}
sl@0
   241
sl@0
   242
/**
sl@0
   243
The client has requested the current list of changes
sl@0
   244
*/
sl@0
   245
void CLogServViewBase::RequestChangesL(const RMessage2& aMessage)
sl@0
   246
	{
sl@0
   247
	if	(!iSql)
sl@0
   248
		::PanicClientL(aMessage, ELogViewNotSetupForChangesFetch);
sl@0
   249
	else
sl@0
   250
		iChangeManager->DeliverChangesL(aMessage);
sl@0
   251
	}
sl@0
   252
sl@0
   253
/**
sl@0
   254
Set up the server-side view based upon the client-side filter. This
sl@0
   255
method essentially fetches a client-side filter and then dynamically
sl@0
   256
executes the associated SELECT statement on the database to build up
sl@0
   257
a view. This view is then cached in terms of the entry ids (iViewContents).
sl@0
   258
*/
sl@0
   259
void CLogServViewBase::SetupL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
sl@0
   260
	{
sl@0
   261
	// Get the query string
sl@0
   262
	const TPtrC pSQL(GetQueryStringL(aMessage, aFilterType));
sl@0
   263
	HBufC* buf = pSQL.AllocLC();
sl@0
   264
	// Setup the contents
sl@0
   265
	PrepareViewContentsL(pSQL);
sl@0
   266
	// Tidy up
sl@0
   267
	CleanupStack::Pop(buf);
sl@0
   268
	delete iSql;
sl@0
   269
	iSql = buf;
sl@0
   270
	}
sl@0
   271
sl@0
   272
/**
sl@0
   273
Returns the number of entries in this view
sl@0
   274
*/
sl@0
   275
TInt CLogServViewBase::Count() const
sl@0
   276
	{
sl@0
   277
	return const_cast<CLogServViewBase*>(this)->RebuildViewContentsIfNecessary() ? 0 : iViewContents.Count(); 
sl@0
   278
	}
sl@0
   279
sl@0
   280
/**
sl@0
   281
Get the log id at the specified index
sl@0
   282
*/
sl@0
   283
TLogId CLogServViewBase::At(TInt aIndex) const
sl@0
   284
	{
sl@0
   285
	return (TUint)aIndex < iViewContents.Count() ? iViewContents[aIndex] : KLogNullId;   
sl@0
   286
	}
sl@0
   287
sl@0
   288
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   289
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   290
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   291
sl@0
   292
void CLogServViewBase::DestroyList(TAny *aPtr)
sl@0
   293
	{
sl@0
   294
	CLogFilterList* filter = reinterpret_cast<CLogFilterList*>(aPtr);
sl@0
   295
	filter->ResetAndDestroy();
sl@0
   296
	delete filter;
sl@0
   297
	}
sl@0
   298
sl@0
   299
void CLogServViewBase::InitializeColumnsL(RDbRowSet& aRowSet)
sl@0
   300
    {
sl@0
   301
    if(CLogServViewBase::iIdColNo == 0)
sl@0
   302
        {
sl@0
   303
        CDbColSet* colset = aRowSet.ColSetL();
sl@0
   304
        CLogServViewBase::iIdColNo = colset->ColNo(KLogFieldIdString);
sl@0
   305
        CLogServViewBase::iTypeColNo = colset->ColNo(KLogFieldEventTypeString);
sl@0
   306
        for(TInt i=0;i<KLogFlagsCount;++i)
sl@0
   307
            {
sl@0
   308
            TDbColName colname;
sl@0
   309
            colname.Format(KLogFieldEventFlagString, i + 1);
sl@0
   310
            CLogServViewBase::iFlagColNo[i] = colset->ColNo(colname);
sl@0
   311
            __ASSERT_DEBUG(CLogServViewBase::iFlagColNo[i] > 0, User::Invariant());
sl@0
   312
            }
sl@0
   313
        delete colset;
sl@0
   314
        }
sl@0
   315
    __ASSERT_DEBUG(CLogServViewBase::iIdColNo > 0 && CLogServViewBase::iTypeColNo > 0, User::Invariant());  
sl@0
   316
    }
sl@0
   317
sl@0
   318
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   319
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   320
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   321
sl@0
   322
void CLogServViewBase::ResetViewContentsL(RDbRowSet& aRowSet)
sl@0
   323
	{
sl@0
   324
	// Get the view contents
sl@0
   325
	RArray<TLogId> viewContents(KLogViewContentsGranuality);
sl@0
   326
	CleanupClosePushL(viewContents);
sl@0
   327
	viewContents.ReserveL(aRowSet.CountL());
sl@0
   328
	if(aRowSet.FirstL())
sl@0
   329
		{
sl@0
   330
		do
sl@0
   331
			{
sl@0
   332
			// Get the id at the current position
sl@0
   333
			aRowSet.GetL();
sl@0
   334
			const TLogId id = aRowSet.ColInt32(CLogServViewBase::iIdColNo);
sl@0
   335
			TUint8 eventTypeIndex = aRowSet.ColUint8(CLogServViewBase::iTypeColNo);
sl@0
   336
			if(IsAllowed(EReadOp, eventTypeIndex))
sl@0
   337
			    {
sl@0
   338
				TInt err = viewContents.Append(id);
sl@0
   339
		        __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
sl@0
   340
			    }
sl@0
   341
			}
sl@0
   342
		while(aRowSet.NextL());
sl@0
   343
		}
sl@0
   344
	// Tidy up - don't leave from below here
sl@0
   345
    CleanupStack::Pop(&viewContents);
sl@0
   346
	iViewContents.Close();
sl@0
   347
	iViewContents = viewContents;
sl@0
   348
    iViewContentsReady = ETrue;
sl@0
   349
	}
sl@0
   350
sl@0
   351
void CLogServViewBase::PrepareViewContentsL(const TDesC& aSQL)
sl@0
   352
	{
sl@0
   353
	// Generate the view
sl@0
   354
    RLogDbView view;
sl@0
   355
    view.PrepareLC(iDatabase.DTIDatabase(), aSQL);
sl@0
   356
    InitializeColumnsL(view);
sl@0
   357
	// Reset the view
sl@0
   358
	ResetViewContentsL(view);
sl@0
   359
	CleanupStack::PopAndDestroy(&view);
sl@0
   360
	}
sl@0
   361
sl@0
   362
void CLogServViewBase::RebuildViewL()
sl@0
   363
	{
sl@0
   364
	if	(iSql && iSql->Length())
sl@0
   365
		PrepareViewContentsL(*iSql);
sl@0
   366
	}
sl@0
   367
sl@0
   368
//
sl@0
   369
//  The last change notification indication was not handled correctly.
sl@0
   370
//  Attempt to re-initialise the view
sl@0
   371
//
sl@0
   372
TInt CLogServViewBase::RebuildViewContentsIfNecessary()
sl@0
   373
	{
sl@0
   374
	TInt error = KErrNone;
sl@0
   375
	//
sl@0
   376
	if	(iRebuildViewContents && iSql && iSql->Length())
sl@0
   377
		{
sl@0
   378
		TRAP(error, 
sl@0
   379
sl@0
   380
			RebuildViewL();
sl@0
   381
sl@0
   382
			// The view is okay now
sl@0
   383
			iRebuildViewContents = EFalse;
sl@0
   384
			);
sl@0
   385
		}
sl@0
   386
	return error;
sl@0
   387
	}
sl@0
   388
sl@0
   389
void CLogServViewBase::DoHandleChangeEventsL(const CLogChangeDefinition& aChanges)
sl@0
   390
	{
sl@0
   391
    if(!ViewIsReady())
sl@0
   392
        {
sl@0
   393
        return;
sl@0
   394
        }
sl@0
   395
	
sl@0
   396
	// Generate the view
sl@0
   397
    RLogDbView view;
sl@0
   398
    view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
sl@0
   399
    InitializeColumnsL(view);
sl@0
   400
	_LIT(KLogIdQuery, "Id = %d");
sl@0
   401
	TBuf<15> find;
sl@0
   402
	TInt changeIndex;
sl@0
   403
sl@0
   404
	// Prepare for a change transaction
sl@0
   405
	iChangeManager->ChangeTransactionPrepare();
sl@0
   406
sl@0
   407
	const TInt count = aChanges.Count();
sl@0
   408
	for(TInt i=0; i<count; i++)
sl@0
   409
		{
sl@0
   410
		// Fetch the change details
sl@0
   411
		TLogId logId = KLogNullId;
sl@0
   412
		TLogDatabaseChangeType type = aChanges.At(i, logId);
sl@0
   413
sl@0
   414
		// Mark the insertion position as 'not found'
sl@0
   415
		changeIndex = KErrNotFound;
sl@0
   416
sl@0
   417
		// Format the find query
sl@0
   418
		find.Format(KLogIdQuery, logId);
sl@0
   419
sl@0
   420
		// Handle the various change descriptions
sl@0
   421
		switch(type)
sl@0
   422
			{
sl@0
   423
		case ELogChangeTypeEventAdded:
sl@0
   424
			{
sl@0
   425
			__ASSERT_DEBUG(iViewContents.Find(logId) == KErrNotFound, Panic(ELogEventAlreadyInView));
sl@0
   426
sl@0
   427
			// See if the event is in the view
sl@0
   428
			if(view.FirstL())
sl@0
   429
				{
sl@0
   430
				const TDbQuery dbQuery(find);
sl@0
   431
				changeIndex = view.FindL(RDbRowSet::EForwards, dbQuery);
sl@0
   432
				if	(changeIndex >= 0)
sl@0
   433
					{
sl@0
   434
					view.GetL();
sl@0
   435
					TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
sl@0
   436
					if (IsAllowed(EReadOp, eventTypeIndex))
sl@0
   437
						User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
sl@0
   438
					
sl@0
   439
					iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
sl@0
   440
					}
sl@0
   441
				}
sl@0
   442
			}
sl@0
   443
			break;
sl@0
   444
		case ELogChangeTypeEventChanged:
sl@0
   445
		case ELogChangeTypeEventChangedHidden:
sl@0
   446
			{
sl@0
   447
			// See if the event is in the view
sl@0
   448
			if	(view.FirstL() && (changeIndex = view.FindL(RDbRowSet::EForwards, TDbQuery(find))) >= KErrNone)
sl@0
   449
				{
sl@0
   450
				// If the event was already in the view then it has changed otherwise it's been added
sl@0
   451
				const TInt findIndex = iViewContents.Find(logId);
sl@0
   452
				if	(findIndex >= KErrNone)
sl@0
   453
					{
sl@0
   454
					// If the item that changed also caused its position within the view to be altered
sl@0
   455
					// then we need to simulate a delete, followed by an addition
sl@0
   456
					if	(findIndex != changeIndex)
sl@0
   457
						{
sl@0
   458
						iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, findIndex);
sl@0
   459
						iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
sl@0
   460
						}
sl@0
   461
					// Only tell the view if the CLogEvent has changed
sl@0
   462
					else if (type != ELogChangeTypeEventChangedHidden)
sl@0
   463
						{
sl@0
   464
						iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventChanged, changeIndex);
sl@0
   465
						}
sl@0
   466
					}
sl@0
   467
				else
sl@0
   468
					{
sl@0
   469
					User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
sl@0
   470
					iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
sl@0
   471
sl@0
   472
					// Update the type to indicate that this change action
sl@0
   473
					// really resulted in an addition
sl@0
   474
					type = ELogChangeTypeEventAdded;
sl@0
   475
					}
sl@0
   476
				}
sl@0
   477
			else
sl@0
   478
				{
sl@0
   479
				changeIndex = iViewContents.Find(logId);
sl@0
   480
sl@0
   481
				// If it used to be in the view then it's been removed because it's 
sl@0
   482
				// not in there anymore
sl@0
   483
				if	(changeIndex >= KErrNone)
sl@0
   484
					{
sl@0
   485
					iViewContents.Remove(changeIndex);
sl@0
   486
					iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
sl@0
   487
sl@0
   488
					// Update the type to indicate that this change action
sl@0
   489
					// really resulted in a deletion
sl@0
   490
					type = ELogChangeTypeEventDeleted;
sl@0
   491
					}
sl@0
   492
				}
sl@0
   493
			}
sl@0
   494
			break;
sl@0
   495
		case ELogChangeTypeEventDeleted:
sl@0
   496
			{
sl@0
   497
			changeIndex = iViewContents.Find(logId);
sl@0
   498
sl@0
   499
			// If it used to be in the view then tell it about the deletion
sl@0
   500
			if	(changeIndex >= KErrNone)
sl@0
   501
				{
sl@0
   502
				iViewContents.Remove(changeIndex);
sl@0
   503
				iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
sl@0
   504
				}
sl@0
   505
			}
sl@0
   506
			break;
sl@0
   507
		case ELogChangeTypeLogCleared:
sl@0
   508
			{
sl@0
   509
			RebuildViewL();
sl@0
   510
			iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeLogCleared, 0);
sl@0
   511
			}
sl@0
   512
			break;
sl@0
   513
		default:
sl@0
   514
			__ASSERT_DEBUG(EFalse, Panic(ELogUnrecognizedChangeType));
sl@0
   515
			break;
sl@0
   516
			}
sl@0
   517
		}
sl@0
   518
sl@0
   519
	CleanupStack::PopAndDestroy(&view);
sl@0
   520
sl@0
   521
	// Commit the transaction. Will notify client if necessary
sl@0
   522
	iChangeManager->ChangeTransactionCommitL();
sl@0
   523
	}
sl@0
   524
sl@0
   525
TBool CLogServViewBase::IsAllowed(TEventOp aEventOp, TUint8 aEventTypeIndex)
sl@0
   526
	{
sl@0
   527
	TBool result = ETrue;
sl@0
   528
sl@0
   529
	const TLogServCacheTypeEntry& entry = iDatabase.DTICacheTypes().FindById(aEventTypeIndex);
sl@0
   530
	TUid eventTypeUid = entry.iEventType->Uid();
sl@0
   531
	TInt count = iStandardTypeSecurityCache.Count();
sl@0
   532
		
sl@0
   533
	for(TInt i=0;i<count;++i)
sl@0
   534
		{
sl@0
   535
		if (eventTypeUid == iStandardTypeSecurityCache[i].eventType)
sl@0
   536
			{
sl@0
   537
			result = (aEventOp == EWriteOp) ? iStandardTypeSecurityCache[i].writeAccess : iStandardTypeSecurityCache[i].readAccess;
sl@0
   538
			break;
sl@0
   539
			}
sl@0
   540
		}
sl@0
   541
	
sl@0
   542
	return result;
sl@0
   543
	}
sl@0
   544
sl@0
   545
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   546
// -----> CLogServViewLockObserver (source)
sl@0
   547
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   548
sl@0
   549
CLogServViewLockObserver::CLogServViewLockObserver(MLogServBackupInterface& aBackupInterface)
sl@0
   550
:	iBackupInterface(aBackupInterface), iLockEvents(KLogViewLockStatusEventGranularity)
sl@0
   551
	{
sl@0
   552
	}
sl@0
   553
sl@0
   554
CLogServViewLockObserver::~CLogServViewLockObserver()
sl@0
   555
	{
sl@0
   556
	iBackupInterface.BIObserverRemove(*this);
sl@0
   557
	iLockEvents.Close();
sl@0
   558
	}
sl@0
   559
sl@0
   560
void CLogServViewLockObserver::ConstructL()
sl@0
   561
	{
sl@0
   562
	// Register for backup events
sl@0
   563
	iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectViewLock);
sl@0
   564
	}
sl@0
   565
sl@0
   566
CLogServViewLockObserver* CLogServViewLockObserver::NewL(MLogServBackupInterface& aBackupInterface)
sl@0
   567
	{
sl@0
   568
	CLogServViewLockObserver* self = new(ELeave) CLogServViewLockObserver(aBackupInterface);
sl@0
   569
	CleanupStack::PushL(self);
sl@0
   570
	self->ConstructL();
sl@0
   571
	CleanupStack::Pop(self);
sl@0
   572
	return self;
sl@0
   573
	}
sl@0
   574
sl@0
   575
void CLogServViewLockObserver::BOHandleEventL(TLogServBackupEvent aEvent)
sl@0
   576
	{
sl@0
   577
	// Map event
sl@0
   578
	TLogViewLockStatus status = ELogViewWindowOpen;
sl@0
   579
	if	(aEvent == MLogServBackupObserver::EBackupStarting)
sl@0
   580
		status = ELogViewWindowLocked;
sl@0
   581
sl@0
   582
	// Cache or complete immediately
sl@0
   583
	if	(!HaveLockStatusChangePointer())
sl@0
   584
		User::LeaveIfError(iLockEvents.Append(status));
sl@0
   585
	else
sl@0
   586
		CompleteLockStatusChangeMessage(status);
sl@0
   587
	}
sl@0
   588
sl@0
   589
/**
sl@0
   590
The client has requested lock status change notifications
sl@0
   591
*/
sl@0
   592
void CLogServViewLockObserver::RequestLockStatusChanges(const RMessage2& aMessage)
sl@0
   593
	{
sl@0
   594
	if	(!HaveLockStatusChangePointer())
sl@0
   595
		{
sl@0
   596
		iLockStatusChangeMessage = aMessage;
sl@0
   597
		
sl@0
   598
		// Already have one cached event
sl@0
   599
		if	(iLockEvents.Count())
sl@0
   600
			{
sl@0
   601
			CompleteLockStatusChangeMessage(iLockEvents[0]);
sl@0
   602
			iLockEvents.Remove(0);
sl@0
   603
			}
sl@0
   604
		}
sl@0
   605
	else
sl@0
   606
		PanicClient(aMessage, ELogViewLockStatusChangeRequestAlreadyIssued);
sl@0
   607
	}
sl@0
   608
sl@0
   609
/**
sl@0
   610
The client has cancelled a previous change notification request
sl@0
   611
*/
sl@0
   612
void CLogServViewLockObserver::RequestLockStatusChangesCancel()
sl@0
   613
	{
sl@0
   614
	if	(HaveLockStatusChangePointer())
sl@0
   615
		CompleteLockStatusChangeMessage(KErrCancel);
sl@0
   616
	}
sl@0
   617
sl@0
   618
void  CLogServViewLockObserver::CompleteLockStatusChangeMessage(TInt aCompletionCode)
sl@0
   619
	{
sl@0
   620
	__ASSERT_ALWAYS(HaveLockStatusChangePointer(), Panic(ELogViewNoLockStatusChangeMessage));
sl@0
   621
	iLockStatusChangeMessage.Complete(aCompletionCode);
sl@0
   622
	}
sl@0
   623
sl@0
   624
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   625
// -----> CLogServViewEvent (source)
sl@0
   626
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   627
CLogServViewEvent::CLogServViewEvent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   628
:	CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeEvent, aViewId, aMessage)
sl@0
   629
	{
sl@0
   630
	}
sl@0
   631
sl@0
   632
CLogServViewEvent* CLogServViewEvent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   633
	{
sl@0
   634
	CLogServViewEvent* self = new(ELeave) CLogServViewEvent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
sl@0
   635
	CleanupStack::PushL(self);
sl@0
   636
	self->ConstructL();
sl@0
   637
	CleanupStack::Pop(self);
sl@0
   638
	return self;
sl@0
   639
	}
sl@0
   640
sl@0
   641
/**
sl@0
   642
Setup the view
sl@0
   643
Fetch the client-side SQL query string which this view uses to obtain a data-set.
sl@0
   644
*/
sl@0
   645
TPtrC CLogServViewEvent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType) 
sl@0
   646
	{
sl@0
   647
	// Read stuff from the client
sl@0
   648
	iPackage.ResizeL(aMessage.GetDesLengthL(2));
sl@0
   649
	aMessage.ReadL(2, iPackage.Ptr());
sl@0
   650
sl@0
   651
	// Decode the parameters we've read from the client
sl@0
   652
	CLogFilterList* filter = new(ELeave)CLogFilterList;
sl@0
   653
	CleanupStack::PushL(TCleanupItem(DestroyList, filter));
sl@0
   654
	iPackage.GetLogFilterListL(*filter);
sl@0
   655
	RLogDynBuf expr;
sl@0
   656
    TLogFilterExprBuilder exprBuilder(iDatabase);
sl@0
   657
    exprBuilder.BuildExprLC(expr, *filter, KLogWhere, aFilterType);
sl@0
   658
    // Generate the query string that will be used
sl@0
   659
    TheSql.Format(KLogSqlEventViewString, &KLogViewSelectColList, &expr.DesC());
sl@0
   660
    CleanupStack::PopAndDestroy(2, filter);
sl@0
   661
	return TheSql;
sl@0
   662
	}
sl@0
   663
sl@0
   664
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   665
// -----> CLogServViewRecent (source)
sl@0
   666
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   667
CLogServViewRecent::CLogServViewRecent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   668
:	CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeRecent, aViewId, aMessage)
sl@0
   669
	{
sl@0
   670
	}
sl@0
   671
sl@0
   672
CLogServViewRecent* CLogServViewRecent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   673
	{
sl@0
   674
	CLogServViewRecent* self = new(ELeave) CLogServViewRecent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
sl@0
   675
	CleanupStack::PushL(self);
sl@0
   676
	self->ConstructL();
sl@0
   677
	CleanupStack::Pop(self);
sl@0
   678
	return self;
sl@0
   679
	}
sl@0
   680
sl@0
   681
/**
sl@0
   682
Setup the view
sl@0
   683
Fetch the client-side SQL query string which this view uses to obtain a data-set.
sl@0
   684
*/
sl@0
   685
TPtrC CLogServViewRecent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
sl@0
   686
	{
sl@0
   687
	// Read stuff from the client
sl@0
   688
	iPackage.ResizeL(aMessage.GetDesLengthL(2));
sl@0
   689
	aMessage.ReadL(2, iPackage.Ptr());
sl@0
   690
sl@0
   691
	// Decode the parameters we've read from the client
sl@0
   692
	CLogFilterList* filter = new(ELeave)CLogFilterList;
sl@0
   693
	CleanupStack::PushL(TCleanupItem(DestroyList, filter));
sl@0
   694
	iPackage.GetLogFilterListL(*filter);
sl@0
   695
	RLogDynBuf expr;
sl@0
   696
	TLogFilterExprBuilder exprBuilder(iDatabase);
sl@0
   697
	exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
sl@0
   698
    iRecentList = static_cast<TLogRecentList>(aMessage.Int3());
sl@0
   699
    // Generate the view that will be used
sl@0
   700
    if (iRecentList == KLogNullRecentList)
sl@0
   701
        {
sl@0
   702
        TheSql.Format(KLogSqlAllRecentViewString, &KLogViewSelectColList, &expr.DesC());
sl@0
   703
        }
sl@0
   704
    else
sl@0
   705
        {
sl@0
   706
        TheSql.Format(KLogSqlRecentViewString, &KLogViewSelectColList, iRecentList, &expr.DesC());
sl@0
   707
        }
sl@0
   708
    CleanupStack::PopAndDestroy(2, filter);
sl@0
   709
	return TheSql;
sl@0
   710
	}
sl@0
   711
sl@0
   712
/**
sl@0
   713
Remove an entry from the view.
sl@0
   714
Note the client can call this even if the view isn't valid.
sl@0
   715
*/
sl@0
   716
void CLogServViewRecent::RemoveL(const RMessage2& aMessage)
sl@0
   717
	{
sl@0
   718
	if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
sl@0
   719
		User::Leave(KErrPermissionDenied);
sl@0
   720
		
sl@0
   721
	const TLogId id = static_cast<TLogId>(aMessage.Int2());
sl@0
   722
    TBuf<20> num;
sl@0
   723
    num.AppendNum(id);
sl@0
   724
sl@0
   725
	iDatabase.DTIBeginWithRollBackProtectionLC();
sl@0
   726
	
sl@0
   727
    TheSql.Copy(KLogSqlRemoveDuplicateEvents);
sl@0
   728
    TheSql.Append(KIdEqStr);
sl@0
   729
    TheSql.Append(num);
sl@0
   730
    TheSql.Append(KLogOr);
sl@0
   731
    TheSql.Append(KDuplicateEqStr);
sl@0
   732
    TheSql.Append(num);
sl@0
   733
    User::LeaveIfError(iDatabase.DTIExecuteSql(TheSql));
sl@0
   734
sl@0
   735
	// This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
sl@0
   736
	iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
sl@0
   737
	iDatabase.DTICommitAndCancelRollbackProtectionL();
sl@0
   738
	}
sl@0
   739
sl@0
   740
/**
sl@0
   741
Clear all duplicate events associated with this recent list.
sl@0
   742
*/
sl@0
   743
void CLogServViewRecent::ClearDuplicatesL(const RMessage2& aMessage)
sl@0
   744
	{
sl@0
   745
	if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
sl@0
   746
		User::Leave(KErrPermissionDenied);
sl@0
   747
	
sl@0
   748
	if	(iRecentList > 0)
sl@0
   749
		{
sl@0
   750
		// Get list of duplicates
sl@0
   751
		TheSql.Format(KLogSqlSelectAllDuplicatesString, iRecentList);
sl@0
   752
        RLogDbView view;
sl@0
   753
        view.PrepareLC(iDatabase.DTIDatabase(), TheSql);
sl@0
   754
        InitializeColumns2L(view);
sl@0
   755
		if(view.FirstL())
sl@0
   756
			{
sl@0
   757
            iDatabase.DTIBeginWithRollBackProtectionLC();
sl@0
   758
			// Iterate through the events
sl@0
   759
			do
sl@0
   760
				{
sl@0
   761
				// Get current event id
sl@0
   762
				view.GetL();
sl@0
   763
				const TLogId id = view.ColInt32(CLogServViewRecent::iIdColNo);
sl@0
   764
				// Make the change
sl@0
   765
				view.UpdateL();
sl@0
   766
				view.SetColNullL(CLogServViewRecent::iRecentColNo);
sl@0
   767
				view.SetColNullL(CLogServViewRecent::iDuplicateColNo);
sl@0
   768
				view.PutL();
sl@0
   769
				// This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
sl@0
   770
				iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
sl@0
   771
				}
sl@0
   772
			while(view.NextL());
sl@0
   773
			iDatabase.DTICommitAndCancelRollbackProtectionL();
sl@0
   774
			}
sl@0
   775
		CleanupStack::PopAndDestroy(&view);
sl@0
   776
		}
sl@0
   777
	else
sl@0
   778
		::PanicClientL(aMessage, ELogInvalidRecentView);
sl@0
   779
	}
sl@0
   780
sl@0
   781
void CLogServViewRecent::InitializeColumns2L(RDbRowSet& aRowSet)
sl@0
   782
    {
sl@0
   783
    if(CLogServViewRecent::iIdColNo == 0)
sl@0
   784
        {
sl@0
   785
        CDbColSet* colset = aRowSet.ColSetL();
sl@0
   786
        CLogServViewRecent::iIdColNo = colset->ColNo(KLogFieldIdString);
sl@0
   787
        CLogServViewRecent::iRecentColNo = colset->ColNo(KLogFieldEventRecentString);
sl@0
   788
        CLogServViewRecent::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
sl@0
   789
        delete colset;
sl@0
   790
        }
sl@0
   791
    __ASSERT_DEBUG(CLogServViewRecent::iIdColNo > 0 && 
sl@0
   792
            CLogServViewRecent::iRecentColNo > 0 && 
sl@0
   793
            CLogServViewRecent::iDuplicateColNo > 0, User::Invariant());  
sl@0
   794
        
sl@0
   795
    }
sl@0
   796
sl@0
   797
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   798
// -----> CLogServViewDuplicate (source)
sl@0
   799
/////////////////////////////////////////////////////////////////////////////////////////
sl@0
   800
CLogServViewDuplicate::CLogServViewDuplicate(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   801
:	CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeDuplicate, aViewId, aMessage)
sl@0
   802
//
sl@0
   803
//	Duplicate view
sl@0
   804
//
sl@0
   805
	{
sl@0
   806
	}
sl@0
   807
sl@0
   808
CLogServViewDuplicate* CLogServViewDuplicate::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
sl@0
   809
	{
sl@0
   810
	CLogServViewDuplicate* self = new(ELeave) CLogServViewDuplicate(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
sl@0
   811
	CleanupStack::PushL(self);
sl@0
   812
	self->ConstructL();
sl@0
   813
	CleanupStack::Pop(self);
sl@0
   814
	return self;
sl@0
   815
	}
sl@0
   816
sl@0
   817
/**
sl@0
   818
Setup the view
sl@0
   819
Fetch the client-side SQL query string which this view uses to obtain a data-set.
sl@0
   820
*/
sl@0
   821
TPtrC CLogServViewDuplicate::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
sl@0
   822
	{
sl@0
   823
	// Read stuff from the client
sl@0
   824
	iPackage.ResizeL(aMessage.GetDesLengthL(2));
sl@0
   825
	aMessage.ReadL(2, iPackage.Ptr());
sl@0
   826
sl@0
   827
	// Decode the parameters we've read from the client
sl@0
   828
	CLogFilterList* filter = new(ELeave)CLogFilterList;
sl@0
   829
	CleanupStack::PushL(TCleanupItem(DestroyList, filter));
sl@0
   830
	iPackage.GetLogFilterListL(*filter);
sl@0
   831
	RLogDynBuf expr;
sl@0
   832
	TLogFilterExprBuilder exprBuilder(iDatabase);
sl@0
   833
	exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
sl@0
   834
	iSourceId = (TInt)aMessage.Ptr3();
sl@0
   835
    // Generate the view that will be used
sl@0
   836
    TheSql.Format(KLogSqlDuplicateViewString2, &KLogViewSelectColList, iSourceId, &expr.DesC());
sl@0
   837
    CleanupStack::PopAndDestroy(2, filter);
sl@0
   838
	return TheSql;
sl@0
   839
	}
sl@0
   840
sl@0
   841
/**
sl@0
   842
Remove an entry from the view.
sl@0
   843
*/
sl@0
   844
void CLogServViewDuplicate::RemoveL(const RMessage2& aMessage)
sl@0
   845
	{
sl@0
   846
	if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
sl@0
   847
		User::Leave(KErrPermissionDenied);
sl@0
   848
sl@0
   849
	const TLogId id = static_cast<TLogId>(aMessage.Int2());
sl@0
   850
sl@0
   851
	iDatabase.DTIBeginWithRollBackProtectionLC();
sl@0
   852
sl@0
   853
	// Do the actual work
sl@0
   854
	TheSql.Format(KLogSqlRemoveDuplicateString, id, iSourceId);
sl@0
   855
	const TInt error = iDatabase.DTIExecuteSql(TheSql);
sl@0
   856
	User::LeaveIfError(error);
sl@0
   857
	//
sl@0
   858
	// This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
sl@0
   859
	iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
sl@0
   860
	iDatabase.DTICommitAndCancelRollbackProtectionL();
sl@0
   861
	}