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.
17 #include "U32STD_DBMS.H"
19 // Class CDbStoreDatabase::CCompactor
21 NONSHARABLE_CLASS(CDbStoreDatabase::CCompactor) : public CDbStoreDatabase::CStepper
24 static CCompactor* NewL(CDbDatabase::TUtility aType, CStreamStore& aStore,
25 TInt& aReclaim, TInt& aStep);
28 inline CCompactor(TInt& aReclaim);
30 TInt StepL(TInt aStep);
32 RStoreReclaim iReclaimer;
36 inline CDbStoreDatabase::CCompactor::CCompactor(TInt& aReclaim)
41 CDbStoreDatabase::CCompactor* CDbStoreDatabase::CCompactor::NewL(CDbDatabase::TUtility aType,
43 TInt& aReclaim,TInt& aStep)
45 CCompactor* self=new(ELeave) CCompactor(aReclaim);
46 CleanupStack::PushL(self);
47 if (aType==CDbDatabase::ECompact)
48 self->iReclaimer.CompactL(aStore,aStep);
50 self->iReclaimer.OpenL(aStore,aStep);
55 CDbStoreDatabase::CCompactor::~CCompactor()
61 // Single step the compactor
62 // We cannot deal with the "in use" scenario as we could end up locking out forever
63 // that has to be left to clients using the RDbIncremental interface
65 TInt CDbStoreDatabase::CCompactor::StepL(TInt aStep)
67 iReclaimer.NextL(aStep);
70 iReclaim=iReclaimer.Available();
77 // Class CDbStoreDatabase
79 EXPORT_C CDbStoreDatabase::CDbStoreDatabase()
80 :iReclaim(KErrGeneral)
85 // Create a StoreDatabase object. This type shares the store
87 CDbStoreDatabase* CDbStoreDatabase::NewLC(CStreamStore* aStore)
90 CDbStoreDatabase* self=new(ELeave) CDbStoreDatabase;
91 CleanupStack::PushL(self);
98 //SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
99 CDbDatabase* CDbStoreDatabase::CreateL(CStreamStore* aStore,TStreamId& aStreamId)
101 CDbStoreDatabase* self=NewLC(aStore);
102 aStreamId=self->ConstructL();
103 CDbDatabase* db=self->InterfaceL();
104 CleanupStack::Pop(); // self
108 // SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
109 // Phase 2 construction for creating a new database
110 // Initialise a new database object, creating the required persistent structure
112 EXPORT_C TStreamId CDbStoreDatabase::ConstructL()
114 __ASSERT(iStore); // this must have been provided by now
115 iVersion=TUint8(EDbStoreVersion2);
117 iPagePool->Create(Store());
118 iTokenId=Store().ExtendL();
120 iSchemaId=Store().ExtendL();
126 // SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
127 // Open phase #2: Authenticate the client
129 EXPORT_C void CDbStoreDatabase::AuthenticateL()
133 // first client to open the database, so complete initialisation now
139 // SYMBIAN_REMOVE_TRIVIAL_ENCRYPTION version of the method.
140 void CDbStoreDatabase::InitPagePoolL()
142 iPagePool = new(ELeave) RStorePagePool;
146 CDbSource* CDbStoreDatabase::OpenL(CStreamStore* aStore,TStreamId aStreamId)
148 CDbStoreDatabase* self=NewLC(aStore);
149 self->RestoreL(aStreamId);
150 CDbSource* src=self->SourceL();
151 CleanupStack::Pop(); // self
156 // Phase 2 construction for opening a database
157 // Client must still authenticate before it can be used
159 EXPORT_C void CDbStoreDatabase::RestoreL(TStreamId aStreamId)
161 __ASSERT(iStore); // this must have been provided by now
163 // read the databse header for encryption information
164 RStoreReadStream strm;
165 strm.OpenLC(Store(),aStreamId);
167 CleanupStack::PopAndDestroy(); // strm
171 // Load the root stream header (up to the security key)
173 void CDbStoreDatabase::ReadHeaderL(RReadStream& aStream)
177 if (uid!=KDbmsStoreDatabase)
178 __LEAVE(KErrArgument);
182 case EDbStoreCompressed:
183 aStream>>CompressionL();
185 case EDbStoreVersion2:
188 __LEAVE(KErrNotSupported);
193 CDbStoreCompression& CDbStoreDatabase::CompressionL()
195 CDbStoreCompression* c=iCompression;
197 iFilter=iCompression=c=CDbStoreCompression::NewL();
201 EXPORT_C CDbStoreDatabase::~CDbStoreDatabase()
205 iPagePool->Release();
208 delete iClusterCache;
216 // Validate the column set first
218 EXPORT_C CDbTableDef* CDbStoreDatabase::CreateTableL(const TDesC& aName,const CDbColSet& aColSet,const CDbKey* aPrimaryKey)
221 __LEAVE(KErrNotSupported); // Store database does not support primary keys
222 CDbStoreDef* def=CDbStoreDef::NewLC(aName,aColSet);
223 def->SetTokenId(CDbStoreRecords::CreateL(ClusterCacheL()));
228 EXPORT_C CDbTableIndexDef* CDbStoreDatabase::CreateIndexL(const CDbTableDef& aTable,const TDesC& aName,const CDbKey& aKey)
230 CDbStoreIndexDef* def=CDbStoreIndexDef::NewLC(aName,aKey,aTable.Columns());
231 def->SetTokenId(CDbStoreIndex::CreateL(*this,*def));
232 CleanupStack::Pop(); // IndexDef
237 // Destroy the entire database...
239 EXPORT_C void CDbStoreDatabase::DestroyL()
241 iPagePool->Discard();
242 iPagePool->ReclaimAllL(); // reclaim all page pool space
243 iStore->DeleteL(iSchemaId);
244 iStore->DeleteL(iTokenId);
248 EXPORT_C CDbTable* CDbStoreDatabase::TableL(const CDbTableDef& aDef)
250 return new(ELeave) CDbStoreTable(*this,aDef);
254 // load the schema for the database
256 EXPORT_C void CDbStoreDatabase::LoadSchemaL()
258 RDbStoreReadStream strm(*this);
259 strm.OpenLC(Store(),iSchemaId);
261 strm.FilterL(strm.EMixed,iSchemaId.Value());
263 RDbTableSchema& schema=Schema();
266 for (TInt ii=tables;ii>0;--ii)
267 schema.Add(CDbStoreDef::NewL(strm));
268 CleanupStack::PopAndDestroy();
269 strm.OpenLC(Store(),iTokenId);
270 strm>>iFlags>>iPoolToken;
271 iPagePool->Open(Store(),iPoolToken);
272 CleanupStack::PopAndDestroy();
276 // Re-write the schema stream
278 void CDbStoreDatabase::ReplaceSchemaL()
280 RDbStoreWriteStream out(*this);
281 out.ReplaceLC(Store(),iSchemaId);
282 out<<KDbmsStoreDatabase<<iVersion;
285 case EDbStoreCompressed:
286 __ASSERT(iCompression);
289 case EDbStoreVersion2:
294 out.FilterL(out.EMixed,iSchemaId.Value());
296 TSglQueIterC<CDbStoreDef> iter(Schema());
300 out<<TCardinality(count);
302 for (const CDbStoreDef* def;(def=iter++)!=0;)
305 CleanupStack::PopAndDestroy();
309 // Re-write the token stream, removing the mark
311 void CDbStoreDatabase::ReplaceTokenL(TUint aFlags)
313 RStoreWriteStream out;
314 out.ReplaceLC(Store(),iTokenId);
315 out<<TUint8(aFlags&EDamaged)<<iPagePool->Token();
317 CleanupStack::PopAndDestroy();
321 // Return some database property
323 EXPORT_C TInt CDbStoreDatabase::Property(CDbDatabase::TProperty aProperty)
327 case CDbDatabase::EIsDamaged:
328 return iFlags&EDamaged ? 1 : 0;
329 case CDbDatabase::ECompactable:
332 return CDbTableDatabase::Property(aProperty);
337 // mark the database as dirty
339 void CDbStoreDatabase::MarkL()
341 if (!(iFlags&EModified))
343 RStoreWriteStream out;
344 out.OpenLC(Store(),iTokenId);
345 out.WriteUint8L(EDamaged); // mark as dirty
349 CleanupStack::PopAndDestroy();
355 // Reset all cache buffers
357 EXPORT_C void CDbStoreDatabase::Idle()
367 delete iClusterCache;
373 // Commit the store, and when all is well, clear the token
375 void CDbStoreDatabase::SynchStoreL(TDbLockType aLock)
379 TUint newflags=iFlags&~EModified;
380 if (aLock==EDbRecoveryLock)
382 if (aLock==EDbRecoveryLock || iFlags&EModified)
383 ReplaceTokenL(newflags);
384 if (aLock>=EDbWriteLock || iSharedStore)
387 iFlags=TUint8(newflags);
388 iPoolToken=iPagePool->Token();
393 // An index has been successfully recovered, commit it
395 void CDbStoreDatabase::IndexRecoveredL()
397 SynchStoreL(EDbSchemaLock);
401 // Ensure all data is in the store
403 EXPORT_C void CDbStoreDatabase::SynchL(TDbLockType aLock)
405 if (aLock==EDbSchemaLock)
408 iClusterCache->FlushL();
413 // Unwind the store, throw out changes, etc
415 EXPORT_C void CDbStoreDatabase::Revert(TDbLockType aLock)
417 if (aLock>=EDbWriteLock)
420 iClusterCache->Discard();
423 if (iFlags&EModified)
425 iPagePool->Open(Store(),iPoolToken); // reset the page pool
427 else if (!iSharedStore) // don't touch the store if not shared
433 // Ensure we have a cluster cache and return it
435 CClusterCache& CDbStoreDatabase::ClusterCacheL()
437 CClusterCache* cache=iClusterCache;
439 iClusterCache=cache=CClusterCache::NewL(*this);
444 // Ensure we have a page cache and return the pool
446 MPagePool& CDbStoreDatabase::PagePoolL()
450 iPageCache=CPageCache::NewL(EPageCachePages);
451 iPagePool->Set(*iPageCache);
457 // Create an incremental object that compacts the store
459 EXPORT_C CDbTableDatabase::CStepper* CDbStoreDatabase::UtilityL(CDbDatabase::TUtility aType,TInt& aStep)
463 case CDbDatabase::EStats:
464 case CDbDatabase::ECompact:
465 return CCompactor::NewL(aType,Store(),iReclaim,aStep);
466 case CDbDatabase::ERecover:
467 return RecoverL(aStep);
469 return CDbTableDatabase::UtilityL(aType,aStep);
474 // Create an incremental object to destroy a table
476 EXPORT_C CDbTableDatabase::CStepper* CDbStoreDatabase::RecordDiscarderL(const CDbTableDef& aTable,TInt& aStep)
478 CDbStoreTable::CDiscarder* discarder=new(ELeave) CDbStoreTable::CDiscarder;
479 CleanupStack::PushL(discarder);
480 aStep=discarder->OpenL((CDbStoreTable*)TableL(aTable));
486 // Create an incremental object to destroy an index
488 EXPORT_C CDbTableDatabase::CStepper* CDbStoreDatabase::IndexDiscarderL(const CDbTableDef& aTable,const CDbTableIndexDef& anIndex,TInt& aStep)
490 CDbStoreIndex::CDiscarder* discarder=new(ELeave) CDbStoreIndex::CDiscarder;
491 CleanupStack::PushL(discarder);
492 CDbStoreIndex* index=CDbStoreIndex::NewL(*this,(const CDbStoreIndexDef&)anIndex,aTable);
493 aStep=discarder->Open(index);
500 // Provide a stepper to alter the table data
501 // if no data to alter, return 0
503 EXPORT_C CDbTableDatabase::CStepper* CDbStoreDatabase::TableAlterL(CDbTableDef& aTable,const HDbColumnSet& aNewSet,TInt& aStep)
505 CDbStoreDef& def=STATIC_CAST(CDbStoreDef&,aTable);
507 aStep=CDbStoreRecords::CardinalityL(Store(),def);
509 return NULL; // no data to modify
511 // check that all added columns are nullable
512 HDbColumnSet::TIteratorC col=aNewSet.Begin();
513 HDbColumnSet::TIteratorC end=aNewSet.End();
516 if (col->iFlags&TDbColumnDef::EAdded && col->iAttributes&TDbCol::ENotNull)
517 __LEAVE(KErrArgument); // added column is not nullable
520 // check to see if anything is being dropped or changed type
521 col=aTable.Columns().Begin();
522 end=aTable.Columns().End();
523 while (!(col->iFlags&(TDbColumnDef::EDropped|TDbColumnDef::EChangedType|TDbColumnDef::EChangedLen)))
526 { // no changes which affect layout, so no work required
532 CDbStoreTable::CAlter* alter=new(ELeave) CDbStoreTable::CAlter;
533 CleanupStack::PushL(alter);
534 alter->OpenL((CDbStoreTable*)TableL(def),aNewSet);
539 EXPORT_C void CDbStoreDatabase::Reserved_1()
543 EXPORT_C void CDbStoreDatabase::Reserved_2()