fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp
branchRCL_3
changeset 62 19bba8228ff0
parent 0 b497e44ab2fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp	Wed Sep 01 12:27:42 2010 +0100
@@ -0,0 +1,640 @@
+/*
+* Copyright (c) 2005 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:   Fota package state preservation 
+*
+*/
+
+
+
+#include "FotaDB.h"
+#include "FotaSrvDebug.h"
+#include <centralrepository.h>
+#include "fotaserverPrivateCRKeys.h"
+
+#define __LEAVE_IF_ERROR(x) if(KErrNone!=x) {FLOG(_L("LEAVE in %s: %d"), __FILE__, __LINE__); User::Leave(x); }
+
+// ====================== MEMBER FUNCTIONS ===================================
+
+// ---------------------------------------------------------------------------
+// CFotaDB::CFotaDB()
+// ---------------------------------------------------------------------------
+CFotaDB::CFotaDB() : iIsOpen( EFalse )
+	,iTableAltercheck(ETrue)
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CFotaDB::~CFotaDB()
+// ---------------------------------------------------------------------------
+CFotaDB::~CFotaDB()
+    {
+    //Delete columns set
+    if (iColSet)
+    	{
+    	delete iColSet;
+    	iColSet = NULL;
+    	}
+    //Close table
+   	iTable.Close();
+   	
+   	//Close database
+   	iStateDB.Close();
+   	
+   	//Close file server session
+    if (iFSSession.Handle())
+    	iFSSession.Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::NewL()
+// ---------------------------------------------------------------------------
+CFotaDB* CFotaDB::NewL()
+    { 
+    CFotaDB* self=new(ELeave) CFotaDB();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::ConstructL()
+// ---------------------------------------------------------------------------
+void CFotaDB::ConstructL()
+    {
+    TInt err;
+    TBuf<KMaxPath>    tmp;
+    User::LeaveIfError( iFSSession.Connect() );
+    err = iFSSession.CreatePrivatePath( EDriveC );
+    if ( err != KErrNone && err != KErrAlreadyExists ) User::Leave( err );
+    User::LeaveIfError( iFSSession.SetSessionToPrivate( EDriveC ) );
+    User::LeaveIfError( iFSSession.SessionPath (tmp) );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::CreateDatabaseL()
+// Creates db in private dir of fotaserver
+// ---------------------------------------------------------------------------
+void CFotaDB::CreateDatabaseL()
+    {
+    FLOG(_L("CFotaDB::CreateDatabaseL()  >>"));
+    TInt        err;
+    User::LeaveIfError( iStateDB.Create( iFSSession ,KDatabaseName ) );
+    User::LeaveIfError(iStateDB.Begin());
+    User::LeaveIfError(iStateDB.Execute(KCreateTable));
+    err = iStateDB.Commit();
+    if(err) 
+        {
+        FLOG(_L("      cdb err %d"),err);
+        iStateDB.Rollback();
+        User::Leave(err);
+        }
+    User::LeaveIfError( iStateDB.Compact() );
+    FLOG(_L("CFotaDB::CreateDatabaseL()  <<"));
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::AddPackageStateL
+// Adds state to db
+// ---------------------------------------------------------------------------
+void CFotaDB::AddPackageStateL(const TPackageState& aState
+                                ,const TDesC8& aPkgURL)
+    {
+    FLOG(_L("  CFotaDB::AddPackageStateL   >>"));
+    TInt            err;
+    RDbView         view;
+	CleanupClosePushL( view );
+    TPackageState   pkgstate(aState); 
+    pkgstate.iResult = -1; // result should be -1 if no Execs have been done
+	err = view.Prepare( iStateDB, TDbQuery(KSelectAll), RDbView::EInsertOnly);
+    __LEAVE_IF_ERROR(err);
+    FLOG(_L("  CFotaDB::AddPackageStateL   inserting. pkgid:%d result:%d \
+            state:%d"), pkgstate.iPkgId,pkgstate.iResult,pkgstate.iState);
+	view.InsertL();
+    StateToRowL( pkgstate,aPkgURL,view );
+	view.PutL();
+	CleanupStack::PopAndDestroy(); //view
+    FLOG(_L("  CFotaDB::AddPackageStateL   <<"));
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::GetAllL
+// Get all states
+// ---------------------------------------------------------------------------
+void CFotaDB::GetAllL( RArray<TInt>& aStates)
+	{
+	RDbView             view;
+	CleanupClosePushL( view );
+    
+	TInt err = view.Prepare( iStateDB, TDbQuery( KSelectAll ) );
+	__LEAVE_IF_ERROR(err);
+	view.EvaluateAll();
+
+	view.FirstL();
+    FLOG(_L("[fota DB] --- rows --------------------------------------------\
+        ----------------------- v"));		
+	while ( view.AtRow() )
+		{
+        view.GetL();
+        HBufC8*         url;
+        TPackageState   s = RowToStateL(url,view);
+        aStates.Append( s.iPkgId );
+        CleanupStack::PushL ( url );       
+        FLOG(_L("[fotaDB] pkgid: %d profid:%d state:%d  result:%d \
+        url: %d chars sessiontype:%d IapId:%d Pkgsize:%d UpdateLtr:%d"), s.iPkgId, s.iProfileId, s.iState,s.iResult
+        ,url->Des().Length(), s.iSessionType, s.iIapId, s.iPkgSize, s.iUpdateLtr );
+	    CleanupStack::PopAndDestroy(); // url
+		view.NextL();
+		}	
+    FLOG(_L("[fota DB] --- rows --------------------------------------------\
+        ----------------------- ^"));		
+    view.Close();
+	CleanupStack::PopAndDestroy(); //view
+	}
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::OpenDBL()
+// Opens database
+// ---------------------------------------------------------------------------
+void CFotaDB::OpenDBL()
+    {
+    FLOG(_L("CFotaDB::OpenDBL()"));
+    if (!iIsOpen)	//Prevents accidental opening of database twice
+    	{
+	    TInt        err;
+	    err     = iStateDB.Open ( iFSSession ,KDatabaseName);
+	    
+	    if ( err == KErrNotFound )
+	        {
+	        CreateDatabaseL();
+	        iTableAltercheck = EFalse; //Table created newly, hence no alteration required.
+	        }
+	    else if ( err != KErrNone )
+	        {
+	        FLOG(_L("[fota DB openDB]\t db open error: %d"), err);
+	        FLOG(_L("deleting fota DB and creating it again..."));
+	        err = iFSSession.Delete(KDatabaseName);
+	        CreateDatabaseL();
+	        User::LeaveIfError(err);
+	        }
+	    User::LeaveIfError( iTable.Open (iStateDB, KTblState) );
+	    iColSet = iTable.ColSetL();
+	    
+	   	//Check & correct if the table has wrong attributes - this is for data compatibility
+	    if (iTableAltercheck)
+	    	AlterTableIfRequiredL();
+	
+	    iIsOpen = ETrue;
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+// CFotaDB::CloseAndCommitDB
+// Closes and commits DB
+// ---------------------------------------------------------------------------
+void CFotaDB::CloseAndCommitDB()
+    {
+    if ( iColSet )
+        {
+        delete iColSet;
+        iColSet = NULL;
+        }
+    iTable.Close();
+    iStateDB.Close();
+    iIsOpen = EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CFotaDB::IsOpen()
+// Chekcs if db is open
+// ---------------------------------------------------------------------------
+TBool CFotaDB::IsOpen()
+    {
+    return iIsOpen;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::GetStateL
+// Gets pkg state from db
+// ---------------------------------------------------------------------------
+TPackageState CFotaDB::GetStateL(const TInt aPkgId)
+    {   
+	RDbView             view;
+    TPackageState       s;
+	CleanupClosePushL( view ); 
+
+    s.iState = RFotaEngineSession::EIdle; // default state is idle
+
+    HBufC* select  = HBufC::NewLC( KSelect_where_packageid().Length() + 10); 
+    select->Des().Format (KSelect_where_packageid, aPkgId);
+
+    TInt err = view.Prepare( iStateDB, TDbQuery(*select) );
+	__LEAVE_IF_ERROR(err);
+	view.EvaluateAll();
+	view.FirstL();
+
+    while ( view.AtRow() )
+		{
+        view.GetL();
+        HBufC8* url;
+        s = RowToStateL( url,view ); 
+        CleanupStack::PushL( url );     
+        CleanupStack::PopAndDestroy(); // url
+		view.NextL();
+		}	
+	CleanupStack::PopAndDestroy(); //select
+	CleanupStack::PopAndDestroy(); //view
+    return s;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::SetStateL
+// Writes package state to DB. 
+// ---------------------------------------------------------------------------
+void CFotaDB::SetStateL( TPackageState& aState, const TDesC8& aPkgURL
+                        , TUint aChangedFields )
+    {
+    FLOG(_L("  CFotaDB::SetStateL  >>  id %d result %d  state %d sessiontype %d iapid %d pkgsize %d updateltr %d")
+                    ,aState.iPkgId, aState.iResult, aState.iState);
+    __ASSERT_ALWAYS( aChangedFields!=0, User::Panic(KFotaPanic, KErrArgument) );
+
+    TPackageState found = GetStateL( aState.iPkgId );
+    if ( found.iPkgId == KErrNotFound )
+        {
+        AddPackageStateL( aState, aPkgURL);
+        }
+    else
+        {
+        // sml try count must be reset, if state is set
+        if (aChangedFields & EFDBState )
+            {
+            aChangedFields = aChangedFields | EFDBSmlTryCount;
+            SetRetryCount(aState);
+            }
+
+        // Construct a SQL string for update. 
+        // Example: UPDATE State SET Result=40,State=4 WHERE pkgID=5
+        // 
+        TInt        sqlsize = 0;
+        _LIT8( KSqlbegin, "UPDATE State SET " );
+        TBuf<21>    sqlEnd;
+        HBufC8*     sql( NULL );
+        // determine characters needed 
+        sqlsize = DetermineCharNeeded(aChangedFields,aState,aPkgURL);
+        sqlEnd.AppendFormat( _L(" WHERE pkgID=%d"),aState.iPkgId );
+        
+        sql = HBufC8::NewLC( ((TDesC8)KSqlbegin).Length() + sqlsize 
+                                        + sqlEnd.Length() );
+
+        sql->Des().Append ( KSqlbegin );
+
+        if (aChangedFields & EFDBResult )   
+            {
+            // check FUMO compability
+ 			__ASSERT_ALWAYS( aState.iResult>=KErrNotFound 
+ 			&& aState.iResult<=600, User::Panic(KFotaPanic, KErrArgument) );
+            sql->Des().AppendFormat(_L8("Result=%d,"),aState.iResult);
+            }
+        if (aChangedFields & EFDBState )    
+            {
+            // check FUMO compability
+ 			__ASSERT_ALWAYS( aState.iState>=0 && aState.iState<=100
+ 				, User::Panic(KFotaPanic, KErrArgument) );
+            sql->Des().AppendFormat(_L8("State=%d,"),aState.iState);
+            }
+        if (aChangedFields & EFDBProfileId) 
+            {
+            sql->Des().AppendFormat(_L8("profileid=%d,"),aState.iProfileId);
+            }
+        if (aChangedFields & EFDBPkgUrl )   
+            {
+            sql->Des().AppendFormat(_L8("pkgurl='%S',"), &aPkgURL );
+            }
+        if (aChangedFields & EFDBPkgName )  
+            {
+            sql->Des().AppendFormat(_L8("pkgname='%S',") 
+                ,&(aState.iPkgName)) ;
+            }
+        if (aChangedFields & EFDBVersion )  
+            {
+            sql->Des().AppendFormat(_L8("Version='%S',")
+                    ,&(aState.iPkgVersion));
+            }
+        if ( aChangedFields & EFDBSmlTryCount )
+            {
+ 			__ASSERT_ALWAYS( aState.iSmlTryCount>=0
+ 				, User::Panic(KFotaPanic, KErrArgument) );            
+            sql->Des().AppendFormat(_L8("SmlTryCount=%d,")
+                , aState.iSmlTryCount );
+                    
+            }
+        if (aChangedFields & EFDBSessionType )    
+            {
+            sql->Des().AppendFormat(_L8("SessionType=%d,"),aState.iSessionType);
+            }
+        if (aChangedFields & EFDBIapId )    
+            {
+            // validate IAP ID
+ 			__ASSERT_ALWAYS( aState.iIapId>=-1 ,User::Panic(KFotaPanic, KErrArgument) );
+            sql->Des().AppendFormat(_L8("IapId=%d,"),aState.iIapId);
+            }
+        if (aChangedFields & EFDBPkgSize )    
+            {
+            // validate size
+ //			__ASSERT_ALWAYS( aState.iPkgSize>=0 ,User::Panic(KFotaPanic, KErrArgument) ); // to remove compiler warning
+            sql->Des().AppendFormat(_L8("PkgSize=%d,"),aState.iPkgSize);
+            }
+        if (aChangedFields & EFDBUpdateLtr )    
+            {
+            // validate bit
+            sql->Des().AppendFormat(_L8("UpdateLtr=%d,"),aState.iUpdateLtr);
+            }
+        // remove trailing ,
+        if ( aChangedFields )
+            {
+            sql->Des().SetLength ( sql->Des().Length()-1 );
+            }
+        sql->Des().Append ( sqlEnd );
+        HBufC*  sql2 = HBufC::NewLC( sql->Length() ); // to cleanupstack
+        sql2->Des().Copy(sql->Des());
+		FLOG(_L("  sql:%S"),sql2);
+        
+        User::LeaveIfError( iStateDB.Begin() );
+        User::LeaveIfError( iStateDB.Execute(*sql2) );
+        User::LeaveIfError( iStateDB.Commit() );
+        User::LeaveIfError( iStateDB.Compact() );
+
+        CleanupStack::PopAndDestroy( sql2 );  //sql2
+        CleanupStack::PopAndDestroy( sql );  //sql
+        }
+    FLOG(_L("  CFotaDB::SetStateL  <<"));
+    }
+
+// ---------------------------------------------------------------------------
+// CFotaDB::DetermineCharNeeded 
+// Returns the char needed fro the query 
+// ---------------------------------------------------------------------------
+
+TInt CFotaDB::DetermineCharNeeded(TInt aChangedFields,TPackageState& aState,const TDesC8& aPkgURL)
+
+{	 
+	
+	      TInt sqlsize=0;
+	      if (aChangedFields & EFDBResult )       sqlsize += 4 + 7 + 4; 
+        if (aChangedFields & EFDBState )        sqlsize += 4 + 5 + 4;
+        if (aChangedFields & EFDBProfileId )    sqlsize += 4 + 9 + 4;
+        if (aChangedFields & EFDBPkgUrl )       sqlsize += aPkgURL.Length() 
+                                                           + 6 + 4;
+        if (aChangedFields & EFDBPkgName )      sqlsize += 
+                                                   aState.iPkgName.Length() 
+                                                   + 7 + 4;
+        if (aChangedFields & EFDBVersion )      sqlsize += 
+                                                   aState.iPkgVersion.Length() 
+                                                   + 7 + 4;
+        if (aChangedFields & EFDBSmlTryCount )  sqlsize += 4 + 11 + 4;
+        
+        if (aChangedFields & EFDBSessionType )    sqlsize += 4 + 11 + 4;
+        if (aChangedFields & EFDBIapId )    sqlsize += 4 + 5 + 4;
+        if (aChangedFields & EFDBPkgSize )    sqlsize += 4 + 7 + 10;
+        if (aChangedFields & EFDBUpdateLtr ) sqlsize += 4 + 11 + 4;
+        
+        return sqlsize;
+	
+}
+
+// ---------------------------------------------------------------------------
+// CFotaDB::SetRetryCount
+// Sets the retry count
+// ---------------------------------------------------------------------------
+void CFotaDB::SetRetryCount(TPackageState& aState)
+{
+   CRepository* centrep( NULL);
+   TInt err = KErrNone;
+   TInt retry = 0;
+  
+   TRAP(err, centrep = CRepository::NewL( KCRUidFotaServer ) );
+   if ( centrep ) 
+     	   {
+        	err = centrep->Get( KGenericAlertRetries, retry );
+        	delete centrep; centrep = NULL;
+        	}
+        	if(err == KErrNone )
+        	    {
+            	    if(retry < 0 )
+            	    {
+            	    aState.iSmlTryCount = KDefaultSmlTryCount;
+            	    }
+                  	else if( retry == 0 )
+               	    {
+               	     aState.iSmlTryCount = 2 ;
+               	    }
+                	else if (retry > KMaximumSmlTryCount )
+               	    {
+               	     aState.iSmlTryCount = KMaximumSmlTryCount + 1;
+               	    }
+                   	else
+                    {
+                	  aState.iSmlTryCount = retry + 1;
+                    }
+        	    }
+        	 else
+        	    {
+        	    aState.iSmlTryCount = KDefaultSmlTryCount;
+        	    }
+}        	    
+        	    
+
+// ---------------------------------------------------------------------------
+// CFotaDB::DeleteStateL
+// Delete state
+// ---------------------------------------------------------------------------
+TInt CFotaDB::DeleteStateL(const TInt aPkgId)
+    {
+	FLOG(_L("[fota DB Delete]\tdeleting %d"),aPkgId);
+	TInt err( KErrNone );
+
+    if ( iStateDB.InTransaction() )
+    	{
+	    return ( KErrAccessDenied );
+	    }
+
+	_LIT( KSQLDeleteState,"DELETE FROM State WHERE PkgId = %d" );
+
+    HBufC*  del  = HBufC::NewLC( KSQLDeleteState().Length() + 10);
+    del->Des().Format (KSQLDeleteState, aPkgId);
+
+	iStateDB.Begin();
+
+	err = iStateDB.Execute( *del );
+	CleanupStack::PopAndDestroy( del );
+	if ( err < KErrNone )
+		{
+		iStateDB.Rollback();
+		return err;
+		}
+    FLOG(_L("[fota DB Delete]\tdeleted %d"),aPkgId);
+	return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// CFotaDB::RowToStateL
+// Extracts db row contents to package state object and aPkgUrl
+// Returns url in aPkgURL parameter
+// ---------------------------------------------------------------------------
+TPackageState CFotaDB::RowToStateL(HBufC8*& aPkgUrl,const RDbView& aView)
+    {
+    TPackageState   s;
+    TInt            pkgid   = aView.ColInt( iColSet->ColNo(KColPkgId)  );
+	TInt            state   = aView.ColInt( iColSet->ColNo(KColState)  );
+	TInt            result  = aView.ColInt( iColSet->ColNo(KColResult)  );
+    TSmlProfileId   profileid(aView.ColInt( iColSet->ColNo(KColProfileId)));
+    TPtrC           pkgname = aView.ColDes( iColSet->ColNo(KColPkgName)  );
+    TPtrC           version = aView.ColDes( iColSet->ColNo(KColVersion)  );
+    TInt            smltrycount 
+                        = aView.ColInt( iColSet->ColNo(KColSmlTryCount) );
+    TInt            sessiontype = aView.ColInt( iColSet->ColNo(KColSessionType)  );
+    TInt            iapid = aView.ColInt( iColSet->ColNo(KColIapId)  );
+    TUint           pkgsize = aView.ColUint( iColSet->ColNo(KColPkgSize)  );
+    TBool			updateltr = aView.ColUint8( iColSet->ColNo(KColUpdateLtr));
+    
+    s.iPkgId            = pkgid;
+    s.iPkgName.Copy     (pkgname);
+    s.iPkgVersion.Copy  (version);
+    s.iProfileId        = profileid;
+    s.iResult           = result;
+    s.iState            = RFotaEngineSession::TState (state);
+    s.iSmlTryCount      = smltrycount;
+    s.iSessionType 		= sessiontype;
+    s.iIapId 			= iapid;
+    s.iPkgSize 			= pkgsize;
+    s.iUpdateLtr		= updateltr;
+
+    RDbColReadStream    rstream;
+    TInt                len = aView.ColLength(iColSet->ColNo(KColPkgUrl));
+    rstream.OpenLC(aView,iColSet->ColNo(KColPkgUrl) );
+    HBufC*             pkgurl         = HBufC::NewLC( len );
+    TPtr               ptr            = pkgurl->Des();
+    rstream.ReadL( ptr, len );
+
+    HBufC8*             tmp = HBufC8::NewL( pkgurl->Des().Length() );
+    tmp->Des().Copy ( pkgurl->Des() );
+    aPkgUrl = tmp;
+
+    CleanupStack::PopAndDestroy( pkgurl ); 
+    CleanupStack::PopAndDestroy( &rstream );
+    return s;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::StateToRowL
+// Converts state object to database row (into view object)
+// ---------------------------------------------------------------------------
+void CFotaDB::StateToRowL (const TPackageState& aPkg, const TDesC8& aPkgURL
+                                ,RDbView& aView)
+    {
+    HBufC*  pkgname = HBufC::NewLC(aPkg.iPkgName.Length());
+    HBufC*  version = HBufC::NewLC(aPkg.iPkgVersion.Length());
+
+    pkgname->Des().Copy(aPkg.iPkgName);
+    version->Des().Copy(aPkg.iPkgVersion);
+
+    aView.SetColL( iColSet->ColNo( KColPkgId ),      aPkg.iPkgId);
+	aView.SetColL( iColSet->ColNo( KColResult ),     aPkg.iResult);
+	aView.SetColL( iColSet->ColNo( KColState ),      aPkg.iState);
+	aView.SetColL( iColSet->ColNo( KColProfileId ),  aPkg.iProfileId);
+	aView.SetColL( iColSet->ColNo( KColPkgName ),    *pkgname );
+	aView.SetColL( iColSet->ColNo( KColVersion ),    *version );
+	aView.SetColL( iColSet->ColNo( KColSmlTryCount ), aPkg.iSmlTryCount );
+	aView.SetColL( iColSet->ColNo( KColSessionType ), aPkg.iSessionType );
+	aView.SetColL( iColSet->ColNo( KColIapId ), 	  aPkg.iIapId  );
+	aView.SetColL( iColSet->ColNo( KColPkgSize ), 	  aPkg.iPkgSize );
+	aView.SetColL( iColSet->ColNo( KColUpdateLtr ),	  aPkg.iUpdateLtr );
+
+    RDbColWriteStream wstream;
+    CleanupClosePushL( wstream );
+    wstream.OpenL( aView,iColSet->ColNo(KColPkgUrl) );
+    // Cannot write 8 bit descriptors to databae
+    HBufC* buf = HBufC::NewLC( aPkgURL.Length() );
+    buf->Des().Copy( aPkgURL );
+    wstream.WriteL( buf->Des() );
+
+    FLOG(_L("CFotaDB::StateToRowL  id:%d result:%d state:%d profileid:%d \
+    		name:%d chars version: %d chars url: %d chars sessiontype:%d iapid:%d pkgsize:%d updateltr = %d")
+    		,aPkg.iPkgId, aPkg.iResult, aPkg.iState, aPkg.iProfileId
+    		, pkgname->Des().Length(), version->Des().Length()
+    		, buf->Des().Length(),aPkg.iSessionType,aPkg.iIapId,aPkg.iPkgSize, aPkg.iUpdateLtr);
+
+    CleanupStack::PopAndDestroy( buf );
+    CleanupStack::PopAndDestroy( &wstream );
+    CleanupStack::PopAndDestroy( version );
+    CleanupStack::PopAndDestroy( pkgname );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CFotaDB::AlterTableIfRequiredL()
+// Adds the new attributes when fota state table is old.
+// ---------------------------------------------------------------------------
+void CFotaDB::AlterTableIfRequiredL()
+	{
+    FLOG(_L("CFotaDB::AlterTableIfRequired >>"));
+	TInt noofcol = iTable.ColCount();
+	//noofcol = 9 means old database; alteration is needed
+	if (noofcol!=KNoOfDBFields)
+		{
+		FLOG(_L("FotaState table is incompatible; needs alteration!"));
+	    User::LeaveIfError(iStateDB.Begin());
+
+
+	    TInt err (KErrNone);
+	    err = iStateDB.Execute(KAlterTable);
+	    if (!err)
+	    	{
+	    	err = iStateDB.Commit();
+		    if(err) 
+		        {
+		        FLOG(_L(" FotaState table alteration err2 %d, deleting it and recreating it again"),err);
+		    	CloseAndCommitDB();
+		        User::LeaveIfError (iFSSession.Delete(KDatabaseName));
+		        }
+	    	}
+	    else
+	    	{
+	    	FLOG(_L(" FotaState table alteration err1 %d, deleting it and recreating it again"),err);
+	    	CloseAndCommitDB();
+	    	User::LeaveIfError (iFSSession.Delete(KDatabaseName));
+	    	}
+	    if (!err)
+	    	{
+	    	User::LeaveIfError( iStateDB.Compact() );
+	    	CloseAndCommitDB();
+		    FLOG(_L("FotaState table altered successfully, reopening it again."));
+			iTableAltercheck = EFalse;
+	    	}
+	    OpenDBL();
+		}
+	else
+		iTableAltercheck = EFalse;
+
+    FLOG(_L("CFotaDB::AlterTableIfRequired <<"));
+	}