Update contrib.
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.
17 #include "logservpanic.h"
18 #include "LogServDatabaseTransactionInterface.h"
19 #include "LogServDatabaseChangeInterface.h"
20 #include "LogServSqlStrings.h"
21 #include "LogDynBuf.h"
23 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24 ///////////////////////// RLogDbTable /////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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.
34 @param aDb RDbDatabase reference
35 @param aTblName Table name
36 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
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.
42 void RLogDbTable::OpenLC(RDbDatabase& aDb, const TDesC& aTblName, RDbRowSet::TAccess aAccess)
46 User::LeaveIfError(aDb.Recover());
48 __ASSERT_DEBUG(!aDb.IsDamaged(), Panic(ELogDatabaseDamaged2));
49 CleanupClosePushL(*this);
50 User::LeaveIfError(RDbTable::Open(aDb, aTblName, aAccess));
53 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54 ///////////////////////// RLogEventDbTable ////////////////////////////////////////////////////
55 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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;
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.
84 @param aDb RDbDatabase reference
85 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
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.
91 void RLogEventDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess)
93 RLogDbTable::OpenLC(aDb, KLogNameEventString, aAccess);
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.
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.
105 void RLogEventDbTable::InitializeColumnsL()
107 if(RLogEventDbTable::iIdColNo == 0)
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)
126 colname.Format(KLogFieldEventFlagString, i + 1);
127 RLogEventDbTable::iFlagColNo[i] = colset->ColNo(colname);
128 __ASSERT_DEBUG(RLogEventDbTable::iFlagColNo[i] > 0, User::Invariant());
130 RLogEventDbTable::iRecentColNo = colset->ColNo(KLogFieldEventRecentString);
131 RLogEventDbTable::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
132 #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
133 RLogEventDbTable::iSimIdColNo = colset->ColNo(KLogFieldEventSimId);
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());
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());
173 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
174 ///////////////////////// RLogConfigDbTable ///////////////////////////////////////////////////
175 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
177 TDbColNo RLogConfigDbTable::iSizeColNo = 0;
178 TDbColNo RLogConfigDbTable::iRecentColNo = 0;
179 TDbColNo RLogConfigDbTable::iAgeColNo = 0;
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.
188 @param aDb RDbDatabase reference
189 @param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
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.
195 void RLogConfigDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess)
197 RLogDbTable::OpenLC(aDb, KLogNameConfigString, aAccess);
198 InitializeColumnsL();
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.
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.
209 void RLogConfigDbTable::InitializeColumnsL()
211 if(RLogConfigDbTable::iSizeColNo == 0)
213 CDbColSet* colset = ColSetL();
214 RLogConfigDbTable::iSizeColNo = colset->ColNo(KLogFieldConfigSizeString);
215 RLogConfigDbTable::iRecentColNo = colset->ColNo(KLogFieldConfigRecentString);
216 RLogConfigDbTable::iAgeColNo = colset->ColNo(KLogFieldConfigAgeString);
219 __ASSERT_DEBUG(RLogConfigDbTable::iSizeColNo > 0 &&
220 RLogConfigDbTable::iRecentColNo > 0 &&
221 RLogConfigDbTable::iAgeColNo > 0, User::Invariant());
224 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225 ///////////////////////// RLogDbView //////////////////////////////////////////////////////////
226 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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.
235 @param aDb RDbDatabase reference
236 @param aQuery View SQL statement
237 @param aAccess View access mode, one of RDbRowSet::TAccess enum item values
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.
243 void RLogDbView::PrepareLC(RDbDatabase& aDb, const TDesC& aQuery, RDbRowSet::TAccess aAccess)
247 User::LeaveIfError(aDb.Recover());
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());
255 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
256 ///////////////////////// Global functions ////////////////////////////////////////////////////
257 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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.
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.
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.
276 void LogGetRecentEventsLC(MLogServDatabaseTransactionInterface& aDb, TLogRecentList aRecentListId,
277 TLogRecentSize aMaxRecentLogSize, RArray<TLogId>& aEventIds)
279 CleanupClosePushL(aEventIds);
280 TheSql.Format(KLogSqlGetRecent, aRecentListId);
282 view.PrepareLC(aDb.DTIDatabase(), TheSql, RDbRowSet::EReadOnly);
283 TInt count = view.CountL() - aMaxRecentLogSize;
286 (void)view.LastL();//If "count > 0", then there is at least one record => LastL() cannot return EFalse.
287 static TDbColNo idColNo = 0;
290 CDbColSet* colset = view.ColSetL();
291 idColNo = colset->ColNo(KLogFieldIdString);
294 aEventIds.ReserveL(count);
298 aEventIds.AppendL(view.ColInt32(idColNo));
300 while(--count && view.PreviousL());
302 CleanupStack::PopAndDestroy(&view);
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.
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.
312 @leave KErrNoMemory, an out of memory condition has occurred;
316 static void LogBuildPurgeRecentSqlL(const RArray<TLogId>& aEventIds, RLogDynBuf& aSqlBuf)
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)
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);
332 aSqlBuf.SetLength(aSqlBuf.Length() - KLogOr().Length());
336 The function accepts an array of event IDs as a parameter, prepares an UPDATE SQL query and executes
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.
342 @param aDb A reference to MLogServDatabaseTransactionInterface interface
343 @param aEventIds Array with event Ids, used for the construction of the SQL statement
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.
351 void LogPurgeRecentEventsL(MLogServDatabaseTransactionInterface& aDb, const RArray<TLogId>& aEventIds)
353 TInt count = aEventIds.Count();
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)
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]);
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.
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
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.
388 void LogPurgeMainL(MLogServDatabaseTransactionInterface& aDb, RLogEventDbTable& aTbl,
389 TLogSize aMaxLogSize, TInt aCountPlus)
391 User::LeaveIfError(aTbl.SetIndex(KLogNameEventIdx1));
392 TInt count = aTbl.CountL() + aCountPlus - aMaxLogSize;
395 (void)aTbl.FirstL();//If "count > 0", then there is at least one record => FirstL() cannot return EFalse.
396 TBool commit = !aDb.DTIInTransaction();
399 aDb.DTIBeginWithRollBackProtectionLC();
404 TLogId id = aTbl.ColInt32(RLogEventDbTable::iIdColNo);
406 aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventDeleted, id);
408 while(--count && aTbl.NextL());
411 aDb.DTICommitAndCancelRollbackProtectionL();
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.
422 @param aDb A reference to MLogServDatabaseTransactionInterface interface
423 @param aEventId Duplicated event id
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.
431 void LogResetDuplicatesL(MLogServDatabaseTransactionInterface& aDb, TLogId aEventId)
433 TheSql.Format(KLogSqlDuplicateViewString, aEventId, &KNullDesC);
435 view .PrepareLC(aDb.DTIDatabase(), TheSql);
436 // Are there any duplicates?
439 static TDbColNo idColNo = 0;
440 static TDbColNo duplicateColNo = 0;
443 CDbColSet* colset = view.ColSetL();
444 idColNo = colset->ColNo(KLogFieldIdString);
445 duplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
448 TBool commit = !aDb.DTIInTransaction();
451 aDb.DTIBeginWithRollBackProtectionLC();
453 // Get the id of the latest event
455 const TLogId idLatest = view.ColInt32(idColNo);
456 // Mark the event as the latest duplicate
458 view.SetColNullL(duplicateColNo);
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
466 const TLogId id = view.ColInt32(idColNo);
467 view.SetColL(duplicateColNo, idLatest);
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);
474 aDb.DTICommitAndCancelRollbackProtectionL();
477 CleanupStack::PopAndDestroy(&view);