--- /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<CDbStoreDef> 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<CDbStoreIndexDef> 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<CDbStoreIndexDef> 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;
+ }