diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/ustor/US_RCOVR.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/ustor/US_RCOVR.CPP Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,154 @@ +// Copyright (c) 1998-2009 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: +// + +#include "US_STD.H" + +// Class CDbStoreIndex::CRecover + +NONSHARABLE_CLASS(CDbStoreIndex::CRecover) : public CDbTableDatabase::CStepper + { +private: + enum {EClearStep=1}; +public: + CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex); + ~CRecover(); + static inline TInt Steps(TInt aCardinality); +private: + TInt StepL(TInt aStep); +private: + CDbStoreDatabase& iDatabase; + const CDbStoreDef& iTable; + const CDbStoreIndexDef& iIndex; + CDbTableDatabase::CBuildIndex* iBuild; + }; + +inline TInt CDbStoreIndex::CRecover::Steps(TInt aCardinality) + {return CDbTableDatabase::CBuildIndex::Steps(aCardinality)+EClearStep;} + +CDbStoreIndex::CRecover::CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex) + : iDatabase(aDatabase),iTable(aTable),iIndex(anIndex) + {} + +CDbStoreIndex::CRecover::~CRecover() + { + delete iBuild; + } + +TInt CDbStoreIndex::CRecover::StepL(TInt aStep) + { + if (iBuild==NULL) + { // first step + iBuild=CDbTableDatabase::CBuildIndex::NewL(iDatabase,iTable,iIndex); + ((CDbStoreIndex&)iBuild->Index()).DiscardL(); + return aStep-EClearStep; + } + aStep=iBuild->StepL(aStep); + if (aStep==0) + { // final step + iDatabase.IndexRecoveredL(); + delete iBuild; + iBuild=NULL; + } + return aStep; + } + +// Class CDbStoreIndex::CRepair + +NONSHARABLE_CLASS(CDbStoreIndex::CRepair) : public CDbTableDatabase::CStepper + { +private: + enum {ERepairStep=1}; +public: + CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex); + static inline TInt Steps(); +private: + TInt StepL(TInt aStep); +private: + CDbStoreDatabase& iDatabase; + const CDbStoreDef& iTable; + const CDbStoreIndexDef& iIndex; + }; + +inline TInt CDbStoreIndex::CRepair::Steps() + {return ERepairStep;} + +CDbStoreIndex::CRepair::CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex) + : iDatabase(aDatabase),iTable(aTable),iIndex(anIndex) + {} + +TInt CDbStoreIndex::CRepair::StepL(TInt) + { + CDbStoreIndex* index=CDbStoreIndex::NewL(iDatabase,iIndex,iTable); + CleanupStack::PushL(index); + index->OpenL(); + index->RepairL(); + CleanupStack::PopAndDestroy(); + return 0; + } + +// Class CDbStoreDatabase + +CDbTableDatabase::CStepper* CDbStoreDatabase::RecoverL(TInt& aStep) + { + TSglQueIterC iter(SchemaL()); // ensure we have the schema + TInt count=0; + const CDbStoreDef* tDef; + while ((tDef=iter++)!=NULL) + count+=tDef->Indexes().Count(); + CMultiStepper* mStepper=CMultiStepper::NewL(count); + CleanupStack::PushL(mStepper); +// damaged ones first (as they are invoked last + count=0; + iter.SetToFirst(); + while ((tDef=iter++)!=NULL) + { + TInt records=CDbStoreRecords::CardinalityL(Store(),*tDef); + TSglQueIterC xIter(tDef->Indexes().AsQue()); + for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;) + { + if (!CDbStoreIndex::IsDamagedL(*this,*xDef)) + continue; + // rebuild from scratch + CDbStoreIndex::CRecover* rebuild=new(ELeave) CDbStoreIndex::CRecover(*this,*tDef,*xDef); + mStepper->AddStepper(rebuild,rebuild->Steps(records)); + ++count; + } + } + if (count==0) + { // no indexes are actually damaged + aStep=0; + CleanupStack::PopAndDestroy(); + return NULL; + } + // repair the other ones after a reclaim + iter.SetToFirst(); + while ((tDef=iter++)!=NULL) + { + TSglQueIterC xIter(tDef->Indexes().AsQue()); + for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;) + { + if (CDbStoreIndex::IsDamagedL(*this,*xDef)) + continue; + // repair from sequence set + CDbStoreIndex::CRepair* repair=new(ELeave) CDbStoreIndex::CRepair(*this,*tDef,*xDef); + mStepper->AddStepper(repair,repair->Steps()); + } + } + iPagePool->Discard(); + iPagePool->ReclaimAllL(); // recover all page pool space + aStep=mStepper->TotalSteps(); + CleanupStack::Pop(); + return mStepper; + }