sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "U32STD.H" sl@0: #include "D32REC.H" sl@0: #include "D32STOR.H" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // classes defined sl@0: class TDbStoreIndexStats; sl@0: class CDbStoreIndexDef; sl@0: class TRecordSize; sl@0: class CDbStoreDef; sl@0: class RClusterMap; sl@0: class TClusterLinkCache; sl@0: struct TClusterDes; sl@0: class CCluster; sl@0: class CClusterCache; sl@0: class CDbStoreRecords; sl@0: class CDbStoreBlobs; sl@0: class CDbStoreIndex; sl@0: class CDbStoreTable; sl@0: class RDbStoreReadStream; sl@0: class RDbStoreWriteStream; sl@0: class MDbStreamFilter; sl@0: class CDbStoreCompression; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: enum TStorePanic sl@0: { sl@0: EDbUnimplemented, sl@0: EDbNoStore, sl@0: EDbCannotSeek, sl@0: EDbNotFixedFieldType, sl@0: EDbWrongType sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: GLREF_C void Panic(TStorePanic aPanic); sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: GLREF_D const TDbDriver KBuiltinDriver; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: const TUid KDbmsStoreDatabase={268435561}; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: const TInt KDbStoreMaxRecordLength=0x200A; // v5.10 32 nullable longtext columns sl@0: const TInt KClusterLimit=0x1000; sl@0: const TInt KMaxClustering=16; sl@0: const TInt KBlobRefSize=sizeof(TDbBlobId)+sizeof(TInt32); sl@0: const TInt KMinInlineLimit=16; sl@0: const TInt KMaxIndexKeySize=248; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TDbStoreIndexStats sl@0: { sl@0: public: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TBound sl@0: { sl@0: public: sl@0: inline void Set(TReal64 aBound); sl@0: void Set(const TInt64& aBound); sl@0: void Set(const TText8* aPtr,TInt aLen,const TTextOps& aConv); sl@0: void Set(const TText16* aPtr,TInt aLen,const TTextOps& aConv); sl@0: void Set(const TDbLookupKey::SColumn& aBound,const TTextOps& aConv); sl@0: public: sl@0: TReal64 iValue; sl@0: }; sl@0: enum TType {EContinuous,EDiscrete}; sl@0: public: sl@0: inline TDbStoreIndexStats(); sl@0: // sl@0: void InternalizeL(RReadStream& aStream); sl@0: void ExternalizeL(RWriteStream& aStream) const; sl@0: // sl@0: inline void Reset(TInt aCardinality=0); sl@0: inline void Inc(); sl@0: inline void Dec(); sl@0: inline void Refresh(TType aType); sl@0: // sl@0: inline TBool IsValid() const; sl@0: inline TBool NeedsRefresh() const; sl@0: inline TInt Cardinality() const; sl@0: TInt Span(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const; sl@0: private: sl@0: inline void Touch(); sl@0: TInt ReverseSpan(TUint aInclusion,const TDbLookupKey* aLower,const TDbLookupKey* aUpper,const TTextOps& aConv) const; sl@0: private: sl@0: enum {ERefreshFactor=3}; sl@0: enum {EInvalid=-1,ERefresh=0}; sl@0: enum {ERefreshShift=2+ERefreshFactor,EFlagsMask=(1< iCache; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreRecords) : public CDbRecordSpace sl@0: { sl@0: public: sl@0: class TIteratorC; sl@0: class CIter; sl@0: public: sl@0: static TStreamId CreateL(CClusterCache& aCache); sl@0: static CDbStoreRecords* NewL(CClusterCache& aCache,const CDbStoreDef& aDef); sl@0: // sl@0: static TInt CardinalityL(CStreamStore& aStore,const CDbStoreDef& aDef); sl@0: // sl@0: TBool GotoL(TDbPosition aPosition,TIteratorC& anIterator); sl@0: TBool GotoL(TDbRecordId aRecordId,TIteratorC& anIterator); sl@0: TBool DeletedL(TDbPosition aPosition,TIteratorC& anIterator); sl@0: // sl@0: inline TClusterId Head() const; sl@0: inline TInt Count() const; sl@0: TInt DiscardL(TClusterId& aCluster); sl@0: TClusterId AlterL(TClusterId aCluster,CCluster::MAlter& anAlterer); sl@0: void DestroyL(); sl@0: // providing for CDbRecordSpace sl@0: TBool ExistsL(TDbRecordId aRecordId); sl@0: TPtrC8 ReadL(TDbRecordId aRecordId) const; sl@0: TUint8* DoReplaceL(TDbRecordId aRecordId,TInt aRecordSize); sl@0: TUint AutoIncrementL(); sl@0: TUint8* DoNewL(TInt aRecordSize); sl@0: TDbRecordId AppendL(); sl@0: void DoEraseL(TDbRecordId aRecordId); sl@0: CDbRecordIter* IteratorL(); sl@0: TBool RestoreL(); sl@0: void SynchL(); sl@0: private: sl@0: CDbStoreRecords(CClusterCache& aCache); sl@0: ~CDbStoreRecords(); sl@0: // sl@0: TUint8* UpdateRecordL(TDbRecordId aRecordId,TInt aNewSize); sl@0: void DesL(TClusterDes& aDes,TClusterId aCluster); sl@0: void CompleteMapL(); sl@0: TClusterId NextClusterL(TClusterDes& aDes,TClusterId aCluster); sl@0: TClusterId PreviousClusterL(TClusterDes& aDes,TClusterId aCluster); sl@0: TBool LocateL(TClusterId aCluster); sl@0: private: sl@0: class TToken sl@0: { sl@0: public: sl@0: void InternalizeL(RReadStream& aStream); sl@0: void ExternalizeL(RWriteStream& aStream) const; sl@0: public: sl@0: TClusterId iHead; sl@0: TDbRecordId iNext; sl@0: TInt iCount; sl@0: TUint iAutoIncrement; sl@0: }; sl@0: private: sl@0: CClusterCache& iCache; sl@0: TStreamId iTokenId; sl@0: TToken iToken; sl@0: TInt iClustering; sl@0: TClusterLinkCache iLinks; sl@0: RClusterMap iMap; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreBlobs) : public CDbBlobSpace sl@0: { sl@0: public: sl@0: CDbStoreBlobs(CDbStoreDatabase& aDatabase,TInt aInlineLimit); sl@0: // sl@0: MStreamBuf* DoCreateL(TDbBlobId &aBlobId,TDbColType aType); sl@0: MStreamBuf* ReadL(TDbBlobId aBlobId,TDbColType aType) const; sl@0: void DoDeleteL(TDbBlobId aBlobId); sl@0: private: sl@0: CDbStoreDatabase& iDatabase; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreIndex) : public CDbRecordIndex sl@0: { sl@0: public: sl@0: class HKey; sl@0: class HDupKey; sl@0: class CIter; sl@0: class CDiscarder; sl@0: class CRecover; sl@0: class CRepair; sl@0: public: sl@0: static CDbStoreIndex* NewL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef,const CDbTableDef& aTable); sl@0: ~CDbStoreIndex(); sl@0: // sl@0: static TStreamId CreateL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef); sl@0: static TBool IsDamagedL(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef); sl@0: // sl@0: inline HKey& Key() const; sl@0: inline const TBtree& Tree() const; sl@0: inline TInt Count() const; sl@0: void RepairL(); sl@0: void DiscardL(); sl@0: void DestroyL(); sl@0: private: sl@0: CDbStoreIndex(CDbStoreDatabase& aDatabase,const CDbStoreIndexDef& aDef); sl@0: // sl@0: void RefreshStatsL(); sl@0: // CDbTableIndex framework sl@0: TFind FindL(TDbRecordId aRecordId,const RDbTableRow& aRow); sl@0: TBool DoInsertL(TDbRecordId aRecordId,const RDbTableRow& aRow); sl@0: void DoDeleteL(TDbRecordId aRecordId,const RDbTableRow& aRow); sl@0: CDbRecordIter* IteratorL(TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound); sl@0: TBool RestoreL(); sl@0: void AboutToModifyL(); sl@0: void SynchL(); sl@0: private: sl@0: CDbStoreDatabase& iDatabase; sl@0: TStreamId iTokenId; sl@0: TBtree iTree; sl@0: HKey* iKey; sl@0: TBtreeInlineLeafOrg iLeafOrg; sl@0: TBtreeInlineIndexOrg iIndexOrg; sl@0: TDbStoreIndexStats& iStats; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreIndex::CDiscarder) : public CDbTableDatabase::CStepper sl@0: { sl@0: public: sl@0: CDiscarder(); sl@0: ~CDiscarder(); sl@0: TInt Open(CDbStoreIndex* anIndex); sl@0: private: sl@0: TInt StepL(TInt aStep); sl@0: private: sl@0: CDbStoreIndex* iIndex; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreTable) : public CDbTable sl@0: { sl@0: public: sl@0: class CDiscarder; sl@0: class CAlter; sl@0: class CCompressor; sl@0: friend class CDiscarder; sl@0: friend class CAlter; sl@0: friend class CCompressor; sl@0: public: sl@0: CDbStoreTable(CDbStoreDatabase& aDatabase,const CDbTableDef& aDef); sl@0: private: sl@0: inline const CDbStoreDef& Def() const; sl@0: inline CDbStoreDatabase& Database(); sl@0: inline CDbStoreRecords& StoreRecordsL(); sl@0: // sl@0: TInt RowSize(const TUint8* aRec,TInt aLength); sl@0: const TUint8* CopyToRowL(TDbCell* aCell,TInt aSize,const TUint8* aRec); sl@0: TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength,TInt aInlineLimit); sl@0: // providing for CDbTable framework sl@0: TInt IndexSpanL(const CDbTableIndexDef& aIndex,TUint aInclusion,const TDbLookupKey* aLowerBound,const TDbLookupKey* aUpperBound); sl@0: CDbRecordSpace* RecordSpaceL(); sl@0: CDbBlobSpace* BlobSpaceL(); sl@0: CDbRecordIndex* RecordIndexL(const CDbTableIndexDef& anIndex); sl@0: void CopyToRowL(RDbRow& aRow,const TDesC8& aRecord); sl@0: TInt RecordLength(const RDbRow& aRow); sl@0: TInt OptimizedRowLength(const RDbRow& aRow); sl@0: void CopyFromRow(TUint8* aRecord,const RDbRow& aRow); sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreTable::CDiscarder) : public CDbTableDatabase::CStepper, public CCluster::MAlter sl@0: { sl@0: private: sl@0: enum {EDiscardClusters=32,EBlobDiscardClusters=2}; sl@0: public: sl@0: CDiscarder(); sl@0: ~CDiscarder(); sl@0: TInt OpenL(CDbStoreTable* aTable); sl@0: private: sl@0: TInt StepL(TInt aStep); sl@0: TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength); sl@0: private: sl@0: CDbStoreTable* iTable; sl@0: CDbStoreRecords* iRecords; sl@0: TClusterId iCluster; sl@0: RDbRow iRow; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreTable::CAlter) : public CDbTableDatabase::CStepper, public CCluster::MAlter sl@0: { sl@0: public: sl@0: CAlter(); sl@0: ~CAlter(); sl@0: void OpenL(CDbStoreTable* aTable,const HDbColumnSet& aNewSet); sl@0: private: sl@0: TUint8* AlterRecordL(TUint8* aWPtr,const TUint8* aRPtr,TInt aLength); sl@0: TInt RecordExpansion(const TUint8* aRec,TInt aLength); sl@0: TInt StepL(TInt aStep); sl@0: private: sl@0: TInt iExpansion; sl@0: TInt iInlineLimit; sl@0: CDbStoreTable* iTable; sl@0: CDbStoreRecords* iRecords; sl@0: TClusterId iCluster; sl@0: TInt iStep; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class RDbStoreReadStream : public RStoreReadStream sl@0: { sl@0: public: sl@0: enum TType {EMixed,EBinary,EText}; sl@0: public: sl@0: inline RDbStoreReadStream(CDbStoreDatabase& aDatabase) sl@0: :iDatabase(aDatabase) sl@0: {} sl@0: void FilterL(TType aType,TUint32 aInit); sl@0: private: sl@0: CDbStoreDatabase& iDatabase; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class RDbStoreWriteStream : public RStoreWriteStream sl@0: { sl@0: public: sl@0: enum TType {EMixed,EBinary,EText}; sl@0: public: sl@0: inline RDbStoreWriteStream(CDbStoreDatabase& aDatabase) sl@0: :iDatabase(aDatabase) sl@0: {} sl@0: void FilterL(TType aType,TUint32 aInit); sl@0: private: sl@0: CDbStoreDatabase& iDatabase; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class MDbStreamFilter sl@0: { sl@0: public: sl@0: virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType) =0; sl@0: virtual MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType) =0; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: NONSHARABLE_CLASS(CDbStoreCompression) : public CBase, public MDbStreamFilter sl@0: { sl@0: public: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TEncoding sl@0: { sl@0: public: sl@0: enum {ELiterals=256,ELengths=28,ESpecials=1,EDistances=44}; sl@0: enum {ELitLens=ELiterals+ELengths+ESpecials}; sl@0: enum {EEos=ELiterals+ELengths}; sl@0: public: sl@0: TUint32 iLitLen[ELitLens]; sl@0: TUint32 iDistance[EDistances]; sl@0: }; sl@0: public: sl@0: static CDbStoreCompression* NewL(); sl@0: // sl@0: void EncodeL(); sl@0: inline void Inflate(); sl@0: void ExternalizeL(RWriteStream& aStream) const; sl@0: void InternalizeL(RReadStream& aStream); sl@0: // for MDbStreamFilter sl@0: MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreReadStream::TType aType); sl@0: MStreamBuf* FilterL(MStreamBuf* aHost,TUint32 aInit,RDbStoreWriteStream::TType aType); sl@0: private: sl@0: inline CDbStoreCompression(); sl@0: private: sl@0: enum TState {EAnalysis,EEncoding,EDecoding,EInflating}; sl@0: private: sl@0: TState iState; sl@0: TEncoding iEncoding[3]; sl@0: }; sl@0: sl@0: #include "US_STD.INL"