|
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 "LOGQUERY.H" |
|
17 #include "logservpanic.h" |
|
18 #include "LogServDatabaseTransactionInterface.h" |
|
19 #include "LogServDatabaseChangeInterface.h" |
|
20 #include "LogServSqlStrings.h" |
|
21 #include "LogDynBuf.h" |
|
22 |
|
23 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
24 ///////////////////////// RLogDbTable ///////////////////////////////////////////////////////// |
|
25 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
26 |
|
27 /** |
|
28 RLogDbTable "resource acquisition" method. |
|
29 Opens the specified database table with the required access mode. |
|
30 If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde. |
|
31 If the table is opened successfully, the current RLogDbTable object will be put on the cleanup stack. The caller is |
|
32 responsible for the destruction of the RLogDbTable object. |
|
33 |
|
34 @param aDb RDbDatabase reference |
|
35 @param aTblName Table name |
|
36 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values |
|
37 |
|
38 @leave KErrNoMemory, an out of memory condition has occurred; |
|
39 Note that the function may leave with database specific errors and |
|
40 other system-wide error codes. |
|
41 */ |
|
42 void RLogDbTable::OpenLC(RDbDatabase& aDb, const TDesC& aTblName, RDbRowSet::TAccess aAccess) |
|
43 { |
|
44 if(aDb.IsDamaged()) |
|
45 { |
|
46 User::LeaveIfError(aDb.Recover()); |
|
47 } |
|
48 __ASSERT_DEBUG(!aDb.IsDamaged(), Panic(ELogDatabaseDamaged2)); |
|
49 CleanupClosePushL(*this); |
|
50 User::LeaveIfError(RDbTable::Open(aDb, aTblName, aAccess)); |
|
51 } |
|
52 |
|
53 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
54 ///////////////////////// RLogEventDbTable //////////////////////////////////////////////////// |
|
55 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
56 |
|
57 TDbColNo RLogEventDbTable::iIdColNo = 0; |
|
58 TDbColNo RLogEventDbTable::iTypeColNo = 0; |
|
59 TDbColNo RLogEventDbTable::iRemotePartyColNo = 0; |
|
60 TDbColNo RLogEventDbTable::iDirectionColNo = 0; |
|
61 TDbColNo RLogEventDbTable::iTimeColNo = 0; |
|
62 TDbColNo RLogEventDbTable::iDurationTypeColNo = 0; |
|
63 TDbColNo RLogEventDbTable::iDurationColNo = 0; |
|
64 TDbColNo RLogEventDbTable::iStatusColNo = 0; |
|
65 TDbColNo RLogEventDbTable::iSubjectColNo = 0; |
|
66 TDbColNo RLogEventDbTable::iNumberColNo = 0; |
|
67 TDbColNo RLogEventDbTable::iContactColNo = 0; |
|
68 TDbColNo RLogEventDbTable::iLinkColNo = 0; |
|
69 TDbColNo RLogEventDbTable::iDataColNo = 0; |
|
70 TDbColNo RLogEventDbTable::iFlagColNo[] = {0, 0, 0, 0}; |
|
71 TDbColNo RLogEventDbTable::iRecentColNo = 0; |
|
72 TDbColNo RLogEventDbTable::iDuplicateColNo = 0; |
|
73 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM |
|
74 TDbColNo RLogEventDbTable::iSimIdColNo = 0; |
|
75 #endif |
|
76 |
|
77 /** |
|
78 RLogEventDbTable "resource acquisition" method. |
|
79 Opens the "Event" database table with the required access mode. |
|
80 If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde. |
|
81 If the table is opened successfully, the current RLogEventDbTable object will be put on the cleanup stack. The caller is |
|
82 responsible for the destruction of the RLogEventDbTable object. |
|
83 |
|
84 @param aDb RDbDatabase reference |
|
85 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values |
|
86 |
|
87 @leave KErrNoMemory, an out of memory condition has occurred; |
|
88 Note that the function may leave with database specific errors and |
|
89 other system-wide error codes. |
|
90 */ |
|
91 void RLogEventDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess) |
|
92 { |
|
93 RLogDbTable::OpenLC(aDb, KLogNameEventString, aAccess); |
|
94 InitializeColumnsL(); |
|
95 } |
|
96 |
|
97 /** |
|
98 Initializes the static data members ("Event" table column numbers) of the RLogEventDbTable class. |
|
99 The initialization happens just once, during the construction of the first object of RLogEventDbTable type. |
|
100 |
|
101 @leave KErrNoMemory, an out of memory condition has occurred; |
|
102 Note that the function may leave with database specific errors and |
|
103 other system-wide error codes. |
|
104 */ |
|
105 void RLogEventDbTable::InitializeColumnsL() |
|
106 { |
|
107 if(RLogEventDbTable::iIdColNo == 0) |
|
108 { |
|
109 CDbColSet* colset = ColSetL(); |
|
110 RLogEventDbTable::iIdColNo = colset->ColNo(KLogFieldIdString); |
|
111 RLogEventDbTable::iTypeColNo = colset->ColNo(KLogFieldEventTypeString); |
|
112 RLogEventDbTable::iRemotePartyColNo = colset->ColNo(KLogFieldEventRemoteString); |
|
113 RLogEventDbTable::iDirectionColNo = colset->ColNo(KLogFieldEventDirectionString); |
|
114 RLogEventDbTable::iTimeColNo = colset->ColNo(KLogFieldEventTimeString); |
|
115 RLogEventDbTable::iDurationTypeColNo = colset->ColNo(KLogFieldEventDTypeString); |
|
116 RLogEventDbTable::iDurationColNo = colset->ColNo(KLogFieldEventDurationString); |
|
117 RLogEventDbTable::iStatusColNo = colset->ColNo(KLogFieldEventStatusString); |
|
118 RLogEventDbTable::iSubjectColNo = colset->ColNo(KLogFieldEventSubjectString); |
|
119 RLogEventDbTable::iNumberColNo = colset->ColNo(KLogFieldEventNumberString); |
|
120 RLogEventDbTable::iContactColNo = colset->ColNo(KLogFieldEventContactString); |
|
121 RLogEventDbTable::iLinkColNo = colset->ColNo(KLogFieldEventLinkString); |
|
122 RLogEventDbTable::iDataColNo = colset->ColNo(KLogFieldEventDataString); |
|
123 for(TInt i=0;i<KLogFlagsCount;++i) |
|
124 { |
|
125 TDbColName colname; |
|
126 colname.Format(KLogFieldEventFlagString, i + 1); |
|
127 RLogEventDbTable::iFlagColNo[i] = colset->ColNo(colname); |
|
128 __ASSERT_DEBUG(RLogEventDbTable::iFlagColNo[i] > 0, User::Invariant()); |
|
129 } |
|
130 RLogEventDbTable::iRecentColNo = colset->ColNo(KLogFieldEventRecentString); |
|
131 RLogEventDbTable::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString); |
|
132 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM |
|
133 RLogEventDbTable::iSimIdColNo = colset->ColNo(KLogFieldEventSimId); |
|
134 #endif |
|
135 delete colset; |
|
136 } |
|
137 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM |
|
138 __ASSERT_DEBUG(RLogEventDbTable::iIdColNo > 0 && |
|
139 RLogEventDbTable::iTypeColNo > 0 && |
|
140 RLogEventDbTable::iRemotePartyColNo > 0 && |
|
141 RLogEventDbTable::iDirectionColNo > 0 && |
|
142 RLogEventDbTable::iTimeColNo > 0 && |
|
143 RLogEventDbTable::iDurationTypeColNo > 0 && |
|
144 RLogEventDbTable::iDurationColNo > 0 && |
|
145 RLogEventDbTable::iStatusColNo > 0 && |
|
146 RLogEventDbTable::iSubjectColNo > 0 && |
|
147 RLogEventDbTable::iNumberColNo > 0 && |
|
148 RLogEventDbTable::iContactColNo > 0 && |
|
149 RLogEventDbTable::iLinkColNo > 0 && |
|
150 RLogEventDbTable::iDataColNo > 0 && |
|
151 RLogEventDbTable::iRecentColNo > 0 && |
|
152 RLogEventDbTable::iDuplicateColNo > 0 && |
|
153 RLogEventDbTable::iSimIdColNo > 0, User::Invariant()); |
|
154 #else |
|
155 __ASSERT_DEBUG(RLogEventDbTable::iIdColNo > 0 && |
|
156 RLogEventDbTable::iTypeColNo > 0 && |
|
157 RLogEventDbTable::iRemotePartyColNo > 0 && |
|
158 RLogEventDbTable::iDirectionColNo > 0 && |
|
159 RLogEventDbTable::iTimeColNo > 0 && |
|
160 RLogEventDbTable::iDurationTypeColNo > 0 && |
|
161 RLogEventDbTable::iDurationColNo > 0 && |
|
162 RLogEventDbTable::iStatusColNo > 0 && |
|
163 RLogEventDbTable::iSubjectColNo > 0 && |
|
164 RLogEventDbTable::iNumberColNo > 0 && |
|
165 RLogEventDbTable::iContactColNo > 0 && |
|
166 RLogEventDbTable::iLinkColNo > 0 && |
|
167 RLogEventDbTable::iDataColNo > 0 && |
|
168 RLogEventDbTable::iRecentColNo > 0 && |
|
169 RLogEventDbTable::iDuplicateColNo > 0, User::Invariant()); |
|
170 #endif |
|
171 } |
|
172 |
|
173 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
174 ///////////////////////// RLogConfigDbTable /////////////////////////////////////////////////// |
|
175 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
176 |
|
177 TDbColNo RLogConfigDbTable::iSizeColNo = 0; |
|
178 TDbColNo RLogConfigDbTable::iRecentColNo = 0; |
|
179 TDbColNo RLogConfigDbTable::iAgeColNo = 0; |
|
180 |
|
181 /** |
|
182 RLogConfigDbTable "resource acquisition" method. |
|
183 Opens the "Config" database table with the required access mode. |
|
184 If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde. |
|
185 If the table is opened successfully, the current RLogConfigDbTable object will be put on the cleanup stack. The caller is |
|
186 responsible for the destruction of the RLogConfigDbTable object. |
|
187 |
|
188 @param aDb RDbDatabase reference |
|
189 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values |
|
190 |
|
191 @leave KErrNoMemory, an out of memory condition has occurred; |
|
192 Note that the function may leave with database specific errors and |
|
193 other system-wide error codes. |
|
194 */ |
|
195 void RLogConfigDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess) |
|
196 { |
|
197 RLogDbTable::OpenLC(aDb, KLogNameConfigString, aAccess); |
|
198 InitializeColumnsL(); |
|
199 } |
|
200 |
|
201 /** |
|
202 Initializes the static data members ("Config" table column numbers) of the RLogConfigDbTable class. |
|
203 The initialization happens just once, during the construction of the first object of RLogConfigDbTable type. |
|
204 |
|
205 @leave KErrNoMemory, an out of memory condition has occurred; |
|
206 Note that the function may leave with database specific errors and |
|
207 other system-wide error codes. |
|
208 */ |
|
209 void RLogConfigDbTable::InitializeColumnsL() |
|
210 { |
|
211 if(RLogConfigDbTable::iSizeColNo == 0) |
|
212 { |
|
213 CDbColSet* colset = ColSetL(); |
|
214 RLogConfigDbTable::iSizeColNo = colset->ColNo(KLogFieldConfigSizeString); |
|
215 RLogConfigDbTable::iRecentColNo = colset->ColNo(KLogFieldConfigRecentString); |
|
216 RLogConfigDbTable::iAgeColNo = colset->ColNo(KLogFieldConfigAgeString); |
|
217 delete colset; |
|
218 } |
|
219 __ASSERT_DEBUG(RLogConfigDbTable::iSizeColNo > 0 && |
|
220 RLogConfigDbTable::iRecentColNo > 0 && |
|
221 RLogConfigDbTable::iAgeColNo > 0, User::Invariant()); |
|
222 } |
|
223 |
|
224 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
225 ///////////////////////// RLogDbView ////////////////////////////////////////////////////////// |
|
226 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
227 |
|
228 /** |
|
229 RLogDbView "resource acquisition" method. |
|
230 Prepares a database view with the passed as a parameter SQL and with the required access mode. |
|
231 If the database indexes are damaged, before the "prepare view" operation, an attempt will be made to recover the databasde. |
|
232 If the view is prepared successfully, the current RLogDbView object will be put on the cleanup stack and all records |
|
233 evaluated. The caller is responsible for the destruction of the RLogDbView object. |
|
234 |
|
235 @param aDb RDbDatabase reference |
|
236 @param aQuery View SQL statement |
|
237 @param aAccess View access mode, one of RDbRowSet::TAccess enum item values |
|
238 |
|
239 @leave KErrNoMemory, an out of memory condition has occurred; |
|
240 Note that the function may leave with database specific errors and |
|
241 other system-wide error codes. |
|
242 */ |
|
243 void RLogDbView::PrepareLC(RDbDatabase& aDb, const TDesC& aQuery, RDbRowSet::TAccess aAccess) |
|
244 { |
|
245 if(aDb.IsDamaged()) |
|
246 { |
|
247 User::LeaveIfError(aDb.Recover()); |
|
248 } |
|
249 __ASSERT_DEBUG(!aDb.IsDamaged(), Panic(ELogDatabaseDamaged2)); |
|
250 CleanupClosePushL(*this); |
|
251 User::LeaveIfError(RDbView::Prepare(aDb, TDbQuery(aQuery, EDbCompareFolded), aAccess)); |
|
252 User::LeaveIfError(RDbView::EvaluateAll()); |
|
253 } |
|
254 |
|
255 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
256 ///////////////////////// Global functions //////////////////////////////////////////////////// |
|
257 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
258 |
|
259 /** |
|
260 Runs the KLogSqlGetRecent SQL query and puts the IDs of the retrieved events into the aEventIds output array. |
|
261 This happens only if the retrieved events count is bigger than the aMaxRecentLogSize parameter. |
|
262 |
|
263 @param aDb A MLogServDatabaseTransactionInterface reference |
|
264 @param aRecentListId Recent list Id |
|
265 @param aMaxRecentLogSize Max recent list size |
|
266 @param aEventIds Output parameter. The function will put it on the cleanup stack and fill it with |
|
267 the events ids from the recent list. The caller is responsible for the destruction of |
|
268 the aEventIds parameter. |
|
269 |
|
270 @leave KErrNoMemory, an out of memory condition has occurred; |
|
271 Note that the function may leave with database specific errors and |
|
272 other system-wide error codes. |
|
273 |
|
274 @internalComponent |
|
275 */ |
|
276 void LogGetRecentEventsLC(MLogServDatabaseTransactionInterface& aDb, TLogRecentList aRecentListId, |
|
277 TLogRecentSize aMaxRecentLogSize, RArray<TLogId>& aEventIds) |
|
278 { |
|
279 CleanupClosePushL(aEventIds); |
|
280 TheSql.Format(KLogSqlGetRecent, aRecentListId); |
|
281 RLogDbView view; |
|
282 view.PrepareLC(aDb.DTIDatabase(), TheSql, RDbRowSet::EReadOnly); |
|
283 TInt count = view.CountL() - aMaxRecentLogSize; |
|
284 if(count > 0) |
|
285 { |
|
286 (void)view.LastL();//If "count > 0", then there is at least one record => LastL() cannot return EFalse. |
|
287 static TDbColNo idColNo = 0; |
|
288 if(idColNo == 0) |
|
289 { |
|
290 CDbColSet* colset = view.ColSetL(); |
|
291 idColNo = colset->ColNo(KLogFieldIdString); |
|
292 delete colset; |
|
293 } |
|
294 aEventIds.ReserveL(count); |
|
295 do |
|
296 { |
|
297 view.GetL(); |
|
298 aEventIds.AppendL(view.ColInt32(idColNo)); |
|
299 } |
|
300 while(--count && view.PreviousL()); |
|
301 } |
|
302 CleanupStack::PopAndDestroy(&view); |
|
303 } |
|
304 |
|
305 /** |
|
306 The function accepts an array of event IDs as a parameter, prepares an UPDATE SQL query using those IDs and |
|
307 puts the constructed query into aSqlBuf output parameter. |
|
308 |
|
309 @param aEventIds Array with event Ids, used for the construction of the SQL statement |
|
310 @param aSqlBuf Output parameter. A reference to RLogDynBuf object where the SQL is constructed. |
|
311 |
|
312 @leave KErrNoMemory, an out of memory condition has occurred; |
|
313 |
|
314 @internalComponent |
|
315 */ |
|
316 static void LogBuildPurgeRecentSqlL(const RArray<TLogId>& aEventIds, RLogDynBuf& aSqlBuf) |
|
317 { |
|
318 __ASSERT_DEBUG(aEventIds.Count() > 0, User::Invariant()); |
|
319 aSqlBuf.SetLength(0); |
|
320 aSqlBuf.AppendL(KLogSqlRemoveDuplicateEvents); |
|
321 for(TInt i=0,count=aEventIds.Count();i<count;++i) |
|
322 { |
|
323 TBuf<20> num;//buf size of 20 is enough for a 32-bit number |
|
324 num.AppendNum(aEventIds[i]); |
|
325 aSqlBuf.AppendL(KIdEqStr); |
|
326 aSqlBuf.AppendL(num); |
|
327 aSqlBuf.AppendL(KLogOr); |
|
328 aSqlBuf.AppendL(KDuplicateEqStr); |
|
329 aSqlBuf.AppendL(num); |
|
330 aSqlBuf.AppendL(KLogOr); |
|
331 } |
|
332 aSqlBuf.SetLength(aSqlBuf.Length() - KLogOr().Length()); |
|
333 } |
|
334 |
|
335 /** |
|
336 The function accepts an array of event IDs as a parameter, prepares an UPDATE SQL query and executes |
|
337 the query. |
|
338 The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the purged events. |
|
339 Later that information will be used if there are any outstanding notification requests waiting for completion. |
|
340 If the count of the aEventIds elements is 0, then no query will be prepared and executed. |
|
341 |
|
342 @param aDb A reference to MLogServDatabaseTransactionInterface interface |
|
343 @param aEventIds Array with event Ids, used for the construction of the SQL statement |
|
344 |
|
345 @leave KErrNoMemory, an out of memory condition has occurred; |
|
346 Note that the function may leave with database specific errors and |
|
347 other system-wide error codes. |
|
348 |
|
349 @internalComponent |
|
350 */ |
|
351 void LogPurgeRecentEventsL(MLogServDatabaseTransactionInterface& aDb, const RArray<TLogId>& aEventIds) |
|
352 { |
|
353 TInt count = aEventIds.Count(); |
|
354 if(count == 0) |
|
355 { |
|
356 return; |
|
357 } |
|
358 RLogDynBuf sqlBuf; |
|
359 sqlBuf.CreateLC(sizeof(KLogSqlRemoveDuplicateEvents) + count * 32);//32 - approx - length of "Duplicate=N OR Id=N" |
|
360 LogBuildPurgeRecentSqlL(aEventIds, sqlBuf); |
|
361 User::LeaveIfError(aDb.DTIExecuteSql(sqlBuf.DesC())); |
|
362 CleanupStack::PopAndDestroy(&sqlBuf); |
|
363 for(TInt i=0;i<count;++i) |
|
364 { |
|
365 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed |
|
366 aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, aEventIds[i]); |
|
367 } |
|
368 } |
|
369 |
|
370 /** |
|
371 If the number of the events in the "Event" table is bigger than the aMaxLogSize parameter, |
|
372 the oldest events will be deleted from the table. |
|
373 The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the deleted events. |
|
374 Later that information will be used if there are any outstanding notification requests waiting for completion. |
|
375 If the number of the events in the "Event" table is less than the aMaxLogSize parameter, then the function does nothing. |
|
376 |
|
377 @param aDb A reference to MLogServDatabaseTransactionInterface interface |
|
378 @param aTbl A reference to RLogEventDbTable object |
|
379 @param aMaxLogSize The max number of events allowed to exist in the "Event" table |
|
380 @param aCountPlus Integer, added to aMaxLogSize during the "max log size" calculations |
|
381 |
|
382 @leave KErrNoMemory, an out of memory condition has occurred; |
|
383 Note that the function may leave with database specific errors and |
|
384 other system-wide error codes. |
|
385 |
|
386 @internalComponent |
|
387 */ |
|
388 void LogPurgeMainL(MLogServDatabaseTransactionInterface& aDb, RLogEventDbTable& aTbl, |
|
389 TLogSize aMaxLogSize, TInt aCountPlus) |
|
390 { |
|
391 User::LeaveIfError(aTbl.SetIndex(KLogNameEventIdx1)); |
|
392 TInt count = aTbl.CountL() + aCountPlus - aMaxLogSize; |
|
393 if(count > 0) |
|
394 { |
|
395 (void)aTbl.FirstL();//If "count > 0", then there is at least one record => FirstL() cannot return EFalse. |
|
396 TBool commit = !aDb.DTIInTransaction(); |
|
397 if(commit) |
|
398 { |
|
399 aDb.DTIBeginWithRollBackProtectionLC(); |
|
400 } |
|
401 do |
|
402 { |
|
403 aTbl.GetL(); |
|
404 TLogId id = aTbl.ColInt32(RLogEventDbTable::iIdColNo); |
|
405 aTbl.DeleteL(); |
|
406 aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventDeleted, id); |
|
407 } |
|
408 while(--count && aTbl.NextL()); |
|
409 if(commit) |
|
410 { |
|
411 aDb.DTICommitAndCancelRollbackProtectionL(); |
|
412 } |
|
413 } |
|
414 } |
|
415 |
|
416 /** |
|
417 Updates the event records with "Duplicate" column value equal to aEventId. |
|
418 The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the modified events. |
|
419 Later that information will be used if there are any outstanding notification requests waiting for completion. |
|
420 If no duplicates of the passed as a parameter event ID exist, then the function does nothing. |
|
421 |
|
422 @param aDb A reference to MLogServDatabaseTransactionInterface interface |
|
423 @param aEventId Duplicated event id |
|
424 |
|
425 @leave KErrNoMemory, an out of memory condition has occurred; |
|
426 Note that the function may leave with database specific errors and |
|
427 other system-wide error codes. |
|
428 |
|
429 @internalComponent |
|
430 */ |
|
431 void LogResetDuplicatesL(MLogServDatabaseTransactionInterface& aDb, TLogId aEventId) |
|
432 { |
|
433 TheSql.Format(KLogSqlDuplicateViewString, aEventId, &KNullDesC); |
|
434 RLogDbView view; |
|
435 view .PrepareLC(aDb.DTIDatabase(), TheSql); |
|
436 // Are there any duplicates? |
|
437 if(view.FirstL()) |
|
438 { |
|
439 static TDbColNo idColNo = 0; |
|
440 static TDbColNo duplicateColNo = 0; |
|
441 if(idColNo == 0) |
|
442 { |
|
443 CDbColSet* colset = view.ColSetL(); |
|
444 idColNo = colset->ColNo(KLogFieldIdString); |
|
445 duplicateColNo = colset->ColNo(KLogFieldEventDuplicateString); |
|
446 delete colset; |
|
447 } |
|
448 TBool commit = !aDb.DTIInTransaction(); |
|
449 if(commit) |
|
450 { |
|
451 aDb.DTIBeginWithRollBackProtectionLC(); |
|
452 } |
|
453 // Get the id of the latest event |
|
454 view.GetL(); |
|
455 const TLogId idLatest = view.ColInt32(idColNo); |
|
456 // Mark the event as the latest duplicate |
|
457 view.UpdateL(); |
|
458 view.SetColNullL(duplicateColNo); |
|
459 view.PutL(); |
|
460 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed |
|
461 aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, idLatest); |
|
462 // Reset the duplicate id's of the other duplicates |
|
463 while(view.NextL()) |
|
464 { |
|
465 view.UpdateL(); |
|
466 const TLogId id = view.ColInt32(idColNo); |
|
467 view.SetColL(duplicateColNo, idLatest); |
|
468 view.PutL(); |
|
469 // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed |
|
470 aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id); |
|
471 } |
|
472 if(commit) |
|
473 { |
|
474 aDb.DTICommitAndCancelRollbackProtectionL(); |
|
475 } |
|
476 } |
|
477 CleanupStack::PopAndDestroy(&view); |
|
478 } |