diff -r 608f67c22514 -r 896e9dbc5f19 internetradio2.0/ircachemgmt/src/ircachemgmt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internetradio2.0/ircachemgmt/src/ircachemgmt.cpp Wed Aug 18 09:40:26 2010 +0300 @@ -0,0 +1,1544 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: ?Description +* +*/ + + +#include + +#include "irbrowsecatagoryitems.h" +#include "irbrowsechannelitems.h" +#include "ircachecleanup.h" +#include "ircachemgmt.h" +#include "ircacheobserver.h" +#include "irdebug.h" +#include "irhttprequestdata.h" +#include "irisdspreset.h" +#include "irotaupdate.h" +#include "irsettings.h" + +//Default trust period value.24 hrs in secs with which the object is to be initialised +const TInt KDefaultInterval = 24*60*60; +//granualarity for the arrays +//the granualarity value is based on superficial observation of the amount of +//data recieved for a particular request +const TInt KBrowseGranualarity = 32; +const TInt KChannelArrayGranualarity = 32; +const TInt KPresetGranualarity = 12; +//http length format length +// "Sun, 06 Nov 1994 08:49:37 GMT" format +const TInt KHttpDateLength = 25; + +//Max size( critical size ) in Bytes( 90% of the max size ) +//critical size is the size that triggers cleanup action +const TInt KCacheCriticalSizeLimit = KCacheLimitSize*9/10; + +//No of rows deleted will be one fourth of the total number of rows +const TInt KPercentRowsDeleted = 4; + +//The indexing size for the column DataId is set to 100 +const TInt KDataIdIndexSize = 100; + +//database file name +_LIT( KCacheDbFile,"cacheDb.db" ); + +//Table Name CacheTable +_LIT( KCacheTable,"CacheTable" ); + +//CacheTable columns +_LIT( KRowIndexCol, "RowIndex" ); +_LIT( KDataTypeCol, "DataType" ); +_LIT( KDataIdCol, "DataId" ); +_LIT( KTrustPeriodCol, "TrustPeriod" ); +_LIT( KLastModifiedCol, "LastModified" ); +_LIT( KLastAccessedCol, "LastAccessed" ); +_LIT( KTimeCreation, "Created" ); +_LIT( KItemCount, "ItemCount" ); +_LIT( KCachedDataCol, "CachedData" ); +_LIT( KETagHeader, "ETagHeader" ); + +//Table Index Names +_LIT( KRowIndexColIndex, "IndexRowIndex" ); +_LIT( KDataTypeColIndex, "IndexDataType" ); +_LIT( KDataIdColIndex, "IndexDataId" ); +_LIT( KLastAccessedColIndex, "IndexLastAccessed" ); +_LIT( KTimeCreationIndex, "IndexCreated" ); +//Field Lengths + +const TInt KIRObserverArrayGranularity( 2 ); + + +// --------------------------------------------------------------------------- +// Function : OpenL +// Standard two phased construction +// calls ConstructL() +// --------------------------------------------------------------------------- +// +EXPORT_C CIRCacheMgmt* CIRCacheMgmt::OpenL( MIRCacheObserver &aObserver ) + { + IRLOG_DEBUG( "IRCacheMgmt::OpenL - Entering." ); + CIRCacheMgmt* self = reinterpret_cast( Dll::Tls() ); + + if ( self ) + { + User::LeaveIfError( self->Open() ); + } + else + { + self = new ( ELeave ) CIRCacheMgmt( aObserver ); + CleanupClosePushL( *self ); + self->ConstructL(); + User::LeaveIfError( Dll::SetTls( self ) ); + CleanupStack::Pop( self ); + } + IRLOG_DEBUG( "IRCacheMgmt::OpenL - Exiting." ); + return self; + } + + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::~CIRCacheMgmt() +// Standard C++ destructor +// --------------------------------------------------------------------------- +// +CIRCacheMgmt::~CIRCacheMgmt() + { + IRLOG_DEBUG( "IRCacheMgmt::~CIRCacheMgmt - Entering." ); + //array destruction + if ( iPtrPreset ) + { + iPtrPreset->ResetAndDestroy(); + delete iPtrPreset; + iPtrPreset = NULL; + } + if ( iPtrCategory ) + { + iPtrCategory->ResetAndDestroy(); + } + + delete iPtrCategory; + iPtrCategory = NULL; + if ( iPtrChannel ) + { + iPtrChannel->ResetAndDestroy(); + } + + delete iPtrChannel; + iPtrChannel = NULL; + if ( iSettings ) + { + iSettings->Close(); + } + if ( iOTA ) + { + delete iOTA; + iOTA = NULL; + } + iLogoData.Close(); + CloseDb(); + iCacheDb.Close(); + delete iCleanup; + iFsSession.Close(); + iCacheObservers.Close(); + Dll::FreeTls(); + IRLOG_DEBUG( "IRCacheMgmt::~CIRCacheMgmt - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CIRCacheMgmt() +// Standard C++ constructor +// sets the trust period to 24hrs( default ) +// --------------------------------------------------------------------------- +// +CIRCacheMgmt::CIRCacheMgmt ( MIRCacheObserver &aObserver ) + :iCacheObserver( aObserver ), + iCacheObservers( KIRObserverArrayGranularity ) + { + IRLOG_DEBUG( "IRCacheMgmt::CIRCacheMgmt - Entering." ); + //default trust period initially set to 24 hrs + //to be fetched from central repository + iTrustPeriod = TTimeIntervalSeconds( KDefaultInterval ); + IRLOG_DEBUG( "IRCacheMgmt::CIRCacheMgmt - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::ConstructL() +// Standard two phased construction +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::ConstructL() + { + IRLOG_DEBUG( "IRCacheMgmt::ConstructL - Entering." ); + User::LeaveIfError( iFsSession.Connect() ); + //array construction + iPtrPreset = new ( ELeave ) CArrayPtrFlat( + KPresetGranualarity ); + iPtrCategory = new ( ELeave ) CArrayPtrFlat( + KBrowseGranualarity ); + iPtrChannel = new ( ELeave ) CArrayPtrFlat( + KChannelArrayGranualarity ); + iOTA = CIROTAUpdate::NewL(); + iSettings = CIRSettings::OpenL(); + iDatabaseFileName = iSettings->PrivatePath(); + iDatabaseFileName.Append( KCacheDbFile ); + CreateDbConditionalL(); + iCleanup = CIRCacheCleanup::NewL( *this ); + RemoveOtaInfoL(); + IRLOG_DEBUG( "IRCacheMgmt::ConstructL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CreateDbConditionalL( +// Creates dbms conditionally( only if not yet created ) +// calls CreateDb() +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::CreateDbConditionalL() + { + IRLOG_DEBUG( "IRCacheMgmt::CreateDbConditionalL - Entering." ); + TInt err=KErrNone; + if ( !BaflUtils::FileExists( iFsSession, iDatabaseFileName ) ) + { + err=CreateDb(); + if ( KErrNone != err ) + { + User::Leave( err ); + } + } + IRLOG_DEBUG( "IRCacheMgmt::CreateDbConditionalL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CreateDb() +// Creates the tables +// --------------------------------------------------------------------------- +// +TInt CIRCacheMgmt::CreateDb() + { + IRLOG_DEBUG( "IRCacheMgmt::CreateDb - Entering." ); + CloseDb(); + TInt err = iCacheDb.Replace( iFsSession,iDatabaseFileName ); + if ( ( err != 0 ) ) + { + return err; //unable to create file + } + TRAP( err,//trap start + CreateCacheTableL(); + CreateCacheIndexL(); + )//trap end + IRLOG_DEBUG( "IRCacheMgmt::CreateDb - Exiting." ); + return err; + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::OpenCacheDb() +// Opens both the databases +// --------------------------------------------------------------------------- +// +TInt CIRCacheMgmt::OpenCacheDb() + { + IRLOG_DEBUG( "CIRCacheMgmt::OpenCacheDb - Entering" ); + CloseDb(); + TInt error = KErrNone; + if ( !BaflUtils::FileExists( iFsSession, iDatabaseFileName ) ) + { + //if file doesn't exist function leaves with error code + //KErrNotFound + return KErrNotFound; + } + //try and open the db + error = iCacheDb.Open( iFsSession,iDatabaseFileName ); + //return if error + if ( KErrNone != error ) + { + return error; + } + //check if damaged + if ( iCacheDb.IsDamaged() ) + { + //if data base is damaged then + //try to recover + error = iCacheDb.Recover(); + return error; + } + + iOpen = ETrue; + + IRLOG_DEBUG( "CIRCacheMgmt::OpenCacheDb - Exiting." ); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CloseDb() +// Closes the database +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::CloseDb() + { + IRLOG_DEBUG( "IRCacheMgmt::CloseDb - Entering." ); + iCacheDb.Close(); + iOpen = EFalse; + IRLOG_DEBUG( "IRCacheMgmt::CloseDb - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CheckCache() +// API Exposed to Isds Client to check and get the cached items. +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRCacheMgmt::CheckCacheL( TInt aType,const TDesC& aName, + TBool aForceGet,TInt& aReturn ) + { + IRLOG_DEBUG( "CIRCacheMgmt::CheckCacheL - Entering" ); + //opens the db if not open already + if ( !iOpen ) + { + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + aReturn = ENotCached; + return; + } + } + + //calls the function FetchCacheIfAvailable() passing the appropriate + //type and id + + switch( aType ) + { + case ECatagory: + case EChannels: + case EPresets: + case EOtaInfo: + case ELogo: + { + TRAP_IGNORE( FetchCacheIfAvailableL( aType,aName,aForceGet,aReturn ) ) + break; + } + + default: + { + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CacheFailed(); + } + aReturn = ENotCached; + break; + } + } + CloseDb(); + IRLOG_DEBUG( "CIRCacheMgmt::CheckCacheL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::FetchCacheIfAvailable() +// Fetches the cache if available +// --------------------------------------------------------------------------- +// +//generic function to check the validity of the cache +void CIRCacheMgmt::FetchCacheIfAvailableL( TInt aType,const TDesC& aId, + TBool aForceGet,TInt& aReturnVal ) + { + //Algo**** + //1.check the cache table for a request type + //2.if the query returns a row,check for validity + //3.if invalid( stale ) do a conditional get + //4.if valid use cache + IRLOG_DEBUG( "CIRCacheMgmt::FetchCacheIfAvailableL - Entering" ); + //SELECT * FROM KCacheTable WHERE KDataTypeCol = aType AND KDataIdCol=aId + _LIT( query, "SELECT * FROM %S WHERE %S = %d AND %S = '%S'" ); + + HBufC* sqlQuery = HBufC::NewLC( query().Length() + KCacheTable().Length() + + KDataTypeCol().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aId.Length() ); + + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + aType,&KDataIdCol,&aId ); + + IRLOG_DEBUG2( "CIRCacheMgmt::FetchCacheIfAvailableL - \ + Going to evaluate SQL query: %S", sqlQuery ); + + RDbView cacheView; + User::LeaveIfError( cacheView.Prepare( iCacheDb,*sqlQuery ) ); + CleanupStack::PopAndDestroy( sqlQuery ); + CleanupClosePushL( cacheView ); + User::LeaveIfError( cacheView.EvaluateAll() ); + + //if no row match the query there is no cahche available for + //that particular + //request + if ( cacheView.IsEmptyL() ) + { + //Return ENotCached + aReturnVal = ENotCached; + } + else + { + cacheView.FirstL(); + cacheView.GetL(); + CDbColSet* columns = cacheView.ColSetL(); + TTime creationTime = cacheView.ColTime( + columns->ColNo( KTimeCreation ) ); + + TInt cacheValidityTime = cacheView.ColInt( + columns->ColNo( KTrustPeriodCol ) ); + + TInt countItems=cacheView.ColInt( columns->ColNo( KItemCount ) ); + + IRLOG_DEBUG( "CIRCacheMgmt::FetchCacheIfAvailableL - \ + can check validity." ); + + //check if cache is valid + //get it any way if it is "forcedget" + if ( aForceGet || CheckValidity( creationTime,cacheValidityTime ) ) + { + //Fetch the cached data + //FetchCachedData( type,count,&view ) + TRAPD( err,FetchCachedDataL( aType,countItems,cacheView ) ); + if ( err!=KErrNone ) + { + //something goes wrong ,return not cached and fetch new data + aReturnVal = ENotCached; + } + else + { + //cache usable + aReturnVal = ECacheUseable; + } + } + else + { + iLastModified = cacheView.ColTime( + columns->ColNo( KLastModifiedCol ) ); + + iETag = cacheView.ColDes8( columns->ColNo( KETagHeader ) ); + aReturnVal = ECacheNotValid; + cacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CacheInvalid(); + } + } + delete columns; + } + CleanupStack::PopAndDestroy( &cacheView ); + IRLOG_DEBUG( "CIRCacheMgmt::FetchCacheIfAvailableL - Exiting." ); + + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::FetchCachedDataL() +// fetches the cached data from the table into the cached structures +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::FetchCachedDataL( TInt aType,TInt aCountItems, + RDbView& aCacheView ) + { + //Algo**** + //fetch the data and internalize into appropriate structure + + IRLOG_DEBUG( "CIRCacheMgmt::FetchCachedDataL - Entering" ); + CDbColSet* columns = aCacheView.ColSetL(); + TInt columnNo = columns->ColNo( KCachedDataCol ); + delete columns; + switch( aType ) + { + case ECatagory: + { + //Internalize the category items into the + //CIRBrowseCatagoryItems array + RDbColReadStream instream; + instream.OpenLC( aCacheView, columnNo ); + CIRBrowseCatagoryItems* ptr; + if ( iPtrCategory ) + { + iPtrCategory->ResetAndDestroy(); + } + else + { + break; + } + for ( TInt iter = 0; iter < aCountItems; iter++ ) + { + ptr=CIRBrowseCatagoryItems::NewL(); + CleanupStack::PushL( ptr ); + instream>>*ptr; + iPtrCategory->AppendL( ptr ); + CleanupStack::Pop( ptr ); + } + CleanupStack::PopAndDestroy( &instream ); + //update the last accessed time + UpdateLastAccessedTimeL( aCacheView ); + aCacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CachedStructureL( ECatagory ); + } + break; + } + case EChannels: + { + //Internalize the channel items into + //the CIRBrowseChannelItems array + RDbColReadStream instream; + instream.OpenLC( aCacheView, columnNo ); + if ( iPtrChannel ) + { + iPtrChannel->ResetAndDestroy(); + } + CIRBrowseChannelItems *ptr; + for ( TInt iter = 0; iter < aCountItems; iter++ ) + { + ptr = CIRBrowseChannelItems::NewL(); + CleanupStack::PushL( ptr ); + instream>>*ptr; + if ( iPtrChannel ) + { + iPtrChannel->AppendL( ptr ); + } + CleanupStack::Pop( ptr ); + } + CleanupStack::PopAndDestroy( &instream ); + //update the last accessed time + UpdateLastAccessedTimeL( aCacheView ); + aCacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CachedStructureL( EChannels ); + } + break; + } + case EPresets: + { + //Internalize the preset into the CIRIsdsPreset object + RDbColReadStream instream; + instream.OpenLC( aCacheView, columnNo ); + if ( iPtrPreset ) + { + iPtrPreset->ResetAndDestroy(); + } + CIRIsdsPreset *ptr; + for ( TInt iter = 0; iter < aCountItems; iter++ ) + { + ptr = CIRIsdsPreset::NewL(); + CleanupStack::PushL( ptr ); + instream>>*ptr; + if ( iPtrPreset ) + { + iPtrPreset->AppendL( ptr ); + } + CleanupStack::Pop( ptr ); + } + CleanupStack::PopAndDestroy( &instream ); + //update the last accessed time + UpdateLastAccessedTimeL( aCacheView ); + aCacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CachedStructureL( EPresets ); + } + break; + } + case EOtaInfo: + { + //Internalize the ota info into the CIROTAUpdate object + RDbColReadStream instream; + instream.OpenLC( aCacheView, columnNo ); + if ( iOTA ) + { + delete iOTA; + iOTA = NULL; + iOTA = CIROTAUpdate::NewL(); + instream>>*iOTA; + } + + CleanupStack::PopAndDestroy( &instream ); + //update the last accessed time + UpdateLastAccessedTimeL( aCacheView ); + aCacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CachedStructureL( EOtaInfo ); + } + break; + } + case ELogo: + { + //get the logo data from the cache + TInt logoSize = aCacheView.ColSize( columnNo ); + iLogoData.Close(); + iLogoData.Zero(); + iLogoData.CreateL( logoSize ); + + RDbColReadStream instream; + instream.OpenLC( aCacheView, columnNo ); + instream.ReadL( iLogoData,aCacheView.ColLength( columnNo ) ); + CleanupStack::PopAndDestroy( &instream ); + //update the last accessed time + UpdateLastAccessedTimeL( aCacheView ); + aCacheView.Close(); + for ( TInt i = 0; i < iCacheObservers.Count(); i++ ) + { + iCacheObservers[i]->CachedStructureL( ELogo ); + } + break; + } + default: + { + aCacheView.Close(); + } + } + IRLOG_DEBUG( "CIRCacheMgmt::FetchCachedDataL - Exiting." ); + } +// --------------------------------------------------------------------------- +//updates the last accessed field to aid in deletion of old unused data +// +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::UpdateLastAccessedTimeL( RDbView &aCacheView ) + { + IRLOG_DEBUG( "IRCacheMgmt::UpdateTrustPeriod - Entering." ); + //update the last accessed col + CDbColSet* columns = aCacheView.ColSetL(); + TInt updateColNo = columns->ColNo( KLastAccessedCol ); + delete columns; + TTime currentTime; + currentTime.UniversalTime(); + //update the current time value + aCacheView.GetL(); + aCacheView.UpdateL(); + aCacheView.SetColL( updateColNo,currentTime ); + aCacheView.PutL(); + IRLOG_DEBUG( "IRCacheMgmt::UpdateTrustPeriod - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CheckValidity() +// Checks the freshness of the cache +// --------------------------------------------------------------------------- +// +TBool CIRCacheMgmt::CheckValidity( const TTime& aCreateTime, + TInt aTrustPeriod ) const + { + //Algo**** + //1.get the last creation time from the table for the request + //2.calculate creation-time + trust-period < current-time * + //3.if true the cache is valid + //4.else do conditional-get + IRLOG_DEBUG( "CIRCacheMgmt::CheckValidity - Entering" ); + TTimeIntervalSeconds trustPeriod( aTrustPeriod ); + TTimeIntervalSeconds diff; + TTime currentDeviceTime; + currentDeviceTime.UniversalTime(); + currentDeviceTime.SecondsFrom( aCreateTime,diff ); + //Has the cache expired + if ( diff& aPtrCategory, + const TDesC& aName, const CIRHttpResponseData& aResponseHeaders ) + { + //Algo**** + //1.check if similar request is cached + //2.delete if similar request is already present + //3.prepare a view for insertion + //4.push in the requested data as serialized data + + IRLOG_DEBUG( "IRCacheMgmt::CacheCategoryItemsL - Entering" ); + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + + //clear similar data from the cache table before updating it with fresh data + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"DELETE FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aName.Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + ECatagory,&KDataIdCol,&aName ); + iCacheDb.Begin(); + //deletes a similar record if it existed. + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + + //get the cached data view for preset column to update with fresh data. + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query1,"SELECT * FROM %S WHERE %S = %d" ); + HBufC* sqlQuery1 = HBufC::NewLC( query1().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + + KDefaultRealWidth ); + sqlQuery1->Des().Format( query1,&KCacheTable,&KDataTypeCol,ECatagory ); + + RDbView cacheTableView; + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery1 ) ); + CleanupStack::PopAndDestroy( sqlQuery1 ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare insertion values + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + TInt countItems=aPtrCategory.Count(); + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + //write stream + RDbColWriteStream writeStream; + //start insertion into the view + //insert a new row + cacheTableView.InsertL(); + //set values + cacheTableView.SetColL( columns->ColNo( KDataTypeCol ), ECatagory ); + cacheTableView.SetColL( columns->ColNo( KDataIdCol ), aName ); + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KItemCount ), countItems ); + //to be set only if available + cacheTableView.SetColL( columns->ColNo( KLastModifiedCol ), + aResponseHeaders.iLastModified ); + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + //open stream + writeStream.OpenLC( cacheTableView,columns->ColNo( KCachedDataCol ) ); + for ( TInt iter = 0; iter < countItems; iter++ ) + { + aPtrCategory[iter]->ExternalizeL( writeStream ); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy( &writeStream ); + cacheTableView.PutL(); + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "IRCacheMgmt::CacheCategoryItemsL - Exiting." ); + + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CacheChannelItemsL() +// Caches the channel objects array of data.By externalizing it into a file.. +// --------------------------------------------------------------------------- +// + +EXPORT_C void CIRCacheMgmt::CacheChannelItemsL( + CArrayPtrFlat& aPtrChannel, + const TDesC& aName,const CIRHttpResponseData& aResponseHeaders ) + { + //Algo**** + //1.check if similar request is cached + //2.delete if similar request is already present + //3.prepare a view for insertion + //4.push in the cached data request as serialized data + IRLOG_DEBUG( "CIRCacheMgmt::CacheChannelItemsL - Entering" ); + + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + + //convert the id information of descriptor to int value for comparision + //clear data from the cache table before updating it with fresh data + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"DELETE FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aName.Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + EChannels,&KDataIdCol,&aName ); + iCacheDb.Begin(); + //deletes a similar record if it existed. + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + + //get the cached data view for preset column to update with fresh data. + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query1,"SELECT * FROM %S WHERE %S = %d" ); + HBufC* sqlQuery1 = HBufC::NewLC( query1().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDefaultRealWidth ); + RDbView cacheTableView; + sqlQuery1->Des().Format( query1,&KCacheTable,&KDataTypeCol,EChannels ); + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery1 ) ); + CleanupStack::PopAndDestroy( sqlQuery1 ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare insertion values + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + TInt countItems=aPtrChannel.Count(); + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + TBuflastModified; + + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + //write stream + RDbColWriteStream writeStream; + + //start insertion into the view + //insert a new row + cacheTableView.InsertL(); + //set values + cacheTableView.SetColL( columns->ColNo( KDataTypeCol ), EChannels ); + cacheTableView.SetColL( columns->ColNo( KDataIdCol ), aName ); + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KItemCount ), countItems ); + //to be set only if available + cacheTableView.SetColL( columns->ColNo( KLastModifiedCol ), + aResponseHeaders.iLastModified ); + // + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + //open stream + writeStream.OpenLC( cacheTableView,columns->ColNo( KCachedDataCol ) ); + for ( TInt iter = 0; iter < countItems; iter++ ) + { + aPtrChannel[iter]->ExternalizeL( writeStream ); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy( &writeStream ); + cacheTableView.PutL(); + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "CIRCacheMgmt::CacheChannelItemsL - Exiting." ); + + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CachePresetItemL() +// Caches the preset object .By externalizing it into a file. +//multiple presets can be cached at one time +// --------------------------------------------------------------------------- +// + +EXPORT_C void CIRCacheMgmt::CachePresetItemL( + CArrayPtrFlat& aPtrPresets, + const TDesC& aName,const CIRHttpResponseData& aResponseHeaders ) + { + //Algo**** + //1.check if similar request is cached + //2.delete if similar request is already present + //3.prepare a view for insertion + //4.push in the cached data request as serialized data + IRLOG_DEBUG( "CIRCacheMgmt::CachePresetItemL - Entering" ); + + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + //convert the id information of descriptor to int value for comparision + //clear data from the cache table before updating it with fresh data + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"DELETE FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aName.Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + EPresets,&KDataIdCol,&aName ); + iCacheDb.Begin(); + //deletes a similar record if it existed. + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + + //get the cached data view for preset column to update with fresh data. + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query1,"SELECT * FROM %S WHERE %S = %d" ); + HBufC* sqlQuery1 = HBufC::NewLC( query1().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDefaultRealWidth ); + sqlQuery1->Des().Format( query1,&KCacheTable,&KDataTypeCol,EPresets ); + RDbView cacheTableView; + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery1 ) ); + CleanupStack::PopAndDestroy( sqlQuery1 ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare insertion values + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + TBuflastModified; + //default time set to 24hrs + //use iTrustPeriod + //type set to EPresets + //id set to dataId + //last modified time kept null + //item count set to 1 + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + //write stream + RDbColWriteStream writeStream; + TInt countItems; + countItems = aPtrPresets.Count(); + //start insertion into the view + //insert a new row + cacheTableView.InsertL(); + //set values + cacheTableView.SetColL( columns->ColNo( KDataTypeCol ), EPresets ); + cacheTableView.SetColL( columns->ColNo( KDataIdCol ), aName ); + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KItemCount ), countItems ); + //to be set only if available + cacheTableView.SetColL( columns->ColNo( KLastModifiedCol ), + aResponseHeaders.iLastModified ); + // + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + //open stream + writeStream.OpenLC( cacheTableView,columns->ColNo( KCachedDataCol ) ); + for ( TInt iter = 0; iter < countItems; iter++ ) + { + aPtrPresets[iter]->ExternalizeL( writeStream ); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy( &writeStream ); + cacheTableView.PutL(); + + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "CIRCacheMgmt::CachePresetItemL - Exiting." ); + } +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CacheOtaInfoL() +// Caches the OTA information .By externalizing it into a db. +// --------------------------------------------------------------------------- +// + +EXPORT_C void CIRCacheMgmt::CacheOtaInfoL( const CIROTAUpdate& aOta, + const TDesC& aName, + const CIRHttpResponseData& aResponseHeaders ) + { + //Algo**** + //1.check if similar request is cached + //2.delete if similar request is already present + //3.prepare a view for insertion + //4.push in the cached data request as serialized data + IRLOG_DEBUG( "CIRCacheMgmt::CacheOtaInfoL - Entering" ); + + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + //convert the id information of descriptor to int value for comparision + //clear data from the cache table before updating it with fresh data + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"DELETE FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aName.Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + EOtaInfo,&KDataIdCol,&aName ); + + User::LeaveIfError( iCacheDb.Begin() ); + //deletes a similar record if it existed. + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + + //get the cached data view for preset column to update with fresh data. + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query1,"SELECT * FROM %S WHERE %S = %d" ); + HBufC* sqlQuery1 = HBufC::NewLC( query1().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDefaultRealWidth ); + + sqlQuery1->Des().Format( query1,&KCacheTable,&KDataTypeCol,EOtaInfo ); + RDbView cacheTableView; + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery1 ) ); + CleanupStack::PopAndDestroy( sqlQuery1 ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare insertion values + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + TBuflastModified; + //default time set to 24hrs + //use iTrustPeriod + //type set to EPresets + //id set to dataId + //last modified time kept null + //item count set to 1 + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + //write stream + RDbColWriteStream writeStream; + //start insertion into the view + //insert a new row + cacheTableView.InsertL(); + //set values + cacheTableView.SetColL( columns->ColNo( KDataTypeCol ), EOtaInfo ); + cacheTableView.SetColL( columns->ColNo( KDataIdCol ), aName ); + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KItemCount ), 1 ); + //to be set only if available + cacheTableView.SetColL( columns->ColNo( KLastModifiedCol ), + aResponseHeaders.iLastModified ); + // + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + //open stream + writeStream.OpenLC( cacheTableView,columns->ColNo( KCachedDataCol ) ); + aOta.ExternalizeL( writeStream ); + writeStream.CommitL(); + CleanupStack::PopAndDestroy( &writeStream ); + cacheTableView.PutL(); + + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "CIRCacheMgmt::CacheOtaInfoL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CacheLogoL() +// Caches the logo data .By externalizing it into a db. +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRCacheMgmt::CacheLogoL( const TDesC8& aData, const TDesC& aUrl, + const CIRHttpResponseData& aResponseHeaders ) + { + //Algo**** + //1.check if similar request is cached + //2.delete if similar request is already present + //3.prepare a view for insertion + //4.push in the cached data request as serialized data + IRLOG_DEBUG( "CIRCacheMgmt::CacheLogoL - Entering" ); + + + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + //convert the id information of descriptor to int value for comparision + //clear data from the cache table before updating it with fresh data + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"DELETE FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() + + KDefaultRealWidth + aUrl.Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + ELogo,&KDataIdCol,&aUrl ); + iCacheDb.Begin(); + //deletes a similar record if it existed. + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + + //get the cached data view for preset column to update with fresh data. + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query1,"SELECT * FROM %S WHERE %S = %d" ); + HBufC* sqlQuery1 = HBufC::NewLC( query1().Length() + KDataTypeCol().Length() + + KCacheTable().Length() + KDefaultRealWidth ); + sqlQuery1->Des().Format( query1,&KCacheTable,&KDataTypeCol,ELogo ); + RDbView cacheTableView; + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery1 ) ); + CleanupStack::PopAndDestroy( sqlQuery1 ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare insertion values + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + TBuflastModified; + //default time set to 24hrs + //use iTrustPeriod + //type set to ELogo + //id set to dataId + //last modified time kept null + //item count set to 1 + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + //write stream + //start insertion into the view + //insert a new row + cacheTableView.InsertL(); + //set values + cacheTableView.SetColL( columns->ColNo( KDataTypeCol ), ELogo ); + cacheTableView.SetColL( columns->ColNo( KDataIdCol ), aUrl ); + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KItemCount ), 1 ); + //to be set only if available + cacheTableView.SetColL( columns->ColNo( KLastModifiedCol ), + aResponseHeaders.iLastModified ); + // + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KCachedDataCol ), aData ); + + cacheTableView.SetColL( columns->ColNo( KETagHeader ), + aResponseHeaders.iETag ); + + cacheTableView.PutL(); + + + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "CIRCacheMgmt::CacheLogoL - Exiting." ); + + } + + + + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CreateCacheTableL() +// creates the cache table +// --------------------------------------------------------------------------- +// +//CacheTable +// ----------------------------------------------------------------------------------------------------- +//| RowIndex|DataType|DataId|TrustPeriod|LastModified |LastAccessed|Created|ItemCount|CachedData| +//------------------------------------------------------------------------------------------------ +//| auto |TInt |DesC |TInt |TDesC/DateTime|TTime |Time |TInt | Streamed | +//|increment|0,1,2,NotNull|NotNull| NotNull | | | | | Data | +//------------------------------------------------------------------------------------------------------ +void CIRCacheMgmt::CreateCacheTableL() + { + IRLOG_DEBUG( "IRCacheMgmt::CreateCacheTableL - Entering." ); + //the row index column which autoincrements + TDbCol rowIndexCol( KRowIndexCol, EDbColInt32 ); + rowIndexCol.iAttributes = TDbCol::EAutoIncrement; + + //the datatype column,to identify between ECatagory = 0,EChannels=1,EPresets=2 + TDbCol dataTypeCol( KDataTypeCol, EDbColInt32 ); + dataTypeCol.iAttributes = TDbCol::ENotNull; + + //the dataID column,to uniquely identify the cached data + TDbCol dataId( KDataIdCol, EDbColLongText16 ); + dataId.iAttributes = TDbCol::ENotNull; + + //the trust period column to calculate cache validity + TDbCol trustPeriodCol( KTrustPeriodCol, EDbColInt32 ); + + //the lastmodified column to fetch data conditionally + TDbCol lastModifiedCol( KLastModifiedCol, EDbColDateTime ); + + + //the last accessed column used for table clean-up + TDbCol creationTimeCol( KTimeCreation, EDbColDateTime ); + + //the time of creation saved to calculate the cache validity + TDbCol lastAccessedCol( KLastAccessedCol, EDbColDateTime ); + + //the number of items in the data field + TDbCol itemCountCol( KItemCount, EDbColInt32 ); + + //the data column to store cached data + //The column stores a potentially large amount of Unicode text data. + TDbCol cachedDataCol( KCachedDataCol, EDbColLongText8 ); + + //the ETag header received along with the logo data + TDbCol etagHeader( KETagHeader, EDbColText8 ); + + //colset + CDbColSet* cacheTablerColSet = CDbColSet::NewLC(); + //populate colset + cacheTablerColSet->AddL( rowIndexCol ); + cacheTablerColSet->AddL( dataTypeCol ); + cacheTablerColSet->AddL( dataId ); + cacheTablerColSet->AddL( trustPeriodCol ); + cacheTablerColSet->AddL( lastModifiedCol ); + cacheTablerColSet->AddL( creationTimeCol ); + cacheTablerColSet->AddL( lastAccessedCol ); + cacheTablerColSet->AddL( itemCountCol ); + cacheTablerColSet->AddL( cachedDataCol ); + cacheTablerColSet->AddL( etagHeader ); + + // Create the CacheTable table + User::LeaveIfError( iCacheDb.CreateTable( KCacheTable, *cacheTablerColSet ) ); + + CleanupStack::PopAndDestroy( cacheTablerColSet ); + IRLOG_DEBUG( "IRCacheMgmt::CreateCacheTableL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Function : CIRCacheMgmt::CreateCacheIndexL() +// creates the indices for cache table +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::CreateCacheIndexL() + { + IRLOG_DEBUG( "IRCacheMgmt::CreateCacheIndexL - Entering." ); + TDbKeyCol rowIndexCol( KRowIndexCol ); + TDbKeyCol dataTypeCol( KDataTypeCol ); + TDbKeyCol dataIdCol( KDataIdCol,KDataIdIndexSize ); + TDbKeyCol timeCreationCol( KTimeCreation ); + TDbKeyCol lastAccessedCol( KLastAccessedCol ); + + CDbKey* index; + //index on the auto increment row id + index = CDbKey::NewLC(); + index->AddL( rowIndexCol ); + User::LeaveIfError( iCacheDb.CreateIndex( KRowIndexColIndex, KCacheTable, + *index ) ); + CleanupStack::PopAndDestroy( index ); + + //index on the datatype column + index = CDbKey::NewLC(); + index->AddL( dataTypeCol ); + User::LeaveIfError( iCacheDb.CreateIndex( KDataTypeColIndex, KCacheTable, + *index ) ); + CleanupStack::PopAndDestroy( index ); + + //index on the data id column + index = CDbKey::NewLC(); + index->AddL( dataIdCol ); + User::LeaveIfError( iCacheDb.CreateIndex( KDataIdColIndex, KCacheTable, + *index ) ); + CleanupStack::PopAndDestroy( index ); + + //index on the time of record creation column + index = CDbKey::NewLC(); + index->AddL( timeCreationCol ); + User::LeaveIfError( iCacheDb.CreateIndex( KTimeCreationIndex, KCacheTable, + *index ) ); + CleanupStack::PopAndDestroy( index ); + + //index on the last accessed column + index = CDbKey::NewLC(); + index->AddL( lastAccessedCol ); + User::LeaveIfError( iCacheDb.CreateIndex( KLastAccessedColIndex, KCacheTable, + *index ) ); + CleanupStack::PopAndDestroy( index ); + IRLOG_DEBUG( "IRCacheMgmt::CreateCacheIndexL - Exiting." ); + } +// --------------------------------------------------------------------------- +//void CIRCacheMgmt::UpdateTrustPeriod() +//updates the trust period for a not-modified responce +// --------------------------------------------------------------------------- + +// +EXPORT_C void CIRCacheMgmt::UpdateTrustPeriodL( TInt aType, const TDesC& aName, + CIRHttpResponseData& aResponseHeaders ) + { + IRLOG_DEBUG( "IRCacheMgmt::UpdateTrustPeriodL - Entering" ); + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + IRLOG_ERROR2( "IRCacheMgmt::UpdateTrustPeriodL - \ + Error while opening cache DB (%d).", error ); + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + + //SELECT * FROM KCacheTable WHERE KDataTypeCol = TYPE AND KDataIdCol = DATAID + _LIT( query,"SELECT * FROM %S WHERE %S = %d AND %S = '%S'" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + KCacheTable().Length() + + KDataIdCol().Length() + KDataTypeCol().Length() + aName.Length()+ + KDefaultRealWidth ); + + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol, + aType,&KDataIdCol,&aName ); + + //create view + RDbView cacheTableView; + User::LeaveIfError( cacheTableView.Prepare( iCacheDb,*sqlQuery ) ); + CleanupStack::PopAndDestroy( sqlQuery ); + CleanupClosePushL( cacheTableView ); + + User::LeaveIfError( cacheTableView.EvaluateAll() ); + + //prepare the update data + //will go into last accessed aswell as the creation time fields + TTime currentTime; + currentTime.UniversalTime(); + //get the new trust period from the headers + TInt maxAge; + if ( aResponseHeaders.iMaxAge.Length() == 0 ) + { + maxAge=iTrustPeriod.Int(); + } + else + { + TLex8 conv( aResponseHeaders.iMaxAge ); + conv.Val( maxAge ); + maxAge = maxAge * KDefaultInterval; + } + CDbColSet* columns = cacheTableView.ColSetL(); + CleanupStack::PushL( columns ); + cacheTableView.FirstL(); + if ( cacheTableView.AtRow() ) + { + cacheTableView.UpdateL(); + //update values + cacheTableView.SetColL( columns->ColNo( KTrustPeriodCol ), maxAge ); + cacheTableView.SetColL( columns->ColNo( KLastAccessedCol ), currentTime ); + cacheTableView.SetColL( columns->ColNo( KTimeCreation ), currentTime ); + cacheTableView.PutL(); + } + + CleanupStack::PopAndDestroy( columns ); + CleanupStack::PopAndDestroy( &cacheTableView ); + CloseDb(); + IRLOG_DEBUG( "IRCacheMgmt::UpdateTrustPeriod - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Used to dcontrol the cache table size by compacting and clearing up unused items +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::CheckSizeL() + { + IRLOG_DEBUG( "IRCacheMgmt::CheckSizeL - Entering." ); + OpenCacheDb(); + RDbDatabase::TSize dbSize = iCacheDb.Size(); + iCacheDbSize = dbSize.iSize; + TInt size = CacheSize(); + if ( size >= KCacheCriticalSizeLimit ) + { + RemoveOldUnusedDataL(); + OpenCacheDb(); + iCacheDb.Compact(); + //refresh the size information + dbSize = iCacheDb.Size(); + iCacheDbSize = dbSize.iSize; + } + CloseDb(); + IRLOG_DEBUG( "IRCacheMgmt::CheckSizeL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Used to control the cache table size by compacting and clearing up unused items +// --------------------------------------------------------------------------- +// +void CIRCacheMgmt::RemoveOldUnusedDataL() + { + IRLOG_DEBUG( "IRCacheMgmt::RemoveOldUnusedDataL - Entering." ); + OpenCacheDb(); + RDbTable cacheTable; + //open the table in updatable mode + User::LeaveIfError( cacheTable.Open( iCacheDb, KCacheTable, + cacheTable.EUpdatable ) ); + CleanupClosePushL( cacheTable ); + cacheTable.Reset(); + //set index as the last accessed time + cacheTable.SetIndex( KLastAccessedCol ); + //begin transaction + iCacheDb.Begin(); + // no of rows deleted is one fourth of the total number of rows + TInt deleteRows = cacheTable.CountL()/KPercentRowsDeleted; + TInt inc = 0; + //delete incrementally + for ( cacheTable.FirstL(); ( ( inc < deleteRows ) && cacheTable.AtRow() ); inc++ ) + { + cacheTable.GetL(); + cacheTable.DeleteL(); + cacheTable.NextL(); + } + //commit transaction + iCacheDb.Commit(); + CleanupStack::PopAndDestroy( &cacheTable ); + CloseDb(); + IRLOG_DEBUG( "IRCacheMgmt::RemoveOldUnusedDataL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Used to get the cache table size +// --------------------------------------------------------------------------- +// +TInt CIRCacheMgmt::CacheSize() + { + IRLOG_DEBUG( "IRCacheMgmt::CacheSize - Entering." ); + OpenCacheDb(); + RDbDatabase::TSize dbSize = iCacheDb.Size(); + iCacheDbSize = dbSize.iSize; + CloseDb(); + IRLOG_DEBUG( "IRCacheMgmt::CacheSize - Exiting." ); + return iCacheDbSize; + } +// --------------------------------------------------------------------------- +//remove OTA info from cache if data is not valid any longer +// --------------------------------------------------------------------------- +EXPORT_C void CIRCacheMgmt::RemoveOtaInfoL() + { + IRLOG_DEBUG( "IRCacheMgmt::RemoveOtaInfoL - Entering." ); + //check if the silence period param is set. + //if not set that means the cached ota info if present is not valid. + if ( iSettings->GetSilencePeriodL() == 0 ) + { + TInt error = OpenCacheDb(); + if ( KErrNone != error ) + { + //no problems if this function returns here. + //normal flow won't get affected. + //only a particular request wont get cached + return; + } + //clear data from the cache table + //DELETE FROM KCacheTable WHERE KDataTypeCol = TYPE + _LIT( query,"DELETE FROM %S WHERE %S = %d" ); + HBufC* sqlQuery = HBufC::NewLC( query().Length() + + KDataTypeCol().Length() + + KCacheTable().Length() + KDataIdCol().Length() ); + sqlQuery->Des().Format( query,&KCacheTable,&KDataTypeCol,EOtaInfo ); + User::LeaveIfError( iCacheDb.Begin() ); + //no problem if it did not exist + iCacheDb.Execute( *sqlQuery,EDbCompareNormal ); + CleanupStack::PopAndDestroy( sqlQuery ); + iCacheDb.Commit(); + CloseDb(); + } + IRLOG_DEBUG( "IRCacheMgmt::RemoveOtaInfoL - Exiting." ); + } + + + +// --------------------------------------------------------------------------- +// Adds a cache observer +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRCacheMgmt::AddObserverL( MIRCacheObserver* aObserver ) + { + IRLOG_DEBUG( "IRCacheMgmt::AddObserverL - Entering." ); + iCacheObservers.AppendL( aObserver ); + IRLOG_DEBUG( "IRCacheMgmt::AddObserverL - Exiting." ); + } + +// --------------------------------------------------------------------------- +// Removes a cache observer +// --------------------------------------------------------------------------- +// +EXPORT_C void CIRCacheMgmt::RemoveObserver( MIRCacheObserver* aObserver ) + { + IRLOG_DEBUG( "IRCacheMgmt::RemoveObserver - Entering." ); + TInt objectIndex = iCacheObservers.Find( aObserver ); + + if ( objectIndex != KErrNotFound ) + { + iCacheObservers.Remove( objectIndex ); + } + IRLOG_DEBUG( "IRCacheMgmt::RemoveObserver - Exiting." ); + }