// 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;
}