First public contribution.
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.
21 //#include <s32crypt.h>
26 #include "D32Assert.h"
29 class TDbStoreIndexStats;
30 class CDbStoreIndexDef;
34 class TClusterLinkCache;
38 class CDbStoreRecords;
42 class RDbStoreReadStream;
43 class RDbStoreWriteStream;
44 class MDbStreamFilter;
45 class CDbStoreCompression;
62 GLREF_C void Panic(TStorePanic aPanic);
67 GLREF_D const TDbDriver KBuiltinDriver;
72 const TUid KDbmsStoreDatabase={268435561};
77 const TInt KDbStoreMaxRecordLength=0x200A; // v5.10 32 nullable longtext columns
78 const TInt KClusterLimit=0x1000;
79 const TInt KMaxClustering=16;
80 const TInt KBlobRefSize=sizeof(TDbBlobId)+sizeof(TInt32);
81 const TInt KMinInlineLimit=16;
82 const TInt KMaxIndexKeySize=248;
87 class TDbStoreIndexStats
96 inline void Set(TReal64 aBound);
97 void Set(const TInt64& aBound);
98 void Set(const TText8* aPtr,TInt aLen,const TTextOps& aConv);
99 void Set(const TText16* aPtr,TInt aLen,const TTextOps& aConv);
100 void Set(const TDbLookupKey::SColumn& aBound,const TTextOps& aConv);
104 enum TType {EContinuous,EDiscrete};
106 inline TDbStoreIndexStats();
108 void InternalizeL(RReadStream& aStream);
109 void ExternalizeL(RWriteStream& aStream) const;
111 inline void Reset(TInt aCardinality=0);
114 inline void Refresh(TType aType);
116 inline TBool IsValid() const;
117 inline TBool NeedsRefresh() const;
118 inline TInt Cardinality() const;
119 TInt Span(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const;
122 TInt ReverseSpan(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const;
124 enum {ERefreshFactor=3};
125 enum {EInvalid=-1,ERefresh=0};
126 enum {ERefreshShift=2+ERefreshFactor,EFlagsMask=(1<<ERefreshShift)-1};
127 enum {EFlgDiscrete=0x1,EFlgClustering=0x2};
140 class CDbStoreIndexDef : public CDbTableIndexDef
143 static CDbStoreIndexDef* NewLC(const TDesC& aName,const CDbKey& aKey,const HDbColumnSet& aColumns);
144 static CDbStoreIndexDef* NewL(RReadStream& aStream);
145 void ExternalizeL(RWriteStream& aStream) const;
146 inline void SetTokenId(TStreamId anId);
147 inline TStreamId TokenId() const;
149 static TInt KeySize(const TDbKeyCol& aKeyCol,const TDbColumnDef& aColumn);
150 static void CheckSizeL(const CDbKey& aKey,const HDbColumnSet& aColSet);
153 static CDbStoreIndexDef* NewLC(const TDesC& aName);
157 __MUTABLE TDbStoreIndexStats iStats; // cache the statistics here
166 TBool Set(const HDbColumnSet& aColumns);
167 inline TInt Clustering() const;
168 inline TInt InlineLimit() const;
170 static void CheckSizeL(const HDbColumnSet& aColumns);
171 static TInt InlineLimit(const HDbColumnSet& aColumns);
173 static inline TInt FixedFieldSize(TDbColType aType);
178 static TUint8 const FieldSizes[];
184 NONSHARABLE_CLASS(CDbStoreDef) : public CDbTableDef
187 static CDbStoreDef* NewLC(const TDesC& aName,const CDbColSet& aColSet);
188 static CDbStoreDef* NewL(RReadStream& aStream);
189 void ExternalizeL(RWriteStream& aStream) const;
190 inline void SetTokenId(TStreamId anId);
191 inline TStreamId TokenId() const;
192 inline TInt Clustering() const;
193 inline TInt InlineLimit() const;
196 void AlteredColumnSetL(HDbColumnSet& aSet,const CDbColSet& aChange,const CDbColSet& aAdd);
200 static CDbStoreDef* NewLC(const TDesC& aName,TInt aColumnCount);
209 typedef TUint32 TClusterId;
214 const TClusterId KNullClusterId=0;
219 inline TClusterId ClusterId(TDbRecordId aRecordId);
220 inline TInt RecordIndex(TDbRecordId aRecordId);
221 inline TDbRecordId RecordId(TClusterId aId,TInt aIndex);
222 inline TClusterId ClusterId(TStreamId aStreamId);
230 enum {EGranularity=8};
235 TClusterId iPreviousId;
238 enum {ESeparation=16};
240 inline RClusterMap();
243 void ResetL(TClusterId aHeadCluster);
244 inline void BindL(TClusterId aPrevious,TClusterId aCluster);
245 void Drop(TClusterId aCluster,TClusterId aNext);
246 TBool At(TClusterId aCluster,TClusterId& aPrevious);
247 inline TClusterId LastBound() const;
248 inline void Complete(TClusterId aLastCluster);
249 inline TBool IsComplete() const;
251 void AddL(TClusterId aCluster);
252 void InsertL(TClusterId aCluster,TClusterId aPrevious);
253 TIdPair* At(TClusterId aCluster);
258 TClusterId iLastBound;
259 TClusterId iLastMapped;
267 class TClusterLinkCache
270 inline void Invalidate();
271 inline void Reset(TClusterId aBaseId);
272 inline void Bind(TClusterId aPrevious,TClusterId aCluster,RClusterMap& aMap);
273 void Add(const TClusterId* aFirst,const TClusterId* aLast);
274 void Drop(TClusterId aCluster,TClusterId aNext);
275 TBool Has(TClusterId aCluster) const;
276 TBool At(TClusterId aCluster,TClusterId& aPrevious) const;
278 void Add(TClusterId aCluster,RClusterMap& aMap);
280 TClusterId iMap[RClusterMap::ESeparation+1];
290 void InternalizeL(RReadStream& aStream);
291 void ExternalizeL(RWriteStream& aStream) const;
300 NONSHARABLE_CLASS(CCluster) : public CBase
302 friend class CClusterCache;
304 enum {EGranularity=0x200};
305 enum {EExpandBuffer=0x40};
310 NONSHARABLE_CLASS(MAlter)
313 virtual TInt RecordExpansion(const TUint8* aRec,TInt aLength);
314 virtual TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength) =0;
317 static CCluster* NewL(CDbStoreDatabase& aDatabase);
323 void Create(TClusterId aClusterId);
324 void ReadL(TClusterId aCluster);
325 void Relink(TClusterId aNextClusterId);
326 void AlterL(MAlter& anAlterer);
328 TPtrC8 RecordL(TInt aIndex);
329 TUint8* UpdateL(TInt aIndex,TInt aNewSize);
330 TBool DeleteL(TInt aIndex);
331 inline TBool IsFull() const;
333 inline TClusterId Id() const;
334 inline const TClusterDes& Des() const;
336 CCluster(CDbStoreDatabase& aDatabase);
338 TInt SetSizeL(TInt aSize);
339 void AdjustMap(TUint8** aMapEntry,TInt aAdjust);
340 void SetRecordL(TInt aIndex,TInt aNewSize);
341 void AdjustL(TUint8** aMapEntry,TInt aAdjust,TUint8* aData);
344 CDbStoreDatabase& iDatabase;
349 TUint8* iMap[KMaxClustering+1];
355 NONSHARABLE_CLASS(CClusterCache) : public CBase
357 #ifndef MAX_CLUSTER_CACHE_SIZE
358 #define MAX_CLUSTER_CACHE_SIZE 8
360 #if MAX_CLUSTER_CACHE_SIZE < 4
361 #error "MAX_CLUSTER_CACHE_SIZE macro value can't be less than 4"
364 enum {EMaxClusters=MAX_CLUSTER_CACHE_SIZE};
366 static CClusterCache* NewL(CDbStoreDatabase& aDatabase);
372 CCluster* Cluster(TClusterId aCluster);
373 CCluster& ClusterL(TClusterId aCluster);
374 CCluster& ClusterL();
376 inline CDbStoreDatabase& Database();
377 inline CStreamStore& Store();
379 inline CClusterCache(CDbStoreDatabase& aDatabase);
381 void Apply(void (*aFunc)(CCluster*));
382 CCluster& AddClusterL();
383 CCluster& NewClusterL();
384 CCluster& Touch(CCluster& aCluster);
386 CDbStoreDatabase& iDatabase;
387 TClusterId iCachePlus1;
388 TClusterId iCachePlus2;
389 TUint8 iFollowOnHits;
391 TDblQue<CCluster> iCache;
397 NONSHARABLE_CLASS(CDbStoreRecords) : public CDbRecordSpace
403 static TStreamId CreateL(CClusterCache& aCache);
404 static CDbStoreRecords* NewL(CClusterCache& aCache,const CDbStoreDef& aDef);
406 static TInt CardinalityL(CStreamStore& aStore,const CDbStoreDef& aDef);
408 TBool GotoL(TDbPosition aPosition,TIteratorC& anIterator);
409 TBool GotoL(TDbRecordId aRecordId,TIteratorC& anIterator);
410 TBool DeletedL(TDbPosition aPosition,TIteratorC& anIterator);
412 inline TClusterId Head() const;
413 inline TInt Count() const;
414 TInt DiscardL(TClusterId& aCluster);
415 TClusterId AlterL(TClusterId aCluster,CCluster::MAlter& anAlterer);
417 // providing for CDbRecordSpace
418 TBool ExistsL(TDbRecordId aRecordId);
419 TPtrC8 ReadL(TDbRecordId aRecordId) const;
420 TUint8* DoReplaceL(TDbRecordId aRecordId,TInt aRecordSize);
421 TUint AutoIncrementL();
422 TUint8* DoNewL(TInt aRecordSize);
423 TDbRecordId AppendL();
424 void DoEraseL(TDbRecordId aRecordId);
425 CDbRecordIter* IteratorL();
429 CDbStoreRecords(CClusterCache& aCache);
432 TUint8* UpdateRecordL(TDbRecordId aRecordId,TInt aNewSize);
433 void DesL(TClusterDes& aDes,TClusterId aCluster);
435 TClusterId NextClusterL(TClusterDes& aDes,TClusterId aCluster);
436 TClusterId PreviousClusterL(TClusterDes& aDes,TClusterId aCluster);
437 TBool LocateL(TClusterId aCluster);
442 void InternalizeL(RReadStream& aStream);
443 void ExternalizeL(RWriteStream& aStream) const;
448 TUint iAutoIncrement;
451 CClusterCache& iCache;
455 TClusterLinkCache iLinks;
462 NONSHARABLE_CLASS(CDbStoreBlobs) : public CDbBlobSpace
465 CDbStoreBlobs(CDbStoreDatabase& aDatabase,TInt aInlineLimit);
467 MStreamBuf* DoCreateL(TDbBlobId &aBlobId,TDbColType aType);
468 MStreamBuf* ReadL(TDbBlobId aBlobId,TDbColType aType) const;
469 void DoDeleteL(TDbBlobId aBlobId);
471 CDbStoreDatabase& iDatabase;
477 NONSHARABLE_CLASS(CDbStoreIndex) : public CDbRecordIndex
487 static CDbStoreIndex* NewL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef,const CDbTableDef& aTable);
490 static TStreamId CreateL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
491 static TBool IsDamagedL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
493 inline HKey& Key() const;
494 inline const TBtree& Tree() const;
495 inline TInt Count() const;
500 CDbStoreIndex(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef);
502 void RefreshStatsL();
503 // CDbTableIndex framework
504 TFind FindL(TDbRecordId aRecordId,const RDbTableRow& aRow);
505 TBool DoInsertL(TDbRecordId aRecordId,const RDbTableRow& aRow);
506 void DoDeleteL(TDbRecordId aRecordId,const RDbTableRow& aRow);
507 CDbRecordIter* IteratorL(TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound);
509 void AboutToModifyL();
512 CDbStoreDatabase& iDatabase;
516 TBtreeInlineLeafOrg iLeafOrg;
517 TBtreeInlineIndexOrg iIndexOrg;
518 TDbStoreIndexStats& iStats;
524 NONSHARABLE_CLASS(CDbStoreIndex::CDiscarder) : public CDbTableDatabase::CStepper
529 TInt Open(CDbStoreIndex* anIndex);
531 TInt StepL(TInt aStep);
533 CDbStoreIndex* iIndex;
539 NONSHARABLE_CLASS(CDbStoreTable) : public CDbTable
545 friend class CDiscarder;
547 friend class CCompressor;
549 CDbStoreTable(CDbStoreDatabase& aDatabase,const CDbTableDef& aDef);
551 inline const CDbStoreDef& Def() const;
552 inline CDbStoreDatabase& Database();
553 inline CDbStoreRecords& StoreRecordsL();
555 TInt RowSize(const TUint8* aRec,TInt aLength);
556 const TUint8* CopyToRow(TDbCell* aCell,TInt aSize,const TUint8* aRec);
557 TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength,TInt aInlineLimit);
558 // providing for CDbTable framework
559 TInt IndexSpanL(const CDbTableIndexDef& aIndex,TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound);
560 CDbRecordSpace* RecordSpaceL();
561 CDbBlobSpace* BlobSpaceL();
562 CDbRecordIndex* RecordIndexL(const CDbTableIndexDef& anIndex);
563 void CopyToRowL(RDbRow& aRow,const TDesC8& aRecord);
564 TInt RecordLength(const RDbRow& aRow);
565 TInt OptimizedRowLength(const RDbRow& aRow);
566 void CopyFromRow(TUint8* aRecord,const RDbRow& aRow);
572 NONSHARABLE_CLASS(CDbStoreTable::CDiscarder) : public CDbTableDatabase::CStepper, public CCluster::MAlter
575 enum {EDiscardClusters=32,EBlobDiscardClusters=2};
579 TInt OpenL(CDbStoreTable* aTable);
581 TInt StepL(TInt aStep);
582 TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength);
584 CDbStoreTable* iTable;
585 CDbStoreRecords* iRecords;
593 NONSHARABLE_CLASS(CDbStoreTable::CAlter) : public CDbTableDatabase::CStepper, public CCluster::MAlter
598 void OpenL(CDbStoreTable* aTable,const HDbColumnSet& aNewSet);
600 TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength);
601 TInt RecordExpansion(const TUint8* aRec,TInt aLength);
602 TInt StepL(TInt aStep);
606 CDbStoreTable* iTable;
607 CDbStoreRecords* iRecords;
615 class RDbStoreReadStream : public RStoreReadStream
618 enum TType {EMixed,EBinary,EText};
620 inline RDbStoreReadStream(CDbStoreDatabase& aDatabase)
621 :iDatabase(aDatabase)
623 void FilterL(TType aType,TUint32 aInit);
625 CDbStoreDatabase& iDatabase;
631 class RDbStoreWriteStream : public RStoreWriteStream
634 enum TType {EMixed,EBinary,EText};
636 inline RDbStoreWriteStream(CDbStoreDatabase& aDatabase)
637 :iDatabase(aDatabase)
639 void FilterL(TType aType,TUint32 aInit);
641 CDbStoreDatabase& iDatabase;
647 class MDbStreamFilter
650 virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType) =0;
651 virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType) =0;
658 NONSHARABLE_CLASS(CDbStoreCompression) : public CBase, public MDbStreamFilter
667 enum {ELiterals=256,ELengths=28,ESpecials=1,EDistances=44};
668 enum {ELitLens=ELiterals+ELengths+ESpecials};
669 enum {EEos=ELiterals+ELengths};
671 TUint32 iLitLen[ELitLens];
672 TUint32 iDistance[EDistances];
675 static CDbStoreCompression* NewL();
678 inline void Inflate();
679 void ExternalizeL(RWriteStream& aStream) const;
680 void InternalizeL(RReadStream& aStream);
681 // for MDbStreamFilter
682 MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType);
683 MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType);
685 inline CDbStoreCompression();
687 enum TState {EAnalysis,EEncoding,EDecoding,EInflating};
690 TEncoding iEncoding[3];
693 #include "US_STD.INL"