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