os/persistentdata/persistentstorage/dbms/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 
    18 // Class CDbStoreIndex::CRecover
    19 
    20 NONSHARABLE_CLASS(CDbStoreIndex::CRecover) : public CDbTableDatabase::CStepper
    21 	{
    22 private:
    23 	enum {EClearStep=1};
    24 public:
    25 	CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    26 	~CRecover();
    27 	static inline TInt Steps(TInt aCardinality);
    28 private:
    29 	TInt StepL(TInt aStep);
    30 private:
    31 	CDbStoreDatabase& iDatabase;
    32 	const CDbStoreDef& iTable;
    33 	const CDbStoreIndexDef& iIndex;
    34 	CDbTableDatabase::CBuildIndex* iBuild;
    35 	};
    36 
    37 inline TInt CDbStoreIndex::CRecover::Steps(TInt aCardinality)
    38 	{return CDbTableDatabase::CBuildIndex::Steps(aCardinality)+EClearStep;}
    39 
    40 CDbStoreIndex::CRecover::CRecover(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    41 	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    42 	{}
    43 
    44 CDbStoreIndex::CRecover::~CRecover()
    45 	{
    46 	delete iBuild;
    47 	}
    48 
    49 TInt CDbStoreIndex::CRecover::StepL(TInt aStep)
    50 	{
    51 	if (iBuild==NULL)
    52 		{	// first step
    53 		iBuild=CDbTableDatabase::CBuildIndex::NewL(iDatabase,iTable,iIndex);
    54 		((CDbStoreIndex&)iBuild->Index()).DiscardL();
    55 		return aStep-EClearStep;
    56 		}
    57 	aStep=iBuild->StepL(aStep);
    58 	if (aStep==0)
    59 		{	// final step
    60 		iDatabase.IndexRecoveredL();
    61 		delete iBuild;
    62 		iBuild=NULL;
    63 		}
    64 	return aStep;
    65 	}
    66 
    67 // Class CDbStoreIndex::CRepair
    68 
    69 NONSHARABLE_CLASS(CDbStoreIndex::CRepair) : public CDbTableDatabase::CStepper
    70 	{
    71 private:
    72 	enum {ERepairStep=1};
    73 public:
    74 	CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex);
    75 	static inline TInt Steps();
    76 private:
    77 	TInt StepL(TInt aStep);
    78 private:
    79 	CDbStoreDatabase& iDatabase;
    80 	const CDbStoreDef& iTable;
    81 	const CDbStoreIndexDef& iIndex;
    82 	};
    83 
    84 inline TInt CDbStoreIndex::CRepair::Steps()
    85 	{return ERepairStep;}
    86 
    87 CDbStoreIndex::CRepair::CRepair(CDbStoreDatabase& aDatabase,const CDbStoreDef& aTable,const CDbStoreIndexDef& anIndex)
    88 	: iDatabase(aDatabase),iTable(aTable),iIndex(anIndex)
    89 	{}
    90 
    91 TInt CDbStoreIndex::CRepair::StepL(TInt)
    92 	{
    93 	CDbStoreIndex* index=CDbStoreIndex::NewL(iDatabase,iIndex,iTable);
    94 	CleanupStack::PushL(index);
    95 	index->OpenL();
    96 	index->RepairL();
    97 	CleanupStack::PopAndDestroy();
    98 	return 0;
    99 	}
   100 
   101 // Class CDbStoreDatabase
   102 
   103 CDbTableDatabase::CStepper* CDbStoreDatabase::RecoverL(TInt& aStep)
   104 	{
   105 	TSglQueIterC<CDbStoreDef> iter(SchemaL());	// ensure we have the schema
   106 	TInt count=0;
   107 	const CDbStoreDef* tDef;
   108 	while ((tDef=iter++)!=NULL)
   109 		count+=tDef->Indexes().Count();
   110 	CMultiStepper* mStepper=CMultiStepper::NewL(count);
   111 	CleanupStack::PushL(mStepper);
   112 // damaged ones first (as they are invoked last
   113 	count=0;
   114 	iter.SetToFirst();
   115 	while ((tDef=iter++)!=NULL)
   116 		{
   117 		TInt records=CDbStoreRecords::CardinalityL(Store(),*tDef);
   118 		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   119 		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   120 			{
   121 			if (!CDbStoreIndex::IsDamagedL(*this,*xDef))
   122 				continue;
   123 			// rebuild from scratch
   124 			CDbStoreIndex::CRecover* rebuild=new(ELeave) CDbStoreIndex::CRecover(*this,*tDef,*xDef);
   125 			mStepper->AddStepper(rebuild,rebuild->Steps(records));
   126 			++count;
   127 			}
   128 		}
   129 	if (count==0)
   130 		{	// no indexes are actually damaged
   131 		aStep=0;
   132 		CleanupStack::PopAndDestroy();
   133 		return NULL;
   134 		}
   135 	// repair the other ones after a reclaim
   136 	iter.SetToFirst();
   137 	while ((tDef=iter++)!=NULL)
   138 		{
   139 		TSglQueIterC<CDbStoreIndexDef> xIter(tDef->Indexes().AsQue());
   140 		for (const CDbStoreIndexDef* xDef;(xDef=xIter++)!=NULL;)
   141 			{
   142 			if (CDbStoreIndex::IsDamagedL(*this,*xDef))
   143 				continue;
   144 			// repair from sequence set
   145 			CDbStoreIndex::CRepair* repair=new(ELeave) CDbStoreIndex::CRepair(*this,*tDef,*xDef);
   146 			mStepper->AddStepper(repair,repair->Steps());
   147 			}
   148 		}
   149 	iPagePool->Discard();
   150 	iPagePool->ReclaimAllL();	// recover all page pool space
   151 	aStep=mStepper->TotalSteps();
   152 	CleanupStack::Pop();
   153 	return mStepper;
   154 	}