diff -r c8e5c3d81b42 -r 39aa16f3fdc2 fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp --- a/fotaapplication/fotaserver/FotaServer/src/FotaDB.cpp Wed Jun 23 19:10:17 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,640 +0,0 @@ -/* -* 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 -#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 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& 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 <<")); - }