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: #if !defined(__D32TABLE_H__) sl@0: #define __D32TABLE_H__ sl@0: #if !defined(__D32DBAS_H__) sl@0: #include "D32DBAS.H" sl@0: #endif sl@0: #if !defined(__D32REC_H__) sl@0: #include "D32REC.H" sl@0: #endif sl@0: #if !defined(__D32CACHE_H__) sl@0: #include "D32CACHE.H" sl@0: #endif sl@0: sl@0: // classes defined in this file sl@0: class TDbGenerationMark; sl@0: class TDbColumnDef; sl@0: class HDbColumnSet; sl@0: class CDbTableIndexDef; sl@0: class RDbIndexes; sl@0: class RDbTableSchema; sl@0: class CDbTableDef; sl@0: class RDbTableRow; sl@0: class CDbTable; sl@0: class RDbTables; sl@0: class RDbTransaction; sl@0: class CDbTableDatabase; sl@0: sl@0: // classes also referenced sl@0: class CDbTableSource; sl@0: class CDbBlobCleanup; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: const TInt KDbTableMaxIndexes = 32; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CDbTableIndexDef : public CBase sl@0: { sl@0: friend class RDbIndexes; sl@0: public: sl@0: IMPORT_C CDbTableIndexDef(); sl@0: IMPORT_C ~CDbTableIndexDef(); sl@0: IMPORT_C void ConstructL( const TDesC& aName ); sl@0: inline const TDesC& Name() const; sl@0: inline const CDbKey& Key() const; sl@0: inline CDbKey& Key(); sl@0: private: sl@0: TSglQueLink iLink; sl@0: HBufC* iName; sl@0: CDbKey iKey; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class RDbIndexes sl@0: { sl@0: friend class CDbTableDef; sl@0: public: sl@0: inline void Add( CDbTableIndexDef* aDef ); sl@0: inline void Remove( CDbTableIndexDef* aDef ); sl@0: inline const TSglQueBase& AsQue() const; sl@0: CDbTableIndexDef* Find( const TDesC& aName ) const; sl@0: CDbTableIndexDef& FindL( const TDesC& aName ) const; sl@0: IMPORT_C TInt Count() const; sl@0: private: sl@0: inline RDbIndexes(); sl@0: void Close(); sl@0: private: sl@0: TSglQue iRep; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TDbColumnDef sl@0: { sl@0: public: sl@0: IMPORT_C void SetL( const TDbCol& aCol ); sl@0: IMPORT_C void SetL( const TDbColumnDef& aCol ); sl@0: void AsTDbCol( TDbCol& aColumn ) const; sl@0: inline TDbColType Type() const; sl@0: private: sl@0: // don't allow copies sl@0: void operator=( const TDbColumnDef& ); sl@0: public: sl@0: // flags used by AlterTable sl@0: enum { EDropped = 0x1, EChangedType = 0x2, EChangedLen = 0x4, EAdded = 0x8 }; sl@0: public: sl@0: HBufC* iName; sl@0: TInt iMaxLength; sl@0: TUint8 iType; sl@0: TUint8 iAttributes; sl@0: TUint8 iFlags; sl@0: TUint8 iReserved; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class HDbColumnSet sl@0: { sl@0: private: sl@0: enum { ELongColumns = 0x1, EAutoIncrement = 0x2 }; sl@0: public: sl@0: typedef TDbColumnDef* TIterator; sl@0: typedef const TDbColumnDef* TIteratorC; sl@0: public: sl@0: static HDbColumnSet* NewL( TInt aCount ); sl@0: ~HDbColumnSet(); sl@0: // sl@0: inline TIterator Begin(); sl@0: void Complete(); sl@0: IMPORT_C TInt Count() const; sl@0: inline TIteratorC Begin() const; sl@0: inline TIteratorC End() const; sl@0: inline const TDbColumnDef& operator[]( TDbColNo anIndex ) const; sl@0: IMPORT_C TIteratorC ColumnL( const TDesC& aColumn ) const; sl@0: inline TIterator ColumnL( const TDesC& aColumn ); sl@0: IMPORT_C TDbColNo ColNoL( const TDesC& aColumn ) const; sl@0: inline TBool HasLongColumns() const; sl@0: inline TBool HasAutoIncrement() const; sl@0: private: sl@0: HDbColumnSet( TInt aCount ); sl@0: const TIteratorC* IndexL() const; sl@0: private: sl@0: TUint iAttributes; sl@0: TIteratorC* iIndex; sl@0: const TDbColumnDef* const iEnd; sl@0: TDbColumnDef iColumns[1]; // at least one sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CDbTableDef : public CBase sl@0: { sl@0: friend class RDbTableSchema; sl@0: public: sl@0: IMPORT_C ~CDbTableDef(); sl@0: inline const TDesC& Name() const; sl@0: inline HDbColumnSet& Columns(); sl@0: inline const HDbColumnSet& Columns() const; sl@0: inline RDbIndexes& Indexes(); sl@0: inline const RDbIndexes& Indexes() const; sl@0: IMPORT_C virtual void Changed(); sl@0: // sl@0: inline const CDbTableIndexDef* Key( const TDesC& aColumn ) const; sl@0: inline TBool IsIndexed( const TDesC& aColumn ) const; sl@0: // sl@0: virtual void AlteredColumnSetL( HDbColumnSet& aSet, const CDbColSet& aChange, const CDbColSet& aAdd ) = 0; sl@0: void ExchangeColumnSet( HDbColumnSet* aSet ); sl@0: protected: sl@0: IMPORT_C CDbTableDef(); sl@0: IMPORT_C void ConstructL( const TDesC& aName, TInt aColumnCount ); sl@0: private: sl@0: const CDbTableIndexDef* FindKey( const TDesC& aColumn, TBool aFirstColumn ) const; sl@0: private: sl@0: TSglQueLink iLink; sl@0: HBufC* iName; sl@0: HDbColumnSet* iColumns; sl@0: RDbIndexes iIndexes; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class RDbTableSchema sl@0: { sl@0: friend class CDbTableDatabase; sl@0: public: sl@0: inline void Loaded(); sl@0: inline operator TSglQueBase&(); sl@0: inline void Add( CDbTableDef* aDef ); sl@0: // sl@0: inline TBool IsEmpty() const; sl@0: CDbTableDef* Find( const TDesC& aTable ); sl@0: CDbTableDef& FindL( const TDesC& aTable ); sl@0: private: sl@0: inline RDbTableSchema(); sl@0: void Close(); sl@0: // sl@0: inline TBool IsLoaded() const; sl@0: void Discard(); sl@0: inline void Remove( CDbTableDef* aDef ); sl@0: private: sl@0: TSglQue iRep; sl@0: TBool iLoaded; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: typedef TUint TDbGeneration; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class TDbGenerationMark sl@0: { sl@0: public: sl@0: inline void Construct( const TDbGeneration& aGeneration ); sl@0: inline void Mark(); sl@0: inline TBool Changed() const; sl@0: private: sl@0: const TDbGeneration* iGeneration; sl@0: TDbGeneration iMark; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CDbTable : public CBase sl@0: { sl@0: friend class RDbTables; sl@0: public: sl@0: class TValid; sl@0: friend class TValid; sl@0: enum { EUnavailableSpan = -1, EFullIndexSpan = 100 }; sl@0: protected: sl@0: IMPORT_C CDbTable( CDbTableDatabase& aDatabase, const CDbTableDef& aDef ); sl@0: IMPORT_C ~CDbTable(); sl@0: public: sl@0: void Open(); sl@0: void Close(); sl@0: void FlushL(); sl@0: void Abandon(); sl@0: void Release(); sl@0: void Idle(); sl@0: // sl@0: inline TBool IsActive() const; sl@0: inline TBool IsIdle() const; sl@0: inline const CDbTableDef& Def() const; sl@0: inline CDbTableDatabase& Database(); sl@0: // sl@0: inline const TDbGeneration& Generation() const; sl@0: TBool ExistsL( TDbRecordId aRecordId ); sl@0: void NewRowL( RDbRow& aRow ); sl@0: void ReadRowL( RDbRow& aRow, TDbRecordId aRecordId ); sl@0: void PrepareReplaceL( const RDbTableRow& aRow, TDbRecordId aRecordId ); sl@0: void ReplaceRowL( RDbTableRow& aRow, TDbRecordId aRecordId ); sl@0: void PrepareAppendL( const RDbTableRow& aRow ); sl@0: TDbRecordId AppendRowL( const RDbTableRow& aRow ); sl@0: void DeleteRowL( RDbTableRow& aRow, TDbRecordId aRecordId ); sl@0: void DuplicateBlobsL( RDbRow& aRow ); sl@0: IMPORT_C void DiscardBlobsL( RDbRow& aRow ); sl@0: // sl@0: IMPORT_C CDbRecordSpace& RecordsL(); sl@0: IMPORT_C CDbRecordIndex& IndexL( const CDbTableIndexDef& anIndex ); sl@0: IMPORT_C CDbBlobSpace* BlobsL(); sl@0: virtual CDbRecordIndex* RecordIndexL( const CDbTableIndexDef& anIndex ) = 0; sl@0: // sl@0: CDbRecordIter* IteratorL(); sl@0: IMPORT_C virtual TInt IndexSpanL( const CDbTableIndexDef& aIndex, TUint aInclusion, const TDbLookupKey* aLowerBound, const TDbLookupKey* aUpperBound ); sl@0: CDbRecordIter* IteratorL( const CDbTableIndexDef& aIndex, TUint aInclusion = 0, const TDbLookupKey* aLowerBound = 0, const TDbLookupKey* aUpperBound = 0 ); sl@0: CDbRecordIter* IteratorL( const TDesC& aIndex ); sl@0: private: sl@0: typedef void ( *TBlobFuncL )( CDbBlobSpace& aBlobStore, TDbBlob& aBlob, TDbColType aType, CDbBlobCleanup* aCleanup ); sl@0: private: sl@0: inline void Discard(); sl@0: void Disconnect(); sl@0: inline TBool InUse() const; sl@0: inline RDbCache& Cache(); sl@0: // sl@0: void ApplyToBlobsL( RDbRow& aRow, TBlobFuncL aFuncL, CDbBlobCleanup* aCleanup = 0 ); sl@0: void ApplyToComponentsL( void ( *anOperationL )( CDbRecordBase* ) ); sl@0: void EnsureIndexesL(); sl@0: void ValidateL( const RDbRow& aRow ); sl@0: void CheckInliningL( RDbRow& aRow ); sl@0: void DoReplaceRowL( const RDbRow& aRow, TDbRecordId aRecordId ); sl@0: // sl@0: virtual CDbRecordSpace* RecordSpaceL() = 0; sl@0: virtual CDbBlobSpace* BlobSpaceL() = 0; sl@0: // sl@0: virtual void CopyToRowL( RDbRow& aRow, const TDesC8& aRecord ) = 0; sl@0: virtual TInt RecordLength( const RDbRow& aRow ) = 0; sl@0: virtual void CopyFromRow( TUint8* aRecord, const RDbRow& aRow ) = 0; sl@0: private: sl@0: enum { EIdle = -1, ECached = -2 }; sl@0: private: sl@0: TSglQueLink iLink; sl@0: TInt iRef; sl@0: CDbTableDatabase* iDatabase; sl@0: const CDbTableDef* iDef; sl@0: TDbGeneration iGeneration; sl@0: CDbRecordSpace* iRecords; sl@0: CDbBlobSpace* iBlobs; sl@0: CDbRecordIndex* iIndexes[KDbTableMaxIndexes]; sl@0: CDbRecordIndex** iIndexesEnd; sl@0: TUint32 iUpdateMap; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class RDbTableRow : public RDbRow sl@0: { sl@0: public: sl@0: inline RDbTableRow(); sl@0: void Open( CDbTable* aTable ); sl@0: void Close(); sl@0: // sl@0: inline CDbTable& Table() const; sl@0: IMPORT_C void ReadL( TDbRecordId aRecordId ); sl@0: void NewL( TDbRecordId aCopyRecord ); sl@0: void PrepareAppendL(); sl@0: TDbRecordId AppendL(); sl@0: void PrepareReplaceL(); sl@0: TDbRecordId ReplaceL(); sl@0: void DeleteL( TDbRecordId aRecordId ); sl@0: private: sl@0: TDbGenerationMark iMark; sl@0: TDbRecordId iRecord; sl@0: CDbTable* iTable; sl@0: }; sl@0: sl@0: /** sl@0: implementation class sl@0: @internalComponent sl@0: */ sl@0: class RDbTables sl@0: { sl@0: public: sl@0: inline RDbTables(); sl@0: void Close(); sl@0: // sl@0: inline TBool IsEmpty() const; sl@0: inline void Add( CDbTable& aTable ); sl@0: inline void Remove( CDbTable& aTable ); sl@0: CDbTable* Find( const TDesC& aTable ); sl@0: inline operator TSglQueBase&(); sl@0: private: sl@0: TSglQue iRep; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: enum TDbLockType { EDbReadLock = 0, EDbXReadLock, EDbWriteLock, EDbCompactLock, EDbRecoveryLock, EDbSchemaLock }; sl@0: sl@0: /** sl@0: implementation class sl@0: @internalComponent sl@0: */ sl@0: class RDbTransaction sl@0: { sl@0: private: sl@0: class CNotifier; sl@0: friend class CNotifier; sl@0: public: sl@0: inline RDbTransaction(); sl@0: inline void Open( CDbTableDatabase& aDatabase ); sl@0: void Close(); sl@0: // sl@0: inline const TDbGeneration& RollbackGeneration() const; sl@0: inline CDbTableDatabase& Database(); sl@0: // sl@0: void BeginL( const CDbObject& aObject ); sl@0: void CommitL( const CDbObject& aObject ); sl@0: void Rollback( const CDbObject& aObject ); sl@0: // sl@0: void ReadPrepareL( const CDbObject& aObject ); sl@0: void ReadBegin( const CDbObject& aObject ); sl@0: void ReadRelease( const CDbObject& aObject ); sl@0: // sl@0: void DMLCheckL(); sl@0: void DMLPrepareL( const CDbObject& aObject ); sl@0: void DMLBegin(); sl@0: void DMLTouch(); sl@0: void DMLBeginLC(); sl@0: void DMLCommitL(); sl@0: void DMLRollback(); sl@0: // sl@0: void DDLPrepareL( const CDbObject& aObject ); sl@0: void DDLBegin(); sl@0: void DDLBeginLC(); sl@0: void DDLCommitL(); sl@0: void DDLRollback(); sl@0: // sl@0: void UtilityPrepareL( const CDbObject& aObject ); sl@0: void UtilityBegin( CDbDatabase::TUtility aType ); sl@0: void UtilityCommitL(); sl@0: void UtilityRollback(); sl@0: // sl@0: inline TBool IsLocked() const; sl@0: inline void ReadyL() const; sl@0: TBool InTransaction( const CDbObject& aObject ); sl@0: // sl@0: CDbNotifier* NotifierL(); sl@0: #ifdef _ASSERTIONS sl@0: void _Invariant() const; sl@0: #endif sl@0: private: sl@0: typedef const CDbContext* THolder; sl@0: struct TLock sl@0: { sl@0: THolder iHolder; sl@0: TUint iState; sl@0: }; sl@0: enum { ELockListGranularity = 4 }; sl@0: enum { ETransactionLock = 0x80000000 }; sl@0: enum { EState = 0x7f, EFailed = 0x80 }; sl@0: enum { EMaxLock = 255 }; sl@0: private: sl@0: inline TDbLockType LockState() const; sl@0: void PrepareSLockL( const CDbObject& aObject, TUint aInitState ); sl@0: void PrepareXLockL( const CDbObject& aObject ); sl@0: void Unlock( RDbNotifier::TEvent aEvent ); sl@0: void Unlock( TLock& aLock ); sl@0: TLock* GetLock( const CDbObject& aObject ); sl@0: void Event( RDbNotifier::TEvent aEvent ); sl@0: // sl@0: void DoCommitL(); sl@0: void DoRollback(); sl@0: static void DMLAbandon( TAny* aPtr ); sl@0: static void DDLAbandon( TAny* aPtr ); sl@0: private: sl@0: CDbTableDatabase* iDatabase; sl@0: TUint8 iAction; sl@0: TUint8 iLockState; sl@0: TUint8 iLockCount; sl@0: TUint8 iMaxLock; sl@0: TInt iUpdaters; sl@0: TLock iPrimary; sl@0: TLock* iSharers; sl@0: TDbGeneration iRollback; sl@0: CNotifier* iNotifier; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CDbTableDatabase : public CBase sl@0: { sl@0: private: sl@0: class CIncremental; sl@0: class CIncrementalDDL; sl@0: class CCreateIndex; sl@0: class CDropIndex; sl@0: class CDropTable; sl@0: class CAlterTable; sl@0: class CUtility; sl@0: class CInterface; sl@0: class CSource; sl@0: // sl@0: friend class RDbTransaction; sl@0: friend class CInterface; sl@0: friend class CSource; sl@0: friend class CDbTable; sl@0: friend class CIncremental; sl@0: public: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CStepper : public CBase sl@0: { sl@0: protected: sl@0: CStepper() {} sl@0: public: sl@0: virtual TInt StepL( TInt aStep ) = 0; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CMultiStepper : public CStepper sl@0: { sl@0: private: sl@0: struct SStepper sl@0: { sl@0: CStepper* iStepper; sl@0: TInt iStep; sl@0: }; sl@0: public: sl@0: ~CMultiStepper(); sl@0: IMPORT_C static CMultiStepper* NewL( TInt aStepperCount ); sl@0: IMPORT_C void AddStepper( CStepper* aStepper, TInt aSteps ); sl@0: IMPORT_C TInt TotalSteps(); sl@0: TInt StepL( TInt aStep ); sl@0: private: sl@0: inline CMultiStepper( TInt aStepperCount ); sl@0: private: sl@0: SStepper* iStepper; sl@0: SStepper* iEnd; sl@0: SStepper iSteppers[1]; // one or more sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: class CBuildIndex : public CStepper sl@0: { sl@0: private: sl@0: enum { ERecordsPerStep = 16 }; sl@0: public: sl@0: IMPORT_C static CBuildIndex* NewL( CDbTableDatabase& aDatabase, const CDbTableDef& aTable, const CDbTableIndexDef& anIndex ); sl@0: ~CBuildIndex(); sl@0: IMPORT_C static TInt Steps( TInt aCardinality ); sl@0: inline CDbRecordIndex& Index(); sl@0: IMPORT_C TInt StepsL(); sl@0: // from CStepper sl@0: TInt StepL( TInt aStep ); sl@0: private: sl@0: CBuildIndex(); sl@0: private: sl@0: CDbTableSource* iSource; sl@0: TDbPosition iNext; sl@0: CDbRecordIndex* iIndex; sl@0: }; sl@0: protected: sl@0: IMPORT_C CDbTableDatabase(); sl@0: IMPORT_C ~CDbTableDatabase(); sl@0: public: sl@0: inline RDbTransaction& Transaction(); sl@0: // sl@0: IMPORT_C CDbDatabase* InterfaceL(); sl@0: IMPORT_C CDbSource* SourceL(); sl@0: // sl@0: inline RDbTableSchema& Schema(); sl@0: IMPORT_C RDbTableSchema& SchemaL(); sl@0: // sl@0: CDbTableSource* TableSourceL( const TDesC& aTableName ); sl@0: void Release( const CDbTableDef& aDef ); sl@0: // framework functions sl@0: virtual CStepper* TableAlterL( CDbTableDef& aTable, const HDbColumnSet& aNewSet, TInt& aStep ) = 0; sl@0: virtual CStepper* RecordDiscarderL( const CDbTableDef& aTable, TInt& aStep ) = 0; sl@0: virtual CStepper* IndexDiscarderL( const CDbTableDef& aTable, const CDbTableIndexDef& anIndex, TInt& aStep ) = 0; sl@0: IMPORT_C virtual CStepper* UtilityL( CDbDatabase::TUtility aType, TInt& aStep ); sl@0: protected: sl@0: // framework sl@0: IMPORT_C virtual TInt Property( CDbDatabase::TProperty aProperty ); sl@0: private: sl@0: //framework sl@0: virtual void AuthenticateL() = 0; sl@0: IMPORT_C virtual void Idle(); sl@0: virtual void LoadSchemaL() = 0; sl@0: virtual void SynchL( TDbLockType aLock ) = 0; sl@0: virtual void Revert( TDbLockType aLock ) = 0; sl@0: virtual CDbTable* TableL( const CDbTableDef& aDef ) = 0; sl@0: virtual CDbTableDef* CreateTableL( const TDesC& aName, const CDbColSet& aColSet, const CDbKey* aPrimaryKey ) = 0; sl@0: virtual CDbTableIndexDef* CreateIndexL( const CDbTableDef& aTable, const TDesC& aName, const CDbKey& aKey ) = 0; sl@0: virtual void DestroyL() = 0; sl@0: // sl@0: inline void Open(); sl@0: void Close(); sl@0: inline void AddTable( CDbTable& aTable ); sl@0: void RemoveTable( CDbTable& aTable ); sl@0: // sl@0: void CheckIdle(); sl@0: void FlushL( TDbLockType aLock ); sl@0: void Abandon( TDbLockType aLock ); sl@0: void Release(); sl@0: sl@0: void DoCreateTableL( const TDesC& aName, const CDbColSet& aColSet, const CDbKey* aPrimaryKey ); sl@0: CIncremental* OpenCreateIndexL( const TDesC& aName, const TDesC& aTable, const CDbKey& aKey, TInt& aStep ); sl@0: CIncremental* OpenDropIndexL( const TDesC& aName, const TDesC& aTable, TInt& aStep ); sl@0: CIncremental* OpenDropTableL( const TDesC& aTable, TInt& aStep ); sl@0: CIncremental* OpenAlterTableL( const TDesC& aTable, const CDbColSet& aNewDef, TInt& aStep ); sl@0: CDbCursor* PrepareViewL( const TDbQuery& aQuery, const TDbWindow& aWindow, RDbRowSet::TAccess anAccess ); sl@0: CDbCursor* PrepareTableL( const TDesC& aTable, RDbRowSet::TAccess anAccess ); sl@0: // reserved virtual function space sl@0: IMPORT_C virtual void Reserved_1(); sl@0: IMPORT_C virtual void Reserved_2(); sl@0: private: sl@0: TInt iRef; sl@0: RDbCache iCache; sl@0: RDbTransaction iTransaction; sl@0: RDbTableSchema iSchema; sl@0: RDbTables iTables; sl@0: }; sl@0: sl@0: #include "D32TABLE.INL" sl@0: #endif