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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
18 // Class CDbTableDatabase::CMultiStepper
20 inline CDbTableDatabase::CMultiStepper::CMultiStepper( TInt aCount )
21 : iStepper( iSteppers - 1 ), iEnd( iSteppers + aCount )
24 CDbTableDatabase::CMultiStepper::~CMultiStepper()
26 SStepper* const end = iEnd;
27 for ( SStepper* iter = iSteppers; iter < end; ++iter )
28 delete iter->iStepper;
31 EXPORT_C CDbTableDatabase::CMultiStepper* CDbTableDatabase::CMultiStepper::NewL( TInt aStepperCount )
33 return new( ELeave, sizeof( SStepper ) * ( aStepperCount - 1 ) ) CMultiStepper( aStepperCount ); // get the extra size for the entries, leaves on error
36 EXPORT_C void CDbTableDatabase::CMultiStepper::AddStepper( CStepper* aStepper, TInt aStep )
39 __ASSERT( iStepper < iEnd );
40 iStepper->iStepper = aStepper;
41 iStepper->iStep = aStep;
44 EXPORT_C TInt CDbTableDatabase::CMultiStepper::TotalSteps()
46 // Count the number of steps, and normalise the step counts
50 SStepper* const end = iStepper;
51 for( SStepper* stepper = iSteppers; stepper <= end; ++stepper )
53 TInt step = stepper->iStep;
54 stepper->iStep = steps;
60 TInt CDbTableDatabase::CMultiStepper::StepL( TInt aStep )
62 SStepper* stepper = iStepper;
63 __ASSERT( stepper != 0 && stepper >= iSteppers );
67 base = stepper->iStep;
70 if ( --stepper < iSteppers )
74 return stepper->iStepper->StepL( aStep - base ) + base;
77 // Class CDbTableDatabase::CIncremental
79 CDbTableDatabase::CIncremental::CIncremental(RDbTransaction& aTransaction)
80 : iTransaction(aTransaction)
82 Database().Open(); // we reference the database
83 __ASSERT(iState==ERunning);
86 CDbTableDatabase::CIncremental::~CIncremental()
89 Database().Close(); // drop the database reference
92 TBool CDbTableDatabase::CIncremental::NextL(TInt& aStep)
94 // if step is 1 then invopke the last step otherwise do
97 __ASSERT(!IsCommitted());
101 if (aStep!=ELastStep)
103 aStep=DoNextL(aStep);
112 return 0; // return 0 for DDL incremental operations
115 TInt CDbTableDatabase::CIncremental::DoNextL(TInt aStep)
117 // default use of stepper object (re-normalised the step count)
120 return iStepper->StepL(aStep-ELastStep)+ELastStep;
123 // Class CDbTableDatabase::CIncrementalDDL
125 CDbTableDatabase::CIncrementalDDL::CIncrementalDDL(RDbTransaction& aTransaction)
126 : CIncremental(aTransaction)
128 Transaction().DDLBegin();
131 CDbTableDatabase::CIncrementalDDL::~CIncrementalDDL()
134 Transaction().DDLRollback();
137 void CDbTableDatabase::CIncrementalDDL::DoLastL()
139 Transaction().DDLCommitL();
142 // Class CDbTableDatabase::CBuildIndex
144 EXPORT_C CDbTableDatabase::CBuildIndex* CDbTableDatabase::CBuildIndex::NewL(CDbTableDatabase& aDatabase,const CDbTableDef& aTable,const CDbTableIndexDef& anIndex)
146 CBuildIndex* self=new(ELeave) CBuildIndex();
147 CleanupStack::PushL(self);
148 CDbTableSource* source=self->iSource=aDatabase.TableSourceL(aTable.Name());
149 CDbTable& table=source->Table();
150 source->SetIterator(table.IteratorL());
151 self->iIndex=table.RecordIndexL(anIndex);
152 self->iIndex->OpenL();
157 CDbTableDatabase::CBuildIndex::CBuildIndex()
161 CDbTableDatabase::CBuildIndex::~CBuildIndex()
167 EXPORT_C TInt CDbTableDatabase::CBuildIndex::Steps(TInt aCardinality)
169 return aCardinality+1;
172 EXPORT_C TInt CDbTableDatabase::CBuildIndex::StepsL()
174 return Steps(iSource->CountL());
177 TInt CDbTableDatabase::CBuildIndex::StepL(TInt aStep)
179 // One step on an incremental index build
182 for (TInt inc=1;;++inc)
185 if (iSource->CDbDataSource::GotoL(iNext,id)!=CDbDataSource::ESuccess)
186 break; // run out of data
187 iSource->ReadRowL(id);
188 if (!iIndex->InsertL(id,iSource->Row()))
189 __LEAVE(KErrAlreadyExists); // duplicate key - fail
191 if (inc==ERecordsPerStep)
192 return Max(aStep-inc,1);
198 // Class CDbTableDatabase::CCreateIndex
200 CDbTableDatabase::CCreateIndex* CDbTableDatabase::CCreateIndex::NewLC(RDbTransaction& aTransaction)
202 CCreateIndex* self=new(ELeave) CCreateIndex(aTransaction);
203 CleanupStack::PushL(self);
207 TInt CDbTableDatabase::CCreateIndex::ConstructL(const CDbTableDef& aTable,const CDbTableIndexDef& anIndex)
209 CBuildIndex* builder=CBuildIndex::NewL(Database(),aTable,anIndex);
211 return builder->StepsL();
214 // Class CDbTableDatabase::CDropIndex
216 CDbTableDatabase::CDropIndex::~CDropIndex()
221 CDbTableDatabase::CDropIndex* CDbTableDatabase::CDropIndex::NewL(RDbTransaction& aTransaction,const CDbTableDef& aTable,CDbTableIndexDef* anIndex,TInt& aStep)
223 CDropIndex* self=new(ELeave) CDropIndex(aTransaction);
224 CleanupStack::PushL(self);
225 self->Construct(aTransaction.Database().IndexDiscarderL(aTable,*anIndex,aStep));
232 // Class CDbTableDatabase::CDropTable
234 CDbTableDatabase::CDropTable::~CDropTable()
236 Database().Release(*iDef); // discard the table using this definition
240 CDbTableDatabase::CDropTable* CDbTableDatabase::CDropTable::NewL(RDbTransaction& aTransaction,CDbTableDef* aTable,TInt& aStep)
242 CDropTable* self=new(ELeave) CDropTable(aTransaction);
243 CDbTableDatabase& database=aTransaction.Database();
244 CleanupStack::PushL(self);
245 CMultiStepper* mstepper=CMultiStepper::NewL(aTable->Indexes().Count()+1);
246 self->Construct(mstepper);
247 CStepper* stepper=database.RecordDiscarderL(*aTable,aStep);
248 mstepper->AddStepper(stepper,aStep);
249 TSglQueIterC<CDbTableIndexDef> iter(aTable->Indexes().AsQue());
250 for (const CDbTableIndexDef* xDef;(xDef=iter++)!=0;)
252 stepper=database.IndexDiscarderL(*aTable,*xDef,aStep);
253 mstepper->AddStepper(stepper,aStep);
255 aStep=mstepper->TotalSteps()+ELastStep;
261 // Class CDbTableDatabase::CAlterTable
263 CDbTableDatabase::CAlterTable::~CAlterTable()
268 void CDbTableDatabase::CAlterTable::ConstructL(const CDbColSet& aNewDef,TInt& aStep)
270 // get all the deleted columns
271 // check changes to columns still present
272 // get all the new columns
273 // construct a new columns set based on the changes
277 // flag all columns as dropped initially
278 HDbColumnSet& columns=iDef.Columns();
279 HDbColumnSet::TIterator iter=columns.Begin();
280 HDbColumnSet::TIteratorC const end=columns.End();
283 iter->iFlags=TDbColumnDef::EDropped;
284 } while (++iter<end);
286 // look for additions and changes
287 CDbColSet* change=CDbColSet::NewLC();
288 CDbColSet* add=CDbColSet::NewLC();
289 for (TDbColSetIter iterNew(aNewDef);iterNew;++iterNew)
291 const TDbCol& col=*iterNew;
292 TDbColumnDef* def=columns.ColumnL(iterNew->iName);
293 if (!def) // a new column
296 { // see if the definition has changed
297 if (def->iAttributes!=col.iAttributes)
298 __LEAVE(KErrArgument); // can't change attributes
300 if (def->iType!=col.iType)
301 flag=TDbColumnDef::EChangedType;
302 else if (def->iType>=EDbColText8 && col.iMaxLength!=KDbUndefinedLength && col.iMaxLength!=def->iMaxLength)
303 flag=TDbColumnDef::EChangedLen;
306 change->AddL(col); // column has changed
310 // check that all marked columns are not indexed
312 iter=columns.Begin();
315 if (iter->iFlags && iDef.IsIndexed(*iter->iName))
316 __LEAVE(KErrArgument); // can't remove indexed column
317 } while (++iter<end);
319 iNewSet=HDbColumnSet::NewL(aNewDef.Count());
320 iDef.AlteredColumnSetL(*iNewSet,*change,*add);
321 CleanupStack::PopAndDestroy(2); // add, change
322 Construct(Database().TableAlterL(iDef,*iNewSet,aStep));
325 CDbTableDatabase::CAlterTable* CDbTableDatabase::CAlterTable::NewL(RDbTransaction& aTransaction,CDbTableDef& aTable,const CDbColSet& aNewDef,TInt& aStep)
327 // Check the validity of the new definition before asking the implentation to provide
328 // the incremental class
331 CAlterTable* self=new(ELeave) CAlterTable(aTransaction,aTable);
332 CleanupStack::PushL(self);
333 self->ConstructL(aNewDef,aStep);
339 void CDbTableDatabase::CAlterTable::DoLastL()
341 // last step is to change the definition
344 iDef.ExchangeColumnSet(iNewSet);
346 CIncrementalDDL::DoLastL();
349 // Class CDbTableDatabase::CUtility
351 inline CDbTableDatabase::CUtility::CUtility(RDbTransaction& aTransaction,CDbDatabase::TUtility aType)
352 : CIncremental(aTransaction)
353 {Transaction().UtilityBegin(aType);}
355 CDbTableDatabase::CUtility::~CUtility()
358 Transaction().UtilityRollback();
361 CDbTableDatabase::CUtility* CDbTableDatabase::CUtility::NewL(RDbTransaction& aTransaction,CDbDatabase::TUtility aType,TInt& aStep)
363 CUtility* self=new(ELeave) CUtility(aTransaction,aType);
364 CleanupStack::PushL(self);
365 self->Construct(aTransaction.Database().UtilityL(aType,aStep));
371 void CDbTableDatabase::CUtility::DoLastL()
373 Transaction().UtilityCommitL();