1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/pcdbms/ustor/US_RCOVR.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,155 @@
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 +#include "U32STD_DBMS.H"
1.21 +
1.22 +// Class CDbStoreIndex::CRecover
1.23 +
1.24 +NONSHARABLE_CLASS(CDbStoreIndex::CRecover) : public CDbTableDatabase::CStepper
1.25 + {
1.26 +private:
1.27 + enum {EClearStep=1};
1.28 +public:
1.29 + CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
1.30 + ~CRecover();
1.31 + static inline TInt Steps(TInt aCardinality);
1.32 +private:
1.33 + TInt StepL(TInt aStep);
1.34 +private:
1.35 + CDbStoreDatabase& iDatabase;
1.36 + const CDbStoreDef& iTable;
1.37 + const CDbStoreIndexDef& iIndex;
1.38 + CDbTableDatabase::CBuildIndex* iBuild;
1.39 + };
1.40 +
1.41 +inline TInt CDbStoreIndex::CRecover::Steps(TInt aCardinality)
1.42 + {return CDbTableDatabase::CBuildIndex::Steps(aCardinality)+EClearStep;}
1.43 +
1.44 +CDbStoreIndex::CRecover::CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
1.45 + : iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
1.46 + {}
1.47 +
1.48 +CDbStoreIndex::CRecover::~CRecover()
1.49 + {
1.50 + delete iBuild;
1.51 + }
1.52 +
1.53 +TInt CDbStoreIndex::CRecover::StepL(TInt aStep)
1.54 + {
1.55 + if (iBuild==NULL)
1.56 + { // first step
1.57 + iBuild=CDbTableDatabase::CBuildIndex::NewL(iDatabase,iTable,iIndex);
1.58 + ((CDbStoreIndex&)iBuild->Index()).DiscardL();
1.59 + return aStep-EClearStep;
1.60 + }
1.61 + aStep=iBuild->StepL(aStep);
1.62 + if (aStep==0)
1.63 + { // final step
1.64 + iDatabase.IndexRecoveredL();
1.65 + delete iBuild;
1.66 + iBuild=NULL;
1.67 + }
1.68 + return aStep;
1.69 + }
1.70 +
1.71 +// Class CDbStoreIndex::CRepair
1.72 +
1.73 +NONSHARABLE_CLASS(CDbStoreIndex::CRepair) : public CDbTableDatabase::CStepper
1.74 + {
1.75 +private:
1.76 + enum {ERepairStep=1};
1.77 +public:
1.78 + CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
1.79 + static inline TInt Steps();
1.80 +private:
1.81 + TInt StepL(TInt aStep);
1.82 +private:
1.83 + CDbStoreDatabase& iDatabase;
1.84 + const CDbStoreDef& iTable;
1.85 + const CDbStoreIndexDef& iIndex;
1.86 + };
1.87 +
1.88 +inline TInt CDbStoreIndex::CRepair::Steps()
1.89 + {return ERepairStep;}
1.90 +
1.91 +CDbStoreIndex::CRepair::CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
1.92 + : iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
1.93 + {}
1.94 +
1.95 +TInt CDbStoreIndex::CRepair::StepL(TInt)
1.96 + {
1.97 + CDbStoreIndex* index=CDbStoreIndex::NewL(iDatabase,iIndex,iTable);
1.98 + CleanupStack::PushL(index);
1.99 + index->OpenL();
1.100 + index->RepairL();
1.101 + CleanupStack::PopAndDestroy();
1.102 + return 0;
1.103 + }
1.104 +
1.105 +// Class CDbStoreDatabase
1.106 +
1.107 +CDbTableDatabase::CStepper* CDbStoreDatabase::RecoverL(TInt& aStep)
1.108 + {
1.109 + TSglQueIterC<CDbStoreDef> iter(SchemaL()); // ensure we have the schema
1.110 + TInt count=0;
1.111 + const CDbStoreDef* tDef;
1.112 + while ((tDef=iter++)!=NULL)
1.113 + count+=tDef->Indexes().Count();
1.114 + CMultiStepper* mStepper=CMultiStepper::NewL(count);
1.115 + CleanupStack::PushL(mStepper);
1.116 +// damaged ones first (as they are invoked last
1.117 + count=0;
1.118 + iter.SetToFirst();
1.119 + while ((tDef=iter++)!=NULL)
1.120 + {
1.121 + TInt records=CDbStoreRecords::CardinalityL(Store(),*tDef);
1.122 + TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
1.123 + for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
1.124 + {
1.125 + if (!CDbStoreIndex::IsDamagedL(*this,*xDef))
1.126 + continue;
1.127 + // rebuild from scratch
1.128 + CDbStoreIndex::CRecover* rebuild=new(ELeave) CDbStoreIndex::CRecover(*this,*tDef,*xDef);
1.129 + mStepper->AddStepper(rebuild,rebuild->Steps(records));
1.130 + ++count;
1.131 + }
1.132 + }
1.133 + if (count==0)
1.134 + { // no indexes are actually damaged
1.135 + aStep=0;
1.136 + CleanupStack::PopAndDestroy();
1.137 + return NULL;
1.138 + }
1.139 + // repair the other ones after a reclaim
1.140 + iter.SetToFirst();
1.141 + while ((tDef=iter++)!=NULL)
1.142 + {
1.143 + TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
1.144 + for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
1.145 + {
1.146 + if (CDbStoreIndex::IsDamagedL(*this,*xDef))
1.147 + continue;
1.148 + // repair from sequence set
1.149 + CDbStoreIndex::CRepair* repair=new(ELeave) CDbStoreIndex::CRepair(*this,*tDef,*xDef);
1.150 + mStepper->AddStepper(repair,repair->Steps());
1.151 + }
1.152 + }
1.153 + iPagePool->Discard();
1.154 + iPagePool->ReclaimAllL(); // recover all page pool space
1.155 + aStep=mStepper->TotalSteps();
1.156 + CleanupStack::Pop();
1.157 + return mStepper;
1.158 + }