fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 03 May 2010 13:19:46 +0300
changeset 24 bf47f3b79154
parent 0 b497e44ab2fc
permissions -rw-r--r--
Revision: 201015 Kit: 201018

/*
* 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 <<"));
	}