diff -r 000000000000 -r 09774dfdd46b internetradio2.0/cachemgmtsrc/ircachemgmt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internetradio2.0/cachemgmtsrc/ircachemgmt.cpp Mon Apr 19 14:01:53 2010 +0300 @@ -0,0 +1,1505 @@ +/* +* 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(); + } + for(TInt iter=0;iter>*ptr; + if (iPtrCategory) + { + 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>*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>*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.Create(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;iterExternalizeL(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;iterExternalizeL(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;iterExternalizeL(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." ); + } + + + +