First public contribution.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
15 #include "LogServView.h"
16 #include "logpackage.h"
17 #include "logservpanic.h"
18 #include "LogServBackupInterface.h"
19 #include "LogServViewChangeManager.h"
20 #include "LogServDatabaseChangeInterface.h"
21 #include "LogServCacheTypes.h"
22 #include "LogServSqlStrings.h"
26 const TInt KLogViewContentsGranuality = 20;
27 const TInt KLogViewLockStatusEventGranularity = 3;
29 TDbColNo CLogServViewBase::iIdColNo = 0;
30 TDbColNo CLogServViewBase::iTypeColNo = 0;
31 TDbColNo CLogServViewBase::iFlagColNo[] = {0, 0, 0, 0};
33 TDbColNo CLogServViewRecent::iIdColNo = 0;
34 TDbColNo CLogServViewRecent::iRecentColNo = 0;
35 TDbColNo CLogServViewRecent::iDuplicateColNo = 0;
37 //diagnostic message for the platform security
38 const char* KIgnoreDiagnostic = "This diagnostic message does not indicate an error, please ignore it";
40 /////////////////////////////////////////////////////////////////////////////////////////
41 // -----> CLogServViewBase (source)
42 /////////////////////////////////////////////////////////////////////////////////////////
43 CLogServViewBase::CLogServViewBase(MLogServDatabaseTransactionInterface& aDatabase,
44 MLogServBackupInterface& aBackupInterface,
45 CLogPackage& aPackage, TLogViewType aType, TLogViewId aViewId,
46 const RMessage2& aMessage) :
49 iBackupInterface(aBackupInterface),
56 CLogServViewBase::~CLogServViewBase()
58 iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsCancel(*this);
59 iBackupInterface.BIObserverRemove(*this);
61 iViewContents.Close();
63 iStandardTypeSecurityCache.Close();
65 delete iLockChangeObserver;
67 delete iChangeManager;
71 void CLogServViewBase::ConstructL()
73 // Handles changes for this view
74 iChangeManager = CLogServViewChangeManager::NewL(iDatabase.DTIChangeInterface());
76 // Register for change events
77 iDatabase.DTIChangeInterface().DCIRequestChangeNotificationsL(*this);
79 // Register for backup events
80 iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectView);
82 // Observes when the view is locked/unlocked due to a backup
83 iLockChangeObserver = CLogServViewLockObserver::NewL(iBackupInterface);
85 const RArray<TUid>& arrTUids = iDatabase.DTIUidsOfStandardTypes();
86 TInt count = arrTUids.Count();
87 iStandardTypeSecurityCache.ReserveL(count);
88 for(TInt i=0; i < count; i++)
90 SStandardTypeSecurity securitySetting;
91 securitySetting.eventType = arrTUids[i];
92 securitySetting.readAccess = iDatabase.DTIIsAllowed(EReadOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
93 securitySetting.writeAccess = iDatabase.DTIIsAllowed(EWriteOp, iMessage, arrTUids[i], KIgnoreDiagnostic);
94 TInt err = iStandardTypeSecurityCache.Append(securitySetting);
95 __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
99 /////////////////////////////////////////////////////////////////////////////////////////
100 /////////////////////////////////////////////////////////////////////////////////////////
101 /////////////////////////////////////////////////////////////////////////////////////////
103 void CLogServViewBase::DCOHandleChangeEventsL(const CLogChangeDefinition& aChanges)
105 // Just return if the view isn't setup
109 TRAPD(error, DoHandleChangeEventsL(aChanges));
110 if (error != KErrNone)
112 iViewContents.Close();
113 iViewContentsReady = EFalse;
114 iRebuildViewContents = ETrue;
118 /////////////////////////////////////////////////////////////////////////////////////////
119 /////////////////////////////////////////////////////////////////////////////////////////
120 /////////////////////////////////////////////////////////////////////////////////////////
122 void CLogServViewBase::BOHandleEventL(TLogServBackupEvent aEvent)
126 case EBackupStarting:
127 iViewContents.Close();
128 iViewContentsReady = EFalse;
136 /////////////////////////////////////////////////////////////////////////////////////////
137 /////////////////////////////////////////////////////////////////////////////////////////
138 /////////////////////////////////////////////////////////////////////////////////////////
140 #pragma BullseyeCoverage off
143 Remove an entry from the view.
144 By default you can't remove an event from a view.
146 void CLogServViewBase::RemoveL(const RMessage2& /*aMessage*/)
148 User::Leave(KErrNotSupported);
152 By default you can't clear duplicates from a view
154 void CLogServViewBase::ClearDuplicatesL(const RMessage2& /*aMessage*/)
156 User::Leave(KErrNotSupported);
159 #pragma BullseyeCoverage on
162 Set the flags of all the entries in the view.
164 void CLogServViewBase::SetFlagsL(const RMessage2& aMessage)
169 const TLogFlags flags = static_cast<TLogFlags>(aMessage.Int2());
171 view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
172 InitializeColumnsL(view);
175 iDatabase.DTIBeginWithRollBackProtectionLC();
176 // Iterate through the events
179 // Get current event id
181 const TLogId id = view.ColInt32(CLogServViewBase::iIdColNo);
182 TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
183 if(IsAllowed(EWriteOp, eventTypeIndex))
187 TInt bit = KLogFlagsCount;
190 const TBool flagIsSet = flags & (0x1 << bit) ? 1 : 0;
191 view.SetColL(CLogServViewBase::iFlagColNo[bit], flagIsSet);
194 iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChanged, id);
198 iDatabase.DTICommitAndCancelRollbackProtectionL();
200 CleanupStack::PopAndDestroy(&view);
203 ::PanicClientL(aMessage, ELogViewRecentViewNotYetReadyForFlagSetting);
206 /////////////////////////////////////////////////////////////////////////////////////////
207 /////////////////////////////////////////////////////////////////////////////////////////
208 /////////////////////////////////////////////////////////////////////////////////////////
211 The client has requested change notifications
213 void CLogServViewBase::RequestChangeNotifications(const RMessage2& aMessage)
215 iChangeManager->RequestChangeNotifications(aMessage);
219 The client has cancelled a previous change notification request
221 void CLogServViewBase::RequestChangeNotificationsCancel()
223 iChangeManager->RequestChangeNotificationsCancel();
227 The client has requested lock status change notifications
229 void CLogServViewBase::RequestLockStatusChanges(const RMessage2& aMessage)
231 iLockChangeObserver->RequestLockStatusChanges(aMessage);
235 The client has cancelled a previous change notification request
237 void CLogServViewBase::RequestLockStatusChangesCancel()
239 iLockChangeObserver->RequestLockStatusChangesCancel();
243 The client has requested the current list of changes
245 void CLogServViewBase::RequestChangesL(const RMessage2& aMessage)
248 ::PanicClientL(aMessage, ELogViewNotSetupForChangesFetch);
250 iChangeManager->DeliverChangesL(aMessage);
254 Set up the server-side view based upon the client-side filter. This
255 method essentially fetches a client-side filter and then dynamically
256 executes the associated SELECT statement on the database to build up
257 a view. This view is then cached in terms of the entry ids (iViewContents).
259 void CLogServViewBase::SetupL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
261 // Get the query string
262 const TPtrC pSQL(GetQueryStringL(aMessage, aFilterType));
263 HBufC* buf = pSQL.AllocLC();
264 // Setup the contents
265 PrepareViewContentsL(pSQL);
267 CleanupStack::Pop(buf);
273 Returns the number of entries in this view
275 TInt CLogServViewBase::Count() const
277 return const_cast<CLogServViewBase*>(this)->RebuildViewContentsIfNecessary() ? 0 : iViewContents.Count();
281 Get the log id at the specified index
283 TLogId CLogServViewBase::At(TInt aIndex) const
285 return (TUint)aIndex < iViewContents.Count() ? iViewContents[aIndex] : KLogNullId;
288 /////////////////////////////////////////////////////////////////////////////////////////
289 /////////////////////////////////////////////////////////////////////////////////////////
290 /////////////////////////////////////////////////////////////////////////////////////////
292 void CLogServViewBase::DestroyList(TAny *aPtr)
294 CLogFilterList* filter = reinterpret_cast<CLogFilterList*>(aPtr);
295 filter->ResetAndDestroy();
299 void CLogServViewBase::InitializeColumnsL(RDbRowSet& aRowSet)
301 if(CLogServViewBase::iIdColNo == 0)
303 CDbColSet* colset = aRowSet.ColSetL();
304 CLogServViewBase::iIdColNo = colset->ColNo(KLogFieldIdString);
305 CLogServViewBase::iTypeColNo = colset->ColNo(KLogFieldEventTypeString);
306 for(TInt i=0;i<KLogFlagsCount;++i)
309 colname.Format(KLogFieldEventFlagString, i + 1);
310 CLogServViewBase::iFlagColNo[i] = colset->ColNo(colname);
311 __ASSERT_DEBUG(CLogServViewBase::iFlagColNo[i] > 0, User::Invariant());
315 __ASSERT_DEBUG(CLogServViewBase::iIdColNo > 0 && CLogServViewBase::iTypeColNo > 0, User::Invariant());
318 /////////////////////////////////////////////////////////////////////////////////////////
319 /////////////////////////////////////////////////////////////////////////////////////////
320 /////////////////////////////////////////////////////////////////////////////////////////
322 void CLogServViewBase::ResetViewContentsL(RDbRowSet& aRowSet)
324 // Get the view contents
325 RArray<TLogId> viewContents(KLogViewContentsGranuality);
326 CleanupClosePushL(viewContents);
327 viewContents.ReserveL(aRowSet.CountL());
332 // Get the id at the current position
334 const TLogId id = aRowSet.ColInt32(CLogServViewBase::iIdColNo);
335 TUint8 eventTypeIndex = aRowSet.ColUint8(CLogServViewBase::iTypeColNo);
336 if(IsAllowed(EReadOp, eventTypeIndex))
338 TInt err = viewContents.Append(id);
339 __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved));
342 while(aRowSet.NextL());
344 // Tidy up - don't leave from below here
345 CleanupStack::Pop(&viewContents);
346 iViewContents.Close();
347 iViewContents = viewContents;
348 iViewContentsReady = ETrue;
351 void CLogServViewBase::PrepareViewContentsL(const TDesC& aSQL)
355 view.PrepareLC(iDatabase.DTIDatabase(), aSQL);
356 InitializeColumnsL(view);
358 ResetViewContentsL(view);
359 CleanupStack::PopAndDestroy(&view);
362 void CLogServViewBase::RebuildViewL()
364 if (iSql && iSql->Length())
365 PrepareViewContentsL(*iSql);
369 // The last change notification indication was not handled correctly.
370 // Attempt to re-initialise the view
372 TInt CLogServViewBase::RebuildViewContentsIfNecessary()
374 TInt error = KErrNone;
376 if (iRebuildViewContents && iSql && iSql->Length())
382 // The view is okay now
383 iRebuildViewContents = EFalse;
389 void CLogServViewBase::DoHandleChangeEventsL(const CLogChangeDefinition& aChanges)
398 view.PrepareLC(iDatabase.DTIDatabase(), *iSql);
399 InitializeColumnsL(view);
400 _LIT(KLogIdQuery, "Id = %d");
404 // Prepare for a change transaction
405 iChangeManager->ChangeTransactionPrepare();
407 const TInt count = aChanges.Count();
408 for(TInt i=0; i<count; i++)
410 // Fetch the change details
411 TLogId logId = KLogNullId;
412 TLogDatabaseChangeType type = aChanges.At(i, logId);
414 // Mark the insertion position as 'not found'
415 changeIndex = KErrNotFound;
417 // Format the find query
418 find.Format(KLogIdQuery, logId);
420 // Handle the various change descriptions
423 case ELogChangeTypeEventAdded:
425 __ASSERT_DEBUG(iViewContents.Find(logId) == KErrNotFound, Panic(ELogEventAlreadyInView));
427 // See if the event is in the view
430 const TDbQuery dbQuery(find);
431 changeIndex = view.FindL(RDbRowSet::EForwards, dbQuery);
432 if (changeIndex >= 0)
435 TUint8 eventTypeIndex = view.ColUint8(CLogServViewBase::iTypeColNo);
436 if (IsAllowed(EReadOp, eventTypeIndex))
437 User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
439 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
444 case ELogChangeTypeEventChanged:
445 case ELogChangeTypeEventChangedHidden:
447 // See if the event is in the view
448 if (view.FirstL() && (changeIndex = view.FindL(RDbRowSet::EForwards, TDbQuery(find))) >= KErrNone)
450 // If the event was already in the view then it has changed otherwise it's been added
451 const TInt findIndex = iViewContents.Find(logId);
452 if (findIndex >= KErrNone)
454 // If the item that changed also caused its position within the view to be altered
455 // then we need to simulate a delete, followed by an addition
456 if (findIndex != changeIndex)
458 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, findIndex);
459 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
461 // Only tell the view if the CLogEvent has changed
462 else if (type != ELogChangeTypeEventChangedHidden)
464 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventChanged, changeIndex);
469 User::LeaveIfError(iViewContents.Insert(logId, changeIndex));
470 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventAdded, changeIndex);
472 // Update the type to indicate that this change action
473 // really resulted in an addition
474 type = ELogChangeTypeEventAdded;
479 changeIndex = iViewContents.Find(logId);
481 // If it used to be in the view then it's been removed because it's
482 // not in there anymore
483 if (changeIndex >= KErrNone)
485 iViewContents.Remove(changeIndex);
486 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
488 // Update the type to indicate that this change action
489 // really resulted in a deletion
490 type = ELogChangeTypeEventDeleted;
495 case ELogChangeTypeEventDeleted:
497 changeIndex = iViewContents.Find(logId);
499 // If it used to be in the view then tell it about the deletion
500 if (changeIndex >= KErrNone)
502 iViewContents.Remove(changeIndex);
503 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeEventDeleted, changeIndex);
507 case ELogChangeTypeLogCleared:
510 iChangeManager->ChangeTransactionSubmitL(logId, ELogChangeTypeLogCleared, 0);
514 __ASSERT_DEBUG(EFalse, Panic(ELogUnrecognizedChangeType));
519 CleanupStack::PopAndDestroy(&view);
521 // Commit the transaction. Will notify client if necessary
522 iChangeManager->ChangeTransactionCommitL();
525 TBool CLogServViewBase::IsAllowed(TEventOp aEventOp, TUint8 aEventTypeIndex)
527 TBool result = ETrue;
529 const TLogServCacheTypeEntry& entry = iDatabase.DTICacheTypes().FindById(aEventTypeIndex);
530 TUid eventTypeUid = entry.iEventType->Uid();
531 TInt count = iStandardTypeSecurityCache.Count();
533 for(TInt i=0;i<count;++i)
535 if (eventTypeUid == iStandardTypeSecurityCache[i].eventType)
537 result = (aEventOp == EWriteOp) ? iStandardTypeSecurityCache[i].writeAccess : iStandardTypeSecurityCache[i].readAccess;
545 /////////////////////////////////////////////////////////////////////////////////////////
546 // -----> CLogServViewLockObserver (source)
547 /////////////////////////////////////////////////////////////////////////////////////////
549 CLogServViewLockObserver::CLogServViewLockObserver(MLogServBackupInterface& aBackupInterface)
550 : iBackupInterface(aBackupInterface), iLockEvents(KLogViewLockStatusEventGranularity)
554 CLogServViewLockObserver::~CLogServViewLockObserver()
556 iBackupInterface.BIObserverRemove(*this);
560 void CLogServViewLockObserver::ConstructL()
562 // Register for backup events
563 iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectViewLock);
566 CLogServViewLockObserver* CLogServViewLockObserver::NewL(MLogServBackupInterface& aBackupInterface)
568 CLogServViewLockObserver* self = new(ELeave) CLogServViewLockObserver(aBackupInterface);
569 CleanupStack::PushL(self);
571 CleanupStack::Pop(self);
575 void CLogServViewLockObserver::BOHandleEventL(TLogServBackupEvent aEvent)
578 TLogViewLockStatus status = ELogViewWindowOpen;
579 if (aEvent == MLogServBackupObserver::EBackupStarting)
580 status = ELogViewWindowLocked;
582 // Cache or complete immediately
583 if (!HaveLockStatusChangePointer())
584 User::LeaveIfError(iLockEvents.Append(status));
586 CompleteLockStatusChangeMessage(status);
590 The client has requested lock status change notifications
592 void CLogServViewLockObserver::RequestLockStatusChanges(const RMessage2& aMessage)
594 if (!HaveLockStatusChangePointer())
596 iLockStatusChangeMessage = aMessage;
598 // Already have one cached event
599 if (iLockEvents.Count())
601 CompleteLockStatusChangeMessage(iLockEvents[0]);
602 iLockEvents.Remove(0);
606 PanicClient(aMessage, ELogViewLockStatusChangeRequestAlreadyIssued);
610 The client has cancelled a previous change notification request
612 void CLogServViewLockObserver::RequestLockStatusChangesCancel()
614 if (HaveLockStatusChangePointer())
615 CompleteLockStatusChangeMessage(KErrCancel);
618 void CLogServViewLockObserver::CompleteLockStatusChangeMessage(TInt aCompletionCode)
620 __ASSERT_ALWAYS(HaveLockStatusChangePointer(), Panic(ELogViewNoLockStatusChangeMessage));
621 iLockStatusChangeMessage.Complete(aCompletionCode);
624 /////////////////////////////////////////////////////////////////////////////////////////
625 // -----> CLogServViewEvent (source)
626 /////////////////////////////////////////////////////////////////////////////////////////
627 CLogServViewEvent::CLogServViewEvent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
628 : CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeEvent, aViewId, aMessage)
632 CLogServViewEvent* CLogServViewEvent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
634 CLogServViewEvent* self = new(ELeave) CLogServViewEvent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
635 CleanupStack::PushL(self);
637 CleanupStack::Pop(self);
643 Fetch the client-side SQL query string which this view uses to obtain a data-set.
645 TPtrC CLogServViewEvent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
647 // Read stuff from the client
648 iPackage.ResizeL(aMessage.GetDesLengthL(2));
649 aMessage.ReadL(2, iPackage.Ptr());
651 // Decode the parameters we've read from the client
652 CLogFilterList* filter = new(ELeave)CLogFilterList;
653 CleanupStack::PushL(TCleanupItem(DestroyList, filter));
654 iPackage.GetLogFilterListL(*filter);
656 TLogFilterExprBuilder exprBuilder(iDatabase);
657 exprBuilder.BuildExprLC(expr, *filter, KLogWhere, aFilterType);
658 // Generate the query string that will be used
659 TheSql.Format(KLogSqlEventViewString, &KLogViewSelectColList, &expr.DesC());
660 CleanupStack::PopAndDestroy(2, filter);
664 /////////////////////////////////////////////////////////////////////////////////////////
665 // -----> CLogServViewRecent (source)
666 /////////////////////////////////////////////////////////////////////////////////////////
667 CLogServViewRecent::CLogServViewRecent(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
668 : CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeRecent, aViewId, aMessage)
672 CLogServViewRecent* CLogServViewRecent::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
674 CLogServViewRecent* self = new(ELeave) CLogServViewRecent(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
675 CleanupStack::PushL(self);
677 CleanupStack::Pop(self);
683 Fetch the client-side SQL query string which this view uses to obtain a data-set.
685 TPtrC CLogServViewRecent::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
687 // Read stuff from the client
688 iPackage.ResizeL(aMessage.GetDesLengthL(2));
689 aMessage.ReadL(2, iPackage.Ptr());
691 // Decode the parameters we've read from the client
692 CLogFilterList* filter = new(ELeave)CLogFilterList;
693 CleanupStack::PushL(TCleanupItem(DestroyList, filter));
694 iPackage.GetLogFilterListL(*filter);
696 TLogFilterExprBuilder exprBuilder(iDatabase);
697 exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
698 iRecentList = static_cast<TLogRecentList>(aMessage.Int3());
699 // Generate the view that will be used
700 if (iRecentList == KLogNullRecentList)
702 TheSql.Format(KLogSqlAllRecentViewString, &KLogViewSelectColList, &expr.DesC());
706 TheSql.Format(KLogSqlRecentViewString, &KLogViewSelectColList, iRecentList, &expr.DesC());
708 CleanupStack::PopAndDestroy(2, filter);
713 Remove an entry from the view.
714 Note the client can call this even if the view isn't valid.
716 void CLogServViewRecent::RemoveL(const RMessage2& aMessage)
718 if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
719 User::Leave(KErrPermissionDenied);
721 const TLogId id = static_cast<TLogId>(aMessage.Int2());
725 iDatabase.DTIBeginWithRollBackProtectionLC();
727 TheSql.Copy(KLogSqlRemoveDuplicateEvents);
728 TheSql.Append(KIdEqStr);
730 TheSql.Append(KLogOr);
731 TheSql.Append(KDuplicateEqStr);
733 User::LeaveIfError(iDatabase.DTIExecuteSql(TheSql));
735 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
736 iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
737 iDatabase.DTICommitAndCancelRollbackProtectionL();
741 Clear all duplicate events associated with this recent list.
743 void CLogServViewRecent::ClearDuplicatesL(const RMessage2& aMessage)
745 if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
746 User::Leave(KErrPermissionDenied);
750 // Get list of duplicates
751 TheSql.Format(KLogSqlSelectAllDuplicatesString, iRecentList);
753 view.PrepareLC(iDatabase.DTIDatabase(), TheSql);
754 InitializeColumns2L(view);
757 iDatabase.DTIBeginWithRollBackProtectionLC();
758 // Iterate through the events
761 // Get current event id
763 const TLogId id = view.ColInt32(CLogServViewRecent::iIdColNo);
766 view.SetColNullL(CLogServViewRecent::iRecentColNo);
767 view.SetColNullL(CLogServViewRecent::iDuplicateColNo);
769 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
770 iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
773 iDatabase.DTICommitAndCancelRollbackProtectionL();
775 CleanupStack::PopAndDestroy(&view);
778 ::PanicClientL(aMessage, ELogInvalidRecentView);
781 void CLogServViewRecent::InitializeColumns2L(RDbRowSet& aRowSet)
783 if(CLogServViewRecent::iIdColNo == 0)
785 CDbColSet* colset = aRowSet.ColSetL();
786 CLogServViewRecent::iIdColNo = colset->ColNo(KLogFieldIdString);
787 CLogServViewRecent::iRecentColNo = colset->ColNo(KLogFieldEventRecentString);
788 CLogServViewRecent::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
791 __ASSERT_DEBUG(CLogServViewRecent::iIdColNo > 0 &&
792 CLogServViewRecent::iRecentColNo > 0 &&
793 CLogServViewRecent::iDuplicateColNo > 0, User::Invariant());
797 /////////////////////////////////////////////////////////////////////////////////////////
798 // -----> CLogServViewDuplicate (source)
799 /////////////////////////////////////////////////////////////////////////////////////////
800 CLogServViewDuplicate::CLogServViewDuplicate(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
801 : CLogServViewBase(aDatabase, aBackupInterface, aPackage, ELogViewTypeDuplicate, aViewId, aMessage)
808 CLogServViewDuplicate* CLogServViewDuplicate::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, CLogPackage& aPackage, TLogViewId aViewId, const RMessage2& aMessage)
810 CLogServViewDuplicate* self = new(ELeave) CLogServViewDuplicate(aDatabase, aBackupInterface, aPackage, aViewId, aMessage);
811 CleanupStack::PushL(self);
813 CleanupStack::Pop(self);
819 Fetch the client-side SQL query string which this view uses to obtain a data-set.
821 TPtrC CLogServViewDuplicate::GetQueryStringL(const RMessage2& aMessage, TLogFilterConstructionType aFilterType)
823 // Read stuff from the client
824 iPackage.ResizeL(aMessage.GetDesLengthL(2));
825 aMessage.ReadL(2, iPackage.Ptr());
827 // Decode the parameters we've read from the client
828 CLogFilterList* filter = new(ELeave)CLogFilterList;
829 CleanupStack::PushL(TCleanupItem(DestroyList, filter));
830 iPackage.GetLogFilterListL(*filter);
832 TLogFilterExprBuilder exprBuilder(iDatabase);
833 exprBuilder.BuildExprLC(expr, *filter, KLogAnd, aFilterType);
834 iSourceId = (TInt)aMessage.Ptr3();
835 // Generate the view that will be used
836 TheSql.Format(KLogSqlDuplicateViewString2, &KLogViewSelectColList, iSourceId, &expr.DesC());
837 CleanupStack::PopAndDestroy(2, filter);
842 Remove an entry from the view.
844 void CLogServViewDuplicate::RemoveL(const RMessage2& aMessage)
846 if(! aMessage.HasCapability(ECapabilityWriteDeviceData))
847 User::Leave(KErrPermissionDenied);
849 const TLogId id = static_cast<TLogId>(aMessage.Int2());
851 iDatabase.DTIBeginWithRollBackProtectionLC();
853 // Do the actual work
854 TheSql.Format(KLogSqlRemoveDuplicateString, id, iSourceId);
855 const TInt error = iDatabase.DTIExecuteSql(TheSql);
856 User::LeaveIfError(error);
858 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
859 iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
860 iDatabase.DTICommitAndCancelRollbackProtectionL();