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 + }