--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -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 <<"));
+ }