1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/loggingservices/eventlogger/LogServ/src/LOGQUERY.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,478 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "LOGQUERY.H"
1.20 +#include "logservpanic.h"
1.21 +#include "LogServDatabaseTransactionInterface.h"
1.22 +#include "LogServDatabaseChangeInterface.h"
1.23 +#include "LogServSqlStrings.h"
1.24 +#include "LogDynBuf.h"
1.25 +
1.26 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.27 +///////////////////////// RLogDbTable /////////////////////////////////////////////////////////
1.28 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.29 +
1.30 +/**
1.31 +RLogDbTable "resource acquisition" method.
1.32 +Opens the specified database table with the required access mode.
1.33 +If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde.
1.34 +If the table is opened successfully, the current RLogDbTable object will be put on the cleanup stack. The caller is
1.35 +responsible for the destruction of the RLogDbTable object.
1.36 +
1.37 +@param aDb RDbDatabase reference
1.38 +@param aTblName Table name
1.39 +@param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
1.40 +
1.41 +@leave KErrNoMemory, an out of memory condition has occurred;
1.42 + Note that the function may leave with database specific errors and
1.43 + other system-wide error codes.
1.44 +*/
1.45 +void RLogDbTable::OpenLC(RDbDatabase& aDb, const TDesC& aTblName, RDbRowSet::TAccess aAccess)
1.46 + {
1.47 + if(aDb.IsDamaged())
1.48 + {
1.49 + User::LeaveIfError(aDb.Recover());
1.50 + }
1.51 + __ASSERT_DEBUG(!aDb.IsDamaged(), Panic(ELogDatabaseDamaged2));
1.52 + CleanupClosePushL(*this);
1.53 + User::LeaveIfError(RDbTable::Open(aDb, aTblName, aAccess));
1.54 + }
1.55 +
1.56 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.57 +///////////////////////// RLogEventDbTable ////////////////////////////////////////////////////
1.58 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.59 +
1.60 +TDbColNo RLogEventDbTable::iIdColNo = 0;
1.61 +TDbColNo RLogEventDbTable::iTypeColNo = 0;
1.62 +TDbColNo RLogEventDbTable::iRemotePartyColNo = 0;
1.63 +TDbColNo RLogEventDbTable::iDirectionColNo = 0;
1.64 +TDbColNo RLogEventDbTable::iTimeColNo = 0;
1.65 +TDbColNo RLogEventDbTable::iDurationTypeColNo = 0;
1.66 +TDbColNo RLogEventDbTable::iDurationColNo = 0;
1.67 +TDbColNo RLogEventDbTable::iStatusColNo = 0;
1.68 +TDbColNo RLogEventDbTable::iSubjectColNo = 0;
1.69 +TDbColNo RLogEventDbTable::iNumberColNo = 0;
1.70 +TDbColNo RLogEventDbTable::iContactColNo = 0;
1.71 +TDbColNo RLogEventDbTable::iLinkColNo = 0;
1.72 +TDbColNo RLogEventDbTable::iDataColNo = 0;
1.73 +TDbColNo RLogEventDbTable::iFlagColNo[] = {0, 0, 0, 0};
1.74 +TDbColNo RLogEventDbTable::iRecentColNo = 0;
1.75 +TDbColNo RLogEventDbTable::iDuplicateColNo = 0;
1.76 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.77 +TDbColNo RLogEventDbTable::iSimIdColNo = 0;
1.78 +#endif
1.79 +
1.80 +/**
1.81 +RLogEventDbTable "resource acquisition" method.
1.82 +Opens the "Event" database table with the required access mode.
1.83 +If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde.
1.84 +If the table is opened successfully, the current RLogEventDbTable object will be put on the cleanup stack. The caller is
1.85 +responsible for the destruction of the RLogEventDbTable object.
1.86 +
1.87 +@param aDb RDbDatabase reference
1.88 +@param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
1.89 +
1.90 +@leave KErrNoMemory, an out of memory condition has occurred;
1.91 + Note that the function may leave with database specific errors and
1.92 + other system-wide error codes.
1.93 +*/
1.94 +void RLogEventDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess)
1.95 + {
1.96 + RLogDbTable::OpenLC(aDb, KLogNameEventString, aAccess);
1.97 + InitializeColumnsL();
1.98 + }
1.99 +
1.100 +/**
1.101 +Initializes the static data members ("Event" table column numbers) of the RLogEventDbTable class.
1.102 +The initialization happens just once, during the construction of the first object of RLogEventDbTable type.
1.103 +
1.104 +@leave KErrNoMemory, an out of memory condition has occurred;
1.105 + Note that the function may leave with database specific errors and
1.106 + other system-wide error codes.
1.107 +*/
1.108 +void RLogEventDbTable::InitializeColumnsL()
1.109 + {
1.110 + if(RLogEventDbTable::iIdColNo == 0)
1.111 + {
1.112 + CDbColSet* colset = ColSetL();
1.113 + RLogEventDbTable::iIdColNo = colset->ColNo(KLogFieldIdString);
1.114 + RLogEventDbTable::iTypeColNo = colset->ColNo(KLogFieldEventTypeString);
1.115 + RLogEventDbTable::iRemotePartyColNo = colset->ColNo(KLogFieldEventRemoteString);
1.116 + RLogEventDbTable::iDirectionColNo = colset->ColNo(KLogFieldEventDirectionString);
1.117 + RLogEventDbTable::iTimeColNo = colset->ColNo(KLogFieldEventTimeString);
1.118 + RLogEventDbTable::iDurationTypeColNo = colset->ColNo(KLogFieldEventDTypeString);
1.119 + RLogEventDbTable::iDurationColNo = colset->ColNo(KLogFieldEventDurationString);
1.120 + RLogEventDbTable::iStatusColNo = colset->ColNo(KLogFieldEventStatusString);
1.121 + RLogEventDbTable::iSubjectColNo = colset->ColNo(KLogFieldEventSubjectString);
1.122 + RLogEventDbTable::iNumberColNo = colset->ColNo(KLogFieldEventNumberString);
1.123 + RLogEventDbTable::iContactColNo = colset->ColNo(KLogFieldEventContactString);
1.124 + RLogEventDbTable::iLinkColNo = colset->ColNo(KLogFieldEventLinkString);
1.125 + RLogEventDbTable::iDataColNo = colset->ColNo(KLogFieldEventDataString);
1.126 + for(TInt i=0;i<KLogFlagsCount;++i)
1.127 + {
1.128 + TDbColName colname;
1.129 + colname.Format(KLogFieldEventFlagString, i + 1);
1.130 + RLogEventDbTable::iFlagColNo[i] = colset->ColNo(colname);
1.131 + __ASSERT_DEBUG(RLogEventDbTable::iFlagColNo[i] > 0, User::Invariant());
1.132 + }
1.133 + RLogEventDbTable::iRecentColNo = colset->ColNo(KLogFieldEventRecentString);
1.134 + RLogEventDbTable::iDuplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
1.135 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.136 + RLogEventDbTable::iSimIdColNo = colset->ColNo(KLogFieldEventSimId);
1.137 +#endif
1.138 + delete colset;
1.139 + }
1.140 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.141 + __ASSERT_DEBUG(RLogEventDbTable::iIdColNo > 0 &&
1.142 + RLogEventDbTable::iTypeColNo > 0 &&
1.143 + RLogEventDbTable::iRemotePartyColNo > 0 &&
1.144 + RLogEventDbTable::iDirectionColNo > 0 &&
1.145 + RLogEventDbTable::iTimeColNo > 0 &&
1.146 + RLogEventDbTable::iDurationTypeColNo > 0 &&
1.147 + RLogEventDbTable::iDurationColNo > 0 &&
1.148 + RLogEventDbTable::iStatusColNo > 0 &&
1.149 + RLogEventDbTable::iSubjectColNo > 0 &&
1.150 + RLogEventDbTable::iNumberColNo > 0 &&
1.151 + RLogEventDbTable::iContactColNo > 0 &&
1.152 + RLogEventDbTable::iLinkColNo > 0 &&
1.153 + RLogEventDbTable::iDataColNo > 0 &&
1.154 + RLogEventDbTable::iRecentColNo > 0 &&
1.155 + RLogEventDbTable::iDuplicateColNo > 0 &&
1.156 + RLogEventDbTable::iSimIdColNo > 0, User::Invariant());
1.157 +#else
1.158 + __ASSERT_DEBUG(RLogEventDbTable::iIdColNo > 0 &&
1.159 + RLogEventDbTable::iTypeColNo > 0 &&
1.160 + RLogEventDbTable::iRemotePartyColNo > 0 &&
1.161 + RLogEventDbTable::iDirectionColNo > 0 &&
1.162 + RLogEventDbTable::iTimeColNo > 0 &&
1.163 + RLogEventDbTable::iDurationTypeColNo > 0 &&
1.164 + RLogEventDbTable::iDurationColNo > 0 &&
1.165 + RLogEventDbTable::iStatusColNo > 0 &&
1.166 + RLogEventDbTable::iSubjectColNo > 0 &&
1.167 + RLogEventDbTable::iNumberColNo > 0 &&
1.168 + RLogEventDbTable::iContactColNo > 0 &&
1.169 + RLogEventDbTable::iLinkColNo > 0 &&
1.170 + RLogEventDbTable::iDataColNo > 0 &&
1.171 + RLogEventDbTable::iRecentColNo > 0 &&
1.172 + RLogEventDbTable::iDuplicateColNo > 0, User::Invariant());
1.173 +#endif
1.174 + }
1.175 +
1.176 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.177 +///////////////////////// RLogConfigDbTable ///////////////////////////////////////////////////
1.178 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.179 +
1.180 +TDbColNo RLogConfigDbTable::iSizeColNo = 0;
1.181 +TDbColNo RLogConfigDbTable::iRecentColNo = 0;
1.182 +TDbColNo RLogConfigDbTable::iAgeColNo = 0;
1.183 +
1.184 +/**
1.185 +RLogConfigDbTable "resource acquisition" method.
1.186 +Opens the "Config" database table with the required access mode.
1.187 +If the database indexes are damaged, before the "table open" operation, an attempt will be made to recover the databasde.
1.188 +If the table is opened successfully, the current RLogConfigDbTable object will be put on the cleanup stack. The caller is
1.189 +responsible for the destruction of the RLogConfigDbTable object.
1.190 +
1.191 +@param aDb RDbDatabase reference
1.192 +@param aAccess Table access mode, one of RDbRowSet::TAccess enum item values
1.193 +
1.194 +@leave KErrNoMemory, an out of memory condition has occurred;
1.195 + Note that the function may leave with database specific errors and
1.196 + other system-wide error codes.
1.197 +*/
1.198 +void RLogConfigDbTable::OpenLC(RDbDatabase& aDb, RDbRowSet::TAccess aAccess)
1.199 + {
1.200 + RLogDbTable::OpenLC(aDb, KLogNameConfigString, aAccess);
1.201 + InitializeColumnsL();
1.202 + }
1.203 +
1.204 +/**
1.205 +Initializes the static data members ("Config" table column numbers) of the RLogConfigDbTable class.
1.206 +The initialization happens just once, during the construction of the first object of RLogConfigDbTable type.
1.207 +
1.208 +@leave KErrNoMemory, an out of memory condition has occurred;
1.209 + Note that the function may leave with database specific errors and
1.210 + other system-wide error codes.
1.211 +*/
1.212 +void RLogConfigDbTable::InitializeColumnsL()
1.213 + {
1.214 + if(RLogConfigDbTable::iSizeColNo == 0)
1.215 + {
1.216 + CDbColSet* colset = ColSetL();
1.217 + RLogConfigDbTable::iSizeColNo = colset->ColNo(KLogFieldConfigSizeString);
1.218 + RLogConfigDbTable::iRecentColNo = colset->ColNo(KLogFieldConfigRecentString);
1.219 + RLogConfigDbTable::iAgeColNo = colset->ColNo(KLogFieldConfigAgeString);
1.220 + delete colset;
1.221 + }
1.222 + __ASSERT_DEBUG(RLogConfigDbTable::iSizeColNo > 0 &&
1.223 + RLogConfigDbTable::iRecentColNo > 0 &&
1.224 + RLogConfigDbTable::iAgeColNo > 0, User::Invariant());
1.225 + }
1.226 +
1.227 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.228 +///////////////////////// RLogDbView //////////////////////////////////////////////////////////
1.229 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.230 +
1.231 +/**
1.232 +RLogDbView "resource acquisition" method.
1.233 +Prepares a database view with the passed as a parameter SQL and with the required access mode.
1.234 +If the database indexes are damaged, before the "prepare view" operation, an attempt will be made to recover the databasde.
1.235 +If the view is prepared successfully, the current RLogDbView object will be put on the cleanup stack and all records
1.236 +evaluated. The caller is responsible for the destruction of the RLogDbView object.
1.237 +
1.238 +@param aDb RDbDatabase reference
1.239 +@param aQuery View SQL statement
1.240 +@param aAccess View access mode, one of RDbRowSet::TAccess enum item values
1.241 +
1.242 +@leave KErrNoMemory, an out of memory condition has occurred;
1.243 + Note that the function may leave with database specific errors and
1.244 + other system-wide error codes.
1.245 +*/
1.246 +void RLogDbView::PrepareLC(RDbDatabase& aDb, const TDesC& aQuery, RDbRowSet::TAccess aAccess)
1.247 + {
1.248 + if(aDb.IsDamaged())
1.249 + {
1.250 + User::LeaveIfError(aDb.Recover());
1.251 + }
1.252 + __ASSERT_DEBUG(!aDb.IsDamaged(), Panic(ELogDatabaseDamaged2));
1.253 + CleanupClosePushL(*this);
1.254 + User::LeaveIfError(RDbView::Prepare(aDb, TDbQuery(aQuery, EDbCompareFolded), aAccess));
1.255 + User::LeaveIfError(RDbView::EvaluateAll());
1.256 + }
1.257 +
1.258 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.259 +///////////////////////// Global functions ////////////////////////////////////////////////////
1.260 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.261 +
1.262 +/**
1.263 +Runs the KLogSqlGetRecent SQL query and puts the IDs of the retrieved events into the aEventIds output array.
1.264 +This happens only if the retrieved events count is bigger than the aMaxRecentLogSize parameter.
1.265 +
1.266 +@param aDb A MLogServDatabaseTransactionInterface reference
1.267 +@param aRecentListId Recent list Id
1.268 +@param aMaxRecentLogSize Max recent list size
1.269 +@param aEventIds Output parameter. The function will put it on the cleanup stack and fill it with
1.270 + the events ids from the recent list. The caller is responsible for the destruction of
1.271 + the aEventIds parameter.
1.272 +
1.273 +@leave KErrNoMemory, an out of memory condition has occurred;
1.274 + Note that the function may leave with database specific errors and
1.275 + other system-wide error codes.
1.276 +
1.277 +@internalComponent
1.278 +*/
1.279 +void LogGetRecentEventsLC(MLogServDatabaseTransactionInterface& aDb, TLogRecentList aRecentListId,
1.280 + TLogRecentSize aMaxRecentLogSize, RArray<TLogId>& aEventIds)
1.281 + {
1.282 + CleanupClosePushL(aEventIds);
1.283 + TheSql.Format(KLogSqlGetRecent, aRecentListId);
1.284 + RLogDbView view;
1.285 + view.PrepareLC(aDb.DTIDatabase(), TheSql, RDbRowSet::EReadOnly);
1.286 + TInt count = view.CountL() - aMaxRecentLogSize;
1.287 + if(count > 0)
1.288 + {
1.289 + (void)view.LastL();//If "count > 0", then there is at least one record => LastL() cannot return EFalse.
1.290 + static TDbColNo idColNo = 0;
1.291 + if(idColNo == 0)
1.292 + {
1.293 + CDbColSet* colset = view.ColSetL();
1.294 + idColNo = colset->ColNo(KLogFieldIdString);
1.295 + delete colset;
1.296 + }
1.297 + aEventIds.ReserveL(count);
1.298 + do
1.299 + {
1.300 + view.GetL();
1.301 + aEventIds.AppendL(view.ColInt32(idColNo));
1.302 + }
1.303 + while(--count && view.PreviousL());
1.304 + }
1.305 + CleanupStack::PopAndDestroy(&view);
1.306 + }
1.307 +
1.308 +/**
1.309 +The function accepts an array of event IDs as a parameter, prepares an UPDATE SQL query using those IDs and
1.310 +puts the constructed query into aSqlBuf output parameter.
1.311 +
1.312 +@param aEventIds Array with event Ids, used for the construction of the SQL statement
1.313 +@param aSqlBuf Output parameter. A reference to RLogDynBuf object where the SQL is constructed.
1.314 +
1.315 +@leave KErrNoMemory, an out of memory condition has occurred;
1.316 +
1.317 +@internalComponent
1.318 +*/
1.319 +static void LogBuildPurgeRecentSqlL(const RArray<TLogId>& aEventIds, RLogDynBuf& aSqlBuf)
1.320 + {
1.321 + __ASSERT_DEBUG(aEventIds.Count() > 0, User::Invariant());
1.322 + aSqlBuf.SetLength(0);
1.323 + aSqlBuf.AppendL(KLogSqlRemoveDuplicateEvents);
1.324 + for(TInt i=0,count=aEventIds.Count();i<count;++i)
1.325 + {
1.326 + TBuf<20> num;//buf size of 20 is enough for a 32-bit number
1.327 + num.AppendNum(aEventIds[i]);
1.328 + aSqlBuf.AppendL(KIdEqStr);
1.329 + aSqlBuf.AppendL(num);
1.330 + aSqlBuf.AppendL(KLogOr);
1.331 + aSqlBuf.AppendL(KDuplicateEqStr);
1.332 + aSqlBuf.AppendL(num);
1.333 + aSqlBuf.AppendL(KLogOr);
1.334 + }
1.335 + aSqlBuf.SetLength(aSqlBuf.Length() - KLogOr().Length());
1.336 + }
1.337 +
1.338 +/**
1.339 +The function accepts an array of event IDs as a parameter, prepares an UPDATE SQL query and executes
1.340 +the query.
1.341 +The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the purged events.
1.342 +Later that information will be used if there are any outstanding notification requests waiting for completion.
1.343 +If the count of the aEventIds elements is 0, then no query will be prepared and executed.
1.344 +
1.345 +@param aDb A reference to MLogServDatabaseTransactionInterface interface
1.346 +@param aEventIds Array with event Ids, used for the construction of the SQL statement
1.347 +
1.348 +@leave KErrNoMemory, an out of memory condition has occurred;
1.349 + Note that the function may leave with database specific errors and
1.350 + other system-wide error codes.
1.351 +
1.352 +@internalComponent
1.353 +*/
1.354 +void LogPurgeRecentEventsL(MLogServDatabaseTransactionInterface& aDb, const RArray<TLogId>& aEventIds)
1.355 + {
1.356 + TInt count = aEventIds.Count();
1.357 + if(count == 0)
1.358 + {
1.359 + return;
1.360 + }
1.361 + RLogDynBuf sqlBuf;
1.362 + sqlBuf.CreateLC(sizeof(KLogSqlRemoveDuplicateEvents) + count * 32);//32 - approx - length of "Duplicate=N OR Id=N"
1.363 + LogBuildPurgeRecentSqlL(aEventIds, sqlBuf);
1.364 + User::LeaveIfError(aDb.DTIExecuteSql(sqlBuf.DesC()));
1.365 + CleanupStack::PopAndDestroy(&sqlBuf);
1.366 + for(TInt i=0;i<count;++i)
1.367 + {
1.368 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.369 + aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, aEventIds[i]);
1.370 + }
1.371 + }
1.372 +
1.373 +/**
1.374 +If the number of the events in the "Event" table is bigger than the aMaxLogSize parameter,
1.375 +the oldest events will be deleted from the table.
1.376 +The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the deleted events.
1.377 +Later that information will be used if there are any outstanding notification requests waiting for completion.
1.378 +If the number of the events in the "Event" table is less than the aMaxLogSize parameter, then the function does nothing.
1.379 +
1.380 +@param aDb A reference to MLogServDatabaseTransactionInterface interface
1.381 +@param aTbl A reference to RLogEventDbTable object
1.382 +@param aMaxLogSize The max number of events allowed to exist in the "Event" table
1.383 +@param aCountPlus Integer, added to aMaxLogSize during the "max log size" calculations
1.384 +
1.385 +@leave KErrNoMemory, an out of memory condition has occurred;
1.386 + Note that the function may leave with database specific errors and
1.387 + other system-wide error codes.
1.388 +
1.389 +@internalComponent
1.390 +*/
1.391 +void LogPurgeMainL(MLogServDatabaseTransactionInterface& aDb, RLogEventDbTable& aTbl,
1.392 + TLogSize aMaxLogSize, TInt aCountPlus)
1.393 + {
1.394 + User::LeaveIfError(aTbl.SetIndex(KLogNameEventIdx1));
1.395 + TInt count = aTbl.CountL() + aCountPlus - aMaxLogSize;
1.396 + if(count > 0)
1.397 + {
1.398 + (void)aTbl.FirstL();//If "count > 0", then there is at least one record => FirstL() cannot return EFalse.
1.399 + TBool commit = !aDb.DTIInTransaction();
1.400 + if(commit)
1.401 + {
1.402 + aDb.DTIBeginWithRollBackProtectionLC();
1.403 + }
1.404 + do
1.405 + {
1.406 + aTbl.GetL();
1.407 + TLogId id = aTbl.ColInt32(RLogEventDbTable::iIdColNo);
1.408 + aTbl.DeleteL();
1.409 + aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventDeleted, id);
1.410 + }
1.411 + while(--count && aTbl.NextL());
1.412 + if(commit)
1.413 + {
1.414 + aDb.DTICommitAndCancelRollbackProtectionL();
1.415 + }
1.416 + }
1.417 + }
1.418 +
1.419 +/**
1.420 +Updates the event records with "Duplicate" column value equal to aEventId.
1.421 +The MLogServDatabaseChangeInterface interface will be used to collect the information about the IDs of the modified events.
1.422 +Later that information will be used if there are any outstanding notification requests waiting for completion.
1.423 +If no duplicates of the passed as a parameter event ID exist, then the function does nothing.
1.424 +
1.425 +@param aDb A reference to MLogServDatabaseTransactionInterface interface
1.426 +@param aEventId Duplicated event id
1.427 +
1.428 +@leave KErrNoMemory, an out of memory condition has occurred;
1.429 + Note that the function may leave with database specific errors and
1.430 + other system-wide error codes.
1.431 +
1.432 +@internalComponent
1.433 +*/
1.434 +void LogResetDuplicatesL(MLogServDatabaseTransactionInterface& aDb, TLogId aEventId)
1.435 + {
1.436 + TheSql.Format(KLogSqlDuplicateViewString, aEventId, &KNullDesC);
1.437 + RLogDbView view;
1.438 + view .PrepareLC(aDb.DTIDatabase(), TheSql);
1.439 + // Are there any duplicates?
1.440 + if(view.FirstL())
1.441 + {
1.442 + static TDbColNo idColNo = 0;
1.443 + static TDbColNo duplicateColNo = 0;
1.444 + if(idColNo == 0)
1.445 + {
1.446 + CDbColSet* colset = view.ColSetL();
1.447 + idColNo = colset->ColNo(KLogFieldIdString);
1.448 + duplicateColNo = colset->ColNo(KLogFieldEventDuplicateString);
1.449 + delete colset;
1.450 + }
1.451 + TBool commit = !aDb.DTIInTransaction();
1.452 + if(commit)
1.453 + {
1.454 + aDb.DTIBeginWithRollBackProtectionLC();
1.455 + }
1.456 + // Get the id of the latest event
1.457 + view.GetL();
1.458 + const TLogId idLatest = view.ColInt32(idColNo);
1.459 + // Mark the event as the latest duplicate
1.460 + view.UpdateL();
1.461 + view.SetColNullL(duplicateColNo);
1.462 + view.PutL();
1.463 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.464 + aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, idLatest);
1.465 + // Reset the duplicate id's of the other duplicates
1.466 + while(view.NextL())
1.467 + {
1.468 + view.UpdateL();
1.469 + const TLogId id = view.ColInt32(idColNo);
1.470 + view.SetColL(duplicateColNo, idLatest);
1.471 + view.PutL();
1.472 + // This is a "hidden" change. It may affect the contents of a view, but the actual event hasn't changed
1.473 + aDb.DTIChangeInterface().DCISubmitChangedEventContextL(ELogChangeTypeEventChangedHidden, id);
1.474 + }
1.475 + if(commit)
1.476 + {
1.477 + aDb.DTICommitAndCancelRollbackProtectionL();
1.478 + }
1.479 + }
1.480 + CleanupStack::PopAndDestroy(&view);
1.481 + }