os/persistentdata/persistentstorage/dbms/ustor/US_RCOVR.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/dbms/ustor/US_RCOVR.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,154 @@
     1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "US_STD.H"
    1.20 +
    1.21 +// Class CDbStoreIndex::CRecover
    1.22 +
    1.23 +NONSHARABLE_CLASS(CDbStoreIndex::CRecover) : public CDbTableDatabase::CStepper
    1.24 +	{
    1.25 +private:
    1.26 +	enum {EClearStep=1};
    1.27 +public:
    1.28 +	CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    1.29 +	~CRecover();
    1.30 +	static inline TInt Steps(TInt aCardinality);
    1.31 +private:
    1.32 +	TInt StepL(TInt aStep);
    1.33 +private:
    1.34 +	CDbStoreDatabase& iDatabase;
    1.35 +	const CDbStoreDef& iTable;
    1.36 +	const CDbStoreIndexDef& iIndex;
    1.37 +	CDbTableDatabase::CBuildIndex* iBuild;
    1.38 +	};
    1.39 +
    1.40 +inline TInt CDbStoreIndex::CRecover::Steps(TInt aCardinality)
    1.41 +	{return CDbTableDatabase::CBuildIndex::Steps(aCardinality)+EClearStep;}
    1.42 +
    1.43 +CDbStoreIndex::CRecover::CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    1.44 +	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    1.45 +	{}
    1.46 +
    1.47 +CDbStoreIndex::CRecover::~CRecover()
    1.48 +	{
    1.49 +	delete iBuild;
    1.50 +	}
    1.51 +
    1.52 +TInt CDbStoreIndex::CRecover::StepL(TInt aStep)
    1.53 +	{
    1.54 +	if (iBuild==NULL)
    1.55 +		{	// first step
    1.56 +		iBuild=CDbTableDatabase::CBuildIndex::NewL(iDatabase,iTable,iIndex);
    1.57 +		((CDbStoreIndex&)iBuild->Index()).DiscardL();
    1.58 +		return aStep-EClearStep;
    1.59 +		}
    1.60 +	aStep=iBuild->StepL(aStep);
    1.61 +	if (aStep==0)
    1.62 +		{	// final step
    1.63 +		iDatabase.IndexRecoveredL();
    1.64 +		delete iBuild;
    1.65 +		iBuild=NULL;
    1.66 +		}
    1.67 +	return aStep;
    1.68 +	}
    1.69 +
    1.70 +// Class CDbStoreIndex::CRepair
    1.71 +
    1.72 +NONSHARABLE_CLASS(CDbStoreIndex::CRepair) : public CDbTableDatabase::CStepper
    1.73 +	{
    1.74 +private:
    1.75 +	enum {ERepairStep=1};
    1.76 +public:
    1.77 +	CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    1.78 +	static inline TInt Steps();
    1.79 +private:
    1.80 +	TInt StepL(TInt aStep);
    1.81 +private:
    1.82 +	CDbStoreDatabase& iDatabase;
    1.83 +	const CDbStoreDef& iTable;
    1.84 +	const CDbStoreIndexDef& iIndex;
    1.85 +	};
    1.86 +
    1.87 +inline TInt CDbStoreIndex::CRepair::Steps()
    1.88 +	{return ERepairStep;}
    1.89 +
    1.90 +CDbStoreIndex::CRepair::CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    1.91 +	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    1.92 +	{}
    1.93 +
    1.94 +TInt CDbStoreIndex::CRepair::StepL(TInt)
    1.95 +	{
    1.96 +	CDbStoreIndex* index=CDbStoreIndex::NewL(iDatabase,iIndex,iTable);
    1.97 +	CleanupStack::PushL(index);
    1.98 +	index->OpenL();
    1.99 +	index->RepairL();
   1.100 +	CleanupStack::PopAndDestroy();
   1.101 +	return 0;
   1.102 +	}
   1.103 +
   1.104 +// Class CDbStoreDatabase
   1.105 +
   1.106 +CDbTableDatabase::CStepper* CDbStoreDatabase::RecoverL(TInt& aStep)
   1.107 +	{
   1.108 +	TSglQueIterC<CDbStoreDef> iter(SchemaL());	// ensure we have the schema
   1.109 +	TInt count=0;
   1.110 +	const CDbStoreDef* tDef;
   1.111 +	while ((tDef=iter++)!=NULL)
   1.112 +		count+=tDef->Indexes().Count();
   1.113 +	CMultiStepper* mStepper=CMultiStepper::NewL(count);
   1.114 +	CleanupStack::PushL(mStepper);
   1.115 +// damaged ones first (as they are invoked last
   1.116 +	count=0;
   1.117 +	iter.SetToFirst();
   1.118 +	while ((tDef=iter++)!=NULL)
   1.119 +		{
   1.120 +		TInt records=CDbStoreRecords::CardinalityL(Store(),*tDef);
   1.121 +		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   1.122 +		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   1.123 +			{
   1.124 +			if (!CDbStoreIndex::IsDamagedL(*this,*xDef))
   1.125 +				continue;
   1.126 +			// rebuild from scratch
   1.127 +			CDbStoreIndex::CRecover* rebuild=new(ELeave) CDbStoreIndex::CRecover(*this,*tDef,*xDef);
   1.128 +			mStepper->AddStepper(rebuild,rebuild->Steps(records));
   1.129 +			++count;
   1.130 +			}
   1.131 +		}
   1.132 +	if (count==0)
   1.133 +		{	// no indexes are actually damaged
   1.134 +		aStep=0;
   1.135 +		CleanupStack::PopAndDestroy();
   1.136 +		return NULL;
   1.137 +		}
   1.138 +	// repair the other ones after a reclaim
   1.139 +	iter.SetToFirst();
   1.140 +	while ((tDef=iter++)!=NULL)
   1.141 +		{
   1.142 +		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   1.143 +		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   1.144 +			{
   1.145 +			if (CDbStoreIndex::IsDamagedL(*this,*xDef))
   1.146 +				continue;
   1.147 +			// repair from sequence set
   1.148 +			CDbStoreIndex::CRepair* repair=new(ELeave) CDbStoreIndex::CRepair(*this,*tDef,*xDef);
   1.149 +			mStepper->AddStepper(repair,repair->Steps());
   1.150 +			}
   1.151 +		}
   1.152 +	iPagePool->Discard();
   1.153 +	iPagePool->ReclaimAllL();	// recover all page pool space
   1.154 +	aStep=mStepper->TotalSteps();
   1.155 +	CleanupStack::Pop();
   1.156 +	return mStepper;
   1.157 +	}