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