--- /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 <bautils.h>
+
+#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<CIRCacheMgmt*>(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<CIRIsdsPreset>(
+ KPresetGranualarity);
+ iPtrCategory = new (ELeave) CArrayPtrFlat<CIRBrowseCatagoryItems>(
+ KBrowseGranualarity);
+ iPtrChannel = new (ELeave) CArrayPtrFlat<CIRBrowseChannelItems>(
+ 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<aCountItems;iter++)
+ {
+ ptr=CIRBrowseCatagoryItems::NewL();
+ CleanupStack::PushL(ptr);
+ instream>>*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<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.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<trustPeriod)
+ {
+ IRLOG_DEBUG( "CIRCacheMgmt::CheckValidity - Exiting (1)." );
+ return ETrue;
+ }
+ //Else return false
+ else
+ {
+ IRLOG_DEBUG( "CIRCacheMgmt::CheckValidity - Exiting (2)." );
+ return EFalse;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Function : CIRCacheMgmt::CacheCategoryItemsL()
+// Caches the category array of data.By externalizing it into a file.
+// ---------------------------------------------------------------------------
+//
+
+EXPORT_C void CIRCacheMgmt::CacheCategoryItemsL(
+ CArrayPtrFlat<CIRBrowseCatagoryItems>& 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<CIRBrowseChannelItems>& 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;
+ }
+ TBuf<KHttpDateLength>lastModified;
+
+ 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<CIRIsdsPreset>& 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;
+ }
+ TBuf<KHttpDateLength>lastModified;
+ //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;
+ }
+ TBuf<KHttpDateLength>lastModified;
+ //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;
+ }
+ TBuf<KHttpDateLength>lastModified;
+ //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." );
+ }
+
+
+
+