os/persistentdata/persistentstorage/dbms/pcdbms/ustor/US_RCOVR.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "US_STD.H"
    17 #include "U32STD_DBMS.H"
    18 
    19 // Class CDbStoreIndex::CRecover
    20 
    21 NONSHARABLE_CLASS(CDbStoreIndex::CRecover) : public CDbTableDatabase::CStepper
    22 	{
    23 private:
    24 	enum {EClearStep=1};
    25 public:
    26 	CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    27 	~CRecover();
    28 	static inline TInt Steps(TInt aCardinality);
    29 private:
    30 	TInt StepL(TInt aStep);
    31 private:
    32 	CDbStoreDatabase& iDatabase;
    33 	const CDbStoreDef& iTable;
    34 	const CDbStoreIndexDef& iIndex;
    35 	CDbTableDatabase::CBuildIndex* iBuild;
    36 	};
    37 
    38 inline TInt CDbStoreIndex::CRecover::Steps(TInt aCardinality)
    39 	{return CDbTableDatabase::CBuildIndex::Steps(aCardinality)+EClearStep;}
    40 
    41 CDbStoreIndex::CRecover::CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    42 	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    43 	{}
    44 
    45 CDbStoreIndex::CRecover::~CRecover()
    46 	{
    47 	delete iBuild;
    48 	}
    49 
    50 TInt CDbStoreIndex::CRecover::StepL(TInt aStep)
    51 	{
    52 	if (iBuild==NULL)
    53 		{	// first step
    54 		iBuild=CDbTableDatabase::CBuildIndex::NewL(iDatabase,iTable,iIndex);
    55 		((CDbStoreIndex&)iBuild->Index()).DiscardL();
    56 		return aStep-EClearStep;
    57 		}
    58 	aStep=iBuild->StepL(aStep);
    59 	if (aStep==0)
    60 		{	// final step
    61 		iDatabase.IndexRecoveredL();
    62 		delete iBuild;
    63 		iBuild=NULL;
    64 		}
    65 	return aStep;
    66 	}
    67 
    68 // Class CDbStoreIndex::CRepair
    69 
    70 NONSHARABLE_CLASS(CDbStoreIndex::CRepair) : public CDbTableDatabase::CStepper
    71 	{
    72 private:
    73 	enum {ERepairStep=1};
    74 public:
    75 	CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    76 	static inline TInt Steps();
    77 private:
    78 	TInt StepL(TInt aStep);
    79 private:
    80 	CDbStoreDatabase& iDatabase;
    81 	const CDbStoreDef& iTable;
    82 	const CDbStoreIndexDef& iIndex;
    83 	};
    84 
    85 inline TInt CDbStoreIndex::CRepair::Steps()
    86 	{return ERepairStep;}
    87 
    88 CDbStoreIndex::CRepair::CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    89 	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    90 	{}
    91 
    92 TInt CDbStoreIndex::CRepair::StepL(TInt)
    93 	{
    94 	CDbStoreIndex* index=CDbStoreIndex::NewL(iDatabase,iIndex,iTable);
    95 	CleanupStack::PushL(index);
    96 	index->OpenL();
    97 	index->RepairL();
    98 	CleanupStack::PopAndDestroy();
    99 	return 0;
   100 	}
   101 
   102 // Class CDbStoreDatabase
   103 
   104 CDbTableDatabase::CStepper* CDbStoreDatabase::RecoverL(TInt& aStep)
   105 	{
   106 	TSglQueIterC<CDbStoreDef> iter(SchemaL());	// ensure we have the schema
   107 	TInt count=0;
   108 	const CDbStoreDef* tDef;
   109 	while ((tDef=iter++)!=NULL)
   110 		count+=tDef->Indexes().Count();
   111 	CMultiStepper* mStepper=CMultiStepper::NewL(count);
   112 	CleanupStack::PushL(mStepper);
   113 // damaged ones first (as they are invoked last
   114 	count=0;
   115 	iter.SetToFirst();
   116 	while ((tDef=iter++)!=NULL)
   117 		{
   118 		TInt records=CDbStoreRecords::CardinalityL(Store(),*tDef);
   119 		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   120 		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   121 			{
   122 			if (!CDbStoreIndex::IsDamagedL(*this,*xDef))
   123 				continue;
   124 			// rebuild from scratch
   125 			CDbStoreIndex::CRecover* rebuild=new(ELeave) CDbStoreIndex::CRecover(*this,*tDef,*xDef);
   126 			mStepper->AddStepper(rebuild,rebuild->Steps(records));
   127 			++count;
   128 			}
   129 		}
   130 	if (count==0)
   131 		{	// no indexes are actually damaged
   132 		aStep=0;
   133 		CleanupStack::PopAndDestroy();
   134 		return NULL;
   135 		}
   136 	// repair the other ones after a reclaim
   137 	iter.SetToFirst();
   138 	while ((tDef=iter++)!=NULL)
   139 		{
   140 		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   141 		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   142 			{
   143 			if (CDbStoreIndex::IsDamagedL(*this,*xDef))
   144 				continue;
   145 			// repair from sequence set
   146 			CDbStoreIndex::CRepair* repair=new(ELeave) CDbStoreIndex::CRepair(*this,*tDef,*xDef);
   147 			mStepper->AddStepper(repair,repair->Steps());
   148 			}
   149 		}
   150 	iPagePool->Discard();
   151 	iPagePool->ReclaimAllL();	// recover all page pool space
   152 	aStep=mStepper->TotalSteps();
   153 	CleanupStack::Pop();
   154 	return mStepper;
   155 	}