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