|
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 |
|
16 #include "LOGCHNGE.H" |
|
17 #include <logwraplimits.h> |
|
18 #include <logcntdef.h> |
|
19 #include "LOGQUERY.H" |
|
20 #include "logservpanic.h" |
|
21 #include "LogServRecentList.h" |
|
22 #include "LogServCacheConfig.h" |
|
23 #include "LogServRecentListManager.h" |
|
24 #include "LogServDatabaseTransactionInterface.h" |
|
25 #include "LogServDatabaseChangeInterface.h" |
|
26 #include "LOGDUP.H" |
|
27 #include "LogServCacheStrings.h" |
|
28 #include "LogServSqlStrings.h" |
|
29 |
|
30 //********************************** |
|
31 // CLogChangeEvent |
|
32 //********************************** |
|
33 |
|
34 CLogChangeEvent::CLogChangeEvent(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority) |
|
35 : CLogActive(aPriority), iDatabase(aDatabase) |
|
36 { |
|
37 } |
|
38 |
|
39 CLogChangeEvent::~CLogChangeEvent() |
|
40 { |
|
41 Cancel(); |
|
42 // |
|
43 delete iEvent; |
|
44 delete iDuplicate; |
|
45 delete iDuplicateFilter; |
|
46 } |
|
47 |
|
48 void CLogChangeEvent::ConstructL() |
|
49 { |
|
50 iEvent = CLogEvent::NewL(); |
|
51 iDuplicate = CLogDuplicate::NewL(iDatabase, Priority()); |
|
52 iDuplicateFilter = CLogFilter::NewL(); |
|
53 } |
|
54 |
|
55 CLogChangeEvent* CLogChangeEvent::NewL(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority) |
|
56 { |
|
57 CLogChangeEvent* self = new(ELeave)CLogChangeEvent(aDatabase, aPriority); |
|
58 CleanupStack::PushL(self); |
|
59 self->ConstructL(); |
|
60 CleanupStack::Pop(); |
|
61 return self; |
|
62 } |
|
63 |
|
64 void CLogChangeEvent::StartL(const CLogEvent& aEvent, const CLogServRecentList* aRecentList, TRequestStatus& aStatus, const RMessage2& aMessage) |
|
65 { |
|
66 __ASSERT_ALWAYS(iState == ELogNone, Panic(ELogBadState2)); |
|
67 __ASSERT_DEBUG(!IsActive(), Panic(ELogAlreadyActive3)); |
|
68 |
|
69 iMessage = &aMessage; |
|
70 iEvent->CopyL(aEvent); |
|
71 iState = ELogChangeEvent; |
|
72 iRecentList = aRecentList; // Need to use this! (5yrs later - okay then :-) |
|
73 iOldRecentList = KLogNullRecentList; |
|
74 |
|
75 Queue(aStatus); |
|
76 TRequestStatus* status = &iStatus; |
|
77 User::RequestComplete(status, KErrNone); |
|
78 SetActive(); |
|
79 } |
|
80 |
|
81 void CLogChangeEvent::DoRunL() |
|
82 { |
|
83 __ASSERT_DEBUG(iState != ELogNone, Panic(ELogBadState3)); |
|
84 |
|
85 switch (iState) |
|
86 { |
|
87 case ELogChangeEvent: |
|
88 DoChangeEventL(); |
|
89 ResetDuplicatesL(); |
|
90 UpdateDuplicateEventsL(); |
|
91 break; |
|
92 case ELogPurgeRecent: |
|
93 { |
|
94 RArray<TLogId> logIds; |
|
95 ::LogGetRecentEventsLC(iDatabase, iRecentList->Id(), iDatabase.DTICacheConfig().Config().iMaxRecentLogSize, logIds); |
|
96 ::LogPurgeRecentEventsL(iDatabase, logIds); |
|
97 CleanupStack::PopAndDestroy(&logIds); |
|
98 } |
|
99 break; |
|
100 default: |
|
101 __ASSERT_DEBUG(ETrue, Panic(ELogBadState4)); |
|
102 break; |
|
103 } |
|
104 } |
|
105 |
|
106 void CLogChangeEvent::DoComplete(TInt& aStatus) |
|
107 { |
|
108 if (iDatabase.DTIInTransaction()) |
|
109 { |
|
110 if (aStatus == KErrNone) |
|
111 aStatus = iDatabase.DTICommitAndEnd(); |
|
112 |
|
113 if (aStatus < KErrNone) |
|
114 iDatabase.DTIRollBack(); |
|
115 } |
|
116 |
|
117 iState = ELogNone; |
|
118 } |
|
119 |
|
120 void CLogChangeEvent::ResetDuplicatesL() |
|
121 { |
|
122 // Was it in a recent list? Is it now changing lists? |
|
123 if (iOldRecentList > 0 && (!iRecentList || iOldRecentList != iRecentList->Id())) |
|
124 { |
|
125 ::LogResetDuplicatesL(iDatabase, iEvent->Id()); |
|
126 } |
|
127 } |
|
128 |
|
129 void CLogChangeEvent::UpdateDuplicateEventsL() |
|
130 { |
|
131 // Detect duplicate events if we've added an event to a recent list |
|
132 if (iOldRecentList > 0 && iRecentList && iOldRecentList != iRecentList->Id()) |
|
133 { |
|
134 iRecentList->GetFilter(*iEvent, *iDuplicateFilter); |
|
135 // If we get here we have added an event to a recent list, which may need to be purged |
|
136 iState = ELogPurgeRecent; |
|
137 // Passing -1 into this will ensure that events are updated so the most recent duplicate is first |
|
138 if (!iDuplicate->StartL(-1, iRecentList->Id(), *iDuplicateFilter, iStatus)) |
|
139 { |
|
140 // Complete ourselves |
|
141 TRequestStatus* status = &iStatus; |
|
142 User::RequestComplete(status, KErrNone); |
|
143 } |
|
144 SetActive(); |
|
145 } |
|
146 } |
|
147 |
|
148 void CLogChangeEvent::DoChangeEventL() |
|
149 { |
|
150 RLogEventDbTable tbl; |
|
151 tbl.OpenLC(iDatabase.DTIDatabase()); |
|
152 User::LeaveIfError(tbl.SetIndex(KLogNameEventIdx1)); |
|
153 if(!tbl.SeekL(TDbSeekKey((TInt)iEvent->Id()))) |
|
154 { |
|
155 User::Leave(KErrNotFound); |
|
156 } |
|
157 User::LeaveIfError(iDatabase.DTIBegin()); |
|
158 tbl.GetL(); |
|
159 iOldRecentList = tbl.ColInt8(RLogEventDbTable::iRecentColNo); |
|
160 DoChangeL(tbl, iDatabase.DTICacheStrings().GetIdL(iEvent->Direction()), iDatabase.DTICacheStrings().GetIdL(iEvent->Status())); |
|
161 CleanupStack::PopAndDestroy();//tbl |
|
162 } |
|
163 |
|
164 void CLogChangeEvent::DoChangeL(RLogEventDbTable& aTbl, TLogStringId aDirectionId, TLogStringId aStatusId) |
|
165 { |
|
166 if(!iDatabase.DTIIsAllowed(EWriteOp, *iMessage, iEvent->EventType())) |
|
167 { |
|
168 User::Leave(KErrPermissionDenied); |
|
169 } |
|
170 |
|
171 aTbl.UpdateL(); |
|
172 |
|
173 if (iEvent->RemoteParty().Length() > 0) |
|
174 aTbl.SetColL(RLogEventDbTable::iRemotePartyColNo, iEvent->RemoteParty()); |
|
175 else |
|
176 aTbl.SetColNullL(RLogEventDbTable::iRemotePartyColNo); |
|
177 |
|
178 if (iEvent->Direction().Length() > 0) |
|
179 aTbl.SetColL(RLogEventDbTable::iDirectionColNo, (TUint32)aDirectionId); |
|
180 else |
|
181 aTbl.SetColNullL(RLogEventDbTable::iDirectionColNo); |
|
182 |
|
183 aTbl.SetColL(RLogEventDbTable::iTimeColNo, iEvent->Time()); |
|
184 aTbl.SetColL(RLogEventDbTable::iDurationTypeColNo, (TInt32)iEvent->DurationType()); |
|
185 |
|
186 if (iEvent->DurationType() != KLogNullDurationType) |
|
187 aTbl.SetColL(RLogEventDbTable::iDurationColNo, iEvent->Duration()); |
|
188 else |
|
189 aTbl.SetColNullL(RLogEventDbTable::iDurationColNo); |
|
190 |
|
191 if (iEvent->Status().Length() > 0) |
|
192 aTbl.SetColL(RLogEventDbTable::iStatusColNo, (TUint32)aStatusId); |
|
193 else |
|
194 aTbl.SetColNullL(RLogEventDbTable::iStatusColNo); |
|
195 |
|
196 if (iEvent->Subject().Length() > 0) |
|
197 aTbl.SetColL(RLogEventDbTable::iSubjectColNo, iEvent->Subject()); |
|
198 else |
|
199 aTbl.SetColNullL(RLogEventDbTable::iSubjectColNo); |
|
200 |
|
201 if (iEvent->Number().Length() > 0) |
|
202 aTbl.SetColL(RLogEventDbTable::iNumberColNo, iEvent->Number()); |
|
203 else |
|
204 aTbl.SetColNullL(RLogEventDbTable::iNumberColNo); |
|
205 |
|
206 if (iEvent->Contact() != KLogNullContactId) |
|
207 aTbl.SetColL(RLogEventDbTable::iContactColNo, iEvent->Contact()); |
|
208 else |
|
209 aTbl.SetColNullL(RLogEventDbTable::iContactColNo); |
|
210 |
|
211 if (iEvent->Link() != KLogNullLink) |
|
212 aTbl.SetColL(RLogEventDbTable::iLinkColNo, iEvent->Link()); |
|
213 else |
|
214 aTbl.SetColNullL(RLogEventDbTable::iLinkColNo); |
|
215 |
|
216 if (iEvent->Data().Length() > 0) |
|
217 aTbl.SetColL(RLogEventDbTable::iDataColNo, iEvent->Data()); |
|
218 else |
|
219 aTbl.SetColNullL(RLogEventDbTable::iDataColNo); |
|
220 |
|
221 // Set the flags |
|
222 TInt bit = KLogFlagsCount; |
|
223 while(bit--) |
|
224 { |
|
225 aTbl.SetColL(RLogEventDbTable::iFlagColNo[bit], (TUint32)((iEvent->Flags() & 0x1 << bit) ? 1 : 0)); |
|
226 } |
|
227 |
|
228 // Set the recent list |
|
229 if (iOldRecentList > 0) |
|
230 { |
|
231 // Removing an event from all recent lists? |
|
232 if (!iRecentList) |
|
233 { |
|
234 aTbl.SetColNullL(RLogEventDbTable::iRecentColNo); |
|
235 aTbl.SetColNullL(RLogEventDbTable::iDuplicateColNo); |
|
236 } |
|
237 // Changing list? |
|
238 else if (iOldRecentList != iRecentList->Id()) |
|
239 { |
|
240 __ASSERT_DEBUG(iRecentList->Id() != KLogNullRecentList, Panic(ELogNullRecentList)); |
|
241 aTbl.SetColL(RLogEventDbTable::iRecentColNo, (TInt32)iRecentList->Id()); |
|
242 |
|
243 // This is set to -1 to prevent it temporarily appearing in a recent or duplicate view |
|
244 // It gets updated properly later when detecting duplicates |
|
245 aTbl.SetColL(RLogEventDbTable::iDuplicateColNo, -1); |
|
246 } |
|
247 } |
|
248 |
|
249 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM |
|
250 if(iEvent->SimId() != KLogNullSimId) |
|
251 aTbl.SetColL(RLogEventDbTable::iSimIdColNo, iEvent->SimId()); |
|
252 else |
|
253 aTbl.SetColNullL(RLogEventDbTable::iSimIdColNo); |
|
254 #endif |
|
255 |
|
256 aTbl.PutL(); |
|
257 |
|
258 iDatabase.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChanged, iEvent->Id()); |
|
259 } |
|
260 |
|
261 //********************************** |
|
262 // CLogChangeConfig |
|
263 //********************************** |
|
264 |
|
265 CLogChangeConfig::CLogChangeConfig(MLogServDatabaseTransactionInterface& aDatabase, const CLogServRecentListManager& aRecentSetup, TInt aPriority) |
|
266 : CLogActive(aPriority), iDatabase(aDatabase), iRecentSetup(aRecentSetup) |
|
267 { |
|
268 } |
|
269 |
|
270 CLogChangeConfig::~CLogChangeConfig() |
|
271 { |
|
272 Cancel(); |
|
273 } |
|
274 |
|
275 CLogChangeConfig* CLogChangeConfig::NewL(MLogServDatabaseTransactionInterface& aDatabase, const CLogServRecentListManager& aRecentSetup, TInt aPriority) |
|
276 { |
|
277 CLogChangeConfig* self = new(ELeave) CLogChangeConfig(aDatabase, aRecentSetup, aPriority); |
|
278 return self; |
|
279 } |
|
280 |
|
281 void CLogChangeConfig::StartL(const TLogConfig& aConfig, TRequestStatus& aStatus) |
|
282 { |
|
283 __ASSERT_ALWAYS(iState == ELogNone, Panic(ELogBadState5)); |
|
284 __ASSERT_DEBUG(!IsActive(), Panic(ELogAlreadyActive4)); |
|
285 |
|
286 iState = ELogChange; |
|
287 iConfig = &aConfig; |
|
288 |
|
289 Queue(aStatus); |
|
290 TRequestStatus* status = &iStatus; |
|
291 User::RequestComplete(status, KErrNone); |
|
292 SetActive(); |
|
293 } |
|
294 |
|
295 void CLogChangeConfig::DoRunL() |
|
296 { |
|
297 switch (iState) |
|
298 { |
|
299 case ELogChange: |
|
300 { |
|
301 // Start a transaction |
|
302 User::LeaveIfError(iDatabase.DTIBegin()); |
|
303 // Change the config, using the existing transaction |
|
304 iDatabase.DTICacheConfig().UpdateL(*iConfig); |
|
305 //Purge old events |
|
306 RLogEventDbTable tbl; |
|
307 tbl.OpenLC(iDatabase.DTIDatabase()); |
|
308 ::LogPurgeMainL(iDatabase, tbl, iConfig->iMaxLogSize, 0); |
|
309 CleanupStack::PopAndDestroy(&tbl); |
|
310 iRecent = 0; |
|
311 // |
|
312 iState = ELogPurgeRecent; |
|
313 TRequestStatus* status = &iStatus; |
|
314 User::RequestComplete(status, KErrNone); |
|
315 SetActive(); |
|
316 break; |
|
317 } |
|
318 case ELogPurgeRecent: |
|
319 { |
|
320 // Are there any more recent lists to check |
|
321 if(iRecent >= iRecentSetup.Count()) |
|
322 { |
|
323 break; |
|
324 } |
|
325 RArray<TLogId> logIds; |
|
326 ::LogGetRecentEventsLC(iDatabase, iRecentSetup.List(iRecent).Id(), iConfig->iMaxRecentLogSize, logIds); |
|
327 ::LogPurgeRecentEventsL(iDatabase, logIds); |
|
328 CleanupStack::PopAndDestroy(&logIds); |
|
329 // Purge next recent list? |
|
330 if (++iRecent < iRecentSetup.Count()) |
|
331 { |
|
332 iState = ELogPurgeRecent; |
|
333 TRequestStatus* status = &iStatus; |
|
334 User::RequestComplete(status, KErrNone); |
|
335 SetActive(); |
|
336 } |
|
337 break; |
|
338 } |
|
339 default: |
|
340 __ASSERT_DEBUG(ETrue, Panic(ELogBadState6)); |
|
341 break; |
|
342 } |
|
343 } |
|
344 |
|
345 void CLogChangeConfig::DoComplete(TInt& aStatus) |
|
346 { |
|
347 // Try and commit the transaction |
|
348 if (iDatabase.DTIInTransaction()) |
|
349 { |
|
350 if (aStatus == KErrNone) |
|
351 aStatus = iDatabase.DTICommitAndEnd(); |
|
352 |
|
353 if (aStatus < KErrNone) |
|
354 { |
|
355 iDatabase.DTICacheConfig().Rollback(); |
|
356 iDatabase.DTIRollBack(); |
|
357 } |
|
358 else |
|
359 { |
|
360 iDatabase.DTICacheConfig().Commit(); |
|
361 } |
|
362 } |
|
363 __ASSERT_DEBUG(!iDatabase.DTICacheConfig().InTransaction(), Panic(ELogChangeConfigLogicError)); |
|
364 iState = ELogNone; |
|
365 } |